我想使用类似
的语句添加到集合中myCollection.Add myItem, After:=Iif(myCollection.Count > 0, myCollection.Count, vbNull)
换句话说,我想决定是否要指定参数" After",如果我不想,那么我想在其中传递非值值'的地方。
比为每个场景单独调用要简单得多。
这可以在VBA中使用吗?
答案 0 :(得分:5)
是的,可以在VBA中(更新以避免CopyMemory的复杂化)
使用以下代码将新模块 mdlMissingVariant 添加到您的VBA项目中:
Public Function getMissingVariant(Optional v As Variant) As Variant
getMissingVariant = v
End Function
现在,只要您想让VBA认为您没有为参数提供值,请使用getMissingVariant()
(不提供参数)。例如,定义以下函数:
Public Sub testOpt(Optional v As Variant)
Debug.Print IsMissing(v)
End Sub
用...测试
testOpt getMissingVariant()
...看到VBA IsMissing函数检测到未提供参数。这可行的原因是Variant is a 16-byte structure,其中包含2-byte code describing the type of data it contains。其中一种类型(实际上是10种)是VT_ERROR。如果未向可选Variant提供参数,则内部VBA会将Variant的类型更改为“VT_ERROR”并指定值& H80020004(Long),即the Windows error code for "Parameter not found"。
修改强>
我的立场得到了纠正 - 正如@Nik指出的那样,“缺失的”Variant 可以用作IIF
的参数,因此您的代码可以正常工作!
答案 1 :(得分:5)
我将首先提出一个警告,即Collection.Add
使用IIf
语句调用{strong> 不 &#34 ;清洁"而不是有两个不同的电话。 IIf
是函数,带有函数调用的开销。此外,由于true部分和false部分都作为参数传递, 的评估 ,无论 条件是真还是假。这意味着您总是两次致电myCollection.Count
。除了效率低得多之外,它的可读性要低得多。除非你code golfing,否则根本没有充分理由使用IIf
。这在几个层面上要好得多:
If myCollection.Count > 0 Then
myCollection.Add myItem, , myCollection.Count
Else
myCollection.Add myItem
End If
此外,正如评论中所述,Collection
保留已添加项目的顺序,因此上述代码与以下代码相同:
myCollection.Add myItem
好的,如果您真的感到被迫这样做了......另一个选择是简单地提供您自己的IIf
重载和可选参数:< / p>
Private Function IIf(condition As Boolean, Optional truepart As Variant, _
Optional falsepart As Variant)
IIf = VBA.IIf(condition, truepart, falsepart)
End Function
请注意,这&#34;隐藏&#34;您声明函数的范围内的内置VBA函数,因此您应该对其进行大量注释,并确保它不会破坏代码中其他位置的IIf
的其他调用。提供重载后,您可以像内置一样使用它,但省略参数:
Public Sub Example()
ValueOfIIf IIf(True, , "Foo")
End Sub
Public Sub ValueOfIIf(result As Variant)
Debug.Print IsMissing(result) '<--True
End Sub
答案 2 :(得分:2)
除了在这个特殊情况下,我认为它是多余的,因为它们应该按顺序添加到集合中,而不指定“后”;我想到了两件事:
1)您可以使用iif功能并利用“缺失”属性(不确定是否有更好的方法)。
Sub my_collection(Optional b As Variant)
Dim x As Collection
Set x = New Collection
'if you just run my_collection without passing anything
'b will be "missing"
x.Add "Test", After:=IIf(x.Count, x.Count, b)
End Sub
因为你从未将b传递给my_collection,所以b将永远“缺失”(你可以使用IsMissing()
进行测试)
2)添加值的功能
Sub my_collection()
Dim x As Collection
Set x = New Collection
Dim v As String
v = "test"
Call add_to_collection(x, v)
End Sub
Sub add_to_collection(ByRef y As Collection, q As Variant)
If y.Count Then
y.Add q, After:=y.Count
Else
y.Add q
End If
End Sub