受 Dirk 解决方案的启发,我添加了一些功能来使表单动态化。这只是为了展示这个概念,它确实与原始问题有关,特别是处理来自输入的动态范围的列。不同之处在于该数组考虑了输入列的动态范围,然后根据数组中的项目数量创建文本框。
这是做什么的:
- 命令按钮使用范围的 lastCol 变量复制行(例如:“A”)。您可以绕过这一点,因为用户窗体将粘贴剪贴板而不管其来源如何,前提是您已经复制了该行。
- 打开带有 1 个文本框的用户表单
- 剪贴板内容会自动粘贴到 Text1 中。
- 创建了一个数组,将 Text1 的值按 TAB 分开。
- 用户窗体已调整大小以适合每个文本框。
- 对于数组中的每一项(不包括要分配给 Text1 的索引 (0)),都会创建一个新的 TextBox 并分配数组值。
- 关闭用户窗体后,除 Text1 外的所有名称以“Text”开头的 TextBox 都将被删除,重新设置表单以供下次使用。
注意事项:
- 使用这种命名方法,TextBoxes 将被命名为“Text1” - “Text(n)”
- 我不包括文本框的标签。
- 如果您有大量的列/文本框,请在用户窗体上设置属性。
'ScrollBars = 2 fmScrollBarsVertical'
可选: 事件从 Row1 复制数据并启动 UserForm,放置在模块中。
Sub DynamicTextFormLaunch()
Dim lastCol As Long
lastCol = ActiveSheet.Cells(1, Columns.count).End(xlToLeft).column
With ActiveSheet
.Range("A1", (.Cells(1, lastCol))).Copy
UserFormName.Show 'Set your UserForm name here
End With
End Sub
用户表单代码:下面的所有内容都在用户表单代码中
Sub UserForm_Activate()
Text1.Paste
End Sub
文字改变事件:
Sub Text1_Change()
Dim csvArray() As String
Dim lCount As Long, maxCols As Long
Dim tempHeight As String
csvArray = Split(Text1.Value, vbTab)
maxCols = UBound(csvArray) + 1
Text1.Value = csvArray(0)
tempHeight = 55 + (15.5 * maxCols) 'Set new height for 15.5 pixels per TextBox
Me.Height = tempHeight
For lCount = 2 To maxCols 'Not using 1 for Loop because Text1 was already set.
'Create a new TextBox and assign its size, name, and value.
Set ctlTXT = Controls.Add("Forms.TextBox.1", "Text" & lCount)
ctlTXT.name = "Text" & lCount
ctlTXT.Left = 15
ctlTXT.Height = 15: ctlTXT.Width = 100
ctlTXT.Top = (lCount - 1) * 17 + 2
ctlTXT.Value = csvArray(lCount - 1) 'Set the value of the new TextBox
Next lCount
End Sub
关闭事件:
Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer)
Call ResetBoxes
End Sub
删除已创建的文本框。
Private Sub ResetBoxes()
Dim ctrl As Control
Dim tempName As String
Dim tempNum As String
For Each ctrl In Me.Controls
tempName = Left(ctrl.name, 4)
tempNum = Right(ctrl.name, 1)
'Checking to NOT delete Text1
If tempName = "Text" And tempNum <> "1" Then
Me.Controls.Remove (ctrl.name)
End If
Next
MsgBox ("Removed new TextBoxes, and reset UserForm to original controls.")
End Sub