提问人:Shiela 提问时间:10/8/2023 更新时间:10/9/2023 访问量:91
ListBox 中的 ComboBox 更改事件结果
ComboBox change event result in ListBox
问:
这是从这里开始的更新问题。这篇文章的答案非常有效,特别是对于级联组合框更改。我只是在 ListBox1 中根据上次更改事件中 Sheet1 中匹配的所有结果显示结果时遇到问题。
这是原始数据:
Col. A Col. B Col. G Col. J Col. L
YEAR || NAME || COLOR || MONTH || SHAPE
2023 || LINA || GREEN || AUGUST || HEART
2023 || LINA || GREEN || SEPTEMBER|| CIRCLE
2024 || GARY || GREEN || SEPTEMBER|| DIAMOND
2024 || GARY || GREEN || SEPTEMBER|| RECTANGLE
2024 || GARY || RED || AUGUST || OVAL
2023 || GARY || RED || AUGUST || RECTANGLE
2023 || GARY || GREEN || AUGUST || SQUARE
2024 || GARY || GREEN || SEPTEMBER|| STAR
2024 || TOM || RED || AUGUST || HEART
2024 || TOM || RED || SEPTEMBER|| CIRCLE
2024 || TOM || RED || SEPTEMBER|| DIAMOND
2024 || TOM || YELLOW|| SEPTEMBER|| OVAL
2024 || TOM || YELLOW|| OCTOBER || RECTANGLE
2024 || TOM || YELLOW|| OCTOBER || CIRCLE
2024 || TOM || YELLOW|| OCTOBER || SQUARE
2024 || TOM || YELLOW|| OCTOBER || STAR
2024 || TOM || YELLOW|| OCTOBER || STAR
2024 || TOM || BLUE || OCTOBER || SQUARE
更改事件的代码:
Private Sub ComboBox4_Change()
If Not ComboBox4.Value = "" Then
Dim ws As Worksheet
Dim rcell As Range, Key
Dim arrData, arrList(), i As Long, j As Long
Set ws = Worksheets("Sheet1")
arrData = ws.Range("A1:L" & ws.Cells(Rows.count, "B").End(xlUp).Row)
ReDim arrList(1 To 2, 1 To UBound(arrData, 2))
For j = 1 To UBound(arrData, 2)
arrList(1, j) = arrData(1, j)
Next
For i = 2 To UBound(arrData)
If arrData(i, 2) = ComboBox1.Value And arrData(i, 1) = CStr(ComboBox2.Value) _
And arrData(i, 7) = ComboBox3.Value And arrData(i, 10) = ComboBox4.Value Then
For j = 1 To UBound(arrData, 2)
arrList(2, j) = arrData(i, j)
Next
Exit For
End If
Next
With Me.ListBox1
.ColumnHeads = False
.ColumnWidths = "35,35,0,0,0,0,40,0,0,50,0,50"
.ColumnCount = UBound(arrData, 2)
.List = arrList
End With
End If
End Sub
如您所见,使用上面的更改事件代码仅返回 1 行数据(如果我在 2024 年选择黄色和 10 月份的 Tom),而它应该返回更多行以在 ListBox1 中显示,因为它有多个形状(如果形状在 Sheet1 中重复,则很好):
更改事件代码中应更改哪些内容以更正此问题。感谢您的帮助。
答:
2赞
taller
10/8/2023
#1
列表框的项计数不是固定的。使用动态数组收集项。
Private Sub ComboBox4_Change()
If Not ComboBox4.Value = "" Then
Dim ws As Worksheet
Dim rcell As Range, iIdx As Integer
Dim arrData, arrList(), i As Long, j As Long
Set ws = Worksheets("Sheet1")
arrData = ws.Range("A1:L" & ws.Cells(Rows.Count, "B").End(xlUp).Row)
ReDim Preserve arrList(1 To UBound(arrData, 2), 1 To 1)
For j = 1 To UBound(arrData, 2)
arrList(j, 1) = arrData(1, j)
Next
iIdx = 1
For i = 2 To UBound(arrData)
If arrData(i, 2) = ComboBox1.Value And arrData(i, 1) = CStr(ComboBox2.Value) _
And arrData(i, 7) = ComboBox3.Value And arrData(i, 10) = ComboBox4.Value Then
iIdx = iIdx + 1
ReDim Preserve arrList(1 To UBound(arrData, 2), 1 To iIdx)
For j = 1 To UBound(arrData, 2)
arrList(j, iIdx) = arrData(i, j)
Next
End If
Next
With Me.ListBox1
.ColumnHeads = False
.ColumnWidths = "35,35,0,0,0,0,40,0,0,50,0,50"
.ColumnCount = UBound(arrData, 2)
.List = Application.Transpose(arrList)
End With
End If
End Sub
评论
0赞
Notus_Panda
10/9/2023
太糟糕了,你不能像使用范围那样限制你传递到列表框的内容,即 当 arr 较大时。Range("A1").Resize(rCount,colCount) = arr
0赞
Shiela
10/9/2023
让我试试这个 BRB
0赞
T.M.
10/10/2023
请允许我对你的工作代码进行一些提示(使用转置的行/列元素):我会首先(重新)维度到它的最大边界(),并且只在主循环之外进行第二次。- 它可能对其他用户有指导意义,因为您知道您可以避免通过 listboxe 的属性重新转置:@taller_ExcelHomearrList
arrList
ReDim Preserve arrList(1 To UBound(arrData, 2), 1 To UBound(arrData, 1))
ReDim Preserve arrList(1 To UBound(arrData, 2), 1 To idx)
.Column
.Column = arrList
0赞
taller
10/10/2023
@T.M. 谢谢你的分享。我不明白为什么 redim array 更好.its maximum boundaries
3赞
FaneDuru
10/9/2023
#2
请尝试下一个改编的代码:
Private Sub ComboBox4_Change()
If Not ComboBox4.value = "" Then
Dim ws As Worksheet, rng As Range, count As Long, K As Long
Dim arrData, arrList(), i As Long, j As Long
Set ws = Worksheets("Sheet1")
Set rng = ws.Range("A1:L" & ws.cells(rows.count, "B").End(xlUp).Row)
arrData = rng.value
'determine the necessary number of final array rows:
count = WorksheetFunction.CountIfs(rng.Columns(1), CStr(ComboBox2.value), rng.Columns(2), ComboBox1.value, rng.Columns(7), ComboBox3.value, rng.Columns(10), ComboBox4.value)
ReDim arrList(1 To count + 1, 1 To UBound(arrData, 2))
For j = 1 To UBound(arrData, 2)
arrList(1, j) = arrData(1, j) 'the header
Next
K = 1
For i = 2 To UBound(arrData)
If arrData(i, 2) = ComboBox1.value And arrData(i, 1) = CStr(ComboBox2.value) _
And arrData(i, 7) = ComboBox3.value And arrData(i, 10) = ComboBox4.value Then
K = K + 1
For j = 1 To UBound(arrData, 2)
arrList(K, j) = arrData(i, j) 'matching data
Next
End If
Next
With Me.ListBox1
.ColumnHeads = False
.ColumnWidths = "35,35,0,0,0,0,40,0,0,50,0,50"
.ColumnCount = UBound(arrData, 2)
.List = arrList
End With
End If
End Sub
评论
0赞
Shiela
10/9/2023
让我试试这个 BRB
0赞
Shiela
10/9/2023
这在另一个工作簿中对我来说更容易,谢谢
1赞
T.M.
10/10/2023
我祝贺您提出了使用 CountIfs
函数立即确定结果行元素总数的有用想法。这允许数组立即在第一维中正确确定尺寸,而无需后续且需要将列和行转置两次 +:) @FaneDuruReDim
评论