簡體   English   中英

使用 VBA 向 Excel 用戶窗體中的框架添加控件

[英]Adding controls to a frame in an Excel userform with VBA

我需要動態創建標簽和按鈕,然后將它們添加到用戶窗體中的框架中。 我該怎么做呢? 看起來它應該比實際更容易。

以下代碼演示了如何使用控件動態填充用戶窗體中的框架...

在我使用的窗體中,我有一個名為 Frame1 的框架控件,因此在 UserForm_Initialize 中調用 Frame1.Controls.Add 將控件嵌入到框架中。 您可以設置返回到您在 UserForm 代碼模塊中定義的 WithEvents 控件變量的控件,以便您可以響應您想要的任何控件上的事件...

因此,使用此方法,您需要為您創建的任何控件預先編寫所需的任何事件代碼...

另請注意,即使頂部、左側、寬度和高度屬性不一定出現在智能感知中,您也可以定位和調整控件的大小...

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

我對上述主題的變體。 不過,這僅適用於 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

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

像這樣使用枚舉的美妙之處在於我們現在對所有控件都有智能感知,而不必記住所有控件。

演示顯示智能感知

演示

為了演示它,我們可以通過循環枚舉將每個控件添加到一個空白的用戶窗體中。

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

帶有所有控件的演示用戶表單

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM