2011-06-17 59 views
7

Tôi có mười trình đơn thả xuống trên một trang tính mỗi trong số đó sẽ phản hồi giống với sự kiện GotFocus().Làm thế nào để gán một sự kiện cho nhiều đối tượng với excel vba?

Tôi đã viết đoạn mã sau nhưng tôi nhận được một lỗi thời gian chạy (459) - "Object hoặc lớp không hỗ trợ các thiết lập nếu sự kiện"

Trong một lớp được gọi là clsPDRinput Tôi đã điều sau đây:

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 

tôi sau đó chạy đoạn mã sau đó là sản xuất các lỗi:

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 

tôi không chắc chắn điều gì gây ra lỗi này. Mặc dù tôi có là OLEObject quá chung chung và không phải mọi sự kiện OLEObject đều hỗ trợ sự kiện GotFocus() và đó là lý do mã này đưa ra thông báo lỗi?

Tôi đã thử thay thế OLEObject bằng MSForms.ComboBox nhưng điều đó không giải quyết được sự cố.

Bất kỳ ý tưởng - có googled cho hai tiếng đồng hồ bây giờ và đưa ra trống ...

EDIT - Cập nhật về những gì tôi nghĩ rằng vấn đề là ...

tôi đã điều tra hơn và đây là những gì vấn đề là xa như tôi có thể nói.

  1. Nếu bạn khai báo một biến như OLEObject (như trong ...inputObj as OLEObject) thì chỉ sự kiện tiếp xúc là GotFocus()LostFocus().
  2. Nếu bạn khai báo một biến như MSForms.ComboBox (như trong ...inputObj as MSForms.ComboBox) sau đó một loạt các sự kiện được tiếp xúc (ví dụ Change(), Click(), DblClick()) nhưng sự kiện GotFocus()LostFocus()không tiếp xúc

điểm 1 và 2 phù hợp với mô hình đối tượng trong excel. Do đó, khi tôi cố chỉ định một số ComboBox cho lớp học của mình, tôi gặp lỗi (xem bài đăng gốc) vì ComboBox không hỗ trợ các sự kiện GotFocus()LostFocus.

Bây giờ cho câu đố. Nếu tôi thêm một ComboBox vào một bảng tính (bằng cách sử dụng Control ToolBox) và tôi nhấp đúp vào ComboBox để nhận được mã sau đó tất cả các sự kiện được tiếp xúc, bao gồm GotFocus()LostFocus()!

+0

'Đối với mỗi myObj' ...' Đầu vào tiếp theoObj' không nhất quán và sẽ không biên dịch, tôi nghĩ vậy. Đây có phải là mã thực của bạn không? –

+0

Ngoài ra, 'Dim tbCollection As Collection' nằm trong lớp của bạn, nhưng bạn sử dụng' tbCollection' trong 'Sub InitializePDRInput', mà tôi đoán là trong một mô-đun. Những gì đang xảy ra ở đây? –

+0

@ Jean-Francois Corbett - Về điểm đầu tiên của bạn, đây là phiên bản cắt mã. Vấn đề 'For each..' bạn chỉ là một lỗi đánh máy (tôi sẽ sửa bài viết). Đối với điểm 2, một lần nữa, typo - 'Dim tbCollection ...' nằm trong một mô-đun –

Trả lời

5

Thông tin bên dưới phù hợp với tôi. Đã xảy ra sự cố với mã của bạn và các combobox không có sự kiện GotFocus, vì vậy bạn sẽ phải sử dụng một sự kiện khác. Bộ sưu tập cần phải là toàn cầu trong mô-đun, phần quan trọng của lớp. Tôi không thể làm điều này để làm việc bằng cách sử dụng phương pháp "OLEobject" chung (cùng một lỗi bạn nhận được).

' ### 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

Cảm ơn câu trả lời. Mã của bạn hoạt động (như vậy +1) nhưng tôi không thể sử dụng nó khi tôi cần sự kiện 'GotFocus()' –

1

Cập nhật

tôi đã quá tập trung trong việc đưa ra các biên dịch mã và ai đó đã đủ đẹp để chỉ ra rằng câu trả lời dưới đây là bad juju. Vì vậy, không sử dụng. Nó không biên dịch, nhưng không phải là một câu trả lời hay.


tôi sao chép lỗi của bạn và cố định bằng cách thay đổi tuyên bố sau đây:

Public WithEvents inputObj As OLEObject 

này:

Public inputObj As New OLEObject 

Tất nhiên, đây là một loại khác nhau của lời tuyên bố vì vậy tôi không chắc chắn nếu nó sẽ làm việc cho bạn. Nó loại bỏ ngoại lệ.

Tôi cũng muốn lưu ý rằng nếu bạn không có tùy chọn Explicit set, bạn nên làm như vậy. Có một số biến trong mã của bạn không được khai báo. Tôi đoán là bạn có lẽ đã sửa đổi mã trước khi đăng câu hỏi của bạn.

Chỉ cần đảm bảo.

+0

'Đầu vào công khaiObj As New OLEObject': Đây được gọi là biến tự động sửa đổi. Khi biến 'inputObj' được gặp lần đầu tiên trong mã, một cá thể mới được tạo ra. Nói chung, bạn nên tránh các biến tự động kích hoạt vì hai lý do: Thứ nhất, nó thêm phí vào mã vì biến phải được kiểm tra cho 'Nothing' mỗi lần nó gặp phải trong mã. –

+0

Thứ hai, bạn không có cách nào để kiểm tra xem một biến tự động là 'Nothing' bởi vì hành động sử dụng tên biến trong câu lệnh' If Obj Is Nothing Then' sẽ tự động tạo một thể hiện của biến. [source] (http://www.cpearson.com/excel/classes.aspx) –

+0

@ Jean-François Corbett Tôi không biết; Cảm ơn đã chỉ ra điều đó. – ray

Các vấn đề liên quan