I am working on an legacy VBA/Excel app and stumbled over some lines of code where a long string (read from a file) is cut into pieces. Those lines look like this:
Range("E16").Value = Mid(line, 49, [6])
Obviously, writing [6]
means taking 6 characters, but I never saw this syntax to put square brackets around a number.
I did some tests and found out that putting those square brackets doesn't do any obvious to the number
Dim x As Double
x = 5.1
Debug.Print [2], [3.1], [-5], x
Debug.Print [3.1] * [x] * [-5]
>> 2 3.1 -5 5.1
>> -79.05
So, no truncation, no rounding, no abs-value.
I did some more tests to check if it does some magic similar to putting parentheses around a variable to prevent modifying a value that is passed by reference, but that's not the case:
x = 5.1: test2 x: Debug.Print x
x = 5.1: test2 (x): Debug.Print x
x = 5.1: test2 [x]: Debug.Print x
Sub test2(ByRef y As Double)
y = y * 2
End Sub
>> 10.2
>> 5.1
>> 10.2
Surprised that the compiler even accepts this syntax: What is the meaning of using those brackets?
Square brackets in VBA/VB6 are used for accessing "foreign identifiers", i.e. identifiers that would otherwise not be legal. For example:
Public Enum Foo
Some
Thing
[Some Thing] ' please don't do this
End Enum
And hidden members whose name begins with an underscore:
Public Property Get NewEnum() As IUnknown
Set NewEnum = myCollection.[_NewEnum]
End Property
However in the context of the code in this question, the square brackets are, as Scott indicated, essentially shorthand notation for [_Global].Evaluate
, which ultimately resolves to Application.Evaluate
... assuming we're not in a Worksheet
module's code-behind, in which case it's shorthand for Worksheet.Evaluate
- and both return a Variant
, which means any chained member calls are blind, late-bound calls resolved at run-time: Option Explicit
can't save you from a typo.
That's why Rubberduck (an open-source VBIDE add-in project I manage / contribute to) resolves them as "runtime expressions":
In other words this:
Range("E16").Value = Mid(line, 49, [6])
Could just as well be written like this:
[E16] = Mid(line, [49], [6])
...which is arguably terrible code with a ton of redundant implicit operations going on.
There is never, NEVER any reason whatsoever to square-bracket an integer literal: it's nothing more than a rather roundabout way to turn an Integer
literal into a Double
(since worksheet numeric values are Variant/Double
):
Debug.Print TypeName(42)
Integer
Debug.Print TypeName([42])
Double
Which is much better off done with an explicit conversion:
Debug.Print TypeName(CDbl(42))
Double
...or even with a (gasp) type hint:
Debug.Print TypeName(42#)
Double
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With