Excel VBA 工作表更改事件上的组合框

Excel VBA combobox on worksheet change event

我正在 Excel sheet 上动态创建一组组合框,但我只想为它们全部使用一个通用的“操作”方法。我从一个作品sheet中获取数据来填充主要作品sheet

上的连击

我的代码在下面,但是当事件触发时我无法访问每个单独的组合框(它确实触发了)。有没有办法知道触发了哪个组合框?即使它只是索引、名称或其他内容,这样我就可以找到相关的组合框。 (组合的数量总共将达到 200,并且由于其他原因,这里不是我们想要的形式,这就是为什么它在 sheet 中。)

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" & (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" & 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

您的代码创建了一个表单 Drop-Down 组合框。 Sheet 表单控件类型 不公开任何事件...

您可以为其指定一个宏,任意命名(甚至 cbDataType_Change),使用 .OnAction,就像您所做的那样。

现在,可以从 Application.Caller 开始返回使用的对象,其中 returns 控件名称。基于它,可以设置控制对象,使用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