2

社区,

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

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

解决方案:为了防止这种失去焦点,在用户窗体的 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

好的,这就是我能够防止组合框在组合框列表的底部/顶部按下/向上时切换到不同控件的方式。

有谁知道更清洁的方法来做到这一点?也许一种不使用代码就能做到这一点的方法?

4

3 回答 3

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

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

于 2013-07-11T08:28:57.113 回答
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

好的,就是这样。如果您的用户表单中有一堆想要应用相同代码的组合框,这将很有帮助。在这种情况下,如果您希望在列表末尾捕获向上和向下按钮,那么此代码将适用于每个单独的组合框。

请记住,如果您只希望某些组合框具有此功能,则需要为您想要的组合框添加标签。然后在用户窗体初始化中,在“For...Each”子句中,您需要在“if”语句中添加该标记的条件子句。

好的,总结一下。这个类模块很重要,因为您不需要为您想要的每个组合框维护用户表单代码。你只需要编写一段代码。

祝你好运!

于 2013-07-21T19:12:49.847 回答
1

在我将“MSForms.Label”替换为“MSForms.ComboBox”之后,我尝试了最后一个建议并且效果很好。

于 2017-11-15T08:52:10.033 回答