VBA USERFORM:在KEYDOWN时防止COMBOBOX ESCAPE

时间:2013-07-11 01:54:49

标签: excel vba combobox keypress userform

社区,

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

问题:当在ComboBox中列表的末尾时,如果你点击向下箭头,它会移动你到活动组合框下面的任何控件。反之亦然,因为它位于组合框的顶部并且向上箭头。这是草率和适得其反的。 MS Excel 2013。

解决方案:为防止失去焦点,请在userform的ComboBox代码中输入以下内容:

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列表的底部/顶部按下/向上时阻止组合框切换到不同控件的方式。

有谁知道更清洁的方法吗?也许这是一种不使用代码的方法吗?

3 个答案:

答案 0 :(得分:4)

我不相信有一个非代码解决方案虽然您可以通过简单地在需要时将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
如果你经常需要这个代码,你可以使用一个类

答案 1 :(得分:1)

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

基本上,下面的内容是对上述解决方案的演变使用。在这里:

步骤#1:创建课程模块

'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

好的,就是这样。如果您的userform中有一堆ComboBox,您希望将相同的代码应用于此,这将非常有用。在这种情况下,如果你想要陷入困境。在列表末尾的向下按钮,这个代码将适用于每个组合框。

请注意,如果您只想让某些组合框具有此功能,则需要在所需的组合中添加标记。然后在userform初始化中,在“For ... Each”子句中,您需要在“if”语句中添加该标记的条件子句。

好的,把它包起来。这个类模块很重要,因为您不需要为每个&你想要的每一个组合框。你只需要制作一段代码。

祝你好运!

答案 2 :(得分:1)

我尝试了最后一个建议,在我更换了" MSForms.Label"之后,它完美地工作了。使用" MSForms.ComboBox"。