> ## Content Index
> Fetch the complete content index at: https://nolongerset.com/llms.txt
> Use this file to discover other available public pages before exploring further.

# Bang! Dot. Default
- URL: https://nolongerset.com/bang-dot-default/
- Published: 2020-12-10T04:34:00.000Z
- Updated: 2026-05-08T12:49:34.000Z
- Description: Three ways to reference form and report controls. Which way is best?
- Author: Mike Wolfe
- Tags: Intermediate, #Import 2026-05-20 02:59

Let's talk about one of the most confusing aspects of Microsoft Access's VBA syntax.

### A simple textbox

We'll start with a form and add a single textbox to it. Next, let's add a command button to the form. We've got three controls: `Text0`, `Label1`, and `Command2`. Let's add some code to the button's on click event:

```vba
Private Sub Command2_Click()
    Debug.Print "Bang:    "; Me!Text0
    Debug.Print "Dot:     "; Me.Text0
    Debug.Print "Default: "; Text0
End Sub
```

Now, let's switch to Form view, enter "Test" in the text box, and click \[Command2\].

![](https://storage.ghost.io/c/eb/d7/ebd732c1-5f03-4f07-b386-5d08557e15c9/content/images/2020/12/image-6.png)

Here are the results in the immediate window:

```vba
Bang:    Test
Dot:     Test
Default: Test
```

So far, so good. These three approaches seem pretty interchangeable.

### Scope priority

Now, let's declare a local variable in our code-behind named `Text0`:

```vba
Private Sub Command2_Click()
    Dim Text0 As String
    
    Debug.Print "Bang:    "; Me!Text0
    Debug.Print "Dot:     "; Me.Text0
    Debug.Print "Default: "; Text0
End Sub
```

Look what happens when we click the \[Command2\] button now:

```vba
Bang:    Test
Dot:     Test
Default: 
```

What happened? VBA, like most languages, resolves variables in scope priority, where the closest scope wins. In this case, we introduced a new local variable that happens to match the name of the textbox on our form. Now, when we use the identifier `Text0` in our routine, it resolves to the local variable and not our text box.

### Property collisions

"Text0" is not a very descriptive name for our text box. Since we are going to use that text box on our form to prompt the user for their name, let's go ahead and rename it from "Text0" to "Name". I changed the Label1 caption, too.

![](https://storage.ghost.io/c/eb/d7/ebd732c1-5f03-4f07-b386-5d08557e15c9/content/images/2020/12/image-7.png)

With the change in control name, we have to update our code-behind or it won't compile:

```vba
Private Sub Command2_Click()
    Dim Name As String
    
    Debug.Print "Bang:    "; Me!Name
    Debug.Print "Dot:     "; Me.Name
    Debug.Print "Default: "; Name
End Sub
```

Who can guess what will happen when we click \[Command2\] now?

```vba
Bang:    John Doe
Dot:     Form1
Default: 
```

The Default is blank due to scope priority as before. But now the Dot operator is returning the name of the form instead of the contents of the Name textbox. That's because Name is a named public member of the Form object.

Now we're getting into the difference between Dot and Bang. The best definition of the bang operator I've read comes from Josh Honig at [bytecomb.com](https://web.archive.org/web/20130725045624/http://bytecomb.com/the-bang-exclamation-operator-in-vba/):

> The bang operator provides **late-bound** access to the **default member** of an object, by passing the literal name following the bang operator as a string argument to that default member.

Contrast this with Josh's definition of the Dot operator:

> The dot is the one and only way to access a named public member of an object.

Read Josh's entire article. It's the best explanation of the differences between VBA's dot and bang operators anywhere on the internet.

### So...always use bang?

After working through my examples, one might come to the conclusion that since the Default and Dot operators each failed, the Bang operator is the obvious choice. 

Not so fast! The bang operator has flaws of its own. Most notably, since it is late-bound, we lose the benefit of compile-time checking. 

Let's say I decide to change the name of my texbox to something other than Name, since that's causing property collisions. I change it to `tbText0`. 

That means I have to update my code. Not paying attention, I restore the code to how it was before when my textbox was named "Text0." When I run a Debug -> Compile, VBA skips right over the Bang line and warns me about the Dot line:

![](https://storage.ghost.io/c/eb/d7/ebd732c1-5f03-4f07-b386-5d08557e15c9/content/images/2020/12/image-8.png)

I resolve that line then try compiling again:

![](https://storage.ghost.io/c/eb/d7/ebd732c1-5f03-4f07-b386-5d08557e15c9/content/images/2020/12/image-9.png)

After I fix that last line, my code compiles. But, when I click the Command2 button, the Bang line raises an error:

![](https://storage.ghost.io/c/eb/d7/ebd732c1-5f03-4f07-b386-5d08557e15c9/content/images/2020/12/image-10.png)

We want to find broken code as soon as possible. Thus, code that fails at compile time is better than similar code that does not fail until runtime.

## My Preference: Dot

In the majority of my code, I prefer to use the dot operator. My main reason? I'm lazy ;-). The compile-time checking is great and all, but the real reason I use the dot operator is for all that **delicious IntelliSense**. 

The big drawback to that approach is the potential for naming collisions. I rely on [Allen Browne](http://allenbrowne.com/AppIssueBadWord.html) to help me with that, though.

*Image by [Thomas Mühl](https://pixabay.com/users/kloxklox%5Fcom-242049/?utm%5Fsource=link-attribution&utm%5Fmedium=referral&utm%5Fcampaign=image&utm%5Fcontent=366829) from [Pixabay](https://pixabay.com/?utm%5Fsource=link-attribution&utm%5Fmedium=referral&utm%5Fcampaign=image&utm%5Fcontent=366829)*

***UPDATE*** *\[2023-06-02\]:* *Changed the bytecomb.com link to point to the preserved page in the Internet Archive as the site has been abandoned (h/t Chris M in the comments below).*