从 MultiSelect ListBox 填充 AdvancedFilter Criteria
Populate AdvancedFilter Criteria from a MultiSelect ListBox
有个类似这个的问题,但是不符合这里的规范
我有一个 MultiSelect ListBox 和一个代表 AdvancedFilter 条件的 table。
我想用从 ListBox 中选择的所有值填充这个 table 的列 "Level",每个值都应该在单独的行中(AdvancedFilter 的 OR 条件)。
我要的结果:
如果没有选择任何项目,它应该删除在 table 中添加的行并且只填充“<>0”。
到目前为止我编写的代码实现了前两张图片中显示的技巧,但是当我取消选择所有项目时它不再起作用:
Private Sub ListBox1_LostFocus()
Dim aArray() As Single
ReDim aArray(1 To 1) As Single
With ListBox1
For I = 0 To .ListCount - 1
If .Selected(I) Then
aArray(UBound(aArray)) = .List(I)
ReDim Preserve aArray(1 To UBound(aArray) + 1) As Single
End If
Next I
End With
Range(Cells(3, "S"), Cells(UBound(aArray) - 1, "S"))= Application.Transpose(aArray)
End Sub
有人处理过这个问题吗?任何帮助将非常感激!非常感谢!
我想这会做你想要的。根据我关于使用“<>0”预加载的评论 - 这是不可能的,因为您的数组是 Single。所以你需要捕获它。此外,我调整了您要写入的范围,因为在我的模型中,如果选择了 1 个或更多,我会在最后得到一个零。
Dim aArray() As Single
ReDim aArray(1 To 1) As Single
With ListBox1
For I = 0 To .ListCount - 1
If .Selected(I) Then
aArray(UBound(aArray)) = .List(I)
ReDim Preserve aArray(1 To UBound(aArray) + 1) As Single
End If
Next I
End With
Range("S3:S10").ClearContents ' change this range to suit
If UBound(aArray) = 1 Then
Range("S3") = "<>0"
Else
Range(Cells(3, "S"), Cells(3 + UBound(aArray) - 2, "S")) = Application.Transpose(aArray)
End If
看起来很复杂,但做起来很巧妙。
Private Sub ListBox1_LostFocus()
'
'is called when you finish selecting items from the ListBox
'
Dim aArray() As Single
ReDim aArray(1 To 1) As Single
'fetch selected items of listbox into aArray
With ListBox1
For I = 0 To .ListCount - 1
If .Selected(I) Then
aArray(UBound(aArray)) = .List(I)
ReDim Preserve aArray(1 To UBound(aArray) + 1) As Single
End If
Next I
End With
'clear old items in the advanced filter's condition table to replace them with those we fetched
'/!\ if there was more old items than new items, we would need to delete their rows from the table
Range("Condition[Level]").ClearContents
'we need to compare the size of the array with the size of the table so that we don't have extra rows
'(the advanced filter interpretates empty rows as '*' so we absolutely need to get rid of them)
r = UBound(aArray)
n = Range("Condition[#Data]").Rows.count
If UBound(aArray) = 1 Then
Range("Condition[Level]") = "<>0" 'if nothing is selected, fetch every item meaning numeric and non numeric (more powerful than "*")
Range("Condition[Serial]") = "*" 'columns to the left of 'Level' are not automatically replicated in the table (contrary to those on the right which gets previous row's) values so they become empty, that's why we need to fill them with the value we want
Range("Condition[#Data]").RemoveDuplicates Columns:=Array(1, 2), Header:=xlYes
Else
Range(Cells(3, "S"), Cells(3 + UBound(aArray) - 2, "S")) = Application.Transpose(aArray)
If n > r - 1 Then
[Condition].Rows(r & ":" & n).Select ' r+1 to skip the headers' row
[Condition].Rows(r & ":" & n).Delete 'doing a select before the delete prevents a bug which would delete the entire rows of the sheet
End If
End If
如果你对我的代码有改进,我很乐意采纳!我对 VBA 有点陌生,我相信有很多方法可以改进它。
如果您有类似此问题的需求,欢迎随时提问。
有个类似这个的问题,但是不符合这里的规范
我有一个 MultiSelect ListBox 和一个代表 AdvancedFilter 条件的 table。
我想用从 ListBox 中选择的所有值填充这个 table 的列 "Level",每个值都应该在单独的行中(AdvancedFilter 的 OR 条件)。
我要的结果:
如果没有选择任何项目,它应该删除在 table 中添加的行并且只填充“<>0”。
到目前为止我编写的代码实现了前两张图片中显示的技巧,但是当我取消选择所有项目时它不再起作用:
Private Sub ListBox1_LostFocus()
Dim aArray() As Single
ReDim aArray(1 To 1) As Single
With ListBox1
For I = 0 To .ListCount - 1
If .Selected(I) Then
aArray(UBound(aArray)) = .List(I)
ReDim Preserve aArray(1 To UBound(aArray) + 1) As Single
End If
Next I
End With
Range(Cells(3, "S"), Cells(UBound(aArray) - 1, "S"))= Application.Transpose(aArray)
End Sub
有人处理过这个问题吗?任何帮助将非常感激!非常感谢!
我想这会做你想要的。根据我关于使用“<>0”预加载的评论 - 这是不可能的,因为您的数组是 Single。所以你需要捕获它。此外,我调整了您要写入的范围,因为在我的模型中,如果选择了 1 个或更多,我会在最后得到一个零。
Dim aArray() As Single
ReDim aArray(1 To 1) As Single
With ListBox1
For I = 0 To .ListCount - 1
If .Selected(I) Then
aArray(UBound(aArray)) = .List(I)
ReDim Preserve aArray(1 To UBound(aArray) + 1) As Single
End If
Next I
End With
Range("S3:S10").ClearContents ' change this range to suit
If UBound(aArray) = 1 Then
Range("S3") = "<>0"
Else
Range(Cells(3, "S"), Cells(3 + UBound(aArray) - 2, "S")) = Application.Transpose(aArray)
End If
看起来很复杂,但做起来很巧妙。
Private Sub ListBox1_LostFocus()
'
'is called when you finish selecting items from the ListBox
'
Dim aArray() As Single
ReDim aArray(1 To 1) As Single
'fetch selected items of listbox into aArray
With ListBox1
For I = 0 To .ListCount - 1
If .Selected(I) Then
aArray(UBound(aArray)) = .List(I)
ReDim Preserve aArray(1 To UBound(aArray) + 1) As Single
End If
Next I
End With
'clear old items in the advanced filter's condition table to replace them with those we fetched
'/!\ if there was more old items than new items, we would need to delete their rows from the table
Range("Condition[Level]").ClearContents
'we need to compare the size of the array with the size of the table so that we don't have extra rows
'(the advanced filter interpretates empty rows as '*' so we absolutely need to get rid of them)
r = UBound(aArray)
n = Range("Condition[#Data]").Rows.count
If UBound(aArray) = 1 Then
Range("Condition[Level]") = "<>0" 'if nothing is selected, fetch every item meaning numeric and non numeric (more powerful than "*")
Range("Condition[Serial]") = "*" 'columns to the left of 'Level' are not automatically replicated in the table (contrary to those on the right which gets previous row's) values so they become empty, that's why we need to fill them with the value we want
Range("Condition[#Data]").RemoveDuplicates Columns:=Array(1, 2), Header:=xlYes
Else
Range(Cells(3, "S"), Cells(3 + UBound(aArray) - 2, "S")) = Application.Transpose(aArray)
If n > r - 1 Then
[Condition].Rows(r & ":" & n).Select ' r+1 to skip the headers' row
[Condition].Rows(r & ":" & n).Delete 'doing a select before the delete prevents a bug which would delete the entire rows of the sheet
End If
End If
如果你对我的代码有改进,我很乐意采纳!我对 VBA 有点陌生,我相信有很多方法可以改进它。
如果您有类似此问题的需求,欢迎随时提问。