3

I try to understand the VBA scope type, it's impossible to make this such of thing in VBA, but it's possible in other language (java,scala,etc):

public sub try()

    dim myVar as String
    myvar = "hello world" 

    Call displayVar()

end sub

public sub displayVar()
   msgbox (myvar)
end sub

Can you give me some information about this type of limited scoping ? It's dynamical or lexical, i don't really understand the difference :/

reyman64
  • 523
  • 4
  • 34
  • 73
  • you may consider using VBA classes - see http://www.cpearson.com/excel/classes.aspx and http://stackoverflow.com/questions/118863/when-to-use-a-class-in-vba – JMax Jan 06 '12 at 09:11
  • Ok, so it's only possible to make this with class, i understand. Thanks ! – reyman64 Jan 06 '12 at 11:03
  • 1
    The code you posted will not compile with `option explicit on` I would suggest turning that on as this may be disguising what you *think* is happening – Matt Wilko Jan 06 '12 at 11:30
  • 1
    A side note - whenever you see a space after a method call and before the first bracket this means you are passing the parameter `ByVal` in most cases you don't want this so you either need to add `Call` or remove the brackets e.g. `Call MsgBox(myvar)` or `MsgBox myvar` – Matt Wilko Jan 06 '12 at 11:34
  • 1
    @reyman64, VBA definitely uses lexical scoping, not dynamic. Your confusion probably arises from the fact that VBA does allow *implicit* variable declaration. So in your example, the second `myvar` is local to its routine. It's implicitly declared there and has nothing to do with the first one, which is also local to its own routine. @Matt's comment suggesting you look at the VBA `Option Explicit` is the key to understanding what's going on. – jtolle Jan 07 '12 at 17:14

2 Answers2

3

Franck Leveque has provided a clear and simple demonstratation of the difference between local and global declarations.

However, like most languages, VBA allows you to pass parameters to subroutines. Sometimes a global variable is the only choice or the only sensible choice. But normally it it is better to declare myVar within try and pass it as a parameter to displayVar. This prevents displayVar from accidentally changing myVar because, by default, parameters are passed as values. If you want a subroutine to change the value of a parameter you must explicitly pass the parameter as a reference. This is true of most modern programming languages.

Note also that Public means these subroutines are visible to subroutines in other modules. If Public was omitted or replaced by Private, try and displayVar would only be visible within their module.

In the code below I have passed the value of myVar as a parameter to displayVar.

Public Sub try()

  Dim myVar As String

  myvar = "hello world"
  Call displayVar(myVar)

End Sub

Public Sub displayVar(Stg As String)
  Call Msgbox(Stg, VBOKOnly)
End Sub
Tony Dallimore
  • 12,335
  • 7
  • 32
  • 61
  • 1
    hum, i'm ok with all of this, except in vba parameters are passed byref by default – reyman64 Jan 06 '12 at 11:01
  • @reyman64. Thanks for pointing out my error. VBA is not my main programming language and since I prefer to explicitly declare ByRef and ByVal I had not noticed ByRef was the default. I like this site because no matter how much you think you know, you still learn something everyday. Thanks again. – Tony Dallimore Jan 06 '12 at 11:32
1

Variable myVar is declared in the function try()

As such, you can only use it in the try() function scope.

By try() function scope, I mean all the instruction written between public sub try() and end sub.

You try to call your variable from another function (displayVar). Which define it's own scope and is not inside the try function scope.

If you want this, you have to declare your variable in the global scope (outside any function)

For example :

dim myVar as String

public sub try()

    myvar = "hello world" 

    Call displayVar()

end sub

public sub displayVar()
   msgbox (myvar)
end sub
Franck LEVEQUE
  • 440
  • 3
  • 11
  • I'm ok with this, but langage have different type of scoping, do you know what is the type of scoping of vba ? http://en.wikipedia.org/wiki/Scope_(computer_science) – reyman64 Jan 06 '12 at 11:02
  • 1
    As described in wikipedia, I would say vba is of lexical scoping type. For more information on the scope of vba, you should try this article : http://support.microsoft.com/kb/141693 – Franck LEVEQUE Jan 11 '12 at 09:41