Создайте серию динамически создаваемых кнопок, щелкая каждую из них в Excel VBA. - PullRequest
1 голос
/ 19 марта 2020

Пожалуйста, не рассматривайте этот вопрос как повторяющийся вопрос! Этот вопрос явно отличается от ранее похожих запросов.

Последние несколько дней я практикую модуль класса в Excel VBA.

Я поставил перед собой очень простую задачу, но все получилось как чемпион!

Моя задача очень проста!

Challange

У меня есть BLANK Userform , вставленный вручную! С этого момента никакие элементы управления не будут добавлены вручную.

Как только вы инициализируете пользовательскую форму, она должна появиться с одной единственной кнопкой CommandButton в верхнем левом углу формы.

Теперь, нажмите на кнопку, и вы станете сервером другой CommandButton справа от кнопки! Итак, нажмите на вновь созданную кнопку, и еще раз будет создана другая кнопка прямо под предыдущей кнопкой, и процесс будет продолжаться до тех пор, пока вы продолжаете нажимать на только что созданные CommandButtons.

Проблема, с которой я сталкиваюсь

Я могу создать первую кнопку в пользовательской форме после ее инициализации, а также создать новую кнопку под ней , Но ничего после этого. Ничего не происходит, когда я нажимаю на вторую / вновь созданную кнопку.

Вот мой код пользовательской формы

Dim A As New Class2       ' Create an object of the Class (where we declared the events).

Private Sub UserForm_Initialize()

    ' Create and add the button control.
    Dim btEx As MSForms.CommandButton
    Set btEx = UserForm1.Controls.Add("Forms.CommandButton.1")

    With btEx
        .Top = 12
        .Left = 12
        .Width = 72
        .Height = 36
        .Caption = "Click Me"
    End With

    Set A.btEvents = btEx

End Sub

Вот модуль класса

Public WithEvents btEvents As MSForms.CommandButton

Private Sub btEvents_click()

    ' Create and add the button control.
    Dim btEx As MSForms.CommandButton
    Set btEx = UserForm1.Controls.Add("Forms.CommandButton.1")

    With btEx
        .Top = 30
        .Left = 30
        .Width = 72
        .Height = 36
        .Caption = "Click Me"
    End With

End Sub

Нужно ваше понимание или помогите понять я иду правильным путем? Я не могу назначить событие динамически созданному CommandButton из модуля класса.

Пожалуйста, дайте мне знать, я что-то упустил или это даже невозможно на платформе? Я действительно своего рода новичок ie в программировании в Excel VBA Class Module.

Заранее спасибо.

Ответы [ 2 ]

2 голосов
/ 20 марта 2020

Реализация коллекции классов, в которой каждый класс содержит кнопку, является ключом к выполнению этой работы. Недостатки общего подхода заключаются в том, что класс содержит ссылку на пользовательскую форму, а события обрабатываются в самом классе. В идеале мы хотели бы вернуть весь код кнопки обратно в пользовательскую форму, включая обработку событий.

Как это можно сделать, поскольку коллекции не могут быть объявлены с помощью WithEvents? Это может быть достигнуто с помощью глобального механизма уведомлений:

UserForm

Option Explicit

Private WithEvents MyNotifier As Notifier
Private MyControls As Collection

Private Sub UserForm_Initialize()
   Set MyNotifier = GetNotifier()
   Set MyControls = New Collection
   AddButton
End Sub

Private Sub MyNotifier_Click()
   AddButton
End Sub

Private Sub AddButton()
   Dim c As MSForms.CommandButton
   Set c = UserForm1.Controls.Add("Forms.CommandButton.1")
   c.Width = 72
   c.Height = 36
   c.Top = UserForm1.Controls.Count * c.Height
   c.Left = 12
   c.Caption = "Click Me"

   Dim mc As MyControl
   Set mc = New MyControl
   mc.Add c
   MyControls.Add mc
End Sub

Существует 3 вспомогательных модуля с этой архитектурой. Первый - это модуль, который содержит глобальный уведомитель. Мы создаем и получаем доступ к этому уведомителю через метод GetNotifier. Этот метод гарантирует, что существует один и только один экземпляр.

Модуль

Option Explicit

Private m_Notifier As Notifier

Public Function GetNotifier() As Notifier
   If m_Notifier Is Nothing Then Set m_Notifier = New Notifier

   Set GetNotifier = m_Notifier
End Function

Второй - это класс, который определяет уведомитель. Этот одноэлементный класс является координатором событий. Он позволяет перенаправлять события, в данном случае из класса MyControl обратно в UserControl.

Класс уведомлений

Option Explicit

Public Event Click()

Public Function Click()
   RaiseEvent Click
End Function

Третий класс - это класс, содержащий кнопку. , Ответом на событие нажатия кнопки является вызов метода нашего Уведомителя, который, в свою очередь, вызывает событие обратно в UserControl:

MyControl Class

Option Explicit

Private MyNotifier As Notifier
Private WithEvents btEx As MSForms.CommandButton

Public Sub Add(ByVal c As MSForms.CommandButton)
   Set MyNotifier = GetNotifier()
   Set btEx = c
End Sub

Private Sub btEx_Click()
   MyNotifier.Click
End Sub
1 голос
/ 20 марта 2020

Можете ли вы попробовать это. Немного поспешно, поэтому не удивлюсь, если что-то пойдет не так, но вернусь завтра, если так.

За формой

Private col As Collection

Private Sub UserForm_AddControl(ByVal Control As MSForms.Control)

Dim cl As Class2
Dim ctl As MSForms.CommandButton

Set col = New Collection

For Each ctl In Me.Controls
    Set cl = New Class2
    Set cl.btEvents = ctl
    col.Add cl
Next ctl

End Sub

Private Sub UserForm_Initialize()

Dim btEx As MSForms.CommandButton
Set btEx = UserForm1.Controls.Add("Forms.CommandButton.1")

With btEx
    .Top = 12
    .Left = 12
    .Width = 72
    .Height = 36
    .Caption = "Click Me"
End With

End Sub

Модуль класса Единственное изменение здесь - добавить интервал, чтобы кнопки не появлялись друг над другом.

Public WithEvents btEvents As MSForms.CommandButton

Private Sub btEvents_click()

Dim btEx As MSForms.CommandButton
Set btEx = UserForm1.Controls.Add("Forms.CommandButton.1")

With btEx
    .Top = 30 * UserForm1.Controls.Count
    .Left = 30
    .Width = 72
    .Height = 36
    .Caption = "Click Me"
End With

End Sub

enter image description here

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...