问题
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
回答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
回答2:
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
来源:https://stackoverflow.com/questions/25250733/dynamically-adjusting-the-width-of-a-combobox-in-excel-vba