使用后期绑定但不是早期绑定时使用Dictionary的运行时错误

时间:2014-10-27 10:49:58

标签: excel vba dictionary

我所做的是将字典放入子例程中的数组

这就是定义

Dim Arr() As Variant
ReDim Arr(0 To Dict.Count - 1)
For c= 0 To Dict.Count - 1 
   Arr(c) = Dict.Keys(c) ' <~~~~~~ Error here
Next c 

编译器说

  

运行时错误451:属性let过程未定义,属性get过程未返回对象。

效果很好
Public Sub SubRoutine(Dict As Scripting.Dictionary) 

但不是

Public Sub SubRoutine(Dict As Object) –

请参阅Declare a dictionary without Microsoft Scripting Runtime

2 个答案:

答案 0 :(得分:6)

<Solution>

你这样做

Dim Arr() As Variant
ReDim Arr(0 To Dict.Count - 1)
For c = 0 To Dict.Count - 1
    Arr(c) = Dict.Keys(c)
Next c

但是像这样循环是非常不必要的。这就是Arr = Dict.Keys的作用。所以不是上面的,而是做

Dim Arr As Variant
Arr = Dict.Keys

额外的好处是这会使错误消失

</Solution>


但为什么错误发生在代码的后期绑定版本而不是早期绑定?

<Educated guess slash wild speculation>

通过早期绑定,编译器知道the .Keys method不带参数 - 它只返回一个数组。因此它将Dict.Keys(c)解释为{returned array}(c)并返回该返回数组的c元素。

使用 late 绑定,我猜对象容器不知道.Keys方法不接受参数(又称参数),因此它将c发送到它作为参数。但是没有定义这样的getter(或setter),因此错误。要解决问题,您可以apparently force it通过说KeysDict.Keys()(c)方法向{returned array}(c)方法发送任何参数,这会导致</Educated guess slash wild speculation>行为。

{{1}}

这是我第一次碰到这样的情况,其中后期绑定代码的行为与早期绑定不同。

答案 1 :(得分:1)

这有效:

Dim Arr() As Variant
ReDim Arr(0 To Dict.Count - 1)
For c = 0 To Dict.Count - 1
   Arr(c) = Dict.Keys()(c)
Next c