2

我已经制作了几个基于单元格值通过右键单击菜单按钮运行的宏。通常,如果我右键单击值为“XYZ”的单元格,菜单按钮将显示为“为 XYZ 运行宏”,然后执行一系列操作:显示几个用户表单、运行 SQL 查询、显示和格式化结果数据.

在原始 .xlsm 文件的“Thisworkbook”上,我有以下代码:

Public WithEvents mxlApp  As Application

Public WithEvents mxlSh  As Worksheet

Private Sub mxlApp_SheetBeforeRightClick(ByVal Sh As Object, ByVal Target As Range, Cancel As 
Boolean)

... (do stuff here) ...

End Sub

...

Private Sub Workbook_Open()

    Call AutoExec

End Sub

...

在一个单独的模块上,我有以下函数用于设置我的事件处理程序

Public Sub AutoExec()

        Set mxlApp = Application

        Set ColectionOfMxlEventHandlers = New Collection

        ColectionOfMxlEventHandlers.Add mxlApp

        Debug.Print ThisWorkbook.Name & " Initialized"

End Sub

问题:在原始的 .xlsm 文件上,代码运行良好:每次我右键单击符合特定条件的单元格时,都会得到“为 XYZ 运行宏”,一切都很好。

一旦我将文件保存为 .xlam 并将其加载为插件,代码将无法工作。

我一直在互联网上和这里到处寻找,无法弄清楚如何解决这个问题。

编辑:

按照 creamyegg 的建议修改代码后,这就是我所拥有的:

在类模块中clsAppEvents

Private WithEvents mxlApp As Excel.Application

Private Sub Class_Initialize()

    Set mxlApp = Excel.Application

End Sub

Private Sub mxlApp_SheetBeforeRightClick(ByVal Sh As Object, ByVal Target As Range, Cancel As Boolean)

Dim cBut As CommandBarButton

    On Error Resume Next

        Call CleanMenu

        If Len(Target.Value) = 8 Then

            MyId = Target.Value

            With Application

                Set cBut = .CommandBars("Cell").Controls.Add(Temporary:=True)

            End With

            With cBut

               .Caption = "Run SQL Query for " & MyId

               .Style = msoButtonCaption

               .FaceId = 2554

               .OnAction = "CallGenericQuery"

            End With

        End If

        With Application

                Set cBut = .CommandBars("Cell").Controls.Add(Temporary:=True)

        End With

        With cBut

           .Caption = "Columns_Select"

           .Style = msoButtonCaption

           .FaceId = 255

           .OnAction = "CallShowHide"

        End With

    On Error GoTo 0

End Sub

Thisworkbook课堂上我有

Public m_objMe As clsAppEvents

Private Sub Workbook_Open()

    Set m_objMe = New clsAppEvents

    Debug.Print ThisWorkbook.Name & " Initialized"

End Sub

Private Sub Workbook_BeforeClose(Cancel As Boolean)

    On Error Resume Next

           Call CleanMenu

    On Error GoTo 0

    Set m_objMe = Nothing

End Sub

Private Sub Workbook_Deactivate()

    Call CleanMenu

End Sub

MyIdCallShowHide在包含和子的主模块中定义为公共callGenericQuery字符串

4

1 回答 1

1

这个问题听起来你WithEvents还在ThisWorkbook课堂上吗?您需要做的是创建一个新类,然后在Workbook_Open()您的加载项事件中实例化它的一个实例。例如:

新类 ( clsAppEvents):

Private WithEvents mxlApp As Excel.Application

Private Sub Class_Initialize()
    Set mxlApp = Excel.Application
End Sub

Private Sub mxlApp_SheetBeforeRightClick(ByVal Sh As Object, ByVal Target As Range, Cancel As Boolean)
...
End Sub

插件ThisWorkbook类:

Private m_objMe As clsAppEvents

Private Sub Workbook_Open()
    Set m_objMe = New clsAppEvents
End Sub

Private Sub WorkbookBeforeClose(Cancel As Boolean)
    Set m_objMe = Nothing
End Sub
于 2012-11-19T14:02:28.980 回答