4

I'm struggling to set up a combobox (in Excel VBA) in such a way that its width is automatically adjusted according to the length of the longest string that it contains.

I'm trying to create a drop-down list (using a combobox in a form named "WorksheetSelectionForm") that, once a particular workbook is opened, appears on screen and allows the user to select which of the workbook's worksheets they wish to open.

I want the width of the combobox to adjust to the length of the longest text string in the drop-down list. Currently my drop-down list contains three items (the names of the worksheets that currently exist in the workbook). They are the following:

  • "Profit and loss account" (23 characters)
  • "Balance sheet" (13 characters)
  • "Cashflow report" (15 characters)

More worksheets could be added to the workbook and hence more items added to the drop-down list, hence why I don't want to simply fix the combobox's width at 23 points (the length of what's currently the longest string in the drop-down list).

I've been referring to the following thread from OzGrid for ideas (see entry #3): http://www.ozgrid.com/forum/showthread.php?t=55098. Their proposed solution is given below:

Dim iWidth As Double 
ComboBox1.AutoSize = True 
iWidth = 0 

For i = 0 To ComboBox1.ListCount - 1 
    ComboBox1.ListIndex = i 
    If iWidth < ComboBox1.Width Then 
        iWidth = ComboBox1.Width 
    End If 
Next 

ComboBox1.Width =  iWidth 
ComboBOx1.AutoSize = False 
ComboBox1.ListCount = 0 

The problem with this solution is that the code ComboBox1.Width in the if-then statement doesn't actually seem to work out the length of the combobox item that's currently in focus in the for-next loop.

Below is the code that I've written so far:

Private Sub Workbook_Open()

Dim Sheet As Worksheet, CmBox As MSForms.ComboBox, LWidth As Double, i As Integer
Set CmBox = WorksheetSelectionForm.ComboBox_Worksheets
LWidth = 0

'Populate the drop-down list with the names of the worksheets
For Each Sheet In Worksheets
    CmBox.AddItem Sheet.Name
Next Sheet

'Find out the length of the longest string in the combobox
For i = 0 To CmBox.ListCount - 1
    CmBox.ListIndex = i
    If Len(CmBox.Value) > LWidth Then
        LWidth = Len(CmBox.Value)
    End If
Next i

'Set the combobox's width to the length of the longest string in the combobox
CmBox.ListWidth = LWidth

'Show the form on screen
WorksheetSelectionForm.Show

End Sub

This code, when run, doesn't seem to be setting the combobox's width as desired. It also generates a combobox that's missing all of its items (the names of the worksheets). Where have I gone wrong?

Below is the code for when an item in the combobox is selected by the user (just in case it's of use to you):

Private Sub ComboBox_Worksheets_Change()

'Activate the worksheet whose name has been selected in the combobox
Sheets(ComboBox_Worksheets.Value).Activate

'Close the form
Unload WorksheetSelectionForm

End Sub
Community
  • 1
  • 1
  • 1
    `hence why I don't want to simply fix the combobox's width at 23 points` Tom already given you a very good link to start with. However if you do not want to get into the complexity of the code then here is an alternative. The max characters that can go into the naming of the sheet is 32. Why not by default set that as the width keeping the font and it's size in mind. The only problem with this approach is that you will have to keep in mind different screen resolutions that your app may come across... – Siddharth Rout Aug 11 '14 at 20:58

2 Answers2

1

It's not too hard. It requires an API call. I've done it, but don't have the exact code with me, but this may do it. vb macro string width in pixel

If not, google these APIs:

  • GetCharABCWidths (for true type fonts)
  • GetChartABCWidthsFloat
  • GetCharWidth (probably the most useful one)
  • GetCharWidth32 (probably even more useful)
  • GetCharWidthFloat
Community
  • 1
  • 1
Tom Collins
  • 4,069
  • 2
  • 20
  • 36
0

i used your code for a start base, and this is the outcome:

Private Sub Workbook_Open()

Dim Sheet As Worksheet, CmBox As MSForms.ComboBox, LWidth As Double, i As Integer
dim Wb as workbook
load WorksheetSelectionForm
with WorksheetSelectionForm
    Set CmBox = .ComboBox_Worksheets
    'LWidth = 0

    'Populate the drop-down list with the names of the worksheets
    with cmBox
        .clear
        for each Wb in workbooks
            For Each Sheet In WB.Worksheets 'i wasn't sure your way works for filling the list, did you verify it ?, so i do it my way
                h = Sheet.Name
                .AddItem h
                if len(h)>Lwidth then LWidth = Len(h) 'no need to loop again when list is full
            Next Sheet
        next Wb
    end with

    'Find out the length of the longest string in the combobox
    'For i = 0 To CmBox.ListCount - 1
    '    tmp_Length = len(CmBox.List(i))    'this is an other way of doing it, without changing the cmBox value (could trigger events)
    '    If tmp_Length > LWidth Then
    '        LWidth = tmp_Length
    '    End If
    'Next i

    'Set the combobox's List's width to the length of the longest string in the combobox
    CmBox.ListWidth = LWidth*8 'according to the list's Text Font size , you will need to adjust the *8

    'Show the form on screen
    .Show
end with

End Sub

Patrick Lepelletier
  • 1,596
  • 2
  • 17
  • 24