4

我正在寻找一种更好的方法来禁用在 Excel 工作簿中触发 ActiveX 事件(尽管这将适用于所有具有 ActiveX 对象的 Office 应用程序)。

希望类似于 的东西Application.EnableEvents = false,尽管这不适用于 ActiveX。

在下面的示例中,使用全局布尔值很简单,但我的 ActiveX 对象有很多事件处理程序,而且对于我可以普遍应用的东西来临时禁用 ActiveX 事件会非常容易。我真的不想为这些方法中的每一个添加一个 if/exit 子语句。

要演示此问题,请在工作表中创建一个 ActiveX 组合框并将以下内容添加到该工作表模块

Public initializingContent As Boolean 
Private Sub intializeAllActiveXContent()

    'this doesn't apply to activeX events :'(
    Application.EnableEvents = False

    'this could work but is not really elegant
    'change this to false to show my problem in 
    'the intermediate window (called not once but twice)
    initializingContent = True

    ComboBoxTest.Clear

    ComboBoxTest.AddItem ("item1")
    ComboBoxTest.AddItem ("item2")
    ComboBoxTest.AddItem ("item3")

    'select the top value in the box
    ComboBoxTest.value = "item1"

    initializingContent = False

    Application.EnableEvents = True

     End Sub

Private Sub ComboBoxTest_Change()
    'I really don't want to have to wrap EVERY single ActiveX method
    'with something like this for a whole variety of reasons...
    If initializingContent Then Exit Sub

    Debug.Print "do stuff I don't want to happen when intializeAllActiveXContent() runs " & _
        "but I do when user changes box"
         End Sub
4

4 回答 4

6

我知道这真的很老了。但是任何查找此内容的人(第一次点击谷歌)可能想要一个简单的答案:

假设您有一个 Private Sub ActiveXControl_Change() 在 Application.EnableEvents = False 期间被调用,并且您希望它跳过此步骤:

Private Sub ActiveXControl_Change()
If Application.EnableEvents = True Then
'enter you code here

End If
End Sub
于 2017-05-31T07:00:15.167 回答
4

为什么不禁用它们?这样您也不必担心他们的个人代码。

试试这个

Sub DisableActiveXControls()
    Dim ws As Worksheet
    Dim OLEobj As OLEObject

    Set ws = ThisWorkbook.Sheets("Sheet1")

    With ws
        For Each OLEobj In ws.OLEObjects

        If TypeOf OLEobj.Object Is MSForms.ComboBox Then
            OLEobj.Enabled = False
        End If
        Next OLEobj
    End With
End Sub

屏幕截图之前/之后:

在此处输入图像描述

评论跟进:

事实证明,这破坏了组合在一起的对象的核心,但我可以取消组合对象(我猜它们不再在“Sheet1.OLEobjects”中)。我仍然不太喜欢这个,因为它依赖于这个事实,并且有时我确实想对对象进行分组.. – enderland 17 分钟前

要禁用组中的 ActiveX 控件,您不需要取消组合它们。使用此代码。下面的代码将禁用组中的组合框。

Sub Disable_ActiveX_Controls_In_A_Group()
    Dim shp As Shape, indvShp As Shape
    Dim OLEobj As OLEObject
    Dim ws As Worksheet

    Set ws = ThisWorkbook.Sheets("Sheet1")

    For Each shp In ws.Shapes
        If shp.Type = msoGroup Then
            For Each indvShp In shp.GroupItems
                Set objOLE = indvShp.OLEFormat.Object

                If objOLE.progID = "Forms.ComboBox.1" Then _
                objOLE.Enabled = False
            Next
        End If
    Next
End Sub
于 2013-10-09T17:24:12.883 回答
1

在搜索类似问题时遇到了这篇文章。我认为此处发布的答案不适合我的情况,并提出了其他建议。我的方法在这里也可能有用。

在我的工作簿中,我有一组 20 个(Activex)复选框。这些基本上过滤了要包含在报告中的 20 种产品类别。每次更改这些复选框之一时都会运行一个例程,只需从 CheckBox_Click 例程调用路由即可。

然后我还有一个组合框,可以选择这些复选框的各个。麻烦的是,当 20 个复选框中的每一个都被组合框代码(未)选中时,就会触发计算例程。

我想要的是在组合框的末尾只运行一次计算例程但如果我手动更改单个复选框,它仍然可以工作。

我的解决方案 - 在隐藏的工作表的某个单元格中输入一个 TRUE/FALSE 代码,该代码不碍事且不会干扰。

然后 CheckBox_Click 代码变为(对于 20 个复选框中的每一个):

Private Sub CheckBox6_Click()
If (Sheets("Data").Range("G60")) Then
    Call RangeFind
End If
End Sub

组合框代码适当地修改了这个相同的单元格:

Private Sub ComboBox28_Change()

Sheets("Data").Range("G60").Value = False
Select Case Sheets("Data").Range("F50").Value
    Case "1"

    CheckBox1.Value = False
    CheckBox2.Value = False
    CheckBox3.Value = False

....

End Select

'  This turns the checkboxes back on
Sheets("Data").Range("G60").Value = True

'  This now actually calls the calculation ONCE
Call RangeFind

ActiveSheet.Range("A1").Activate

End Sub

干杯,

迈克尔

于 2014-08-30T01:11:37.127 回答
0

这是一种选择:

Private Sub ToggleButton1_Click()
    If Application.EnableEvents = True Then
        'This next line forces at least 1 of the toggle's to be selected at all 
        'times; remove it from all routines if this is not desired.
        If Not ToggleButton1.Value Then ToggleButton1.Value = True
        Application.EnableEvents = False
        ToggleButton2.Value = False
        ToggleButton3.Value = False
        Application.EnableEvents = True
    End If
End Sub

Private Sub ToggleButton2_Click()
    If Application.EnableEvents = True Then
        If Not ToggleButton2.Value Then ToggleButton2.Value = True
        Application.EnableEvents = False
        ToggleButton1.Value = False
        ToggleButton3.Value = False
        Application.EnableEvents = True
    End If
End Sub

Private Sub ToggleButton3_Click()
    If Application.EnableEvents = True Then
        If Not ToggleButton3.Value Then ToggleButton3.Value = True
        Application.EnableEvents = False
        ToggleButton1.Value = False
        ToggleButton2.Value = False
        Application.EnableEvents = True
    End If
End Sub
于 2018-08-24T02:38:30.707 回答