这是以下问题的后续: Can't set Userform.KeyPreview to true

总结一下:目标是构建一个带有一些命令按钮和一个包含复选框的框架的表单。 复选框在框架中的userform_initialize处动态填充,因此用户可以滚动浏览它们。 我的问题是键盘快捷键。 不可能为每个复选框强制编写 KeyDown 处理程序,因为我不知道哪些会存在。 不幸的是,Excel 不支持KeyPreview所以我不得不模拟我自己的版本。 感谢@UGP 为我提供了看似有效但并不完全有效的途径...

首先,这是我的类模块clsReasonPickKP 我为每个复选框创建一个新实例来监听KeyDown事件:

Option Explicit

Dim WithEvents vChkBx As MSForms.CheckBox

Friend Sub initializeListener(cControl As control)
Set vChkBx = cControl
End Sub

Private Sub vChkBx_KeyDown(ByVal keyCode As MSForms.ReturnInteger, ByVal shift As Integer)
frm2.keyChooser keyCode
End Sub

frm2.keyChooser keyCode启动位于用户frm2.keyChooser keyCode代码模块中的快速子。 代码如下:

Public Sub keyChooser(ByVal keyCode As MSForms.ReturnInteger)
Select Case keyCode
    Case vbKeyEscape: cancelBtn_Click
    Case vbKeyReturn: completeDecision_Click
    Case vbKeyN: customizeNote_Click
    Case vbKeyS: resetDecisionNote_Click
    Case vbKeyR: chkRefGrnds_Click
End Select
End Sub

我已经复制了下面UserForm_Initialize子的相关部分。 循环为每个创建复选框和事件侦听器。

Sub UserForm_Initialize()
Dim x As Long, maxWidth as Long
Dim cControl As control
Dim keyPreviewCollection As New Collection
Dim keyPreviewer As clsReasonPickKP
For x = 1 To dTbl.Rows.Count - 1
    Set cControl = chkBoxFrame.Controls.Add("Forms.CheckBox.1", "chkBox" & x, True)
    With cControl
        .AutoSize = True
        .WordWrap = False
        .Left = 10
        .Top = 16 * x - 12
        .Caption = dTbl(x, 1).Value
        If .Width > maxWidth Then maxWidth = .Width
    End With
Set keyPreviewer = New clsReasonPickKP
keyPreviewer.initializeListener cControl
keyPreviewCollection.Add keyPreviewer
Next x
'Additional initialization code here
End Sub

奇怪的是,除非我在keyPreviewCollection.Add keyPreviewer之后破坏代码,否则监听器似乎不会处理该事件。 例如,如果我在Next xx > 1处设置断点,然后完成初始化,那么当表单完成初始化并出现时,侦听器调用keyChooser并且一切正常; 如果我不那样破坏代码,它就不会捕获事件或调用 sub 等。

为了keyPreviewer故障,我尝试不将keyPreviewer添加到集合中,然后无论我是否中断或何时中断,侦听器也不起作用。 似乎将对象添加到集合中,并在将其添加到集合后处于代码中断模式,以某种方式使侦听器捕获事件。

同样有趣的是,如果我在vChkBx_KeyDown模块中放置一个断点,它会在引发事件时中断(假设如上所述的适当中断)。 但是,在我运行代码之后,它会在KeyDown事件引发时停止处理它。

如果有帮助,我目前正在使用 Excel 2010。

有人知道发生了什么吗? 知道如何解决这个问题,即使使用不同的代码方法?

一如既往地感谢大家的帮助。

#1楼 票数:1 已采纳

原来,问题就这么简单,就在我眼前。 我只需要在我的用户表单代码模块中公开keyPreviewerkeyPreviewCollection变量。

这仍然不能回答为什么在将对象添加到集合后破坏代码执行使 VBA 将其视为公共的,但很高兴一切正常。

#2楼 票数:0

DoEvents 可能是票。 请参阅下面的文章:

https://www.automateexcel.com/vba/doevents/

  ask by PKB translate from so

未解决问题?本站智能推荐:

1回复

用户形式的事件顺序

因此,如果我在用户窗体中具有此功能: 我在所说的用户表单上有单独命令按钮的click事件: 我的问题是,当我从某个地方调用该函数(“ MyFunc”)时,按钮(“ cmdButton”)的单击事件会在允许该函数继续运行之前继续进行处理,还是基本上是抛硬币? 此stringVar
1回复

动态定义的复选框的 Excel VBA 事件未触发

这是我在这个论坛上的第一篇文章。 到目前为止,我已经通过浏览可用答案设法解决了所有困难。 这次不行了 我使用这个示例创建了一个自填充用户窗体 (Userform1),其中包含一些复选框,其中包含以示例中描述的方式定义的事件,方法是使用要运行的代码创建类模块并将类子分配给复选框。 然后将 UserF
1回复

如何绕过用户表单中其他子项的卸载?

此段代码检查用户窗体文本框中的重复值,并强制用户填写信息。 很棒! 我唯一的问题是,现在我无法在不触发事件的情况下卸载用户窗体,如果我要完全取消,那是个问题...(我有一些要启动...) 您对如何绕过或阻止此操作有任何想法吗? 我尝试将事件抑制为布尔值,关闭显示警报无效...
3回复

Excel VBA-更新ComboBox时暂停事件

我有一个用VBA for Excel编写的应用程序,可以接收实时数据提要。 只要数据发生变化,VBA内就会触发各种事件。 我也有一些带有ComboBoxes的UserForm。 我的问题是,当我单击组合框上的向下箭头并尝试进行选择时,当我从数据源中获取更新时,组合框就会重置。 我想做
2回复

设置 ForeColor 不会在退出事件中执行

我有一个带有两个滚动条的小型用户表单,用于更改单元格值。 它们按 Tab 键顺序排列,我想在它们获得焦点时显示。 因此,我在Enter上更改了它们的前景色,并在Exit上将其改回。 除了颜色没有变回外,一切正常。 它在 Enter 时发生变化,但在 Exit 时不会发生变化。 这是其中之一的代码。
2回复

动态定义VBA中复选框的事件

我已经为我的用户窗体动态定义了复选框。 看代码: 好吧,对于这些复选框,我需要一个“点击”事件。 例如: 我怎样才能使动态? 我不需要命令按钮。 这意味着,当用户单击复选框时,事件处理程序将启动。
1回复

VBA-在动态创建的文本框上捕获事件

我正在用Excel编写VBA应用程序。 我有一个用户窗体,该窗体根据其中一个工作表中包含的数据动态地自行构建。 创建各种组合框,文本框和标签的所有代码都在工作。 我创建了一个类模块来捕获Combobox的OnChange事件,然后再次按预期工作。 现在,我需要为某些文本框捕获OnChan
2回复

Excel UserForm动态TextBox控件退出事件

更新:在对象浏览器中进行进一步研究后,似乎MSForms.TextBox既不实现.Name属性也不实现_Exit事件-仅实现_Change事件。 有没有办法确定哪个特定的TextBox生成了更改事件? 或者可以通过此技术使用MSForms.Control吗? Control对象实现.N