我想使用类似的语句添加到集合中
myCollection.Add myItem, After:=Iif(myCollection.Count > 0, myCollection.Count, vbNull)
Run Code Online (Sandbox Code Playgroud)
换句话说,我想决定是否要指定参数"After",如果我不这样做,那么我想在它的位置传递一个非值值.
它比为每个场景单独调用要清理得多.
这可能在VBA中吗?
是的,可以在VBA中使用(更新以避免CopyMemory的复杂化)
使用以下代码将新模块mdlMissingVariant添加到VBA项目:
Public Function getMissingVariant(Optional v As Variant) As Variant
getMissingVariant = v
End Function
Run Code Online (Sandbox Code Playgroud)
现在,只要你想让VBA认为你没有为参数提供值,就可以使用getMissingVariant()(不提供参数).例如,定义以下函数:
Public Sub testOpt(Optional v As Variant)
Debug.Print IsMissing(v)
End Sub
Run Code Online (Sandbox Code Playgroud)
并测试...
testOpt getMissingVariant()
Run Code Online (Sandbox Code Playgroud)
...要查看VBA IsMissing函数检测到未提供参数.其工作原理是Variant是一个16字节的结构,包括一个描述其包含的数据类型的2字节代码.其中一种类型(实际上是10种)是VT_ERROR.如果未向可选Variant提供参数,则内部VBA会将Variant的类型更改为"VT_ERROR"并指定值&H80020004(Long),这是"未找到参数"的Windows错误代码.
编辑
我纠正了 - 正如@Nik指出的那样,"缺失的"Variant 可以用作参数IIF,所以你的代码会正常工作!
我将首先提出一个警告,即Collection.Add用这样的IIf语句调用并不比有两个不同的调用更"干净". IIf是一个函数,带有函数调用的开销.此外,由于真实部分和假部分都作为参数传递,因此无论条件是真还是假,都会评估它们.这意味着你总是打myCollection.Count两次电话.除了效率低得多之外,它的可读性要低得多.除非你打码打高尔夫球,否则根本没有充分理由使用它IIf.这在几个层面上要好得多:
If myCollection.Count > 0 Then
myCollection.Add myItem, , myCollection.Count
Else
myCollection.Add myItem
End If
Run Code Online (Sandbox Code Playgroud)
此外,如评论中所述,Collection 确实保留了添加项目的顺序,因此上述代码与以下内容相同:
myCollection.Add myItem
Run Code Online (Sandbox Code Playgroud)
好的,如果您真的觉得有必要这样做,那么另一个选择就是简单地提供您自己的IIf带有可选参数的重载:
Private Function IIf(condition As Boolean, Optional truepart As Variant, _
Optional falsepart As Variant)
IIf = VBA.IIf(condition, truepart, falsepart)
End Function
Run Code Online (Sandbox Code Playgroud)
请注意,这会在您声明函数的范围内"隐藏"内置VBA函数,因此您应该对其进行大量注释,并确保它不会破坏IIf对代码中其他位置的其他调用.提供重载后,您可以像内置一样使用它,但省略参数:
Public Sub Example()
ValueOfIIf IIf(True, , "Foo")
End Sub
Public Sub ValueOfIIf(result As Variant)
Debug.Print IsMissing(result) '<--True
End Sub
Run Code Online (Sandbox Code Playgroud)