如何在 VBA 过程中使用可选数组参数?

Posted

技术标签:

【中文标题】如何在 VBA 过程中使用可选数组参数?【英文标题】:How can I use an optional array argument in a VBA procedure? 【发布时间】:2010-02-15 10:47:01 【问题描述】:

我在 MS Access 的 VBA 脚本中有一个私有过程:

Private Sub drawLineDiagram(chartSpace As Variant, title As String, caption As String, x_val() As Variant, y_val() As Variant, Optional y_val2() As Variant = ????)

如您所见,我想为值数组添加一个可选的最后一个参数。

我必须分配什么样的默认参数?如果我用一个可选的整数值来做它并分配它,例如0 没关系。

如果我使用如上所示的数组并分配一个数组,则该行将标记为红色 => 为错误(并且不会编译)。

【问题讨论】:

【参考方案1】:

如果您需要 VBA 中的可选数组,请将其声明为 Variant 而不使用数组说明符,但无论如何都要将其作为数组访问。这样你就得到了一个Variant(单个变量),它包含一个Variants 的数组,而不仅仅是Variants 的数组。不需要默认值:

Private Sub drawLineDiagram(chartSpace As Variant, title As String, caption As String, x_val As Variant, y_val As Variant, Optional y_val2 As Variant)

为了保持一致性,另外两个参数也声明为普通的Variants。

如果您讨厌 IDE,请不要使用它。 使用记事本。然后粘贴写好的代码。

【讨论】:

谢谢,我试试。我实际上并不讨厌 IDE,我只是觉得这个 IDE 和例如 netbeans 之间存在很大的可用性差距。在我看来,缺乏可用性会导致效率降低。 这是因为 VBA IDE 的目标受众是经理和其他被认为很聪明但可能不是程序员的人。因此,有关语法错误和缺乏高级功能的消息框。与 VS.NET IDE 相比,这对于经理来说无疑是一种过度杀伤力。 好的,这很好。没想到 => 典型程序员的观点.... ;) VS.NET IDE 是一款非常不错的软件,但我同意:这对他们来说太过分了。 感谢您的解决方案。我喜欢将数组传递给变体的想法,因为它可以很容易地用 'If IsArray(somevar) Then' 进行检查,然后我们就走了。还要在 IDE 上投入两分钱:VBA IDE 与我们的老朋友 Visual Studio 6 中的 IDE 有 99% 相同。因为,你看……VB6 从未消亡。它在过去 10 年中一直存在于其后代 VBA 中——尽管它更小且未编译。它一直持续到 Office 2010、2013 和 2016...直到基于云的 Office 365 废话开始。【参考方案2】:

也许你想要一个参数数组:

在过程声明中,定义 以正常方式的参数列表。 除最后一项外的所有参数 必须是必需的(不是可选的(视觉 基本))。

在最后一个参数名称前加上 关键字 ByVal ParamArray。这 参数是自动可选的。 不要包含 Optional 关键字。

-- How to: Overload a Procedure that Takes an Indefinite Number of Parameters (Visual Basic)

VBA 参考:Understanding parameter arrays

【讨论】:

【参考方案3】:

IDE 可能用处不大,但帮助(仅此一次)包含答案:ParamArray 选修的。仅用作 arglist 中的最后一个参数,以指示最后一个参数是 Variant 元素的可选数组。 ParamArray 关键字允许您提供任意数量的参数。 ParamArray 不能与 ByVal、ByRef 或 Optional 一起使用。

【讨论】:

当数据流(即图表点)以数组形式出现时,使用 ParamArray 没有意义。对于想要在代码中将它们的值作为文字列出并且不想为此声明另一个数组变量的人类来说,这是一种语法糖。【参考方案4】:

这个问题有一个更简单但不一定更好的答案。 Sebastian 说:“如果我使用如上所示的数组并分配一个数组,则该行被标记为红色 => 为错误(并且不会编译)。”

您的代码包括“可选 y_val2() As Variant = ????”。您不需要那里的“()”来将 Variant 数组作为参数。因此,如果您真的想这样做,您可以使用诸如“可选 y_val2 = FALSE”之类的内容。

最初传递参数时,如果要传递数组,则只需确保 that 是 Variant 数组。

我确实认为在那里不使用默认值会更优雅,所以我总体上同意 GSerg 的回答(并赞成这个问题和原始问题)。

但是对于 GSerg 和 spinjector,是的,您可以使用“If IsArray(YourOptionalVariantParameter) Then”检查可选参数,但如果您使用的是 Variant, "IsMissing(YourOptionalVariantParameter)" 方便而优雅,可能会更快一些,并且可以在(且仅当)将 Variant 作为参数传递时使用,以检查它是否存在。

如果你执行“IsArray(YourOptionalVariantParameter)”并且不存在这样的参数,那么我们所做的就是检查一个不存在的变量是否是一个数组。如果您使用 FALSE 之类的默认参数值(如我的第一个示例),那么首先检查变量是否为数组是有意义的。

顺便说一句,我不同意您需要将所有参数声明为 Variants 以保持一致性。变体的效率低于其他类型,因此我认为应该仅在必要时使用。

【讨论】:

以上是关于如何在 VBA 过程中使用可选数组参数?的主要内容,如果未能解决你的问题,请参考以下文章

VBA ADO 将数组参数传递给存储过程

Excel vba 编译错误 - 参数不是可选的,

如何测试是否提供了可选参数?

如何测试是不是提供了可选参数?

如何在存储过程中设置日期时间可选参数?

如何在C#中调用的存储过程正确插入数据而不提供所有可选参数?