Добавление элементов управления во фрейм в пользовательской форме Excel с помощью VBA

Мне нужно динамически создавать ярлыки и кнопки, а затем добавлять их во фрейм в пользовательской форме. Как мне это сделать? Кажется, что это должно быть проще, чем есть на самом деле.


person notnot    schedule 19.02.2009    source источник


Ответы (3)


Следующий код демонстрирует, как вы можете динамически заполнять фрейм в пользовательской форме элементами управления...

В форме, которую я использовал, у меня был элемент управления фреймом с именем Frame1, поэтому в UserForm_Initialize вы вызываете Frame1.Controls.Add для встраивания элемента управления в фрейм. Вы можете установить элемент управления, который возвращается в управляющую переменную WithEvents, которую вы определили в модуле кода UserForm, чтобы вы могли реагировать на события в любых элементах управления, которые вы хотите...

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

Также обратите внимание, что вы можете размещать и изменять размер элементов управления, даже если свойства top, left, width и height не обязательно появляются в intellisense...

Private WithEvents Cmd As MSForms.CommandButton
Private WithEvents Lbl As MSForms.Label

Private Sub UserForm_Initialize()
    Set Lbl = Frame1.Controls.Add("Forms.Label.1", "lbl1")
    Lbl.Caption = "Foo"
    Set Cmd = Frame1.Controls.Add("Forms.CommandButton.1", "cmd1")
End Sub

Private Sub Cmd_Click()
    Cmd.Top = Cmd.Top + 5
End Sub

Private Sub Lbl_Click()
    Lbl.Top = Lbl.Top + 5
End Sub
person Jon Fournier    schedule 25.02.2009
comment
Почему "1" в конце имени класса в методе add? - person Tristian; 03.02.2012
comment
Я не знаю. Я знаю, что без этого не получится. - person Jon Fournier; 21.07.2015
comment
Мне бы очень хотелось знать, почему это тоже должно быть Forms.CommandButton.1 - person FinancialRadDeveloper; 04.01.2018
comment
Это 1 версия. - person baka_toroi; 22.12.2020

Моя вариация на тему выше. Это только для массива кнопок 4x4. Создайте пользовательскую форму и добавьте это в ее код. Те же концепции можно использовать с вашими ярлыками (или см. предыдущий ответ):

Private cmdLots(20) As MSForms.CommandButton

Private Sub UserForm_Initialize()
For i = 1 To 4
For j = 1 To 4
    k = i + (4 * j)
    Set cmdLots(k) = UserForm2.Controls.Add("Forms.CommandButton.1", "cmd1")
    With cmdLots(k)
        .Top = i * 25
        .Left = (j * 80) - 50
        .BackColor = RGB(50 * i, 50 * j, 0)
        .Caption = "i= " & i & "  j= " & j
    End With
Next j
Next i
End Sub
person tjSTAR    schedule 06.08.2010
comment
как использовать эти шестнадцать кнопок? - person Qbik; 28.05.2014
comment
Также прочитайте stackoverflow.com/questions/10130300/ - person Robino; 10.10.2014

Метод Add

Чтобы добавить элементы управления в пользовательскую форму или фрейм, используйте add.

SetControl = object.Add(ProgID [, Name [, Visible ]] )

Первый аргумент будет ссылаться на тип элемента управления, который вы хотите добавить, и это ProgID, который определяется как

Программный идентификатор. Текстовая строка без пробелов, идентифицирующая класс объекта. Стандартный синтаксис для ProgID: ... ProgID сопоставляется с идентификатором класса (CLSID).

Функциональное решение

Чтобы упростить этот процесс, давайте воспользуемся перечислением, которое поможет нам управлять различными элементами управления.

' List of all the MSForms Controls.
Public Enum MSFormControls
    CheckBox
    ComboBox
    CommandButton
    Frame
    Image
    Label
    ListBox
    MultiPage
    OptionButton
    ScrollBar
    SpinButton
    TabStrip
    TextBox
    ToggleButton
End Enum

С помощью этого перечисления мы теперь можем легко создать функцию для получения строки ProgID для всех элементов управления.

' Gets the ProgID for each individual control. Used to create controls using `Object.add` method.
' @see https://docs.microsoft.com/en-us/office/vba/language/reference/user-interface-help/add-method-microsoft-forms
Public Function GetMSFormsProgID(control As MSFormControls) As String
    Select Case control
      Case MSFormControls.CheckBox:       GetMSFormsProgID = "Forms.CheckBox.1"
      Case MSFormControls.ComboBox:       GetMSFormsProgID = "Forms.ComboBox.1"
      Case MSFormControls.CommandButton:  GetMSFormsProgID = "Forms.CommandButton.1"
      Case MSFormControls.Frame:          GetMSFormsProgID = "Forms.Frame.1"
      Case MSFormControls.Image:          GetMSFormsProgID = "Forms.Image.1"
      Case MSFormControls.Label:          GetMSFormsProgID = "Forms.Label.1"
      Case MSFormControls.ListBox:        GetMSFormsProgID = "Forms.ListBox.1"
      Case MSFormControls.MultiPage:      GetMSFormsProgID = "Forms.MultiPage.1"
      Case MSFormControls.OptionButton:   GetMSFormsProgID = "Forms.OptionButton.1"
      Case MSFormControls.ScrollBar:      GetMSFormsProgID = "Forms.ScrollBar.1"
      Case MSFormControls.SpinButton:     GetMSFormsProgID = "Forms.SpinButton.1"
      Case MSFormControls.TabStrip:       GetMSFormsProgID = "Forms.TabStrip.1"
      Case MSFormControls.TextBox:        GetMSFormsProgID = "Forms.TextBox.1"
      Case MSFormControls.ToggleButton:   GetMSFormsProgID = "Forms.ToggleButton.1"
    End Select
End Function

И, наконец, давайте создадим функцию, которая добавляет форму или фрейм, используя нашу новую функцию.

' Easly add control to userform or a frame.
' @returns {MSForms.control} The control that was created
Public Function AddControl(userformOrFrame As Object _
                         , control As MSFormControls _
                         , Optional name As String = vbNullString _
                         , Optional visable As Boolean = True _
                        ) As MSForms.control
    Set AddControl = userformOrFrame.Controls.Add(GetMSFormsProgID(control), name, visable)
End Function

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

Демонстрация, показывающая IntelliSense

Демо

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

Private Sub UserForm_Initialize()
    demoAddingControlsToUserform
End Sub

Private Sub demoAddingControlsToUserform()
    ' Offset used to prevent controls
    ' overlapping as well as provide
    ' a height for the scrollbars
    Dim offsetHeight As Double
    
    ' Add each control to the userform
    ' and set top to make sure they are not overlapping
    ' (Although this looks odd, you can actually loop enums this way.)
    Dim control As MSFormControls
    For control = CheckBox To ToggleButton
        With AddControl(Me, control)
            .Top = offsetHeight
            offsetHeight = offsetHeight + .Height
        End With
    Next
    
    ' Show scrollbars and adjust the height to show
    ' all the added controls.
    With Me
        .ScrollBars = fmScrollBarsVertical
        .ScrollHeight = offsetHeight + 20
    End With
End Sub

Демонстрационная форма пользователя со всеми элементами управления

person Robert Todar    schedule 10.11.2020