【问题标题】:VBA Display in a listbox based on two dynamic comboboxesVBA 在基于两个动态组合框的列表框中显示
【发布时间】:2020-04-21 04:30:24
【问题描述】:

我想在一个列表框中显示 2 个组合框的结果,但我不知道该怎么做...

这是我到目前为止所得到的:

根据左侧组合框,它暗示右侧组合框的结果。

1/ 我想显示软件包版本 ($E) 和软件包版本 ($F) 软件包名称selected 在左侧组合框选中项目的右侧组合框上(本例中为“监控”)。

2/ 如果我选择“ALL”包名,我想显示$E$F

这是我当前的代码:

Private Sub CommanButton1_Click()
    Unload UserForm1
End Sub

Private Sub UserForm_Initialize()
    Dim ws As Worksheet, rCell As Range, Key
    Dim Dic As Object: Set Dic = CreateObject("Scripting.Dictionary")
    Set ws = Worksheets("system-packages-installed")
    UserForm1.ComboBox1.Clear
    For Each rCell In ws.Range("B2", ws.Cells(Rows.Count, "B").End(xlUp))
        If Not Dic.exists(LCase(rCell.Value)) Then
            Dic.Add LCase(rCell.Value), Nothing
        End If
    Next rCell
    UserForm1.ComboBox1.AddItem "ALL"
    For Each Key In Dic
        UserForm1.ComboBox1.AddItem Key
    Next
End Sub

Private Sub ComboBox1_Click()
    Dim rCell As Range, Key
    Dim Dic As Object: Set Dic = CreateObject("Scripting.Dictionary")
    Set ws = Worksheets("system-packages-installed")
    UserForm1.ComboBox2.Clear
    For Each rCell In ws.Range("B2", ws.Cells(Rows.Count, "B").End(xlUp))
        If rCell.Value = ComboBox1.Value Then
            If Not Dic.exists(LCase(rCell.Offset(, 1).Value)) Then
                Dic.Add LCase(rCell.Offset(, 1).Value), Nothing
            End If
        End If
    Next rCell
    UserForm1.ComboBox2.AddItem "ALL"
    For Each Key In Dic
        UserForm1.ComboBox2.AddItem Key
    Next

End Sub

Private Sub ComboBox2_Click()
    'This is a test'
    With UserForm1.ListBox1
        .ColumnCount = 27
        .ColumnWidths = "50"
        .RowSource = "'system-packages-installed'!E:E"
    End With
End Sub

如果您有任何问题,请随时问我。

提前致谢。

编辑:

这是表格:

<style type="text/css">
.tg  {border-collapse:collapse;border-spacing:0;}
.tg td{font-family:Arial, sans-serif;font-size:14px;padding:10px 5px;border-style:solid;border-width:1px;overflow:hidden;word-break:normal;border-color:black;}
.tg th{font-family:Arial, sans-serif;font-size:14px;font-weight:normal;padding:10px 5px;border-style:solid;border-width:1px;overflow:hidden;word-break:normal;border-color:black;}
.tg .tg-0pky{border-color:inherit;text-align:left;vertical-align:top}
</style>
<table class="tg">
  <tr>
    <th class="tg-0pky">System_id<br></th>
    <th class="tg-0pky">Machine</th>
    <th class="tg-0pky">package_name</th>
    <th class="tg-0pky">package_epoch</th>
    <th class="tg-0pky">package_version</th>
    <th class="tg-0pky">package_release</th>
  </tr>
  <tr>
    <td class="tg-0pky">1000010000</td>
    <td class="tg-0pky">monitoring</td>
    <td class="tg-0pky">acl</td>
    <td class="tg-0pky"></td>
    <td class="tg-0pky">2.2.51</td>
    <td class="tg-0pky">14.el7</td>
  </tr>
  <tr>
    <td class="tg-0pky">1000010000</td>
    <td class="tg-0pky">monitoring</td>
    <td class="tg-0pky">alsa-lib</td>
    <td class="tg-0pky"></td>
    <td class="tg-0pky">1.1.6</td>
    <td class="tg-0pky">2.el7</td>
  </tr>
  <tr>
    <td class="tg-0pky">1000010000</td>
    <td class="tg-0pky">monitoring</td>
    <td class="tg-0pky">apg</td>
    <td class="tg-0pky"></td>
    <td class="tg-0pky">2.3.0b</td>
    <td class="tg-0pky">24.el7</td>
  </tr>
  <tr>
    <td class="tg-0pky">1000010000</td>
    <td class="tg-0pky">monitoring</td>
    <td class="tg-0pky">apr</td>
    <td class="tg-0pky"></td>
    <td class="tg-0pky">1.4.8</td>
    <td class="tg-0pky">3.el7_4.1</td>
  </tr>
  <tr>
    <td class="tg-0pky">1000010000</td>
    <td class="tg-0pky">monitoring</td>
    <td class="tg-0pky">apr-util</td>
    <td class="tg-0pky"></td>
    <td class="tg-0pky">1.5.2</td>
    <td class="tg-0pky">6.el7</td>
  </tr>
  <tr>
    <td class="tg-0pky">1000010000</td>
    <td class="tg-0pky">monitoring</td>
    <td class="tg-0pky">at</td>
    <td class="tg-0pky"></td>
    <td class="tg-0pky">3.1.13</td>
    <td class="tg-0pky">24.el7</td>
  </tr>
  <tr>
    <td class="tg-0pky">1000010000</td>
    <td class="tg-0pky">monitoring</td>
    <td class="tg-0pky">audit</td>
    <td class="tg-0pky"></td>
    <td class="tg-0pky">2.8.4</td>
    <td class="tg-0pky">4.el7</td>
  </tr>
</table>

【问题讨论】:

  • 请不要将数据添加为图像,将它们添加为文本。你可以用谷歌搜索“markdown table”并从中制作一个表格。
  • 另外,您当前的代码有什么问题?
  • 我真的不明白你为什么说“不要将数据添加为图像”......我当前的代码是正确的。但我真的不知道如何根据我的两个组合框显示值...
  • 他是说您在 Excel 工作表中显示数据的图片。但是,如果有人想重现您的情况并测试他们的答案,他们必须输入(而不是复制和粘贴)所有这些数据。

标签: excel vba combobox listbox userform


【解决方案1】:

我的规则是永远不要使用RowSource。通常,如果您可以将信息放在一个数组中,那么您可以将该数组分配给Lisbtobx.List 属性。另一种方法是使用AddItem 添加一个新项目,然后使用List() 属性填写其余列。下面是一个例子。我对您现有的代码和 ComboBox2_Change 代码做了一些小改动,我认为这是您感兴趣的。

Private Sub ComboBox1_Change()

    Dim rCell As Range, ws As Worksheet
    Dim dc As Scripting.Dictionary

    Set dc = New Scripting.Dictionary
    dc.Add "ALL", "ALL"

    Set ws = Worksheets("system-packages-installed")
    Me.ComboBox2.Clear
    For Each rCell In ws.Range("B2", ws.Cells(ws.Rows.Count, "B").End(xlUp)).Cells
        If rCell.Value = Me.ComboBox1.Value Then
            If Not dc.exists(LCase(rCell.Offset(0, 1).Value)) Then
                dc.Add LCase(rCell.Offset(0, 1).Value), LCase(rCell.Offset(0, 1).Value)
            End If
        End If
    Next rCell

    Me.ComboBox2.List = dc.Items

End Sub

Private Sub ComboBox2_Change()

    Dim rCell As Range
    Dim ws As Worksheet

    Set ws = Worksheets("system-packages-installed")
    Me.ListBox1.Clear
    For Each rCell In ws.Range("B2", ws.Cells(ws.Rows.Count, "B").End(xlUp)).Cells
        If LCase(rCell.Value) = LCase(Me.ComboBox1.Value) Or Me.ComboBox1.Value = "ALL" Then
            If LCase(rCell.Offset(0, 1).Value) = LCase(Me.ComboBox2.Value) Or Me.ComboBox2.Value = "ALL" Then
                With Me.ListBox1
                    .AddItem rCell.Value 'column 1
                    .List(.ListCount - 1, 1) = rCell.Offset(0, 1).Value 'column 2
                    .List(.ListCount - 1, 2) = rCell.Offset(0, 3).Value 'column 3
                    .List(.ListCount - 1, 3) = rCell.Offset(0, 4).Value 'column 4
                End With
            End If
        End If
    Next rCell
End Sub

Private Sub UserForm_Initialize()
    Dim ws As Worksheet, rCell As Range

    Dim dc As Scripting.Dictionary

    Set dc = New Scripting.Dictionary
    dc.Add "ALL", "ALL"

    Set ws = Worksheets("system-packages-installed")
    Me.ComboBox1.Clear
    For Each rCell In ws.Range("B2", ws.Cells(ws.Rows.Count, "B").End(xlUp)).Cells
        If Not dc.exists(LCase(rCell.Value)) Then
            dc.Add LCase(rCell.Value), LCase(rCell.Value)
        End If
    Next rCell

    Me.ComboBox1.List = dc.Items

End Sub

【讨论】:

  • 感谢您的详细回答。我不知道为什么,但是您所做的代码不起作用。似乎问题出在子“UserForm1_Initialize”期间,但我暂时找不到。
  • 我在主要问题上添加了我的表格的一部分。我没发现问题出在哪里...
  • @AChichi - [1] 表单代码中没有UserForm1_Initialize 事件,只有UserForm_Initialize 事件;值得一提的是,引用 UserForm1.ComboBox2 之类的控件会解决表单的默认实例,避免这种情况 - 仅使用控件的名称或 Me. 限定符(例如 Me.ComboBox2),而不是像 Dick 演示的那样解决实际的当前实例。 [2.] 您是否为 eac 列分配了.ColumnCount 属性(例如分配给4)或.ColumnWidths 属性(例如分配给"50;50;50;50")?顺便说一句See
  • @T.M.正如你告诉我的那样添加.ColumnCount = 4 后,它运行良好。非常感谢您的帮助:)
  • @AChichi - 很高兴你得到了迪克绝对正确的解决方案。 FYI 通过所谓的 early binding 使用字典,您需要通过 VBA Editor 添加引用 ~> Tools ~> References ~> 添加 Microsoft Scripting Runtime 在速度和速度方面具有一些优势IntelliSense 舒适度 - 自行检查与 后期绑定 的差异 :-)
猜你喜欢
  • 2018-05-29
  • 2012-01-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多