Reputation: 9
I am a newbie to VB.NET (learning it because I thought it might be like the BASIC I learned on my Commodore PET, just to give an idea of how ancient I am) and I get ByRef and ByVal, but find them kind of a pain the arse. I want to use certain variables as switches across subroutines, including event handlers (where you can't use ByRef and ByVal). Is there a special class of variables whose values are accessible to all subroutines? Again, sorry if this is a really basic question.
Upvotes: 0
Views: 1424
Reputation: 49329
Ok, you have two ways of doing this.
The "fancy" term is called scope. So, the topmost scope is local to a sub routine in a form.
So, we drag a button on a form, double click on the button, and we jump into code.
You get this:
Public Class Form2
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim strLocalTothisSub As String
strLocalTothisSub = "hello"
MsgBox(strLocalTothisSub)
End Sub
End Class
In above, as you likely figured out that one string variable "strLoclToThisSub" can ONLY be used in that sub. Once the sub exits, then all of these variables declared will not exist anymore. As a result, we can't use that variable in other subs, and EVEN if we use and declare the variable as the same name, it will be a fresh new separate copy of that variable. What this means is you can as a nice habit freely as a developer use the same variable names over and over. I might have one sub that has
dim i as integer
For i = 1 to 10
Call Sub2
Next i
And in sub2? I can declare and use i as integer again. This allows what we called modular programming. It means that one bit of code, and messing around with variables will NOT effect other routines. The old APPLE II BASIC, PET etc. was nice in that any variable you create could be used anyplace else. As a program would grow, then what part of the program used what variable became difficult to manage. You could also not cut + paste and re-use little bits of code over and over (even on-line posted code) because who knows if other small routines have used those variables. So vb allows a VERY high degree of isolation and this means your development only has to look at one wee small code routine and what variables you use, create etc. don't effect any other routine.
Of course there are MANY cases in which we need + want to share variables just like we did with that PET basic. And you can do this.
Ok, so this first "scope" is called local variables. I do encourage their use when possible.
Next scope: All for the one form.
The next scope is variables to be shared in the one form. So, lets assume I want the variable to be available for ALL code in that form, and don't want to have to pass parameters between everything. The simple trick is to then declare the variables at the start of the form.
eg: like this:
Public Class Form2
Dim strLocalToThisForm As String
Dim strTest As String
Dim User As String
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim strLocalTothisSub As String
strLocalTothisSub = "hello"
MsgBox(strLocalTothisSub)
End Sub
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
End Sub
End Class
So, you can define and create as many variables BEFORE any code routines. See the starting part? I put the dim vars before ANY code routine.
Now, those variables can be used in ANY sub or function in that form. No need to pass parameters. Once you set a variable, then any and all code in that form can use the variables. If you make then public, then even OTHER forms can use those variables, but only while the form is open. So "public" is not all that useful, but sometimes you might want one form to grab or use variables from another form,and again this means you don't have to pass parameters.
So, the scope is now "form" level. As long as that form is open, then the form level (scope) variables can be used, and remain and keep their values. But, you lose them all when the form closes.
Application wide scope. This are usually called global variables. They keep their values for the WHOLE application. This type of variables are JUST like the old BASIC of yester year.
This varibles stay alive and hold their values for the life time of the application (while it is open and running).
Because a form can be closed. And a sub with local vars can exit, then these variables have limited scope. (they go away, or what we call "out of scope")
To create application wide (global) variables?
You have to add a code module to your project. So right click on the project exporter (the name of your project. And choose add->new item
From the list we now choose a code module. "Module".
Don't use "code file", don't use "Class". Use module.
You code should look like this:
Module Module1
Public strEveryWhere As String = "Test"
Public MoreEveryWhere As String = "More fun"
End Module
Note that we use "Public" in place of "dim". In fact, in near all of the previous examples, we could have used Public in place of dim.
So, for example, in that first form example? I could have used Public. What this does is mean that as long as the form is open, then even OTHER routines could use the forms "variables". Those are the ones at the "form level scope". But of course ONLY while the form is open.
If you place variables (and subs) in the above module? Then any variable, and any sub you create can be used any ad all places - even in forms.
So in our public form, we might have this:
Module Module1
Public strEveryWhere As String = "Test"
Public MoreEveryWhere As String = "More fun"
Public Function CurrentUser() As String
Return Environment.UserName
End Function
End Module
Note that this code module is also were you would place general code routines that you want to call + use from any and all forms.
So, anything (variables, functions, subs) you place in that standard code module can be used in any form, or any code at any place. (so global vars, subs, functions). These functions thus behave just like the basic of olden days. But, you have as noted far more control over the scope, and this is as noted a huge advantage. For example, you might find some cool prime number generate routine on the internet. But, you can freely cut + paste that routine into the above module. Note that variables declared INSIDE of the routines in that code module are ONLY available to the one routine and are not global. So the key concept is WHERE you place the "dim" (or now public) of the var/sub/function will determine the scope.
If you have a global variable of say I, and a routine ALSO declares I, then the local routine will use its "own" I variable and ignore the global one. This again means you can't mess up the scope.
Upvotes: 1