tags:

views:

467

answers:

2

I have a sub routine where I pull in information from a database. I want to use variables from this sub routine in another sub routine. I tried making everything public but it doesn't want to be friendly and share.

Dim strEmail as String
Public Sub readDB()
strEmail = "[email protected]"
End Sub

Public Sub submit_btn(ByVal sender As Object, ByVal e As EventArgs)
Response.Write(strEmail)
End Sub

The readDB would read the database and set the variables and do whatever it needs to do. Then when they submit the form it would e-mail the form to whatever the email address was.

+1  A: 

Passing them as arguments is great, if the sequence of calls to the subs in question makes that feasible. If you literally need a variable that is visible to different subs in the same class (code-behind page in ASP.Net), what you are looking for is probably a private member variable. Declare it outside of any sub or function with the access modifier Private, and all the subs in the class will be able to access it.

Private _foo As String

The underscore is a convention that some people love, some hate. It comes in handy in VB if you want to define a property to expose the variable, where you can't use Foo as distinctly different from foo, but that's another story.

This is not the same as what would generally be understood by the term Global variable in the ASP.Net sense, where the variable would be visible throughout the application context, which lends itself to unintended consequences in the least. A private member variable is only visible to the class that owns it.

EDIT: Your example code was added after my initial answer. My VB is a little rusty but as you've written it, strEmail looks like it should have class-level visibility, including inside of submitbtn (someone correct me if I'm wrong). One possibility, since you mentioned that you are calling readDB in Page_Load is if you're checking for postback in page load, and only calling readDB on the initial load, not on postback, which would be the case when the button is clicked. You may have seen examples that include a check for Postback out of hand and not realized what it does (I only suggest that because you mentioned that you are new to ASP.Net and it's not intuitive if you're new to it--no offense intended).

Protected Sub Page_Load (sender as object, e as EventArgs)
    If Not IsPostback
        // this doesn't get called when the button is clicked so
        // strEmail would not be populated when submitbtn is invoked
        readDB
    End If
End Sub

That's a bit of a guess out of nowhere though, so it might be way off base. Have you set break-points in Page_Load, readDB and submitbtn to see the state of strEmail in each?

I Have the Hat
I think it will still be wiped out if its not inside the session. The submit event will be processed before page_load, when all the globals are still empty.
magnifico
Postback events are handled after the Load event (http://msdn.microsoft.com/en-us/library/ms178472.aspx).
I Have the Hat
If a member is initialized in the load event handler on every request, then consumed later in the page lifecycle on the same request its value will be available and there is no need to store it in session.
I Have the Hat
On the other hand, if the intent is to initialize the member on the first request to the page only, and not any subsequent ones, but the initialized value is to be consumed on a subsequent request, then you are correct and some persistence method will be needed between requests.
I Have the Hat
+3  A: 

Every time an asp.net page loads, the global variables are wiped out. You can avoid this by using Session variables.

Public Sub readDB()
   Session("strEmail") = "[email protected]"
End Sub

Then:

Public Sub submit_btn(ByVal sender As Object, ByVal e As EventArgs)
    Response.Write(CStr(Session("strEmail")))
End Sub
magnifico