我正在寻找一种方法来过滤具有评估表达式的数组,例如:
Dim arr1(), arr2(), arr3()
arr1 = Array(1, 2, 3, 4, 5) ' > [1, 2, 3, 4, 5]
arr2 = Map(arr1, "Values() * 2") ' > [2, 4, 6, 8, 10]
arr3 = Filter(arr2, "Values() > 6") ' > [8, 10]
我已经使用UDF和Map
实现了Application.Evaluate("INDEX(expression, )")
功能,但我努力使其适用于Filter
:
Private arr_()
Public Function Values() As Variant()
Values = arr_
End Function
Public Function Map(arr(), expression As String) As Variant()
arr_ = arr
Map = Application.Evaluate("INDEX(" & expression & ",)")
End Function
Public Function Filter(arr(), expression As String) As Variant()
arr_ = arr
Filter = Application.Evaluate("INDEX(Values(), " & expression & ")")
End Function
除了循环/移动每个值之外,还有其他方法吗? Maby与VLOOKUP
?
答案 0 :(得分:1)
虽然我是数组的忠实粉丝,并将大部分工作委托给Excel的内置插件,但对于这个,我发现最合适的是在VBA中完成主要工作,使用Excel来Evaluate
个别项目的表达。
Public Function FilterArr(arr(), expression As String)
Dim match As Boolean, i As Long, val
ReDim ret(LBound(arr) To UBound(arr))
i = LBound(arr) - 1
On Error Resume Next
For Each val In arr
match = False
match = Application.Evaluate(val & expression)
If match Then
i = i + 1
ret(i) = val
End If
Next
If i >= LBound(arr) Then
ReDim Preserve ret(LBound(arr) To i)
FilterArr = ret
End If
End Function
Sub test()
Dim arr1(), arr2(), arr3()
arr1 = Array(10, 20, 30, 40, 50)
arr3 = FilterArr(arr1, ">25") ' <--- usage like this
' arr3 = (30, 40, 50)
End Sub
P.S。一个有趣的扩展是允许使用AND
的多个标准(即ParamArray
编辑在一起)。未来工作的良好候选人......
答案 1 :(得分:1)
首先将功能更改为以下内容......
Public Function Filter(arr(), sValues As String, sCriteria As String) As Variant()
Dim Cnt As Long
arr_ = arr
Cnt = Application.Evaluate("SUMPRODUCT(--(" & sValues & sCriteria & "))")
If Cnt > 0 Then
Filter = Application.Evaluate("TRANSPOSE(INDEX(SMALL(IF(" & sValues & sCriteria & "," & _
sValues & "),ROW(INDEX(A:A,1):INDEX(A:A," & Cnt & "))),0))")
Else
Filter = Array()
End If
End Function
然后这样称呼它......
arr3 = Filter(arr2, "Values()", ">6")