Ped*_*ara 5 excel vba worksheet-function
我正在尝试创建一个函数 MonstersInLevel(),它根据第一列的值过滤我的“LevelMonsters”命名范围的第二列。该范围的第一列表示游戏级别 ID,第二列表示出现在该级别中的怪物 ID。这是我的范围的样子。
如果我调用 MonstersInLevel(2),我希望该函数返回一个由“2”、“3”和“4”组成的范围。
Function MonstersInLevel(level As Integer) As Range
MonstersInLevel = Application.WorksheetFunction.Filter(Range("LevelMonsters").Columns(2), Range("LevelMonsters").Columns(1) = level)
End Function
Run Code Online (Sandbox Code Playgroud)
我得到:
公式中使用的值的数据类型错误
我将 FILTER 函数用作 Excel 公式。我认为 FILTER 标准的 Excel 和 VBA 语法存在一些差异。
我自己刚遇到这个问题,想发布我的解决方法。
我们需要向工作表函数返回一个True/数组False。为此,我创建了一个函数,它接受一个二维数组、想要的列和要比较的值。然后它返回一个包含必要True/的二维单列数组False。
Function myeval(arr() As Variant, clm As Long, vl As Variant) As Variant()
Dim temp() As Variant
ReDim temp(1 To UBound(arr, 1), 1 To 1)
Dim i As Long
For i = 1 To UBound(arr, 1)
temp(i, 1) = arr(i, clm) = vl
Next i
myeval = temp
End Function
Run Code Online (Sandbox Code Playgroud)
所以在这种特殊情况下,它将被称为:
Function MonstersInLevel(level As Integer) As Variant
MonstersInLevel = Application.WorksheetFunction.Filter(Range("LevelMonsters").Columns(2), myeval(Range("LevelMonsters").Value, 1, level),"""")
End Function
Run Code Online (Sandbox Code Playgroud)
没有任何支持VBA函数的解决方案:
Function MonstersInLevel(level As Integer) As Variant
With Application.WorksheetFunction
MonstersInLevel = .Filter(Range("LevelMonsters").Columns(2), _
.IfError(.XLookup(Range("LevelMonsters").Columns(1), level, True), False))
End With
End Function
Run Code Online (Sandbox Code Playgroud)
#N/AXLookup 返回一个or的数组True。IfError 将错误替换为False. 最后,Filter 函数接收一个布尔数组作为第二个参数。
编辑
IfError感谢@ScottCraner删除了该功能:
Function MonstersInLevel(level As Integer) As Variant
With Application.WorksheetFunction
MonstersInLevel = .Filter(Range("LevelMonsters").Columns(2), _
.XLookup(Range("LevelMonsters").Columns(1), level, True, False))
End With
End Function
Run Code Online (Sandbox Code Playgroud)
我无法解决你的问题,但当我尝试对此主题进行一些测试时,我想我应该分享我的发现:
根据这篇微软社区帖子,或者至少是那里的答案,看来你需要以一种或另一种方式循环输出......
这个问题似乎想要实现与你想做的事情相同的目标(我认为?)。
另一方面,我从未使用过该WorksheetFunction.Filter方法,最接近的方法是这样:
这是我的示例数据 -RangeOne是Column A,RangeTwo是Column B。我已使用=FILTER()单元格C1中的函数评估D1中的输入以作为预期结果的参考。自然这个功能就按预期工作了!VBA 例程输出到 E、F 和 G 列。
Sub TestFilterFunction()
Dim TestArray As Variant
Range("E1:E3") = Application.Filter(Range("RangeTwo"), Range("RangeOne"), Range("D1"))
Range("F1:F3") = Application.Filter(Range("RangeTwo"), Range("RangeOne") = Range("D1")) 'Runtime Error 13
Range("G1:G3") = Application.Filter(Range("RangeTwo"), Range("RangeOne"))
TestArray = Application.Filter(Range("RangeTwo"), Range("RangeOne"), Range("D1"))
TestArray = Application.Filter(Range("RangeTwo"), Range("RangeOne") = Range("D1")) 'Runtime Error 13
TestArray = Application.Filter(Range("RangeTwo"), Range("RangeOne"))
Range("H1:H3") = Application.Filter(Range("RangeTwo", "RangeOne"), Range("RangeOne"), Range("D1"))
TestArray = Application.Filter(Range("A1:B9"), Range("RangeOne"), "2")
End Sub
Run Code Online (Sandbox Code Playgroud)
E 列返回 的前 3 个值RangeTwo。F 列尚未填充 - 这是因为该行抛出了Runtime error 13 - Type Mismatch
Column G 返回的前 3 个值RangeTwo。H 列返回“A1:B9”中的前 3 个值(两个范围在一起) - 特别是 A 列的前 3 个值。
我认为这很奇怪,所以我放入了一个数组来将值分配给而不是直接分配给工作表;
第一TestArray行和第三TestArray行都用整个值填充数组RangeTwo;
我意识到,通过第一次和第三次尝试的语法WorksheetFunction.Filter,返回整个范围(即第一个参数 - Arg1 - 范围),但是当尝试包含 时 = Range("D1"),它返回Type Mismatch错误。
最后的TestArray尝试与 Column H 测试的语法相同,返回二维数组中的两列(现在TestArray(1 To 9, 1 To 2))。
我应该注意,我根本找不到任何文档,WorksheetFunction.Filter因此我假设它确实遵循与 Excel 工作表函数相同的语法。
如果我在这个主题上找到更多内容,我会回来编辑它,但现在看起来可能是使用循环或索引/匹配函数的解决方案也需要碰巧在 VBA 中返回数据。
我考虑过也许将工作表公式写入单元格,然后将其抓取到数组或其他内容中,但 Excel@现在插入其中,只返回单个单元格结果,即
Range("J1").Formula = "=FILTER(B1:B9, A1:A9 = D1)"
Run Code Online (Sandbox Code Playgroud)
将返回J1:
=@FILTER(B1:B9, A1:A9 = D1)
Run Code Online (Sandbox Code Playgroud)
对于我们的示例数据,只会返回2in J1,而不是预期/期望的2,3并且4in J1:J3。
不幸的是,我无法找到一种方法来删除它,@因为它是在将函数写入单元格时应用的,但希望上述任何内容都可以帮助某人找到解决方案。