用户在按钮单击事件上创建后保存用户窗体控件布局

时间:2019-05-27 19:44:04

标签: vba user-controls

我已经在Excel VBA中设置了一个动态用户窗体,该窗体允许用户在组合框和文本框的组合中选择所需的行数。用户在此创建表格后,我希望能够处理计算,因为他们从下拉列表中选择项目并输入数值。

我能够毫无问题地创建表单,但是似乎无法与创建的控件一起使用,因为它们似乎没有保存在我可以访问它们的内存中。

我的控件创建循环按顺序预定义了名称,但是,将其保存为起始用户窗体的一部分时,我的更改代码似乎没有像通常那样引用它们。

我一直在尝试尝试在创建的表单创建后将其导出,但这似乎不起作用,并且实际上不是一个可行的选择,因为多个用户将使用他们自己的表单实例。

以下是成功创建列表以及正确的属性和源数据的代码。

'Create new door list based on user number input
Private Sub btnds1dl1CreatDoorList_Click()

Dim i As Long, x As Integer, number As Long
Dim txtB1, cmbB1 As Control

number = InputBox("Enter # or door list rows to create", "Enter number between 1 and 100")
number = number + 1

With UForm
    For i = 2 To number

        'Add each row from left to right starting at control 1 and ending at 11.

        '<<=========================  ADD 2 COMBO BOXES
        'ADD CABINET
        Set cmbB1 = Controls.Add("Forms.ComboBox.1", "cmdboxs1dlcab" & i)
        With cmbB1
            '.Name = "cmdboxs1dlcab" & i
            .Height = 18
            .Width = 72
            .Left = 18
            .Top = 24 * (i - 1) + 228
            .RowSource = "CABINET_TYPE"
            .Value = "Select"
            .BackStyle = 0
        End With

        'ADD SINGLE OR PAIR
        Set cmbB1 = Controls.Add("Forms.ComboBox.1", "cmdboxs1dlsp" & i)
        With cmbB1
            '.Name = "cmdboxs1dlsp" & i
            .Height = 18
            .Width = 72
            .Left = 96
            .Top = 24 * (i - 1) + 228
             .RowSource = "SINGLE_PAIR"
            .Value = "Select"
            .BackStyle = 0
        End With


        '<<=========================  ADD 9 TEXT BOXES
        'ADD QTY OPENINGS
        Set txtB1 = Controls.Add("Forms.TextBox.1")
        With txtB1
            .Name = "txtboxds1dl1qo" & i
            .Height = 18
            .Width = 43
            .Left = 186
            .Top = 24 * (i - 1) + 228
        End With

        'ADD OPENING WIDTH
        Set txtB1 = Controls.Add("Forms.TextBox.1")
        With txtB1
            .Name = "txtboxds1dl1ow" & i
            .Height = 18
            .Width = 43
            .Left = 246
            .Top = 24 * (i - 1) + 228
        End With

        'ADD OPENING HEIGHT
        Set txtB1 = Controls.Add("Forms.TextBox.1")
        With txtB1
            .Name = "txtboxds1dl1oh" & i
            .Height = 18
            .Width = 43
            .Left = 306
            .Top = 24 * (i - 1) + 228
        End With

        'ADD FINISH NET WIDTH
        Set txtB1 = Controls.Add("Forms.TextBox.1")
        With txtB1
            .Name = "txtboxds1dl1fnw" & i
            .Height = 18
            .Width = 43
            .Left = 378
            .Top = 24 * (i - 1) + 228
        End With

        'ADD FINISH NET HEIGHT
        Set txtB1 = Controls.Add("Forms.TextBox.1")
        With txtB1
            .Name = "txtboxds1dl1fnh" & i
            .Height = 18
            .Width = 43
            .Left = 444
            .Top = 24 * (i - 1) + 228
        End With

        'ADD QUANTITY
        Set txtB1 = Controls.Add("Forms.TextBox.1")
        With txtB1
            .Name = "txtboxds1dl1q" & i
            .Height = 18
            .Width = 43
            .Left = 522
            .Top = 24 * (i - 1) + 228
        End With

        'ADD WIDTH
        Set txtB1 = Controls.Add("Forms.TextBox.1")
        With txtB1
            .Name = "txtboxds1dl1w" & i
            .Height = 18
            .Width = 43
            .Left = 575
            .Top = 24 * (i - 1) + 228
        End With

        'ADD HEIGHT
        Set txtB1 = Controls.Add("Forms.TextBox.1")
        With txtB1
            .Name = "txtboxds1dl1h" & i
            .Height = 18
            .Width = 43
            .Left = 627
            .Top = 24 * (i - 1) + 228
        End With

         'ADD AREA (SQ FT.)
        Set txtB1 = Controls.Add("Forms.TextBox.1")
        With txtB1
            .Name = "txtboxds1dl1a" & i
            .Height = 18
            .Width = 43
            .Left = 678
            .Top = 24 * (i - 1) + 228
        End With

        Call AdjustScrollBar ' Adjust scroll bar to account for new rows

    Next i

    Call AdjustFormHeight ' Adjust form height to account for new rows

End With


End Sub

我希望得到的结果是在触发此代码之后,将表单保存到内存中,并像以这种方式启动表单一样使用它。我希望能够根据用户输入自动进行各种更改,并具有监视和引用更改的所有功能的全部功能。

感谢您的帮助

1 个答案:

答案 0 :(得分:0)

这是一个非常简单的示例,它仅将控件链接到工作表单元格:以这种形式,可以通过设置ControlSourcehttps://www.ozgrid.com/Excel/free-training/ExcelVBA2/excelvba2lesson15.htm)来更轻松地处理它,但是如果您希望它更灵活(即能够验证输入),那么您将需要处理事件并以此方式进行操作。

事件处理类“ clsControl”的代码:

Option Explicit

Public linkedCell As Range
Public WithEvents cbo As MSForms.ComboBox
Public WithEvents txt As MSForms.TextBox

Private Sub cbo_Change()
    'here you handle the change in a combo box
    Me.linkedCell.Value = cbo.Value
End Sub

Private Sub txt_Change()
    'here you handle the change in a text box
    Me.linkedCell.Value = txt.Value
End Sub

用户表单中的代码:

Option Explicit

Private ControlsCollection As Collection

Private Sub UserForm_Activate()

    Dim n As Long, t As Long, rngCombo As Range, rngTxt As Range
    Dim con As Object

    Set ControlsCollection = New Collection

    t = 20 'top position
    'start positions for linked cells
    Set rngCombo = Sheet2.Range("A2")
    Set rngTxt = Sheet2.Range("C2")

    For n = 1 To 10

        Set con = Me.Controls.Add("Forms.ComboBox.1", "cmbo_" & n)
        With con
            .Height = 18
            .Width = 72
            .Left = 18
            .top = t + (n - 1) * 25
            .RowSource = "Some_List"
        End With
        ControlsCollection.Add ControlWrapper(con, rngCombo.Offset(n - 1, 0))

        Set con = Me.Controls.Add("Forms.TextBox.1", "txt_" & n)
        With con
            .Height = 18
            .Width = 72
            .Left = 100
            .top = t + (n - 1) * 25
        End With
        ControlsCollection.Add ControlWrapper(con, rngTxt.Offset(n - 1, 0))

    Next n

End Sub

'Create an instance of our event-handling class, and assign a control
'   and a linked cell
Private Function ControlWrapper(con As Object, rng As Range) As clsControl
    Dim rv As New clsControl
    'assign to the appropriate control type in the calss instance
    Select Case TypeName(con)
        Case "ComboBox": Set rv.cbo = con
        Case "TextBox": Set rv.txt = con
    End Select
    Set rv.linkedCell = rng
    Set ControlWrapper = rv
End Function

在填写一些值之后,生成的forn和链接的单元格:

enter image description here