excel 在VBA中,是否有一个全局帧事件可以对单击其包含的任何对象做出React?

l2osamch  于 2023-02-05  发布在  React
关注(0)|答案(1)|浏览(129)

在EXCEL VBA中,创建一个包含2个框架的表单。每个框架中有20个控件按钮。该表单上总共有40个控件按钮。每一组20个控件都有一个简单的任务,即定义一个名为strLocation的全局字符串的值。
strLocation总共可以有40个不同的字符串值,每个按钮只有一行代码,例如:
strLocation= “Something”
仅当用户单击工作表中的某些特定单元格时,才会显示表单,其中某些条件定义了是否显示表单。如果不满足单元格的条件,表单将保持隐藏状态,用户可以继续执行其他任务。如果满足条件,则会显示表单,在2个框架中显示40个按钮。
用户任务是选择40个按钮中的一个,然后strLocation将被定义。(当40个按钮中的任何一个被单击时)将隐藏表单并将单元格值设置为strLocation字符串值。所有这些都工作得很好,除了我找不到如何触发一个事件来对40个按钮中的任何一个做出React。我想在表单代码中实现类似下面的内容:

Private Sub ( one event that would encompasses any of the 40 buttons being clicked )
    Selection = strLocation
    formLOCATION.Hide
End Sub

当然,我可以包含额外的40行代码,每个按钮代码一行,调用一个Sub来完成这项工作。我怀疑有一种更优雅的方式来捕获全局事件,该事件将与表单中包含的每个按钮或每个框架中包含的每个按钮相关。

由于框架是其所有对象的全局容器,因此是否不存在用于捕获对其所包含的任何对象的单击的事件?

类似于捕获任何单元格单击的EXCEL工作表或捕获任何工作表SheetActivate事件的EXCEL工作簿中可用的内容。

xxls0lw8

xxls0lw81#

你可以使用一个自定义类来创建一个框架中所有按钮的"控件数组"。参见(例如)https://bettersolutions.com/excel/macros/vba-control-arrays.htm
大概是这样的
在工作表代码模块中-如果在C3:C13中选择了单元格,则显示窗体

Private Sub Worksheet_SelectionChange(ByVal Target As Range)
    Dim frm As frmSelect, c As Range
    
    If Target.Cells.CountLarge > 1 Then Exit Sub
    Set c = Application.Intersect(Me.Range("C3:C13"), Target)
    If c Is Nothing Then Exit Sub
    
    Set frm = New frmSelect  'create userform
    Set frm.theCell = c      'assign the selected cell
    frm.Show                 'show the form
    Unload frm
End Sub

用户表单frmSelect

Option Explicit

Dim rng As Range
Dim col As Collection 'must be Global (to the form)

Private Sub UserForm_Activate()
    Dim con As Object, evt As Object
    
    Set col = New Collection
    For Each con In Me.Frame1.Controls 'buttons are in Frame1
        Set evt = New clsButton        'assuming all contained controls are buttons...
        evt.Init con, Me               'set up the class instance
        col.Add evt                    'store the object in the collection
    Next con
End Sub

'the cell to be populated
Property Set theCell(c As Range)
    Set rng = c
End Property

'called from the event class on clicking a button
Public Sub SetCell(txt As String)
    rng.Value = txt
    Me.Hide
End Sub

最后,类clsButton用于管理事件

Option Explicit

Private WithEvents btn As MSForms.CommandButton
Private frm As frmSelect

'set up the class instance
Public Sub Init(objBtn As MSForms.CommandButton, objFrm As Object)
    Set btn = objBtn
    Set frm = objFrm
End Sub

'handle the click event
Private Sub btn_Click()
    frm.SetCell btn.Caption 'call Sub in the form
End Sub

相关问题