In terms of VBA syntax, one thing I find annoying is the need to use the Set keyword for assignment of object references. I think I forget it as often as not, particularly when using my own classes. For example:
Dim myrange as Range
Set myrange = Range(“Source_Data”)
Why is this necessary? I’m not aware of other object-based languages that require a similar keyword.
VBA is obviously capable of inspecting the type of the right-hand-side expression, to see whether it is a valid object type (same as the left-hand-side type, or implements it, or nothing). That’s why it raises an error if Set is missing. So why does it need the keyword?
As far as I can tell from the Mediaeval Mystery that is the VBA Reference Manual, there is no valid use of Set with a non-object type on the right-hand-side, so it’s not there to disambiguate any such case from the default (Let) assignment.
If anyone can shed light on this, please comment…
I think it’s because objects have default properties. Should the last line of this sub be an object assignment or an assignment of the default Value property?
Sub TestSet()
Dim MyRange As Range
Set MyRange = Range(“A1″)
MyRange = Range(“B1″)
End Sub
Hi Dick,
Actually, Range.Value isn’t a default property – Range doesn’t have one (whereas TextBox.Value, etc, are defaults). Tricky…
However, I take your general point. But in this case, MyRange is typed as a Range, so it must be the result of the Range() function that we want here, so no ambiguity.
I guess the complications are assignments to generalised types (Variant, Object): the left-hand-side type could accommodate either the target object or its default property. And also where the type of the default property is the same as that of the target object (does that ever happen)?
Given a choice, I’d rather have no default properties and no Set keyword
Just be glad we don’t still have to use Set’s deprecated cousin, Let, as well
Let a = 5
Ouch!
VB.Net doesn’t even use Set any more.
“Actually, Range.Value isn’t a default property – Range doesn’t have one (whereas TextBox.Value, etc, are defaults). Tricky…”
Roy – if you declare a variable as a variant then:
MyVariant1 = Range(“A1:A3″)
and
MyVariant2 = Range(“A1:A3″).value
will both return the same thing, a 3×1 array containing the values in A1:A3
whereas
Set MyVariant3 = Range(“A1:A3″)
will return a range object
I’m with you on the default properties Roy – they serve no purpose as far as I can tell apart from generating this sort of potential confusion. As far as variants go, my thinking would be, if you want to assign an array, use Range(ref).Value, and if you want to assign a range object, use Range(ref).
I enjoy working with VBA, but this is one peculiarity of its syntax that sets my teeth on edge.
(Doug wrote)
“if you declare a variable as a variant then:
MyVariant1 = Range(”A1:A3″)
and
MyVariant2 = Range(”A1:A3″).value
will both return the same thing, a 3×1 array containing the values in A1:A3″
So in the first case, the value of the RHS expression depends on the type of the LHS variable? Yuk! And Value is a sort of Default property, but doesn’t show up as such in the Object Browser…
The second case is okay, although it would be better with a proper Array type (as in most other languages).
As I said, I could live without default properties.
/Roy
“The second case is okay, although it would be better with a proper Array type (as in most other languages).”
Well you can declare the variable as an array of course, but if you do then
Dim MyArray() as double
MyArray = Range(”A1:A3″).value
will generate an error, something like “cannot assign to an array”.
Goodnesss knows why; you can assign to an array, but only if you call it a variant.
There may be some logic behind that, but I don’t know what it is.
The default property thing is indeed the reason – it’s a legacy thing going back to some ancient version of VB, quite possibly v1.0 although my memory doesn’t seem to have that info any longer.
Set has gone in VB.Net because default properties have been done away with.