Reputation: 85
For Each cell In wb.Sheets("RP Analysis").Range("F5:F" & lastRow)
structure = "Layer " & WorksheetFunction.RoundDown(cell.Value, 2) & ": " & WorksheetFunction.RoundDown(cell.Offset(0, 2).Value / 1000000, 2) & " xs " & WorksheetFunction.RoundDown(cell.Offset(0, 3).Value / 1000000, 2) & " attaches at "
RMS = RMS & structure & WorksheetFunction.RoundDown(cell.Offset(0, 10).Value, 2) & "m and exhausts at " & WorksheetFunction.RoundDown(cell.Offset(0, 11).Value, 2) & "m" & vbLf
AIR = AIR & structure & WorksheetFunction.RoundDown(cell.Offset(0, 6).Value, 2) & "m and exhausts at " & WorksheetFunction.RoundDown(cell.Offset(0, 7).Value, 2) & "m" & vbLf
Next cell
For Each cell In wb.Sheets("RP Analysis").Range("A9:A" & 19)
gucurve = gucurve & cell.Value & ":- " & Format(cell.Offset(0, 2).Value / cell.Offset(0, 1).Value, "Percent") & vbLf
Next cell
TextBox1.Value = "RP years RMS/AIR difference" & vbLf & gucurve & vbLf & "AIR" & vbLf & AIR & vbLf & "RMS" & vbLf & RMS
This produces
Layer 1: 25 xs 50 attaches at 8.16m and exhausts at 10.4m
Layer 2: 100 xs 75 attaches at 10.4m and exhausts at 20.15m
Layer 3: 44 xs 175 attaches at 20.15m and exhausts at 24.96m
Layer 4: 144 xs 175 attaches at 20.15m and exhausts at 34.86m
I want it to produce
Layer 1: 25 xs 50 attaches at 8.16m and exhausts at 10.4m
Layer 2:100 xs 75 attaches at 10.4m and exhausts at 20.15m
Layer 3: 44 xs 175 attaches at 20.15m and exhausts at 24.96m
Layer 4:144 xs 175 attaches at 20.15m and exhausts at 34.86m
So I think I need fixed columns with defined widths with everything right centered. The numbers won't be more than 4 digits ever
How do I go about this?
Upvotes: 4
Views: 1204
Reputation: 5040
One method is to create your own function that returns fixed length strings. The below takes a string and prefixes with as many spaces as needed to hit the required length. Oversized strings are not trimmed, but this would be a simple change if required.
Public Function Pad(ByVal OriginalString As String, ByVal RequiredLength As Integer) As String
' Prefixes the passed string with spaces, to return a fixed width string.
' Check padding required.
If RequiredLength > Len(OriginalString) Then
' Required, prefix with spaces.
Pad = Space(RequiredLength - Len(OriginalString)) & OriginalString
Else
' Padding not required, return original value.
Pad = OriginalString
End If
End Function
You would call this function like so:
..."Layer " & Pad(WorksheetFunction.RoundDown(cell.Value, 2), 10) &...
EDIT
@Michael posted a much neater approach. I wanted to rewrite my pad function using his code. At one line; the body of the function is now much easier to debug/follow. I'd forgotten just how flexible VBA's format function is.
Public Function Pad(ByVal OriginalString As String, ByVal RequiredLength As Integer) As String
' Prefixes the passed string with spaces, to return a fixed width string.
Pad = Format(OriginalString, String(RequiredLength, "@"))
End Function
Upvotes: 1
Reputation: 949
You could use Format
with the @
symbol to pad and align each value on the right:
Format("123", "@@@@@@@@@@") ' returns " 123"
Or on the left :
Format("123", "!@@@@@@@@@@") ' returns "123 "
And by providing the number of characters:
Format("123", String(25, "@")) ' returns " 123"
Upvotes: 3
Reputation: 22205
I've found that the easiest code to maintain for column formatting is just building the output with fixed width strings. They will default to left aligned if you assign with =
or use LSet
. You can right align them by using RSet
. Also keep in mind that a fixed length string will truncate if you try to assign a string that is longer than it can hold.
Example:
Private Function ToColumns(layer As Long, percent As Long, xs As Long, attach As Double, _
exhaust As Double) As String
Dim col1 As String * 1 'Change the widths here to adjust your columns.
Dim col2 As String * 3
Dim col3 As String * 3
Dim col4 As String * 5
Dim col5 As String * 5
RSet col1 = layer
RSet col2 = percent
RSet col3 = xs
RSet col4 = Format$(attach, "#.##")
RSet col5 = Format$(exhaust, "#.##")
ToColumns = "Layer " & col1 & ":" & _
col2 & " xs " & _
col3 & " attaches at " & _
col4 & "m and exhausts at " & _
col5 & "m"
End Function
Usage:
Debug.Print ToColumns(1, 25, 50, 8.16, 10.4)
Debug.Print ToColumns(2, 100, 75, 10.4, 20.15)
Output:
Layer 1: 25 xs 50 attaches at 8.16m and exhausts at 10.4m
Layer 2:100 xs 75 attaches at 10.4m and exhausts at 20.15m
Note that as mentioned by other posters, if you are displaying this in UI you'll need a monospace font.
Upvotes: 1
Reputation:
Reference: Monospaced font
You need to use a monospaced font, also called a fixed-pitch, fixed-width, or non-proportional font, is a font whose letters and characters each occupy the same amount of horizontal space. This contrasts with variable-width fonts, where the letters and spacings have different widths.
Reference: Microsoft-Supplied Monospaced TrueType Fonts
The only monospaced TrueType fonts shipped by Microsoft are Courier New, which shipped with Windows 3.1, and Lucida Sans Typewriter, which was included in the TrueType Font Pack. All other TrueType fonts included with Windows 3.1 and the TrueType Font Pack are proportional fonts.
Upvotes: 0