#excel #vba #events #combobox #worksheet
#excel #vba #Мероприятия #выпадающий список #рабочий лист
Вопрос:
Я создаю набор выпадающих списков динамически на листе Excel, но мне нужен только один общий метод «Действия» для них всех. Я получаю данные с одного рабочего листа для заполнения комбинаций на основном рабочем листе
Мой код приведен ниже, но я не могу получить доступ к каждому отдельному выпадающему списку при срабатывании события (оно срабатывает). Есть ли способ узнать, какой выпадающий список был запущен? Даже если это просто индекс, или имя, или что-то в этом роде, поэтому я могу пойти и найти соответствующий выпадающий список. (Всего количество комбинаций будет 200, и форма — это не то, что мы хотим здесь по другим причинам, поэтому она находится на листе.)
Option Explicit
Dim i As Integer
' This is used to programme the comboboxes
Private Sub GenerateComboboxes()
On Error GoTo ErrorHandler
Dim DestinationDataTypeCombo As Object, DestinationDataTextCombo As Object, oObject As Object
Dim ws As Worksheet, sString As String, rng As Range
Dim nCombos, nStartLine As Integer
Dim i2, iHeight, iLeft, iTop, iWidth As Integer
nCombos = 5
nStartLine = 2
Set ws = Worksheets("User Entry")
ws.Activate
'Clear what was there before
For Each oObject In ws.Shapes
oObject.Delete
Next
' add each combo to the worksheet
For i = 0 To nCombos - 1
sString = "D" amp; (i nStartLine)
Set rng = ws.Range(sString)
' Create a Combo instance
Set DestinationDataTypeCombo = ws.Shapes.AddFormControl(xlDropDown, _
Left:=rng.Left, _
Top:=rng.Top, _
Width:=rng.Width, _
Height:=rng.Height)
' Set up the properties
With DestinationDataTypeCombo
.ControlFormat.DropDownLines = 5
.Name = "cbDataType" amp; i
For i2 = 2 To 17
sString = Worksheets("Static Data").Cells(i2, 1)
.ControlFormat.AddItem sString
Next
' Set a generic OnAction for ALL combos to use
.OnAction = "cbDataType_Change"
End With
Next i
Exit Sub
ErrorHandler:
MsgBox Err.Description
End Sub
Public Sub cbDataType_Change()
On Error GoTo ErrorHandler
Dim sValue As String
'This works so I know the change event fires
MsgBox "Test"
' Want to get the value selected, this line errors
sValue = cbDataType.Value
MsgBox sValue
Exit Sub
ErrorHandler:
MsgBox Err.Description
End Sub
Ответ №1:
Ваш код создает раскрывающийся список формы. Тип элемента управления формой листа не предоставляет никаких событий…
Вы можете назначить ему макрос с любым именем, которое вы хотите (четным cbDataType_Change
), используя .OnAction
, как вы это делали.
Теперь используемый объект может быть возвращен, начиная с Application.Caller
, который возвращает имя элемента управления. На его основе можно задать объект управления, используя Sheet.Shapes
. И, наконец, значение такого элемента управления можно получить немного более сложным способом, используя объект OLEFormat.Object.list
. Итак, ваше Sub
назначение всем элементам управления должно быть таким:
Sub cbDataType_Change() 'this is not an event!
Dim cb As Object
Set cb = ActiveSheet.Shapes(Application.Caller) 'the object which called this Sub
Debug.Print cb.Name, cb.ControlFormat.Value 'returns the control name and its index
MsgBox cb.OLEFormat.Object.list(cb.ControlFormat.Value) 'the control value
End Sub