The bang operator (!
) is shorthand for accessing members of a Collection
or other enumerable object, such as the Fields
property of an ADODB.Recordset
.
For example, you can create a Collection
and add a few keyed items to it:
Dim coll As Collection
Set coll = New Collection
coll.Add "First Item", "Item1"
coll.Add "Second Item", "Item2"
coll.Add "Third Item", "Item3"
You can access an item in this collection by its key in three ways:
coll.Item("Item2")
This is the most explicit form.
coll("Item2")
This works because Item
is the default method of the Collection
class, so you can omit it.
coll!Item2
This is short-hand for both of the above forms. At run-time, VB6 takes the text after the bang and passes it as a parameter to the Item
method.
People seem to make this more complicated than it should be, which is why it's hard to find a straightforward explanation. Usually the complications or "reasons not to use the bang operator" stem from a misunderstanding of how simple it actually is. When someone has a problem with the bang operator, they tend to blame it instead of the real cause of the problem they are having, which is often more subtle.
For example, some people recommend not using the bang operator to access controls on a form. Thus, Me.txtPhone
is preferred over Me!txtPhone
. The "reason" this is seen as bad is that Me.txtPhone
will be checked at compile-time for correctness, but Me!txtPhone
won't.
In the first case, if you mistype the code as Me.txtFone
and there is no control with that name, your code won't compile. In the second case, if you wrote Me!txtFone
, you won't get a compile error. Instead, your code will blow up with a run-time error if it reaches the line of code that used Me!txtFone
.
The problem with the argument against the bang operator is that this problem has nothing to do with the bang operator itself. It's behaving exactly the way it's supposed to.
When you add a control to a form, VB automatically adds a property to your form with the same name as the control you added. This property is part of the form's class, so the compiler can check for typos at compile-time if you access controls using the dot (".") operator (and you can access them using the dot operator precisely because VB created a named control property for you).
Since Me!ControlName
is actually short-hand for Me.Controls("ControlName")
1, it should not be suprising that you don't get any compile-time checks against mistyping the control name.
Put another way, if the bang operator is "bad" and the dot operator is "good", then you might think
Me.Controls("ControlName")
is better than
Me!ControlName
because the first version uses a dot, but in this case, the dot isn't any better at all, since you are still accessing the control name via a parameter. It's only "better" when there is an alternative way to write the code such that you will get compile-time checking. This happens to be the case with controls due to VB creating properties for each control for you, and this is why Me.ControlName
is sometimes recommended over Me!ControlName
.
- I had originally stated that the
Controls
property was the default property of the Form
class, but David pointed out in the comments that Controls
isn't the default property of Form
. The actual default property returns a collection that includes the contents of Me.Controls
, which is why the bang short-hand still works.