bossman1111
bossman1111

Reputation: 85

Fixed Width Columns in Textbox VBA

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

Answers (4)

David Rushton
David Rushton

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

michael
michael

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

Comintern
Comintern

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

user6432984
user6432984

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

Related Questions