表单内部的自定义VBA UserForm热键

表单内部的自定义VBA UserForm热键,vba,excel,userform,Vba,Excel,Userform,我希望在不使用快捷键的情况下关闭userform(或其他命令) 例如,当用户按F4时,将从Excel打开以下表单。我也希望它关闭(卸载我)与F4太 这就是我目前正在使用的,尽管它看起来不必要的大: Private Sub TextBoxA_KeyDown(ByVal keycode As MSForms.ReturnInteger, ByVal Shift As Integer) moveme Val(keycode) End Sub Private Sub TextBoxB_KeyDown(B

我希望在不使用快捷键的情况下关闭userform(或其他命令)

例如,当用户按F4时,将从Excel打开以下表单。我也希望它关闭(卸载我)与F4太

这就是我目前正在使用的,尽管它看起来不必要的大:

Private Sub TextBoxA_KeyDown(ByVal keycode As MSForms.ReturnInteger, ByVal Shift As Integer)
moveme Val(keycode)
End Sub
Private Sub TextBoxB_KeyDown(ByVal keycode As MSForms.ReturnInteger, ByVal Shift As Integer)
moveme Val(keycode)
End Sub
Private Sub TextBoxC_KeyDown(ByVal keycode As MSForms.ReturnInteger, ByVal Shift As Integer)
moveme Val(keycode)
End Sub
Private Sub TextBoxD_KeyDown(ByVal keycode As MSForms.ReturnInteger, ByVal Shift As Integer)
moveme Val(keycode)
End Sub
Private Sub TextBoxE_KeyDown(ByVal keycode As MSForms.ReturnInteger, ByVal Shift As Integer)
moveme Val(keycode)
End Sub
Private Sub TextBoxF_KeyDown(ByVal keycode As MSForms.ReturnInteger, ByVal Shift As Integer)
moveme Val(keycode)
End Sub
Private Sub TextBoxG_KeyDown(ByVal keycode As MSForms.ReturnInteger, ByVal Shift As Integer)
moveme Val(keycode)
End Sub
Private Sub TextBoxH_KeyDown(ByVal keycode As MSForms.ReturnInteger, ByVal Shift As Integer)
moveme Val(keycode)
End Sub
Private Sub TextBoxI_KeyDown(ByVal keycode As MSForms.ReturnInteger, ByVal Shift As Integer)
moveme Val(keycode)
End Sub
Private Sub TextBoxJ_KeyDown(ByVal keycode As MSForms.ReturnInteger, ByVal Shift As Integer)
moveme Val(keycode)
End Sub
Private Sub TextBoxK_KeyDown(ByVal keycode As MSForms.ReturnInteger, ByVal Shift As Integer)
moveme Val(keycode)
End Sub
Private Sub TextBoxM_KeyDown(ByVal keycode As MSForms.ReturnInteger, ByVal Shift As Integer)
moveme Val(keycode)
End Sub
Private Sub TextBoxN_KeyDown(ByVal keycode As MSForms.ReturnInteger, ByVal Shift As Integer)
moveme Val(keycode)
End Sub
Private Sub TextBoxO_KeyDown(ByVal keycode As MSForms.ReturnInteger, ByVal Shift As Integer)
moveme Val(keycode)
End Sub
Sub moveme(keycode As Integer)
If keycode = 115 Then Unload Me
End Sub
我想我在找这样的东西,但我不知道:

loop:
Private Sub TextBox[i]_KeyDown(ByVal keycode As MSForms.ReturnInteger, ByVal Shift As Integer)
Sub moveme(keycode As Integer)
If keycode = 115 Then Unload Me
End Sub

每个文本框都需要自己的事件处理程序,原因有很多,而且,虽然我知道您想要做什么,但您不能在过程之外执行语句,因此您不能在过程之外创建一系列
私有子文本框[I]…

幸运的是,使用
应用程序.OnKey
可能有一种更简单的方法来实现这一点

在标准模块中,如果有一个用于初始化窗体的宏,请执行以下操作:

Sub showform()
    'Displays/initializes the form and assigns hotkey function to F4
    Application.OnKey "{F4}", "CloseForm"
    UserForm1.Show vbModeless
End Sub

Sub CloseForm()
    'Sub to close the userform when F4 is pressed
    Unload UserForm1
    'optionally, revert F4 to its normal behavior
    'Application.OnKey "{F4}"

    'reset F4 to open the form:
    Application.OnKey "{F4}", "showform"
End Sub
如果已经在使用F4打开表单,则需要稍微调整逻辑,例如检查表单是否已显示,或进行一些错误处理等

但有一些问题:在窗体有焦点时不起作用,因此除非窗体显示为
vbModeless
。这在显示的窗体上不起作用,因为当窗体以这种方式显示时,只会识别窗体事件,因此热键不会触发关闭函数,除非它是从窗体对象的事件处理程序调用的


否则,我认为您将无法以现有方式处理每个表单对象的事件,或者可能探索
with events
选项。

在Access中,您可以将一个函数直接放入控件的事件代码框中,包括用于多个控件的相同函数

在Excel和Word中,我认为唯一的方法是使用WithEvents。这里有几个链接,可以链接到这个主题的一些信息。如果这还不够的话,谷歌“ExcelwithEvents”。(WithEvents是一个词。)


大卫和皮特给了我一些很好的研究见解,因此我认为皮特的观点是正确的-Excel先生论坛链接非常有用。出于代码的考虑,我最终得出以下结论,但没有将其标记为正确,因为对于其他用户来说,它可能太窄了

Userform1代码

Dim TBs() As New TBClass

Private Sub UserForm_Initialize()
    Dim TBCount As Integer
    Dim Ctrl As Control
    TBCount = 0
    For Each Ctrl In Absence_Viewer.Controls
        If TypeName(Ctrl) = "TextBox" Then
            TBCount = TBCount + 1
            ReDim Preserve TBs(1 To TBCount)
            Set TBs(TBCount).TBGroup = Ctrl
        End If
    Next Ctrl
'Do other stuff
End Sub
名为TBClass的类模块

Public WithEvents TBGroup As MSForms.TextBox
Private Sub TBGroup_KeyDown(ByVal keycode As MSForms.ReturnInteger, ByVal Shift As Integer)
If keycode = 115 Then Unload Userform1
End Sub

谢谢Pete,我使用了第二个链接的元素来实现这一点。我已经用代码回答了我自己的问题&将你的答案标记为正确的,因为你的答案通常会帮助其他人。谢谢你的评论David,很高兴能了解更多关于这个主题的细节。为了代码的缘故,我已经回答了自己的问题,但由于另一个用户提供了广泛的选项,我将其答案标记为正确,但您的最后一点WithEvents涵盖了这一点。非常感谢。