2011-06-17 80 views
7

我在工作表上有十個下拉菜單,每個下拉菜單對GotFocus()事件都應該有相同的響應。如何使用excel vba將事件分配給多個對象?

我寫了下面的代碼,但我得到一個運行時錯誤(459) - 「對象或類不支持設置如果事件」

在一類稱爲clsPDRinput我有以下幾點:

Public WithEvents inputObj As OLEObject 

Public Property Set myInput(obj As OLEObject) 
    Set inputObj = obj 
End Property 

Public Sub tbPDRInput_GotFocus() 
    //Do some stuff... 
End Sub 

我然後運行下面的代碼,其產生錯誤:

Dim tbCollection As Collection 

Public Sub InitializePDRInput() 
    Dim myObj As OLEObject 
    Dim obj As clsPDRInput 

    Set tbCollection = New Collection 
     For Each myObj In Worksheets("1. PDR Documentation").OLEObjects 
      If TypeName(myObj.Object) = "ComboBox" Then 
       Set obj = New clsPDRInput 
       Set obj.myInput = myObj <-- **THIS LINE THROWS ERROR** 
       tbCollection.Add obj 
      End If 
     Next myObj 
    Set obj = Nothing 
End Sub 

我不知道是什麼導致這個錯誤。一個雖然我有OLEObject是太普通,並不是每個OLEObject支持GotFocus()事件,這就是爲什麼代碼給出的錯誤信息?

我試過用MSForms.ComboBox替換OLEObject,但這並不能解決問題。

任何想法 - 現在用Google搜索了兩個小時,並拿出空白......

編輯 - 更新什麼我認爲這個問題是...

我沒有更多的調查,這裏是據我所知,問題是什麼。

  1. 如果一個變量聲明爲OLEObject(如...inputObj as OLEObject)然後暴露唯一事件是GotFocus()LostFocus()
  2. 如果一個變量聲明爲MSForms.ComboBox(如...inputObj as MSForms.ComboBox),然後各種各樣的事件暴露(如Change()Click()DblClick()事件GotFocus()LostFocus()暴露

點1和2與excel中的對象模型一致。因此,當我嘗試將ComboBox分配給我的班級時,由於ComboBox不支持GotFocus()LostFocus事件,我得到一個錯誤(請參閱原文)。

現在的難題。如果我在工作表上添加一個組合框(使用Control ToolBox),然後雙擊該組合框以查看代碼,則會顯示所有事件,包括GotFocus()LostFocus()

+0

'For Each myObj' ...'Next inputObj' is inconsistent and would not compile,I think。這是你的實際代碼嗎? –

+0

另外,'Dim tbCollection As Collection'在你的類中,但是你可以在'Sub InitializePDRInput'中使用'tbCollection',我假設它是在一個模塊中。這裏發生了什麼? –

+0

@ Jean-Francois Corbett - 關於你的第一點,這是削減版本的代碼。對於你指出的每個問題,只是一個錯字(我會編輯這篇文章)。至於第2點,再次,錯字 - 'Dim tbCollection ...'在模塊 –

回答

5

以下適用於我。你的代碼有幾個問題,組合框沒有GotFocus事件,所以你必須使用一個不同的事件。該集合必須是模塊中的全局,而不是該類的一部分。我無法使用通用的「OLEobject」方法來使用它(同樣的錯誤)。

' ### in the class 
Public WithEvents inputObj As MSForms.ComboBox 

Private Sub inputObj_Change() 
    MsgBox "Change!" 
End Sub 

' ### in a module 
Dim tbCollection As Collection 

Public Sub InitializePDRInput() 
    Dim myObj As OLEObject 
    Dim obj As clsPDRInput 

    Set tbCollection = New Collection 

    For Each myObj In Worksheets("Sheet1").OLEObjects 
     If TypeName(myObj.Object) = "ComboBox" Then 
      Set obj = New clsPDRInput 
      Set obj.inputObj = myObj.Object 
      tbCollection.Add obj 
     End If 
    Next myObj 

End Sub 
+0

謝謝你的答案。你的代碼工作(所以+1),但我不能使用它,因爲我需要'GotFocus()'事件 –

1

更新

我太專注於使代碼編譯,有人是不夠好指出,下面的答案是bad juju。所以不要使用。它編譯,但不是一個好的答案。


我轉載你的錯誤,並通過改變以下聲明中的固定:

Public WithEvents inputObj As OLEObject 

這樣:

Public inputObj As New OLEObject 

當然,這是一個不同的類型聲明,所以我的不知道它是否會爲你工作。它確實刪除了異常。

我還想指出,如果你沒有Option Explicit set,你應該。你的代碼中有一些變量沒有被聲明。我的猜測是,你可能在發佈你的問題之前修改了代碼。

只要確保。

+0

'公共inputObj作爲新的OLEObject':這被稱爲自動實例化變量。當代碼中第一次遇到變量'inputObj'時,會創建一個新的實例。一般來說,您應該避免自動實例化變量,原因有兩個:首先,它會增加代碼的開銷,因爲每次在代碼中遇到變量時都必須測試「Nothing」。 –

+0

其次,您無法測試自動實例化變量是否爲Nothing,因爲在「If Obj Is Nothing Then」語句中使用變量名的行爲將自動創建該變量的一個實例。 [來源](http://www.cpearson.com/excel/classes.aspx) –

+0

@ Jean-FrançoisCorbett我不知道;感謝您指出。 – ray

相關問題