在 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 <= 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 中将单元格作为参数传递的正确方法是啥?的主要内容,如果未能解决你的问题,请参考以下文章