2014-09-12 213 views
1

我有一個名爲cmd0001的窗體中的現有命令按鈕,並且它的事件處理程序硬編碼在窗體的模塊中。VBA更改命令按鈕在運行時單擊事件處理程序

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無法執行操作保護」。

可以更改按鈕的單擊事件處理程序?其實我會用很多按鈕工作,理想情況下,我想有1個「禁用」按鈕的全局事件處理程序。

我現在發現的所有示例都適用於動態創建的按鈕,如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'Not authorized!''被追加到現有的代碼中。有可能完全覆蓋事件處理程序?

+0

爲什麼不只是禁用按鈕,所以它不能被點擊? – RubberDuck 2014-12-31 15:38:46

+0

@RubberDuck因爲應用程序啓用/禁用按鈕在任何時候取決於用戶的交互。這意味着,即使我禁用了一個按鈕(例如:刪除記錄),稍後當有人點擊列表視圖(包含記錄的網格)時,它將再次啓用。 – 2015-01-05 14:35:38

回答

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 

然後在你的窗體的intialization活動,通過創建窗體的命令按鈕一個新的收集和循環,創建新的自定義按鈕,並將它們添加到集合中。調用代碼可以設置自定義按鈕的布爾值,以確定稍後的點擊事件的行爲。

當然,這隻有在你想讓所有的按鈕以完全相同的方式工作時纔有效。因爲這是一個點擊事件,你可能不想這樣做。在這種情況下,最好和最簡單的解決方案可能就是爲表單上的每個按鈕創建一個私有布爾值。當某個動作發生在要禁用該按鈕的位置時,將該按鈕設置爲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 

如果您需要將布爾值顯示爲外部代碼,請繼續爲它們創建一些公共屬性。

相關問題