Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Runtime Error with Dictionary when using late binding but not early binding

What I do is putting a dictionary into an array within a Sub Routine

That is the definition

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 

The compiler says

Runtime Error 451: Property let procedure not defined and property get Procedure did not return an object.

It works great with

Public Sub SubRoutine(Dict As Scripting.Dictionary) 

but not with

Public Sub SubRoutine(Dict As Object) –

Please refer to Declare a dictionary without Microsoft Scripting Runtime

like image 645
Excel_newbie Avatar asked Oct 27 '14 10:10

Excel_newbie


1 Answers

<Solution>

You do this

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

But looping like this is quite unnecessary. That's what Arr = Dict.Keys does. So instead of the above, just do

Dim Arr As Variant
Arr = Dict.Keys

The added bonus is that this makes the error go away.

</Solution>


But why did the error occur in the late bound version of the code but not the early bound?

<Educated guess>

With early binding, the compiler knows that the .Keys method takes no parameters — it just returns an array. So it interprets Dict.Keys(c) as {returned array}(c) and returns the cth element of that returned array.

With late binding, I guess the Object container doesn't know that the .Keys method doesn't take parameters (a.k.a. arguments), so it sends c to it as a parameter. But there is no such getter (or setter) defined, hence the error. To remedy, you can apparently force it to send no parameters to the Keys method by saying Dict.Keys()(c), which brings back the {returned array}(c) behaviour.

</Educated guess>

This is the first time I bump into a case like this where the late bound code behaves differently than the early bound.

like image 92
Jean-François Corbett Avatar answered Nov 09 '22 00:11

Jean-François Corbett