使用Application.Run评估作为字符串传递的Worksheet函数

时间:2019-09-12 07:55:45

标签: excel vba user-defined-functions

从本质上讲,我有一个简单的语法问题涉及Application.Run。我想写一些代码,在其中我向UDF传递一个字符串,该字符串与工作表函数的名称保持一致,例如'iserror'或其他返回布尔值的UDF。然后,将为传递范围内的每个单元格执行该函数,并根据结果执行某些操作。

但是,我还无法计算出正确的语法。错误消息随着我的试用版而更改,但非特别有用。例如:

?hrCull(Range("Data!A1:B10"),"Worksheetfunction.iserror", False)

(德语错误消息,我会尽力翻译,但可能不会100%与英文版本匹配):

运行时错误1004:

无法执行宏“ Worksheetfunction.iserror”。该宏可能在此工作表中不可用,或者宏已被停用。

当然,宏没有被停用,但是它实际上并不是一个宏。也尝试了不使用前导“ Worksheetfunction”(相同的错误消息)。

在我的代码中,调用看起来像这样:

Public Function hrCull(r As Range, func As String, Optional invert As Boolean = False) As Range
    Dim c           As Range
    Dim selector    As Boolean
    ...
    selector = Application.Run(func, c)
    ...
end function

我省略了不相关的代码。

那什么是正确的语法?

其他:

- I'm Aware that I can not assert that the passed function returns a boolean.
- Excel 2016 on Windows 7

3 个答案:

答案 0 :(得分:1)

使用CallByName的解决方案:

selector = CallByName(Application.WorksheetFunction, "IsError", VbMethod, c)

答案 1 :(得分:0)

我认为您最好声明自己的Enum并在其中添加所需的功能。然后使用内置语法执行它们,而不是尝试评估字符串

Public Enum xlSheetFunction
    xlIsError
End Enum

Public Function hrCull(r As Range, func As xlSheetFunction, Optional Invert As Boolean = False) As Range
    Dim selector As Boolean

    Select Case func
        Case xlIsError
            selector = WorksheetFunction.IsError(r)
    End Select

    Debug.Print selector

    Set hrCull = r
End Function

Public Sub test()
    Debug.Print hrCull(Range("A1"), xlIsError)
End Sub

答案 2 :(得分:0)

丢失WorksheetFunction.前缀,Evaluate不喜欢它,因为Evaluate用于工作表函数。

在您的函数中,使用:

selector = Application.Evaluate(func & "(" & c.Address & ")")

要进行测试,请使用:

Debug.Print hrCull(Range("A1"), "ISERROR")