如何使用工作表函数过滤数组?

mic*_*ael 5 excel vba excel-vba

我正在寻找一种方法来过滤具有评估表达式的数组,例如:

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]
Run Code Online (Sandbox Code Playgroud)

我已经Map使用UDF 实现了该功能 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
Run Code Online (Sandbox Code Playgroud)

除了循环/移动每个值之外还有其他方法吗?Maby跟VLOOKUP

A.S*_*S.H 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
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)

ps 一个有趣的扩展是允许AND使用多个标准(即一起编辑)ParamArray。未来工作的好人选...