我已经在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
我希望得到的结果是在触发此代码之后,将表单保存到内存中,并像以这种方式启动表单一样使用它。我希望能够根据用户输入自动进行各种更改,并具有监视和引用更改的所有功能的全部功能。
感谢您的帮助
答案 0 :(得分:0)
这是一个非常简单的示例,它仅将控件链接到工作表单元格:以这种形式,可以通过设置ControlSource
(https://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和链接的单元格: