4

I'm hesitant to ask, but there's no documentation that I can find for VBA.

Relevant (but I don't think a dupe):

I think I'm using the word "Instantiate" right, but please correct me if I'm wrong. Instantiating is when a variable is created and allocated the resources it requires? So in VBA I see two ways of doing this.

Everything at the top!

Public Sub ToTheTop()
    Dim var1 As Long
    Dim var2 As Long
    Dim var3 As Long

    var1 = 10
    var2 = 20
    var3 = var1 + var1
    Debug.Print var3
End Sub

Or close to use

Public Sub HoldMeCloser()
    Dim var1 As Long
    var1 = 10
    Dim var2 As Long
    var2 = 20
    Dim var3 As Long

    var3 = var1 + var1
    Debug.Print var3
End Sub

I like to put them closer to use so that it's easier to remember what they are, whereas others might want to get them all out of the way. That's personal preference.

But, I think I remember reading somewhere that the VBE goes through a sub/function and instantiates all the variables before going on to anything else. This would indicate that there's no right way to do this in VBA because the variable scopes in time don't change. Not the scope as in Private vs Public.

Whereas in other languages it seems that scope can change based on placement and therefor has a best practice.

I've been searching for this documentation for a while now, but whatever words I'm using aren't pointing me in the right direction, or the documentation doesn't exist.

Community
  • 1
  • 1
Raystafarian
  • 2,902
  • 2
  • 29
  • 42
  • 1
    I agree with Peter's Answer and with Thomas's statement that general accepted practic is to declare variables at the top of a procedure. "Global" variables *must* be at the top of a module, before any procedures. The only "scopes" VBA recognizes is "global" (Public, module-level), module-level (Private, module-level) vs. procedure level. There are no "block scopes", such as within If. – Cindy Meister Apr 20 '16 at 19:30
  • "Instantiated" is about *objects being created*, I'd avoid using it in another context; the correct word would be "initialized", I believe. – Mathieu Guindon Jul 31 '20 at 15:59

2 Answers2

5

According to the reference documentation,

When a procedure begins running, all variables are initialized. A numeric variable is initialized to zero, a variable-length string is initialized to a zero-length string (""), and a fixed-length string is filled with the character represented by the ASCII character code 0, or Chr(0). Variant variables are initialized to Empty. Each element of a user-defined type variable is initialized as if it were a separate variable.

When you declare an object variable, space is reserved in memory, but its value is set to Nothing until you assign an object reference to it using the Set statement.

The implication is that regardless of where the variable declaration is stated, the space/memory for it is allocation when the procedure is entered.

Community
  • 1
  • 1
PeterT
  • 8,232
  • 1
  • 17
  • 38
2

The variables, constants, and objects, are instantiated that way :

  • at module level they are instantiated when the application starts, whether they are declared public, private or static

  • at procedure level (sub/function) they are instantiated when the procedure is executed.

You have to understand that, although it does have a "compiler", vba is NOT a true compiled language. The compiler is a syntax checker that checks for errors in your code to not encounter them at runtime. In MS access the compiler produce something that is called p-code and which is a combination of compiled and interpreted code.

As a rule of thumb:

  • always use option explicit statement (configure your compiler for this)

  • always declare your variables at one place, on top of your module or sub/function, and avoid doing it in the middle of your code, for the sake of clarity only. This doesn't affect the performance in any way.

  • avoid using variant data type

Worth a read doc: Understanding the Lifetime of Variables (official mSDN), Visual/Access Basic Is Both a Compiler and an Interpreter (official MS) and Declaring variables. You might also find interesting this answer I recently gave about the vba garbage collector

Community
  • 1
  • 1
Thomas G
  • 9,886
  • 7
  • 28
  • 41
  • 1
    That is not correct regarding to when procedure variables are created. They are created when the procedure begins execution (lifetime), but are inaccessible before the point of declaration (scope). – GSerg Apr 20 '16 at 19:48
  • *always declare your variables at one place, on top of your module or sub/function, and avoid doing it in the middle of your code, for the sake of clarity only* - this is how we get 30 variables in a wall of declarations at the top of a scope, 10 of which are never used, 4 have a useless name followed by a digit, ...I'll never understand why declaring closer to usage is best for readability *in any language other than VBA*. This isn't personal preference, it's part of the well-outdated set of "best practices" from the 90s, needs to be left in the past with Hungarian Notation. – Mathieu Guindon Jul 31 '20 at 15:55