Пытаюсь сделать универсальный обработчик событий (Change) для определенных контролов (комбобокс и текстбокс) на форме, по аналогии с рабочим кодом (закомментирован) обработчика для одного контрола, но возникает ошибка.
Подскажите, пожалуйста, как лучше это реализовать в одном классе это, не плодить же по классу на каждый тип контрола.
класс clsEventHandler_Universal
Код
Option Explicit
Private WithEvents mControl As MSForms.Control '<-- тут ошибка возникает
Public Sub AssignControl(c As MSForms.Control)
Set mControl = c
End Sub
Private Sub mControl_Change()
Debug.Print TypeName(mControl)
Select Case True
Case TypeName(mControl) = "TextBox"
Debug.Print "txt", mControl.Name
Case TypeName(mControl) = "ComboBox"
Debug.Print "cbo", mControl.Name
End Select
End Sub
юзер форма
Код
Private eventHandlerCollection As New Collection
Private Sub UserForm_Initialize()
Dim c As Control
Dim handler As clsEventHandler_Universal
For Each c In Controls
If TypeName(c) = "ComboBox" Or _
TypeName(c) = "TextBox" Then
Set handler = New clsEventHandler_Universal
handler.AssignControl c
eventHandlerCollection.Add handler
End If
Next
End Sub
user0 написал: не плодить же по классу на каждый тип контрола
а придется для нормальной работы с каждым типом(благо не так уж их и много). Притом совершенно не обязательно плодить именно классы - обработки всех типов можно записать в одном классе без проблем. А универсальный для всех типов через Control не сделать потому, что у каждого типа могут быть свои методы и события, которых нет у других типов. Например, у ComboBox-ов есть событие click, которого нет у TextBox-ов. Поэтому для типа Control вообще нет таких событий - только Enter и Exit, AfterUpdate и BeforeUpdate, которые используются весьма редко. Следовательно, Ваше событие Private Sub mControl_Change() вообще никогда не будет запущено, т.к. оно просто не зарегистрировано для этого типа объекта. А значит нет и смысла создавать обработку по Вашей схеме
Даже самый простой вопрос можно превратить в огромную проблему. Достаточно не уметь формулировать вопросы...
Здравствуйте user0, как-то интересовался этой темой, не скажу что я её до конца понял, но рабочий код нашел(переписал с книги) и сохранил. Правда некоторых событий характерных для тексбокса в модуле класса не хватает. Список событий текстбокса в модуле класса:
sokol92, там в общем написано и, к сожалению, не дает ответа на мой вопрос. Дмитрий(The_Prist) Щербаков, спасибо за развернутое объяснение, стало понятнее. DANIKOLA, спасибо за пример. Ігор Гончаренко, не, мне хватило объяснений Дмитрия про Control чтобы не копать дальше, а сделать обработки пары нужных типов в одном классе (как в примере от DANIKOLA). KISS, YAGNI, вот эта вот вся фигня )
Ваш подход может быть реализован следуюшим образом (см. вложение) - об этом же писал и Дмитрий. Включена обработка событий Change и DblClick элементов управления TextBox и Combobox, но каким же образом можно обработать и все остальные события этих элементов управления, кроме Enter, Exit, AfterUpdate, BeforeUpdate. События Enter и Exit могут быть обработаны косвенно, через анализ событий клавиатуры и мыши. Недавно (по меркам Excel) было предложено универсальное решение для обработки события Enter (через Windows API).
Приложенный пример должен обрабатывать и события динамически добавляемых элементов управления TextBox и Combobox.
Прилагаю пример универсального обработчика всех событий всех элементов управления пользовательской формы (включая Enter, Exit, ...).
Вся основная работа производится в модуле класса CatchEvents2, который взят из этого замечательного сообщения.
Этот модуль класса нельзя редактировать в встроенном редакторе кода VBA (VBE), поскольку текст модуля содержит директивы "Attribute ...", которые не показываются VBE. Перемещать модуль из проекта в проект можно. Для изменения текста необходимо в редакторе VBE экспортировать файл (Menu / File / Export file...), откорректировать выгруженный текстовый файл (в любом редакторе), импортировать обратно (Menu / File / Import file...).
В приложенном примере макрос Event_Handler выводит в окно Immediate наименования элементов управления и событий, кроме событий мыши и клавиатуры (хотя сами события мыши и клавиатуры перехватываются).
При динамическом (на лету) добавлении элементов управления в форму их события так же будут обработаны.
Откройте прилагаемый файл, нажмите кнопку для открытия формы. Поработайте с элементами управления (вводите данные, щелкайте, ...) и затем проанализируйте в окне Immediate (Ctrl+G), какие события были обработаны.
sokol92, сохранил в закладки и потом обязательно разберу Спасибо!
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄