gpt4 book ai didi

VBA - 有条件地调用具有某些可选参数的函数的解决方法?

转载 作者:行者123 更新时间:2023-12-01 17:42:27 25 4
gpt4 key购买 nike

考虑一个具有多个可选参数的函数。例如:

Function foo(Optional a, Optional b, Optional c, Optional d)

如果我只想在参数不为空的情况下调用特定函数,或进行其他测试(因为该函数会引发错误,除非参数丢失)。

Collection 类就是一个例子。 Add 方法有 3 个可选参数。许多自定义类包装此类 - 例如创建“Person”自定义类的可索引类 Persons 或类似的类。包装器必须处理 6 种组合:仅添加 Key、添加 Key 并指定 Before、添加 Key 并指定 After、不添加 Key 并指定 Before、不添加 Key 并指定 After、无 Key 且无 Before/后。如果将包装器编写为具有十几个可选参数的 Workbook.Save 之类的东西,情况会变得更糟。

我不知道有什么办法可以替代一些乏味的结构,例如:

If a <> Null Then
If b <> Null Then
If c <> Null Then
If d <> Null Then
foo a, b, c, d
Else
foo a, b, c
End If
Else
If d <> Null Then
foo a, b, d
Else
foo a, b
End If
End If
Else
'... Etc ...

显然,对于每个附加的可选变量,嵌套 If 的数量和一般代码开销大约会增加一倍。

在 .NET 中,可以传入 System.Type.Missing 类型,从而使表达式变得更加简单。

就像在 C# 中一样,它可以像以下一样干净:

foo(a ?? Missing, b ?? Missing, c ?? Missing, d ?? Missing);

(这表示“如果 a 为 null,则传入 Missing (或者可能在幕后重构调用本身),调用相当于不为可选参数 a 传递任何内容,等等)

如果实现了,则可以在 VBA 中使用内联 iff ('IIF(boolean, true, false)') 进行等效操作

是否有我缺少的 VBA 解决方法?

最佳答案

(编辑时:我合并了 HarveyFrench 对代码的改进)

您可以减少嵌套:

Function foo(Optional a, Optional b, Optional c, Optional d)
Dim passed As String
If Not IsMissing(a) Then passed = "a "
If Not IsMissing(b) Then passed = passed & "b "
If Not IsMissing(c) Then passed = passed & "c "
If Not IsMissing(d) Then passed = passed & "d "
foo = IIf(Len(passed) = 0, "Nothing ", passed) & "passed"
End Function

Function foo_dispatcher(Optional a, Optional b, Optional c, Optional d)
Dim caseNum As Long
caseNum = IIf(IsNull(a) Or IsEmpty(a) Or IsMissing(a), 0, 8)
caseNum = caseNum + IIf(IsNull(b) Or IsEmpty(b) Or IsMissing(b), 0, 4)
caseNum = caseNum + IIf(IsNull(c) Or IsEmpty(c) Or IsMissing(c), 0, 2)
caseNum = caseNum + IIf(IsNull(d) Or IsEmpty(d) Or IsMissing(d), 0, 1)

Select Case caseNum
Case 0: foo_dispatcher = foo()
Case 1: foo_dispatcher = foo(, , , d)
Case 2: foo_dispatcher = foo(, , c)
Case 3: foo_dispatcher = foo(, , c, d)
Case 4: foo_dispatcher = foo(, b)
Case 5: foo_dispatcher = foo(, b, , d)
Case 6: foo_dispatcher = foo(, b, c)
Case 7: foo_dispatcher = foo(, b, c, d)
Case 8: foo_dispatcher = foo(a)
Case 9: foo_dispatcher = foo(a, , , d)
Case 10: foo_dispatcher = foo(a, , c)
Case 11: foo_dispatcher = foo(a, , c, d)
Case 12: foo_dispatcher = foo(a, b)
Case 13: foo_dispatcher = foo(a, b, , d)
Case 14: foo_dispatcher = foo(a, b, c)
Case 15: foo_dispatcher = foo(a, b, c, d)
End Select
End Function

Sub test()
Debug.Print foo_dispatcher(Null, Null, Null, Null)
Debug.Print foo_dispatcher(Null, 1, Null, 2)
Debug.Print foo_dispatcher(1, 2, 3, 4)
Debug.Print foo_dispatcher()
Debug.Print foo_dispatcher(, 1, , 2)
Debug.Print foo_dispatcher(a:=1, d:=Null)
End Sub

测试的输出:

Nothing passed
b d passed
a b c d passed
Nothing passed
b d passed
a passed

显然,这 16 种情况中的操作可以根据 foo 的调用约定进行定制(例如,您可以分派(dispatch)到 foo(a,d) 而不是 foo(a,,,d) 如果你需要的话)。我没有明确检查所有 16 个案例,但它似乎有效。我所做的有点机械。您可以编写一个调度生成器 - 一个函数,它接受字符串函数名称、必需参数数组、可选参数数组以及充当 Null 角色的值并返回调度程序作为一个字符串,可以从直接窗口复制粘贴到代码模块。我想过在这里这样做,但对于概念验证调度程序来说似乎不值得。

关于VBA - 有条件地调用具有某些可选参数的函数的解决方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31808340/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com