Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When are VBA Variables Instantiated

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

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

  • C++ When are global variables created?
  • In Java, should variables be declared at the top of a function, or as they're needed?
  • C++ Declare variables at top of function or in separate scopes?
  • and the most likely relevant When are a module's variables in VB.NET instantiated?
  • I also took a look at C# on programmers.SE.

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.

like image 633
Raystafarian Avatar asked Mar 12 '23 13:03

Raystafarian


2 Answers

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.

like image 53
PeterT Avatar answered Mar 19 '23 15:03

PeterT


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

like image 23
Thomas G Avatar answered Mar 19 '23 16:03

Thomas G