I am attempting to reduce the number of repeated Dim statements in my code and instead declaring Public variables at the top of modules. For some reason, the debugger breaks on the following line, even though the variable is clearly declared at the top of parent module:

strReponse = vbYes

The variable is publicly declared as:

Public strResponse As String

Why might the VBE debugger not see the public declaration?

4 Spice ups

Are you sure vbyes is a string?

Fairly sure. At lease I assume that the MsgBox function I am using returns a string.

strResponse = MsgBox("Add system?" & Chr(10) & Chr(10) & "ID:                  " & strSystem_ID & Chr(10) & "Designator:  " & strSystem_Designator, vbYesNo + vbQuestion, "Add System Confirmation -")

This should return either “vbYes” or “vbNo” depending on which button on the MsgBox is pressed.

@paulfitzpatrick3 ​ - So yes. I am sure that it is a string. When I declare via Dim at the procedure level it works fine. Why does the Public declaration not work?

@donaldfisher3

I just tested on my system and it works being declared as you posted, however the value I get returned is the number 6, which is probably the id for the set of vb values for VBYES, VBNO returns 7.

I tried your msgbox command and it works, I added

If strResponse = vbYes Then
    MsgBox "You chose Yes"
Else
    MsgBox "You chose: " & strResponse
End If

When selecting Yes on the msgbox it recogonized that Yes was chosen and returned the “You chose Yes” , if I select No then I get “You chose: 7”

So I’m not sure why you’re unable to get the public declartion functioning…

Actually, I may see the problem :slight_smile: umm, if you copied that code in, then check the spelling in your declaration, it’s missing the first S in Response (you have Reponse)

1 Spice up

The misspelling was it! Too close and obvious for me to see!

Lol, me too, although I was brushing my teeth when I read it the first time :smiley:

I’m glad it’s sorted, have a great rest of the day!

A bit off point but to help avoid future problems …

Public variables can be useful in certain contexts but casual use risks inadvertent name collisions and other problems, which can have unintended (and perhaps catastrophic) consequences.

If you want to refactor procedure-level declarations to the module level, use Private instead. This limits scope to procedures in the module and corrals things somewhat.

It also helps to add a prefix to a variable name indicating its scope. This helps readability and reduces the likelihood of name collisions. It’s common to use “m” for module-level variables and “g” for public (i.e., global) variables. One also often sees “l” (i.e., lower-case “L”, for local) for procedure-level variables, especially in class modules.

Taken together, these rules of thumb boil down to:

  • For procedure-level variables, use Dim and either “l” or no prefix: Dim lstrName As String.
  • For module-level variables, use Private and an “m” prefix: Private mstrName As String.
  • For global variables, use Public and a “g” prefix: Public gstrName As String.

Another subtle gotcha to be aware of is what’s called passback ByRef errors. A procedure calling a nonlocal variable, or being passed a variable ByRef, can change its value. That’s okay if you’re just reusing a common declaration, or if you intend to revise the variable for other uses. It isn’t okay if other procedures expect the variable to be unchanged once set.

Good luck!

1 Spice up