Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/vba/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Excel UserForm动态文本框控件退出事件_Excel_Vba_Events_Userform - Fatal编程技术网

Excel UserForm动态文本框控件退出事件

Excel UserForm动态文本框控件退出事件,excel,vba,events,userform,Excel,Vba,Events,Userform,更新:在对象浏览器中进一步研究后。。。MSForms.TextBox似乎既不实现.Name属性,也不实现_exitevents-only _Change事件。有没有办法确定哪个特定的文本框生成了更改事件 或者,是否可以使用此技术使用MSForms.Control?控件对象实现.Name属性和_Exit事件 你能监听文本框退出事件吗?类似于普通文本框事件的工作方式?例如 Private Sub TextBox1_Exit(ByVal Cancel As MSForms.ReturnBoolea

更新:在对象浏览器中进一步研究后。。。MSForms.TextBox似乎既不实现.Name属性,也不实现_exitevents-only _Change事件。有没有办法确定哪个特定的文本框生成了更改事件

或者,是否可以使用此技术使用MSForms.Control?控件对象实现.Name属性和_Exit事件

你能监听文本框退出事件吗?类似于普通文本框事件的工作方式?例如

  Private Sub TextBox1_Exit(ByVal Cancel As MSForms.ReturnBoolean)
        'Update a certain label based on the value of the TextBox
  End Sub
以下内容未捕获退出事件。此外,虽然我可以在“本地人”窗口中看到为MyTextBox生成事件的TextBox的.Name属性,但我无法访问该信息来确定要对哪个标签执行操作

这门课的技巧是根据和改编的,它抓住了变化事件

类clsTextBox:

Private WithEvents MyTextBox As MSForms.TextBox

Public Property Set Control(tb As MSForms.TextBox)
    Set MyTextBox = tb
End Property

' Want to handle this event, but it's not caught when exiting the TextBox control
Private Sub MyTextBox_Exit(ByVal Cancel As MSForms.ReturnBoolean)
    'Debug.Print me.Control.name
    'Update a certain label based on the value of the TextBox
    Stop
End Sub

' Catching this event but can't identify the control which triggered it
Private Sub MyTextBox_Change()
    Debug.Print MyTextBox.Value ' <--- This prints the correct value
    Debug.Print Me.Control.Name ' <--- ERROR here on any variation of Me or MyTextBox
    'Update a certain label based on the value of the TextBox
    Stop
End Sub
控件定义输入和退出事件:如果需要处理TextBox.Change,则需要两个WithEvents变量:

Private WithEvents TextBoxEvents As MSForms.TextBox
Private WithEvents ControlEvents As MSForms.Control

Public Property Set Control(ByVal tb As Object)
    Set TextBoxEvents = tb
    Set ControlEvents = tb
End Property
控件也是一个接口,通过它您可以访问诸如名称、顶部、左侧、可见等属性

提示:切勿手动键入事件处理程序过程签名。从代码窗格左上角的下拉列表中选择源接口,然后从右上角的下拉列表中选择要处理的事件;让VBE生成具有正确签名的成员。如果您在处理程序过程中,且左上角的下拉列表显示为general,则您不在事件处理程序中

编辑 虽然上面的代码编译得很好,MSForms.Control接口确实公开了我们希望处理的事件

?TypeOf tb Is MSForms.Control
True
?TypeOf tb Is MSForms.TextBox
True

……幕后有一些网络黑客;VBA有足够的烟雾和镜子来成功编译上述内容,但是,基本上,您看到的是Matrix RuberDuck的解析器中的一个小故障,它与MSForms控件有类似的nope问题:没有任何明显的方法可以让VBA将动态控件对象绑定到其MSForms.control事件。

在ConnectToConnectionPoint API的帮助下,您可以捕获每个事件,也可以输入和退出每个控件

请看这里:

对于出口,它将是

Public Sub myExit(ByVal Cancel As MSForms.ReturnBoolean)
Attribute myExit.VB_UserMemId = -2147384829
'code
End Sub

在类MyTextBox中是相关联的textbox,而不是类的实例itself@TimWilliams我也试过同样的错误。MSForms.TextBox似乎既不实现.Name属性,也不实现_exitevents-onlt _Change事件。有没有办法确定哪个特定的文本框生成了事件?如果无法从MyTextBox中获取名称,则可以将其存储为类中的另一个属性/字段…@ZephyrMays尝试将tb声明为对象,并再次检查WithEvents字段的声明为类型…@ZephyrMays wah我缺少一些内容。。。即时窗格:设置o=UserForm1.Controls.AddForms.TextBox.1,则?o的类型为MSForms.Control-表示为True。但是Set thing.Control=o->不支持事件。奇怪…@Zephyrmais这是。。。复杂的这是一个原因,就是很难弄清楚MSForms控件接口。。。看来VBA的日子也不好过。这不完全是继承,只是。。某种涉及在运行时表单设计器上附加的接口的COM攻击本质上是运行时的。看起来它阻止VBA正确绑定事件源,即使在编译时没有问题。“你把我狠狠地揍了一顿。@Zephyrmais看起来和MSForms无关。不过还是控制事件吧。我发现:-看起来他们有一个可下载的解决方案,但我不确定我是否会信任从某个随机论坛随机下载的内容。这可能有效。请记住,在编译项目后执行在运行时生成的代码时,无法使用断点进行调试,这会使应用程序更容易崩溃,并且需要提升的宏安全设置以及运行VBIDE API的特定权限。经常储蓄!
Public Sub myExit(ByVal Cancel As MSForms.ReturnBoolean)
Attribute myExit.VB_UserMemId = -2147384829
'code
End Sub