2011-06-17 4 views
7

ワークシート上にドロップダウンメニューが10個あり、それぞれがGotFocus()イベントに対応する必要があります。excel vbaを使用して複数のオブジェクトにイベントを割り当てる方法は?

私は、次のコードを書かれているが、私は、実行時エラー(459)を取得 - clsPDRinputと呼ばれるクラスで

私は、次のしている「のイベントがあれば、オブジェクトまたはクラスのセットをサポートしていない」:

私は

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 

:私は、エラーを生成している次のコードを実行しています

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 

このエラーの原因は不明です。私は持っていましたが、OLEObjectはあまりに一般的であり、すべてOLEObjectGotFocus()イベントをサポートしているわけではないので、コードがエラーメッセージを出すのはなぜですか?

OLEObjectMSForms.ComboBoxに置き換えようとしましたが、問題は解決しません。

任意のアイデア - 私はより多くの調査とここにあるんでした私は問題だと思うものに更新...

- 今2時間ググと空白...

EDITを出ています私の言う限り、問題は何か。

  1. あなたは(...inputObj as OLEObjectのように)OLEObjectとして変数を宣言する場合は、が露出イベントだけがGotFocus()LostFocus()です。
  2. あなたは(...inputObj as MSForms.ComboBoxのように)MSForms.ComboBoxとして変数を宣言する場合は、様々なイベントが露出されている(例えばChange()Click()DblClick()が、イベントGotFocus()LostFocus()

ポイントを露出させないされています1と2は、Excelのオブジェクトモデルと一致しています。その結果、ComboBoxを私のクラスに割り当てようとすると、ComboBoxGotFocus()LostFocusのイベントをサポートしないため、エラーが発生します(元の投稿を参照)。

今、パズルのためです。コンボボックスを(Control ToolBoxを使用して)ワークシートに追加し、そのコンボボックスをダブルクリックしてコードを取得すると、GotFocus()LostFocus()などのすべてのイベントが公開されます。

+0

'For each myObj' ...'次のinputObj'は一貫性がなく、コンパイルされません。これは実際のコードですか? –

+0

また、 'Dim tbCollection As Collection'はクラスにありますが、' Sub InitializePDRInput'に 'tbCollection'を使用しています。これはモジュール内にあると思います。何が起きてる? –

+0

@ Jean-Francois Corbett - あなたの最初の点では、これはコードのバージョンを削減しています。あなたが指摘している「For each ...」問題はちょうどタイプミスです(私は投稿を編集します)。ポイント2については、再び、typo - 'Dim tbCollection ... 'がモジュール内にあります –

答えて

5

以下は私の仕事です。コードにはいくつか問題があり、コンボボックスにはGotFocusイベントがないため、別のものを使用する必要があります。コレクションはモジュール内のグローバルである必要があります。クラスのnoty部分です。私はこれを一般的な "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を設定していない場合は、次の点に注意してください。コードに宣言されていない変数がいくつかあります。私の推測では、質問を投稿する前にコードを変更した可能性があります。

+0

'Public inputObj As New OLEObject':これは自動インスタンス変数です。変数 'inputObj'がコード内で最初に見つかると、新しいインスタンスが作成されます。一般に、変数を自動インスタンス化するのは2つの理由から避けなければなりません。まず、コード内で発生するたびに変数に 'Nothing 'をテストする必要があるため、オーバーヘッドが発生します。 –

+0

第2に、 'If Obj Is Nothing Then'ステートメントで変数名を使用するという行為が自動的に変数のインスタンスを作成するため、自動インスタンス化変数が' Nothing'かどうかをテストする方法がありません。 [ソース](http://www.cpearson.com/excel/classes.aspx) –

+0

@ Jean-FrançoisCorbett私は知らなかった。それを指摘してくれてありがとう。 – ray

関連する問題