2015-07-29 2 views
1

Я пытаюсь создать класс, который создаст кнопку. Кнопка должна иметь назначенный макрос. Макрос является функцией класса.VBA Excel: динамически созданная кнопка в модуле класса запускается сразу и только один раз

Код модуля класса заключается в следующем:

'Class Module: btnClass 
Option Explicit 

Dim btn As Button 

Function addButton() 
    'Adding a button 
    Set btn = ActiveSheet.Buttons.Add(_ 
     Range("A1").Left, _ 
     Range("A1").Top, _ 
     Range("A1").Width, _ 
     Range("A1").Height) 
    With btn 
     'Assigning a function 
     .OnAction = Me.onClickAction 
     .Caption = "Button" 
    End With 
End Function 

Function onClickAction() 
    MsgBox ("Click") 
End Function 

код главного макроса заключается в следующем:

'Module 
Option Explicit 
Sub main() 
    Dim btnInstance As btnClass 
    Set btnInstance = New btnClass 

    'Calling a function of the instance that creates a button 
    Call btnInstance.addButton 
End Sub 

Код выше создает кнопку успешно. Однако функция, назначенная кнопке, запускается немедленно (сразу после создания кнопки, а не при нажатии на нее), и только один раз (когда вы нажимаете кнопку позже, ничего не происходит).

Есть ли способ в VBA реализовать требуемую функциональность с помощью модулей классов (хотите создать класс, который не полагается на внешние функции)?

+1

Макрос, который должна выполнять кнопка, не может быть достигнута, поскольку она находится внутри модуля класса. Поместите этот макрос в основной (нормальный) модуль и посмотрите, работает ли это для вас. В противном случае вам, вероятно, придется объявить экземпляр класса как глобальную переменную и использовать withevents, например, mielk show, хотя это потребует еще нескольких настроек. – Tom

+0

Размещение всего в основном (нормальном) модуле делает код работой. Проблема в том, что это простой пример иллюстрации. В действительности мне нужно получить доступ к переменным, хранящимся в экземпляре класса. Если есть способ передать этот экземпляр в качестве параметра функции, вызываемой при нажатии кнопки, то это будет приемлемым решением. Однако быстрый поиск в Google говорит, что нет простого способа сделать это. Пожалуйста, поправьте меня, если я ошибаюсь. – Lena

+0

Вам нужно только поставить макрос, который нужно запустить с помощью кнопки в нормальном модуле. Затем вы можете создать новый экземпляр модуля класса в этом макросе и выполнить всю работу в самом модуле класса. – Tom

ответ

1

Чтобы расширить комментарий Рори, ваш класс должен что-то вроде этого:

Public WithEvents Button As CommandButton 

Private Sub Class_Initialize() 
    Set Me.Button = Sheet1.OLEObjects("Thebutton").Object 
End Sub 

Private Sub Button_Click() 
    MsgBox "Foo" 
End Sub 

Затем в обычном модуле создать публичный экземпляр класса, так что он остается в Memmory:

Public myButt As ButtonClass 

Public Sub AddEvent() 
    Set myButt = New ButtonClass 
End Sub 

Примечание что событие click будет обрабатываться только до тех пор, пока экземпляр класса останется в памяти. Если вы закроете книгу и снова ее откроете, событие больше не будет обработано.

Редактировать: Я забыл упомянуть, вам нужно установить ссылку на Microsoft Forms, чтобы объявить переменную типа CommandButton.

Смежные вопросы