How to auto size listbox column

Irish_Griffin

Board Regular
Joined
Jan 16, 2009
Messages
138
Hello Everyone =-) Hope work / school / life is going well !! :biggrin:

I need to auto size the columns of an excel form listbox.
Thought this would be a matter of finding the longest string and then setting the column width value...... I wish :stickouttounge:

Below, each line of text has 10 characters
xxxxxxxxxx
AAAAAAAAAA
IIIIIIIIII
d8aDNksd9m
bla Blah a

As you can see, the string length is not related to the displayed text width. How can determine the display width value? Perhaps my NooBy-Ness is not aware of a list box option that does column auto sizing for me??

Helps is always appreciated!!
-Griff :help:
 

Excel Facts

Format cells as date
Select range and press Ctrl+Shift+3 to format cells as date. (Shift 3 is the # sign which sort of looks like a small calendar).
Griff

There is no autosize option, but why do you need one anyway?

I can only see that being needed if the listbox was multicolumn.

If it's just one column then all the items should be displayed without any need to change the column width.

Or am I missing something?:)
 
Upvote 0
Griff

There is no autosize option, but why do you need one anyway?

I can only see that being needed if the listbox was multicolumn.

If it's just one column then all the items should be displayed without any need to change the column width.

Or am I missing something?:)


Hi Norie!!
Yep, multi-column list box, where one column is expected to go from 5 characters to 100 ..... just how the data is... ya know =-P

I want to size the form according to the typical string size, and yet capable of showing more when needed.

I was hoping there is some "Text width" function that outputed my value .....

Ohhh!!! *** LIGHT-BULB<light bulb=""> ***
How about an invisible label box, I drop the data into, then look at the label and record the width??? Sounds like it would hurt performance tho.... not to mention the Junkyness of the code method.</light>
 
Upvote 0
You could try using a fixed-width font in the listbox?
 
Upvote 0
Griff

Are you sure a listbox is the best control to be using here?

PS I really don't see where you are going with the 'invisible' label idea.

If you wanted to find the longest string in the data then why not just loop through it?

You could then use the result of that to resize the column.

You are probably partly right about performance impact, but I would be more worried about how exactly you would calculate the column width.

That could be dependent on all sort of factors - font type, font size, screen resolution etc.:)
 
Upvote 0
You could try using a fixed-width font in the listbox?

This is probably the best solution. Didn't even ocure to me. So like system font right?

If it's fixed width, then max string length is all I need.

Cool, I'll provide more details when I'm successful!! :biggrin:

Thanks!
- Griff
 
Upvote 0
You could also use a ListView instead, since that, IIRC, allows the user to resize the columns if required.
 
Upvote 0
Function to autosize Listbox and Combobox Columns and optionally the control's width itself.

VBA Code:
Function ControlsResizeColumns(LBox As MSForms.Control, Optional ResizeListbox As Boolean)
 Application.ScreenUpdating = False
    Dim ws As Worksheet
    If sheetExists("ListboxColumnWidth", ThisWorkbook) = False Then
        Set ws = ThisWorkbook.Worksheets.Add
        ws.Name = "ListboxColumnwidth"
    Else
        Set ws = ThisWorkbook.Worksheets("ListboxColumnwidth")
        ws.Cells.Clear
    End If
    '---Listbox/Combobox to range-----
    Dim rng As Range
    Set rng = ThisWorkbook.Sheets("ListboxColumnwidth").Range("A1")
    Set rng = rng.Resize(UBound(LBox.List) + 1, LBox.ColumnCount)
    rng = LBox.List
    rng.Characters.Font.Name = UserForm1.ListBox1.Font.Name
    rng.Characters.Font.Size = UserForm1.ListBox1.Font.Size
    rng.Columns.AutoFit
    
    '---Get ColumnWidths------
    rng.Columns.AutoFit
    Dim sWidth As String
    Dim vR() As Variant
    Dim n As Integer
    Dim cell As Range
    For Each cell In rng.Resize(1)
        n = n + 1
        ReDim Preserve vR(1 To n)
        vR(n) = cell.EntireColumn.Width + 10 'if not some extra space it cuts a bit off the tail
    Next cell
    sWidth = Join(vR, ";")
    Debug.Print sWidth

    '---assign ColumnWidths----
    With LBox
        .ColumnWidths = sWidth
        '.RowSource = "A1:A3"
        .BorderStyle = fmBorderStyleSingle
    End With

    
    '----Optionaly Resize Listbox/Combobox--------
    If ResizeListbox = True Then
        Dim w As Long
        For i = LBound(vR) To UBound(vR)
            w = w + vR(i)
        Next
        DoEvents
        LBox.Width = w + 10
    End If
        
    'remove worksheet
    Application.DisplayAlerts = False
    ws.Delete
    Application.DisplayAlerts = True
    
    Application.ScreenUpdating = True
End Function

Function sheetExists(sheetToFind As String, Optional InWorkbook As Workbook) As Boolean
    If InWorkbook Is Nothing Then Set InWorkbook = ThisWorkbook
    On Error Resume Next
    sheetExists = Not InWorkbook.Sheets(sheetToFind) Is Nothing
End Function
 
Upvote 0
Function to autosize Listbox and Combobox Columns and optionally the control's width itself.

VBA Code:
Function ControlsResizeColumns(LBox As MSForms.Control, Optional ResizeListbox As Boolean)
 Application.ScreenUpdating = False
    Dim ws As Worksheet
    If sheetExists("ListboxColumnWidth", ThisWorkbook) = False Then
        Set ws = ThisWorkbook.Worksheets.Add
        ws.Name = "ListboxColumnwidth"
    Else
        Set ws = ThisWorkbook.Worksheets("ListboxColumnwidth")
        ws.Cells.Clear
    End If
    '---Listbox/Combobox to range-----
    Dim rng As Range
    Set rng = ThisWorkbook.Sheets("ListboxColumnwidth").Range("A1")
    Set rng = rng.Resize(UBound(LBox.List) + 1, LBox.ColumnCount)
    rng = LBox.List
    rng.Characters.Font.Name = UserForm1.ListBox1.Font.Name
    rng.Characters.Font.Size = UserForm1.ListBox1.Font.Size
    rng.Columns.AutoFit
   
    '---Get ColumnWidths------
    rng.Columns.AutoFit
    Dim sWidth As String
    Dim vR() As Variant
    Dim n As Integer
    Dim cell As Range
    For Each cell In rng.Resize(1)
        n = n + 1
        ReDim Preserve vR(1 To n)
        vR(n) = cell.EntireColumn.Width + 10 'if not some extra space it cuts a bit off the tail
    Next cell
    sWidth = Join(vR, ";")
    Debug.Print sWidth

    '---assign ColumnWidths----
    With LBox
        .ColumnWidths = sWidth
        '.RowSource = "A1:A3"
        .BorderStyle = fmBorderStyleSingle
    End With

   
    '----Optionaly Resize Listbox/Combobox--------
    If ResizeListbox = True Then
        Dim w As Long
        For i = LBound(vR) To UBound(vR)
            w = w + vR(i)
        Next
        DoEvents
        LBox.Width = w + 10
    End If
       
    'remove worksheet
    Application.DisplayAlerts = False
    ws.Delete
    Application.DisplayAlerts = True
   
    Application.ScreenUpdating = True
End Function

Function sheetExists(sheetToFind As String, Optional InWorkbook As Workbook) As Boolean
    If InWorkbook Is Nothing Then Set InWorkbook = ThisWorkbook
    On Error Resume Next
    sheetExists = Not InWorkbook.Sheets(sheetToFind) Is Nothing
End Function
Hi, @alexofrhodes, I know this post is a few years old, but I just came across it and have used it in a project I'm working on. For the most part, the code works fine, but I've got a couple of questions.

I copied your code almost exactly. The only changes I made were (a) removing the optional resize of the listbox; (b) removing the border style; and (c) replacing 'UserForm1.ListBox1' with 'frmNewStudentReg.lstDatabase'. In the Sub, I have the code line 'Call ControlsResizeColumns(lstDatabase)'.

First, the column width setting doesn't seem to take into account the header row:
1653829710852.png

Notice that the headers for columns 1 (Index), 3 (Microsoft), 4 (Headway), 5 (Leerlingnummer), 6 (Gesprekdatum), and 9 (Instapjaar) are all cut off. (And this happens also for a number of other columns in the database.) The headers are in the worksheet 'Database' in row 1. Any idea why it's not considering the lengths of the headers when setting the column widths?

Second, after around 10 or so columns, I notice that the alignment starts going off, and it gets progressively worse as it goes along:
1653830228328.png

Notice that the first character of 'GSM-nummerLL' is just under the column line, and by the time it gets to 'PostCd', the first character is left of the column line. By the end of the database:
1653830374032.png

You can see that the first character starts well before the column line. The first 'trein', for example, should be under the first 'Vervoer' heading, but it's entirely under the previous header. 'Moeder, vader' should be under the column 'Ophalen', and the email addresses should be under the column 'SI Email'. Any idea why this is happening and how to fix it?

Thanks!
Cheers,
Tyler
 
Upvote 0
Hey Tyler.
This may occur because of differenct Font and FontSize between the control and the range.
I'll have a look.
 
Upvote 0

Forum statistics

Threads
1,223,406
Messages
6,171,927
Members
452,434
Latest member
NUC_N_FUTS2

We've detected that you are using an adblocker.

We have a great community of people providing Excel help here, but the hosting costs are enormous. You can help keep this site running by allowing ads on MrExcel.com.
Allow Ads at MrExcel

Which adblocker are you using?

Disable AdBlock

Follow these easy steps to disable AdBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the icon in the browser’s toolbar.
2)Click on the "Pause on this site" option.
Go back

Disable AdBlock Plus

Follow these easy steps to disable AdBlock Plus

1)Click on the icon in the browser’s toolbar.
2)Click on the toggle to disable it for "mrexcel.com".
Go back

Disable uBlock Origin

Follow these easy steps to disable uBlock Origin

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back

Disable uBlock

Follow these easy steps to disable uBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back
Back
Top