2017-08-05 78 views
1

我在Excel中創建了一個表單。它由3個命令按鈕和一個包含複選框的框架組成。根據Excel工作表中的表格,該複選框在userform_initialize處動態填充(該想法易於用戶定製)。該框架的原因是可以有很多複選框,我希望用戶能夠滾動瀏覽它們。無法將Userform.KeyPreview設置爲true

我現在的目標是爲表單創建鍵盤快捷鍵。我陷入困境的是,我不能蠻力爲每個複選框寫KeyDown處理程序,因爲我不知道哪些將會存在。我意識到,如果我可以在表單級別擁有事件處理程序,它也會更好。谷歌搜索找到了我的形式的KeyPreview財產。不幸的是,VBA IDE中的屬性窗口沒有顯示它,當我嘗試通過設置Me.KeyPreview = Trueuserform_initialize以編程方式訪問它時,VBA會發出編譯錯誤:「找不到方法或數據成員」 - 我期望它不是在屬性窗口中,但值得一試。

我覺得好像有什麼東西,我明顯缺失的,所以我想我會花時間學習如何寫,然後完全重寫的形式,一類是在MSDN示例代碼之前問: https://msdn.microsoft.com/en-us/library/system.windows.forms.form.keypreview(v=vs.110).aspx。 我幸運嗎?

我承認正處於我的VBA知識的極限,我正在尋求擴展它。任何一般的概念或上下文,我應該紅,將不勝感激。

UPDATE

現在我想GetAsyncKeyStateApplication.Onkey

據我所知,GetAsyncKeyState只能在無限的DoEvents循環內工作。我試圖啓動一個希望表單仍然會加載,但當然沒有 - 我卡在循環中。

Application.Onkey的問題是我無法將事件函數分配給userform模塊中的鍵。這使我感到困惑,因爲其他事件處理程序可以進入用戶表單模塊。實際上,我將它放在Userform_Initialize程序中。是因爲它不是表單事件而是應用程序事件?

編輯

我似乎有一些作品,但奇怪的問題說明如下: Event handling class will not fire unless I use a breakpoint when initializing form 謝謝@UGP

+0

該鏈接適用於VB.NET而不是VBA。它不能簡單地應用於它。 'KeyPreview'只是Access VBA中的一種方法,不適用於Excel。 – UGP

+0

也許[this](https://codereview.stackexchange.com/questions/44361/form-controls-single-event-handler-for-multiple-controls-without-sacrifices)可以幫助你。 – UGP

+0

非常感謝@UGP,直到最後我都充滿希望。招貼說「'KeyPress'是一種特殊情況 - 通過在表單級別開啓'KeyPreview',我可以在窗體的'Form_KeyPress'事件中捕獲所需的KeyAscii到'mLastKeyPressedAscii'中,並且通過」。看來我回到了第一位?此外,上面發佈更新。 – PKB

回答

0

下面是一個例子它如何工作,發現here

擺在名爲 「的KeyPreview」 一類:

Option Explicit 

Dim WithEvents u As MSForms.UserForm 
Dim WithEvents t As MSForms.TextBox 
Dim WithEvents ob As MSForms.OptionButton 
Dim WithEvents lb As MSForms.ListBox 
Dim WithEvents dp As MSComCtl2.DTPicker 

Event KeyDown(ByVal KeyCode As Integer, ByVal Shift As Integer) 
'Event KeyPress(ByVal KeyAscii As Integer) 

Private FireOnThisKeyCode As Integer 

Friend Sub AddToPreview(Parent As UserForm, KeyCode As Integer) 
Dim c As Control 
Set u = Parent 
FireOnThisKeyCode = KeyCode 
For Each c In Parent.Controls 
Select Case TypeName(c) 
Case "TextBox" 
Set t = c 
Case "OptionButton" 
Set ob = c 
Case "ListBox" 
Set lb = c 
Case "DTPicker" 
Set dp = c 
End Select 
Next c 
End Sub 

Private Sub u_KeyDown(ByVal KeyCode As MSForms.ReturnInteger, ByVal Shift As Integer) 
If KeyCode = FireOnThisKeyCode Then RaiseEvent KeyDown(KeyCode, Shift) 
End Sub 

Private Sub t_KeyDown(ByVal KeyCode As MSForms.ReturnInteger, ByVal Shift As Integer) 
If KeyCode = FireOnThisKeyCode Then RaiseEvent KeyDown(KeyCode, Shift) 
End Sub 

Private Sub ob_KeyDown(ByVal KeyCode As MSForms.ReturnInteger, ByVal Shift As Integer) 
If KeyCode = FireOnThisKeyCode Then RaiseEvent KeyDown(KeyCode, Shift) 
End Sub 

Private Sub lb_KeyDown(ByVal KeyCode As MSForms.ReturnInteger, ByVal Shift As Integer) 
If KeyCode = FireOnThisKeyCode Then RaiseEvent KeyDown(KeyCode, Shift) 
End Sub 

Private Sub dp_KeyDown(KeyCode As Integer, ByVal Shift As Integer) 
If KeyCode = FireOnThisKeyCode Then RaiseEvent KeyDown(KeyCode, Shift) 
End Sub 

要放在用戶窗體:

Option Explicit 

Dim WithEvents kp As KeyPreview 

Private Sub UserForm_Initialize() 
Set kp = New KeyPreview 
kp.AddToPreview Me, 114 
End Sub 

Private Sub kp_KeyDown(ByVal KeyCode As Integer, ByVal Shift As Integer) 
MsgBox "F3 was pressed..." 
End Sub 

它與TextBoxesOptionButtonsListBoxesDTPickers。需要重點關注的其他控件也需要處理。

+0

非常感謝@UGP!可能還有幾天,我可以放棄這一點,因爲9-5的工作並不是如此9-5,但我感謝你的幫助! – PKB

+0

再次感謝@UGP,你可以從https://stackoverflow.com/questions/45662687/event-handling-class-will-not-fire-unless-i-use-a-breakpoint-when-initializing-如果你的方法似乎有效,但我遇到了一個奇怪的問題,我認爲它是自己的帖子。 – PKB

相關問題