我怎样才能获得对 TextBox 本身的引用,而不是对它在 Excel vba 中的默认值的引用?
How can I get a reference to a TextBox itself instead of to its default value in Excel vba?
Windows 10 专业版 64、Office 365 Excel vba
ClassCounter 是一个 class,它对其内部存储的 Long 值进行操作,然后在活动用户窗体的文本框中显示该值。我希望能够动态地将 TextBox 分配给 ClassCounter 对象,这样我就可以使用相同的 class 来实例化多个对象,每个对象都在同一个 UserForm 中引用自己的 TextBox。
它在 class 级别声明了以下私有成员:
Private mctrLinked As ClassCounter
Private mnCount As Long
Private mtbxDisplay As TextBox
Initialize 子例程在 displayTextBox(用于显示值的文本框)和对象之间建立连接。 linkCounter 提供机会 link 到相同 class 的另一个对象,并以菊花链方式在其上启动相同的操作。
Public Sub Initialize(ByRef displayTextBox As msforms.TextBox, Optional linkCounter As ClassCounter = Nothing)
Const kstrMethodName As String = "Initialize"
Set mtbxDisplay = displayTextBox
Set mctrLinked = linkCounter
Clear
End Sub ' Initialize
在另一个class中实例化了class,如下:
Private mobjAllBlankCounter As New ClassCounter
Private mobjAllEnteredCounter As New ClassCounter
Private mobjAllFoundCounter As New ClassCounter
Private mobjAllIssuesCounter As New ClassCounter
...
TextBox 和 ClassCounter 对象之间的连接是通过调用 Initialize 子程序建立的:
Public Sub InitializeAllCounters()
With mufMCP
mobjAllBlankCounter.Initialize .tbxBlankCountAll
mobjAllEnteredCounter.Initialize .tbxEnteredCountAll
mobjAllFoundCounter.Initialize .tbxFoundCountAll
mobjAllIssuesCounter.Initialize .tbxIssuesCountAll
End With
End Sub ' InitializeAllCounters
其中 mufMCP 是定义文本框的用户窗体。
最终,Increment 函数(以及其他类似函数)将对存储的变量进行操作,然后将其显示在引用的 TextBox 中,如下所示:
Public Sub Increment()
Const kstrMethodName As String = "Increment"
If (mtbxDisplay Is Nothing) Then
Err.Raise gknErrNoControlForCounter, mkstrModuleName & "." & kstrMethodName, "Attempt to Increment Counter with no associated control."
Else
mnCount = mnCount + 1
mtbxDisplay.Text = CStr(mnCount)
If (Not (mctrLinked Is Nothing)) Then
mctrLinked.Increment
End If
End If
End Sub ' Increment
我遇到的问题是在 Initialize
子例程中,我试图在该子例程中将 TextBox 参数的值分配给局部变量。分配的右侧不是分配对 TextBox 本身的引用,而是评估 TextBox 的默认值,即它的 Text
属性。结果,我收到类型不匹配错误。
如何让它计算为对 TextBox 本身的引用?我花了几天时间寻找答案并找到了几个消息来源说使用 ByRef displayTextBox As msforms.TextBox
定义参数可以解决问题,但我仍然得到控件的默认值。
正如 FaneDuru 所写,TextBox
和 MsForms.TextBox
是两种不同的对象类型。 TextBox
是放置在 sheet 上的文本框(表单控件,而不是 Active X 控件)。 MsForms.TextBox
是放置在用户表单上的文本框。
坏事 (1):与 sheet 控件相关的名称“表单控件”具有误导性,它与放置在用户表单上的控件不同。
坏事 (2):由于开发人员菜单中不再提供表单控件文本框,因此证明起来并不容易。如果您有兴趣:您仍然可以使用 VBA.
创建它们
Dim tb1 As TextBox
Set tb1 = ActiveSheet.TextBoxes.Add(255, 243, 73.5, 22.5)
Dim tb2 As msforms.TextBox
UserForm1.Show False
Set tb2 = UserForm1.TextBox1
在 VBA 编辑器的 Locals window 中检查两个对象,两者的类型显示为“Textbox/Textbox”。但是,当您查看对象的属性时,您会发现它们是不同的。
因此,使用后缀 msforms
声明所有(用户窗体)控件,以确保您处理的是正确的对象类型。
Windows 10 专业版 64、Office 365 Excel vba
ClassCounter 是一个 class,它对其内部存储的 Long 值进行操作,然后在活动用户窗体的文本框中显示该值。我希望能够动态地将 TextBox 分配给 ClassCounter 对象,这样我就可以使用相同的 class 来实例化多个对象,每个对象都在同一个 UserForm 中引用自己的 TextBox。
它在 class 级别声明了以下私有成员:
Private mctrLinked As ClassCounter
Private mnCount As Long
Private mtbxDisplay As TextBox
Initialize 子例程在 displayTextBox(用于显示值的文本框)和对象之间建立连接。 linkCounter 提供机会 link 到相同 class 的另一个对象,并以菊花链方式在其上启动相同的操作。
Public Sub Initialize(ByRef displayTextBox As msforms.TextBox, Optional linkCounter As ClassCounter = Nothing)
Const kstrMethodName As String = "Initialize"
Set mtbxDisplay = displayTextBox
Set mctrLinked = linkCounter
Clear
End Sub ' Initialize
在另一个class中实例化了class,如下:
Private mobjAllBlankCounter As New ClassCounter
Private mobjAllEnteredCounter As New ClassCounter
Private mobjAllFoundCounter As New ClassCounter
Private mobjAllIssuesCounter As New ClassCounter
...
TextBox 和 ClassCounter 对象之间的连接是通过调用 Initialize 子程序建立的:
Public Sub InitializeAllCounters()
With mufMCP
mobjAllBlankCounter.Initialize .tbxBlankCountAll
mobjAllEnteredCounter.Initialize .tbxEnteredCountAll
mobjAllFoundCounter.Initialize .tbxFoundCountAll
mobjAllIssuesCounter.Initialize .tbxIssuesCountAll
End With
End Sub ' InitializeAllCounters
其中 mufMCP 是定义文本框的用户窗体。
最终,Increment 函数(以及其他类似函数)将对存储的变量进行操作,然后将其显示在引用的 TextBox 中,如下所示:
Public Sub Increment()
Const kstrMethodName As String = "Increment"
If (mtbxDisplay Is Nothing) Then
Err.Raise gknErrNoControlForCounter, mkstrModuleName & "." & kstrMethodName, "Attempt to Increment Counter with no associated control."
Else
mnCount = mnCount + 1
mtbxDisplay.Text = CStr(mnCount)
If (Not (mctrLinked Is Nothing)) Then
mctrLinked.Increment
End If
End If
End Sub ' Increment
我遇到的问题是在 Initialize
子例程中,我试图在该子例程中将 TextBox 参数的值分配给局部变量。分配的右侧不是分配对 TextBox 本身的引用,而是评估 TextBox 的默认值,即它的 Text
属性。结果,我收到类型不匹配错误。
如何让它计算为对 TextBox 本身的引用?我花了几天时间寻找答案并找到了几个消息来源说使用 ByRef displayTextBox As msforms.TextBox
定义参数可以解决问题,但我仍然得到控件的默认值。
正如 FaneDuru 所写,TextBox
和 MsForms.TextBox
是两种不同的对象类型。 TextBox
是放置在 sheet 上的文本框(表单控件,而不是 Active X 控件)。 MsForms.TextBox
是放置在用户表单上的文本框。
坏事 (1):与 sheet 控件相关的名称“表单控件”具有误导性,它与放置在用户表单上的控件不同。
坏事 (2):由于开发人员菜单中不再提供表单控件文本框,因此证明起来并不容易。如果您有兴趣:您仍然可以使用 VBA.
创建它们Dim tb1 As TextBox
Set tb1 = ActiveSheet.TextBoxes.Add(255, 243, 73.5, 22.5)
Dim tb2 As msforms.TextBox
UserForm1.Show False
Set tb2 = UserForm1.TextBox1
在 VBA 编辑器的 Locals window 中检查两个对象,两者的类型显示为“Textbox/Textbox”。但是,当您查看对象的属性时,您会发现它们是不同的。
因此,使用后缀 msforms
声明所有(用户窗体)控件,以确保您处理的是正确的对象类型。