在 VBA 的 UDF 中将单元格作为参数传递的正确方法是啥?

Posted

技术标签:

【中文标题】在 VBA 的 UDF 中将单元格作为参数传递的正确方法是啥?【英文标题】:What is the proper way to pass a cell as a parameter in a UDF in VBA?在 VBA 的 UDF 中将单元格作为参数传递的正确方法是什么? 【发布时间】:2020-05-10 07:07:49 【问题描述】:

我正在尝试创建一个 UDF,它获取引用单元格的值,根据范围测试该值,并根据它是否适合该范围,将产生“X”或“O”。这是我让它工作的唯一方法:

代码:

Public Function ASE(cellRef As Variant)

    Dim setpointU As Integer, setpointL As Integer
    Dim enabled As String, disabled As String

    cellValue = Range(cellRef).Value
    setpointL = 50
    setpointU = 100
    enabled = "O"
    disabled = "X"

        If cellValue >= setpointL Or cellValue <= setpontU Then
            ASE = enabled
        Else
            ASE = disabled
        End If

End Function

公式栏中的函数: =AsE("D7") //(出于某种原因,它会自动将 s 变为小写)结果: X 其他可能有用的信息: D7 的值是 24,它来自单元格的函数 =VALUE(Imported!B5)

详细地说,我可以让它在技术上工作的唯一方法是满足两个条件:1)当我在引用的单元格周围的函数中使用引号时,以及 2)当参数 cellRef 是 Variant 时。如果我不使用引号 [=ASE(D7) 而不是 =ASE("D7")],它就不起作用。如果我将 cellRef 的数据类型更改为 Range 或 String,它就不起作用。它只会返回 #VALUE! 错误。

我应该如何设置它的格式,这样我就不必在引用的单元格周围使用引号?

【问题讨论】:

从您现在删除的其他 Q 中回答您关于变通办法的问题,see here @chrisneilsen 感谢您找到我并分享该链接。在遇到具有相同答案的类似问题后,为了冗余,我将其删除。 【参考方案1】:

传递单元格本身(不带引号):

Public Function ASE(cellRef As Range)

    Dim setpointU As Integer, setpointL As Integer
    Dim enabled As String, disabled As String

    cellValue = cellRef.Value
    setpointL = 50
    setpointU = 100
    enabled = "O"
    disabled = "X"

        If cellValue >= setpointL Or cellValue <= setpointU Then
            ASE = enabled
        Else
            ASE = disabled
        End If

End Function

【讨论】:

【参考方案2】:

你要面对两个麻烦制造者和一些问题。

一个是您的工作表对 AsE 大写的记忆。这是我经常遇到的问题,我不知道如何治愈它。即使我给函数取另一个名字,保存,关闭 Excel,重新启动,然后改回名称,Excel 也会记住错误的大小写。所以,我要做的是永久更改名称。

另一个是cellRef As Variant的模棱两可。如您所知,变体可以是任何东西,而 Excel 似乎在到达 cellValue = Range(cellRef).Value 之前不会下定决心。那时它需要是一个字符串,因此用引号括起来。当然,D7 是一个范围。但是cellValue = Range(cellRef).Value没有意义。如果cellRef 是一个范围,它应该是cellValue = cellRef.Value。您将选择权留给了 Excel,并且承认,它在这种情况下已经做到了最好。

代码顶部缺少Option Explicit 存在问题。它会提醒您注意cellValue 的缺失声明和Or cellValue &lt;= setpontU Then 变量名中的拼写错误。打开 VB 编辑器的 工具 菜单。从选项菜单中选择编辑器标签并选中“需要变量声明”。 VBA 将自动在之后创建的所有代码表中插入Option Explicit。只有这样,您才能放心地忘记它。

最后,请记住,函数的返回也必须有数据类型。由于您没有声明任何返回将是一个变体。显然,您的函数返回一个字符串。是的,Excel 和 VBA 会解决它。但只要你稍加配合,他们就能做得更好。至少你可以分享你所知道的。完成此操作后,您的代码可能如下所示。

Function ASE(cellRef As Range) As String

    Dim cellValue As Variant
    Dim upperSetpoint As Integer, lowerSetpoint As Integer

    cellValue = cellRef.Value
    lowerSetpoint = 50
    upperSetpoint = 100

    If cellValue >= lowerSetpoint And cellValue <= upperSetpoint Then
        ASE = "O"                   ' enabled
    Else
        ASE = "X"                   ' disabled
    End If
End Function

请注意,您的条件中的逻辑错误也已被发现。任何值都必须是 >=SetpointL 或 And 将这两个条件作为先决条件应用,情况会有所不同。

最后,所有程序都是“公共的”,除非它们被声明为“私有”。那么,将程序声明为“公共”有什么意义呢?只标记那些“公开”的会更清楚。

【讨论】:

相信我,我也想知道你提到的很多事情,但我知道问题需要更多地关注 Stack Overflow,所以我坚持 #1 问题。话虽如此,我真的很感谢您花时间为我解释并回答所有“为什么”,并指出那些明显的语法/逻辑错误。谢谢你,很棒的信息!

以上是关于在 VBA 的 UDF 中将单元格作为参数传递的正确方法是啥?的主要内容,如果未能解决你的问题,请参考以下文章

从工作表将二维数组传递给 VBA/UDF 函数

VBA UDF 多单元格引用

自动计算与单元格属性相关的 Excel VBA UDF

如何将不连续的单元格传递给 Excel UDF

将单元格区域作为变量传递并使用函数复制数据

VBA - 优化 UDF(单元颜色计数器)