VBA在运行时更改CommandButton单击事件处理程序

时间:2014-09-12 12:53:35

标签: vba

我在一个名为cmd0001的表单中有一个现有的CommandButton,并且它在表单模块中对其事件处理程序进行了硬编码。

Private Sub cmd0001_Click()
 'code 
End Sub

我需要"禁用"该按钮通过编程方式(在运行时)更改其行为。一种可能性是使用InsertLines更改模块中的过程代码:

Set vbComp = ThisWorkbook.VBProject.VBComponents("formName")
Set vbModule = vbComp.CodeModule
linenr = vbModule.ProcStartLine("cmd0001_Click", vbext_pk_Proc)
vbModule.InsertLines linenr + 2, "msgbox ""no"": exit sub"

遗憾的是,这是受保护的VBAProject,我收到错误:"运行时错误50289由于项目受到保护而无法执行操作"。

可以更改按钮的click事件处理程序吗?实际上我会使用许多按钮,理想情况下我想为"禁用"纽扣。

我现在找到的所有示例都使用动态创建的按钮,例如this示例,但我找不到如何使用已存在的按钮执行此操作的示例。

修改1:

好的,I have found可以使用以下代码创建一个类模块并创建一个点击处理程序:

'in form
Dim btnH As cCtrlHandler
Set btnH = New cButtonHandler
Set btnH.ctrl = btnTest

'class module cButtonHandler
Public WithEvents ctrl As MSForms.CommandButton
Private Sub ctrl_Click()
  MsgBox "Not authorized!"
End Sub

但主要问题是点击处理程序没有被覆盖!新代码,在此示例中是' MsgBox"未授权!"'附加到现有代码。可以完全覆盖事件处理程序吗?

1 个答案:

答案 0 :(得分:0)

你很亲密。绝对是在正确的轨道上。我无法承担this idea的所有功劳,但我认为它会帮助你。

首先,从按钮中删除点击处理程序。你不能过度使用它们,只能添加它们。

接下来,为MSForms.CommandButton创建一个包装类。该课程负责在所有按钮上统一处理点击事件。

Private mClickEnabled As Boolean
Private WithEvents internalButton as MSForms.CommandButton

Public Property Let ClickEnabled(value as Boolean)
    mClickEnabled = value
End Property

Public Property Get ClickEnabled() As Boolean
    ClickEnabled = mClickEnabled
End Property

Public Sub Init(btn as MSForms.CommandButton)
    Set internalButton = btn
End Sub

Private Sub internalButton_Click()
    If ClickEnabled Then
        ' do something
    Else
        MsgBox "NotAuthorized!"
    End If
End Sub

然后在表单的初始化事件中,创建一个新的集合并遍历表单的命令按钮,创建新的自定义按钮并将它们添加到集合中。调用代码可以设置自定义按钮的布尔值,以确定以后单击事件的行为。

当然,只有当您希望所有按钮以完全相同的方式工作时,这才有效。由于这是一个点击事件,您可能不想这样做。在这种情况下,最好和最简单的解决方案可能只是为表单上的每个按钮创建一个私有布尔值。当您想要禁用按钮的操作发生时,请将该特定按钮的设置设置为false。然后你可以使用类似的理论来改变行为。

Private cmd0001Enabled As Boolean

Private Sub cmd0001_Click()
    If cmd0001Enabled Then
        'custom action here
    Else
        HandleDisabledButtonClick
    End If
End Sub

Private Sub HandleDisabledButtonClick()
    MsgBox "Not authorized!"
End Sub

如果您需要将布尔值暴露给外部代码,请继续为它们创建一些公共属性。