WorksheetFunction.Filter 中的数据类型错误

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 语法存在一些差异。

Sco*_*ner 6

我自己刚遇到这个问题,想发布我的解决方法。

我们需要向工作表函数返回一个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)


Cri*_*use 5

没有任何支持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)


Sam*_*son 2

我无法解决你的问题,但当我尝试对此主题进行一些测试时,我想我应该分享我的发现:

根据这篇微软社区帖子,或者至少是那里的答案,看来你需要以一种或另一种方式循环输出......

这个问题似乎想要实现与你想做的事情相同的目标(我认为?)。

另一方面,我从未使用过该WorksheetFunction.Filter方法,最接近的方法是这样:

这是我的示例数据 -RangeOneColumn ARangeTwoColumn 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,而不是预期/期望的23并且4in J1:J3

不幸的是,我无法找到一种方法来删除它,@因为它是在将函数写入单元格时应用的,但希望上述任何内容都可以帮助某人找到解决方案。