【问题标题】:Excel Combo Box Refresh Dropdown?Excel组合框刷新下拉菜单?
【发布时间】:2015-07-27 18:17:58
【问题描述】:

有没有办法刷新组合框? 我有以下 VBA 代码。下拉列表被填充,直到列表被清除并填充匹配项的 If 语句。

此时,下拉列表仅显示带有滚动条的单个项目。但如果我关闭下拉菜单并重新打开,它会正确填充。

Private Sub ComboBox_SiteName_Change()
ComboBox_SiteName.DropDown

Dim v As Variant, i As Long
With Me.ComboBox_SiteName
 .Value = UCase(.Value)
 If .Value <> "" And .ListIndex = -1 Then
   v = Worksheets("Address").Range("Table5[[#All],[SITE NAME]]").Value
   .Clear ' Clear all items
   ' Repopulate with matched items
   For i = LBound(v, 1) To UBound(v, 1)
     If LCase(v(i, 1)) Like "*" & LCase(.Value) & "*" Then
      .AddItem v(i, 1)
     End If
   Next i
  Else
  ' Repopulate with all items
  .List = Worksheets("Address").Range("Table5[[#All],[SITE NAME]]").Value
  End If
 End With
End Sub

当用户在组合框中键入时,ComboBox_Change 函数会被调用。在清除和重新填充匹配项之后,下拉框从列表变为带有向上/向下箭头的单行。 但是如果我关闭下拉部分并重新打开它会列出所有没有向上/向下箭头的项目。 .ListRows 值 = 8 顺便说一句。

我想要一种方法让下拉药水关闭并重新打开.. 或者使用 VBA 函数来刷新下拉部分,请不要使用外部按钮或控件

【问题讨论】:

  • 我不知道“改变”是否是正确的事件。我没有做任何测试,但只是看看可用的事件,“KeyDown”事件会更好吗?再次,只是想知道是否有更好的活动......
  • Table5 的结构如何,里面的数据是什么?
  • 尝试了“KeyDown”事件,但问题没有改变。表 5 有标题,数据主要是数字或通用字符串。例如,站点名称将包含“JOLLY RD”、“ST. JOHNS”、“US23 & JOHNSON”、“ST. JOHNS NORTH”。当用户键入“JO”时,下拉列表会列出所有内容并选择 JOLLY RD,但是一旦他们键入“JOH”,下拉列表就会变成一个带有 Scroll with ST 的条目。 JOHNS 网站。
  • 我想使用 VBA 对用户窗体上的组合框进行排序/过滤,以便它的工作方式与工作表上的标题过滤器下拉工作方式相同。例如,我希望项目在用户输入时进行过滤。例如,当用户键入“ST”时,即使其中一项是“MAIN ST”、“STATE”或“FIRST AVE”,列表中的唯一项目也会包括“ST”

标签: excel vba combobox


【解决方案1】:

让列表只显示与用户输入的文本匹配的值,这是一场噩梦。以下是我写的有效的(但花了我一段时间!)

请注意,组合框的 MacthEntry 属性必须设置为“2 - frmMatchEntryNone”才能使代码正常工作。 (其他值会导致组合框 .value 属性存储与用户键入的内容匹配的第一个值的文本,并且代码依赖于它来存储他们键入的内容。)

另请注意,绕过您观察到的行为的技巧,即组合框列表的值大小不正确,是使用代码行:

LastActiveCell.Activate
ComboBox_SiteName.Activate

此外,代码将选择列表中包含用户在其文本中任意位置键入的字母的任何项目。

无论如何,这是我的代码:

Private Sub ComboBox_SiteName_GotFocus()

    ' When it first gets the focus ALWAYS refresh the list
    ' taking into acocunt what has been typed so far by the user
    RePopulateList FilterString:=Me.ComboBox_SiteName.Value

    Me.ComboBox_SiteName.DropDown

End Sub

' #4 Private Sub ComboBox_SiteName_Change()
Private Sub ComboBox_SiteName_Enter()

    Dim LastActiveCell As Range

    On Error GoTo err_Handler

    Set LastActiveCell = ActiveCell

    Application.ScreenUpdating = False

    With Me.ComboBox_SiteName

        If .Value = "" Then
            ' Used cleared the combo
            ' Repopulate will all values
            RePopulateList

            .DropDown

        Else

            ' #4 reducdant
            ' LastActiveCell.Select
            ' .Activate

            ' ===========================================
            ' #4 new code
            ' CheckBox1 is another control on the form
            ' which can receive the focus and loose it without event firing
            CheckBox1.SetFocus

            ' This will trigger the GotFocus event handler
            ' which will do a refresnh of the list
            .SetFocus
            ' ===========================================


        End If

    End With

    Application.ScreenUpdating = True

Exit Sub
err_Handler:
     Application.ScreenUpdating = True
     Err.Raise Err.Number, "", Err.Description
     Exit Sub
     Resume

End Sub


Private Sub RePopulateList(Optional FilterString As String = "")

    Dim i As Long
    Dim ValidValues() As Variant

    ' #2 range now refers to just the data cells
    ValidValues = Worksheets("Address").Range("Table5[SITE NAME]").Value

    With Me.ComboBox_SiteName

        If FilterString = "" Then

            ' All all values
            .List = ValidValues

        Else

            ' #2: .List cannot be set to have no items.
            ' so remove all but one
            .List = Array("Dummy Value")

            ' Only add values that match the FilterString parameter
            For i = LBound(ValidValues, 1) To UBound(ValidValues, 1)

                If LCase(ValidValues(i, 1)) Like "*" & LCase(FilterString) & "*" Then
                  .AddItem ValidValues(i, 1)
                End If

            Next i

           ' #2 add this line to remove the dummy item
           .RemoveItem (0)

        End If

    End With



End Sub

Private Sub ComboBox_SiteName_KeyDown(ByVal KeyCode As MSForms.ReturnInteger, ByVal Shift As Integer)
    Application.ScreenUpdating = False
End Sub

================================================ ========================

您可以:将您的所有代码替换为应该提供可接受功能的代码(只要数据源是 alpha 顺序),这很容易!但是,它并不能完全满足您的要求。

Private Sub ComboBox_SiteName_GotFocus()

    With Me.ComboBox_SiteName
         .List = Worksheets("Address").Range("Table5[[#All],[SITE NAME]]").Value
    End With

    ComboBox_SiteName.DropDown

End Sub

可以将组合框设置为“根据用户类型进行过滤” - 只要数据按字母顺序排列即可。

================================================ ========================

请注意,在您的代码中,以下两行会导致 ComboBox_SiteName_Change 事件重新开始。我怀疑您需要添加断点并调试更多代码。

.Value = UCase(.Value) 
.Clear ' Clear all items

无论如何,我希望这已经完成了。

如果我得到它,这将是我的第一个赏金,所以如果你需要更多帮助,请告诉我。 (我觉得可能值50分以上)

哈维

================================================ =

第 2 部分:

回答您的评论问题:

(见上面我代码中的#2标签)

要引用表格列的数据,不包括标题使用: =Table5[站点名称] (如果您单击并拖动列中的数据单元格,这将在输入公式时自动生成)。 代码已相应更改。

我使用了 excel 2013 和 2010,发现 .Activate 事件在两者中都有效。 请参阅 #3 进行细微更改。

请重新复制所有代码。

请注意,我引入了代码来尝试使用 Application.ScreenUpdating 停止闪烁,但它没有任何效果 - 我不知道为什么。我已将代码留在其中,因此您可以根据需要进行进一步的实验。

注意新过程 ComboBox_SiteName_KeyDown

================================================ =

第 3 部分:

回答您的评论问题: 这是表格上的组合! - 所以进行上面标有 #4 的更改。

哈维

【讨论】:

  • 谢谢,有几个问题.. ComboBox_SiteName.Activate 不起作用.. (方法或数据输入未找到)但这是正确的想法.. 如果我点击开箱并返回,下拉列表正确列出。还有一件小事,如何从列表中删除表头?我确定它是范围线的一部分。我的列表也不是按字母顺序排列的,因为我使用不同的列(建筑物编号)作为键并且它是按升序排序的。如果我们能解决这个下拉大小问题,我非常乐意奖励您。
  • 顺便说一下,我使用的是 Excel 2010,可能是在 2013 年引入了激活功能?
  • 请参阅我的回答中的第 2 部分。它适用于我的 2010。我不明白为什么您的代码不起作用。该代码将与非字母列表一起使用,但我个人认为如果它们按字母顺序排列,用户体验会更好。你是如何创建控件的?您是否使用使用功能区>开发人员>控件>插入创建的 ActiveX 组合框控件? (即使用 VBA/宏记录添加时,您会看到 ActiveSheet.OLEObjects.Add(ClassType:="Forms.ComboBox.1"....
  • 激活仍然失败,我在用户窗体上使用这个组合框。它不是工作表上的 ActiveX 控件。非常感谢您对此提供的帮助
  • 参见第 3 部分:回答 - 我认为已完成!
【解决方案2】:

解决了!

https://trumpexcel.com/excel-drop-down-list-with-search-suggestions/

您可以通过一些修改来执行链接中的内容:

组合框属性中的“ListFillRange”应该是最后一列(正在改变的那一列)。如果是用户表单,则范围将位于“RowSource”下。

并添加以下代码:

Private Sub ComboBox1_Change()

Sheets("Where the data is").Range("B3") = Me.ComboBox1.Value

End Sub

【讨论】:

    【解决方案3】:

    尝试将命令从 Change 更改为 DropButtonClick

    点击下拉菜单刷新列表

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-02-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-10-22
      • 1970-01-01
      相关资源
      最近更新 更多