excel - 单击 TextBox 打开 FileDialog - 在运行时
问题描述
我正在使用表单在运行时生成 3 组文本框。我正在尝试实现这一点:当用户单击组“txtboxe”的文本框时,会打开一个 FileDialog,以便用户可以选择文件。选择文件后,我想获取文件路径。
问题是,通常,我会使用一个子类 - textboxe_Click - 但我需要它在现有模块中工作,并且每个文本框的名称是在运行时生成的。
所以...有什么想法吗?我尝试多次使用带有“控件”命令的东西,但没有任何成功。我设法从每个文本框中选择数据,但不能控制对文本框组的单击或更改。
我在下面提供代码。
Dim i As Long
Dim o As Long
Dim number As Long
number = InputBox("How many docs?", "Number of docs")
Dim txtB1 As Control
Dim txtB2 As Control
For i = 1 To number
Set txtB1 = Controls.Add("Forms.Textbox.1")
With txtB1
.Name = "txtbox" & i
.Height = 16
.Width = 30
.Left = 60
.Top = 20 + (i * 40)
.Value = i
.Locked = True
.BackColor = &H80000000
End With
Set txtB2 = Controls.Add("Forms.Textbox.1")
With txtB2
.Name = "txtboxw" & i
.Height = 18
.Width = 234
.Left = 162
.Top = 20 + (i * 40)
Debug.Print .Name
End With
Set txtB3 = Controls.Add("Forms.Textbox.1")
With txtB3
.Name = "txtboxe" & i
.Height = 18
.Width = 264
.Left = 420
.Top = 20 + (i * 40)
Debug.Print .Name
End With
Next i
End Sub
Private Sub CommandButton3_Click()
Dim p As Long
For p = 1 To number
cells(p + 1, 1) = Controls("txtbox" & p).Value
cells(p + 1, 2) = Controls("txtboxw" & p).Value
cells(p + 1, 3) = Controls("txtboxe" & p).Value
Next p
End Sub ````
解决方案
使用动态创建的控件注册事件处理程序很棘手。
但是您可以使用类模块和WithEvent
变量来做到这一点。
首先,将以下代码添加为 Class Module ControlEvent
。
Option Explicit
Private WithEvents targetCtrl As MSForms.TextBox
Public Sub SetCtrl(new_ctrl As MSForms.TextBox)
Set targetCtrl = new_ctrl
End Sub
' You can add arbitrary event handlers for TextBox as ``targetCtrl_(Event handler name)``
Private Sub targetCtrl_MouseDown(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single)
With Application.FileDialog(msoFileDialogFilePicker)
If .Show() Then
' You can access the control with the targetCtrl class variable
targetCtrl.Value = .SelectedItems(1)
End If
End With
End Sub
然后,将 UserForm 中的代码修改为以下内容。
我添加了一个数组ctrls
来存储ControlEvent
类实例,并使用方法将创建的控件设置为WithEvents
类变量SetCtrl
。
Private ctrls As Variant ' Added
Sub CommandButton2_Click()
Dim i As Long
Dim o As Long
Dim number As Long
number = InputBox("How many docs?", "Number of docs")
Dim txtB1 As Control
Dim txtB2 As Control
Dim txtB3 As Control
ReDim ctrls(0 To number - 1)
For i = 1 To number
Set txtB1 = Controls.Add("Forms.Textbox.1")
With txtB1
.Name = "txtbox" & i
.Height = 16
.Width = 30
.Left = 60
.Top = 20 + (i * 40)
.Value = i
.Locked = True
.BackColor = &H80000000
End With
Set txtB2 = Controls.Add("Forms.Textbox.1")
With txtB2
.Name = "txtboxw" & i
.Height = 18
.Width = 234
.Left = 162
.Top = 20 + (i * 40)
Debug.Print .Name
End With
Set txtB3 = Controls.Add("Forms.Textbox.1")
With txtB3
.Name = "txtboxe" & i
.Height = 18
.Width = 264
.Left = 420
.Top = 20 + (i * 40)
Debug.Print .Name
End With
Set ctrls(i - 1) = New ControlEvent ' Added
ctrls(i - 1).SetCtrl txtB3 ' Added
Next i
End Sub
推荐阅读
- python - 如何根据日期计算行的平均值
- angular - 拖放 svg 元素适用于 Angular 7,但不适用于 Angular 11
- wordpress - 在 wordpress 目录中禁用 https 重定向
- javascript - 在按钮之间添加管道分隔符?
- python - 如何使用 s3 在 dynamo db 中写入多个项目?
- python - Python:测试函数/方法签名是否已更改的正确方法
- logging - 使用 Sybase 和 Java 记录 SQL 和存储过程调用
- java - Java 扫描程序类跳过字符串输入
- api - 我无法使用 Flutter 发出发布请求(注册)
- apache-kafka - 发生错误时 RabbitTransactionManager 不会在 ChainedTransactionManager 处回滚