VBA用户界面:防止键盘上的COMBOBOX ESCAPE

社区,

在列表结束(或开始)时,有一种方法可以防止活动combobox在按下向下箭头(或向上箭头)时失去焦点。 如果有更好的方法来做到这一点(最好有一个MS标准属性),请分享。

问题:当在combobox列表的最后,如果你点击向下的箭头,它会移动到任何控制物理下的活动combobox。 反之亦然,因为在一个combobox的顶部,并击中向上的箭头。 这是草率的,适得其反。 MS Excel 2013。

解决scheme:为了防止这种焦点丢失,在用户窗体的ComboBox代码中,可以input以下内容:

Private Sub Item1_DropDown_KeyDown(ByVal KeyCode As MSForms.ReturnInteger, ByVal Shift As Integer) Select Case KeyCode Case vbKeyDown If Item1_DropDown.ListIndex = Item1_DropDown.ListCount - 1 Then Item1_DropDown.ListIndex = Item1_DropDown.ListIndex - 1 'when at the bottom, stay in active combobox Else: Item1_DropDown.ListIndex = Item1_DropDown.ListIndex 'if not at the bottom, keep moving down End If Case vbKeyUp If Item1_DropDown.ListIndex = 0 Then 'when at the top, stay in active combobox Item1_DropDown.ListIndex = 1 Else: Item1_DropDown.ListIndex = Item1_DropDown.ListIndex 'if not at the top, keep moving up End If End Select ' where "Item1_DropDown" is the name of my combobox End Sub 

好的,这就是我已经能够防止combobox在ComboBox列表的底部/顶部按下/向上时切换到不同的控件。

有谁知道一个更干净的方式来做到这一点? 也许一种方法来做到这一点,而不使用代码?

我不相信那里有一个非代码解决scheme,虽然你可以通过简单地设置KeyCode为0来缩短你的代码

 Private Sub Item1_DropDown_KeyDown(ByVal KeyCode As MSForms.ReturnInteger, ByVal Shift As Integer) Select Case KeyCode Case vbKeyDown If Item1_DropDown.ListIndex = Item1_DropDown.ListCount - 1 Then KeyCode = 0 Case vbKeyUp If Item1_DropDown.ListIndex = 0 Then KeyCode = 0 End Select ' where "Item1_DropDown" is the name of my combobox End Sub 

如果你经常需要这个代码,你可以使用一个类

有一个更光滑的方法来做到这一点。 它将涉及使用一个类模块以及使用一个集合。 这些是一对能够显着改善你的代码的东西(通过缩短代码并使其更加复杂)。

从根本上说,下面的解决scheme是演变的。 这里是:

第1步:创build类模块

 'clsTask (this is the 'name' of your Class Module | the name is important!) Public WithEvents cBox as MSForms.ComboBox 'create a property for your class/object Public Sub cBox_KeyDown(ByVal KeyCode as MSForms.ReturnInteger, ByVal shift as Integer) Select Case KeyCode Case vbKeyDown if cBox.ListIndex = cBox.ListCount - 1 Then KeyCode = 0 Case vbKeyUp if cBox.ListIndex = 0 Then KeyCode = 0 Case vbKeyEnd cBox.ListIndex = cBox.ListCount - 1 Case vbKeyHome cBox.ListIndex = 0 Case 46 cBox.Value = "" End Select 'this is just the code from above End Sub 

步骤2:声明收集

 'in a standard module (for Excel 2013, you might need to declare this in a standard module; otherwise, anywhere else may suffice) Public BoxColl as Collection 

步骤#3:初始化用户窗体

  '(initialize all desired ComboBoxes in your Userform to use Trap Code (step 1 above)) 'userform code Private Sub Userform_Initialize() Dim ctl as Control, ox as clsTask Set BoxColl = New Collection For Each ctl in Me.Controls If TypeOf ctl is MSForms.Label Then 'you could also include an identifying tag here Set ox = New clsTask Set ox.cBox = ctl BoxColl.Add ox End if Next 'this piece of code sets all of your comboboxes as your defined object/class. 'then it puts each combobox into a collection 'all items in the collection will get the Double Click Event treatment on cue End Sub 

好吧,就是这样。 如果你在你的用户表单中有一堆ComboBox,那么你可以使用相同的代码。 在这种情况下,如果您想要捕捉列表末尾的向上和向下button,则此代码将适用于每个单个combobox。

请记住,如果您只希望某些combobox具有此function,则需要为所需的标签添加标签。 然后在用户表单初始化中,在“For … Each”子句中,需要在“if”语句中添加该标记的条件子句。

好,把这个包起来 这个类模块很重要,因为你不需要维护你想要的每个combobox的用户表单代码。 你只需要制作一段代码。

祝你好运!

我试过这个最后的build议,它完美的工作后,我用“MSForms.ComboBox”replace“MSForms.Label”。

Interesting Posts