I would like to display the result of 2 comboboxes in a listbox but I don't know how to do it...
Here's what I've got so far :
Depending on the left-hand combobox, it implies the results of the right-hand combobox.
1/ I would like to display the package version ($E) and the package release ($F) of the package name selected on the right-hand combobox for the project selected on the left combobox, ("monitoring" in this example).
2/ If I select "ALL" package name, I would like to display $E and $F.
Here is my current code :
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
If you have any question, do not hesitate to ask me.
Thanks in advance.
Edit :
Here is the table :
<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>
My rule is never use RowSource
. Generally, if you can put the information in an array, then you can assign that array to the Lisbtobx.List
property. The other method is to add a new item with AddItem
and then fill out the rest of the columns with the List()
property. Below is an example. I made some minor changes to your existing code and the ComboBox2_Change code I think is what you're interested in.
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