The user than can change that information from within the dialog box.
When the user clicks on the OK button, that information needs to be
returned to the same routine (the textbox doubleclick) that called the
dialog box.
To send data over, I thought to use the .Tag property of the dialog
box.
Dialog.Tag = dMyDateInfo
Dialog.Show 1, Me
The dialog's Activate method deals with the dMyDateInfo sent over.
However, when I wish to send the data back and close the dialog, so as
to test the validity of the info if the user entered a change, the
.Tag cannot be used. This is because the dialog is unloaded.
Now, I know I can create a Global variable and set it to the return
value. But I would like to find ways to minimize the number of Global
variables being added to the project. Once that data is sent back, I
have no other use for such a variable.
What is the suggested way to do this?
Thanks.
Webbiz
A Public variable in the Dialog form.
' In the form's code module:
Public pMyDateInfo
' In the calling form
Dialog.Show 1, Me
MyDateInfo = Dialog.pMyDateInfo
' frmPassword
Option Explicit
Private m_sPassword As String
Public Function GetPassword() As String
Debug.Print "GetPassword called " & Time
m_sPassword = ""
Me.Show vbModal
Debug.Print "GetPassword: after calling Me.Show vbModal " & Time
GetPassword = m_sPassword
End Function
Private Sub btnOK_Click()
m_sPassword = txtPassword.Text
Unload Me
End Sub
Private Sub Form_Initialize()
Debug.Print "Form_Initialize " & Time
End Sub
Private Sub Form_Load()
Debug.Print "Form_Load " & Time
End Sub
Private Sub Form_Terminate()
Debug.Print "Form_Terminate " & Time
End Sub
Private Sub Form_Unload(Cancel As Integer)
Debug.Print "Form_Unload " & Time
Set frmPassword = Nothing ' Must be the last line in Form_Unload
End Sub
' How to use:
' ========
Dim sPassword As String
sPassword = frmPassword.GetPassword()
Debug.Print "Password is " & sPassword
Example output:
===========
Form_Initialize 3:19:14 AM
GetPassword called 3:19:14 AM
Form_Load 3:19:14 AM
Form_Unload 3:19:23 AM
GetPassword: after calling Me.Show vbModal 3:19:23 AM
Form_Terminate 3:19:23 AM
Password is abc
There is some debugging code above to show what sequence of events being
called. Note that I added "Set frmPassword = Nothing" at the end of
Form_Unload. This causes a reference to be released so Form_Terminate is
called. Without this line, Form_Terminate is not called and form level
variables will keep their old values, so the next time you load the form,
you will find that form level variables are not initialized to zero and
blank "" as expected. You could initialize them in Form_Initialize or
Form_Load, but this is cumbersome. Another way to ensure that Form_Terminate
is called is using the following:
Dim sPassword As String
Dim f As frmPassword
Set f = New frmPassword
sPassword = f.GetPassword()
Set f = Nothing
Debug.Print "Password is " & sPassword
In this case, you don't need "Set frmPassword = Nothing" line.
Also, make sure that you don't access any of the form's controls or its
properties and methods after the call to "Me.Show vbModal", otherwise the
form is reloaded. You have to store whatever you need in form level
variables, then check them afterward.
Another example:
Public Function ShowMe(ByVal param1 As Long, ByVal param2 As Long, ByRef
Result1 As Long, ByRef Result2 As Long) As Long
Text1.Text = CStr(param1)
Text2.Text = CStr(param2)
Me.Show vbModal
Result1 = m_Result1
Result2 = m_Result2
ShowMe = m_lErrorCode
End Sub
Usage:
Dim ret As Long, Result1 As Long, Result2 As Long
ret = frmDialog.ShowMe(1, 2, Result1, Result2)
Debug.Print "ShowMe returned " & ret
Debug.Print Result1, Result2
Typo, make that UDT.
To keep things encapsulated you wouldn't want to expose temporary variables
to the outside. One way to get data back from a dialog form is to add a
public function to the form and call that from your main form. You can assign
the return value right where it needs to go, without any intermediary storage,
much like:
Text1.Text = Dialog.TextInput(Text1.Text)
The TextInput function in the dialog form accepts the passed in string
and puts that in the textbox the user will use to edit the text. When it closes
the function returns the value the user edited which goes right into the
textbox on the main form. (vbModal waits for the form to close)
For a demo try out the code below. You would want to use a separate
form for the dialog, whereas I re-used the same Form1 just to give you
the look and feel. On a new form add 2 textboxes and 2 command
buttons and paste in the code below. Try it out, and use as you see fit!
LFS
Option Explicit
Private Enum FormType
Main = 1
Dialog = 2
End Enum
Private Code As FormType
Private Reply As String
Public Function TextInput(Caption As String, Text As String) As String
' Save text for return value
Reply = Text
' Store in edit box
Text1.Text = Text
Text1.SelStart = 0
Text1.SelLength = Len(Text)
PSet (120, 45), Point(120, 15)
Print "Enter " & Caption
' Show form, return reply
Me.Show vbModal
TextInput = Reply
End Function
Private Sub Command1_Click()
Dim Dia As New Form1
Select Case Code
Case Main
' Main form calls the dialog's function
Text1.Text = Dia.TextInput("First Name", Text1.Text)
Case Dialog
' Dialog OK button
Reply = Text1.Text
Unload Me
End Select
End Sub
Private Sub Command2_Click()
Dim Dia As New Form1
Select Case Code
Case Main
' Main form calls the dialog's function
Text2.Text = Dia.TextInput("Last Name", Text2.Text)
Case Dialog
' Dialog Cancel button
Unload Me
End Select
End Sub
Private Sub Form_Activate()
Text1.SetFocus
End Sub
Private Sub Form_Load()
Code = Forms.Count
AutoRedraw = True
Select Case Code
Case Main
Caption = "MAIN"
Move Left, Top, 5000, 2000
Text1.Move 90, 270, 4200, 240
Text2.Move 90, 810, 4200, 240
Text1.Text = ""
Text2.Text = ""
Command1.Move 4325, 270, 300, 240
Command1.Caption = "..."
Command2.Move 4325, 810, 300, 240
Command2.Caption = "..."
PSet (120, 45), Point(120, 15)
Print "First Name"
PSet (120, 600), Point(120, 715)
Print "Last Name"
Case Dialog
Caption = "DIALOG"
Move (Screen.Width - 3000) * 0.5, (Screen.Height - 1500) * 0.4, 3000, 1500
Text1.Move 90, 270, 2700, 240
Text2.Visible = False
Command1.Move 450, 690, 690, 300
Command2.Move 1800, 690, 690, 300
Command1.Caption = "OK"
Command2.Caption = "Cancel"
End Select
End Sub
Private Sub Text1_DblClick()
If Code = Main Then
Dim Dia As New Form1
Text1.Text = Dia.TextInput("First Name", Text1.Text)
End If
End Sub
Private Sub Text2_DblClick()
If Code = Main Then
Dim Dia As New Form1
Text2.Text = Dia.TextInput("Last Name", Text2.Text)
End If
End Sub
Private Sub Text1_KeyDown(KeyCode As Integer, Shift As Integer)
' Return on Enter keypress
If Code = Dialog Then
If KeyCode = vbKeyReturn Then
Reply = Text1.Text
KeyCode = 0
Unload Me
End If
End If
End Sub
Another option is to Hide the Dialog form instead of unloading it.
'In the Dialog's form Unload event:
Private Sub Form_Unload(Cancel As Integer)
Cancel = 1
Me.Hide
End Sub
' In the calling form:
Dialog.Tag = dMyDateInfo
Dialog.Show 1, Me
MyDateInfo = Dialog.Tag
Unload Dialog
Set Dialog = Nothing ' recommended, to clear variables
Suppose you use that in a textbox named txtDateInfo:
Dialog.txtDateInfo.Text = dMyDateInfo
Dialog.Show 1, Me
MyDateInfo = CDate(Dialog.txtDateInfo.Text)
Unload Dialog
Set Dialog = Nothing ' recommended, to clear variables
(Add validation and formatting as required.)
"Webbiz" <nos...@forme.thanks.com> wrote in message
news:c3ksf51ni74289qii...@4ax.com...
There really should be no need for a global variable at all.
I'd say the dialog box form should validate the data prior to unloading.
That way, you don't even unload it until the data's been validated.
But there are other ways to approach this. For example, instead of
unloading the dialog box, hide it. That way you can make it visible again if
the calling procedure (the proc that shows the dialog) has to do the
validation and the validation check fails. Unload the form AFTER the
validation check succeeds.
Another option would be to create a Public property in the dialog box form.
You can unload the form and still access that property without causing the
form to reload. Only a form's intrinsic properties cause the form to reload
when referenced. Properties you add don't cause the form to reload. They
are cleared by setting the form's object variable to Nothing (or writing a
method to clear or explicitly setting the property to a default value).
A tip. Don't use "magic numbers". In your code in which you show the
dialog, instead of using
Dialog.Show 1, Me
you should have:
Dialog.Show vbModal, Me
Use the intrinsic constants that VB provides. It makes your code MUCH more
concise and therefore easier to read and understand and maintain.
--
Mike
>When a user double-clicks a text box, a dialog box is to open and the
>info from that text box sent over so that the dialog box would have
>some initial data to display.
>What is the suggested way to do this?
>
>
>Thanks.
>
>Webbiz
I use the following structure in my dialog calls and it always works.
The called dialog form has a public flag "Cancelled" that is set to
True when clicking the Cancel button or the X control box, and set to
False if the OK button is clicked.
It also has an Init public function (help checking error in set up
with retunr error code...) through which default values are passed.
In the calling form, I put the following code ( in some button_click
event, for example)
Load frmDialog
frmDialog.Init "Default string"
frmDialog.Show vbModal ' this is important
' then wait for user to finish wiht it.
If not frmDialog.Cancelled then
' get the data and place it where it should be
txtTextBox.Text = frmDialog.getNewValue
End If
' finally...
Unload frmDialog
Set frmDailog = Nothing ' this prevent "resources leak"
Eduardo-
Thanks. But sending the data isn't the problem.
The problem is getting data back without resorting to creating a
global variable.
When the dialog box has received the info and displays, the user than
can make changes to it. These changes then need to be returned to the
routine that called the dialog box to begin with.
Unfortunately, if you had that info stored in a variable that it's
scope is the dialog box itself, it goes away when the dialog box
closes.
I know I can create a Global variable outside the scope of the dialog
box to receive the data back. Thing is, I was curious as if there was
as way to 'pass it back', much like a function would pass back, when
the dialog box was being closed.
The next line in the routine that calls the dialog box will not run
until the dialog is closed, because of how I'm showing the dialog box
via Dialog.Show 1, Me. So I won't be able to just grab that info from
the Dialog box from the calling routine while it is still open.
:)
Webbiz
Sweet.
Thanks Larry.
:-)
Webbiz
Hello Nobody (this sounds like someone talking to themselves :)
Thanks for your explanation and example code. Learned a bunch.
Especially this...
"Without this line, Form_Terminate is not called and form level
variables will keep their old values.."
I thought that once the form was unloaded, all variables within would
be lost. This is interesting.
Thanks again.
Webbiz
Comments strewn within.
On Sat, 14 Nov 2009 21:44:10 -0500, "MikeD" <nob...@nowhere.edu>
wrote:
>
>
>There really should be no need for a global variable at all.
>
>I'd say the dialog box form should validate the data prior to unloading.
>That way, you don't even unload it until the data's been validated.
Can certainly do this. Send the data back while still loaded.
>
>But there are other ways to approach this. For example, instead of
>unloading the dialog box, hide it. That way you can make it visible again if
>the calling procedure (the proc that shows the dialog) has to do the
>validation and the validation check fails. Unload the form AFTER the
>validation check succeeds.
If the dialog is vbModal, the calling proc won't be doing anything
until the dialog is unloaded, right?
>
>Another option would be to create a Public property in the dialog box form.
>You can unload the form and still access that property without causing the
>form to reload.
Now this was the part I did not think about until Nobody mentioned it.
In my mind, I'm looking at the Dialog (Form) like a procedure, that
once it is exited all the variables within its scope go bye bye.
However, in reality, now that I think of it, a Dialog or Form is much
like a Module, except it has a visual side to it. So if the Form has a
Global variable, it should be seen by all procedures in the app much
like a Global variable in a Module or Class.
>Only a form's intrinsic properties cause the form to reload
>when referenced. Properties you add don't cause the form to reload. They
>are cleared by setting the form's object variable to Nothing (or writing a
>method to clear or explicitly setting the property to a default value).
>
>A tip. Don't use "magic numbers". In your code in which you show the
>dialog, instead of using
>
>Dialog.Show 1, Me
>
>you should have:
>
>Dialog.Show vbModal, Me
>
>Use the intrinsic constants that VB provides. It makes your code MUCH more
>concise and therefore easier to read and understand and maintain.
Thanks for the tip. I've still to get familiarized with all the
available constants.
Thanks.
Webbiz
Webbiz
OK, that's why I suggested this (to Hide the Dialog instead of unloading
it):
'In the Dialog's form Unload event:
Private Sub Form_Unload(Cancel As Integer)
Cancel = 1
Me.Hide
End Sub
' And in the calling form:
Forgot this detail:
The called dialog must be hidden when either OK or Cancel / X box is
clicked.
What is happening here? Isn't the Form_Unload event triggered by the
Form 'unloading'? Yet, it actually does not unload afterall?
Is this because of Me.Hide? Since this is one of those built-in procs,
it reloads it perhaps? And if so, it reloads it without the vbModal
setting, allowing the calling proc to continue?
Webbiz
No, The event fires before unloading, so at that time you have the
chance to cancel the unloading.
The 'Cancel = 1' is what cancels the unload.
The 'Me.Hide' is there to hide to form, otherwise nothing would happen
and the form would remain shown.
> >Private Sub Form_Unload(Cancel As Integer)
> > Cancel = 1
> > Me.Hide
> >End Sub
>
>
> What is happening here? Isn't the Form_Unload event triggered by the
> Form 'unloading'? Yet, it actually does not unload afterall?
>
> Is this because of Me.Hide? Since this is one of those built-in procs,
> it reloads it perhaps? And if so, it reloads it without the vbModal
> setting, allowing the calling proc to continue?
Yes. When you close the dialog form, it doesn't unload, it will instead
cancel the unload process and simply hide, actually remaining in memory.
When you then go to close the main form, (close the app) the Dialog
form's Unload event will be triggered again, and be again canceled.
That will in effect cancel the unload process for the main form, so you
would never be able to close the application!!!
Sneaky!
LFS
Reading Larry's comment I realize that I forgot something:
Put a flag to allow the unload at the line 'Unload Dialog'.
I usually use a Public variable at form's module level, but you could
also use the Tag property.
For example:
'In the Dialog's form Unload event:
Private Sub Form_Unload(Cancel As Integer)
If Me.Tag <> "1" Then
Cancel = 1
Me.Hide
End If
End Sub
' And in the calling form:
Dialog.txtDateInfo.Text = dMyDateInfo
Dialog.Show 1, Me
MyDateInfo = CDate(Dialog.txtDateInfo.Text)
Dialog.Tag = "1"
Unload Dialog
Set Dialog = Nothing ' recommended, to clear variables
Or
'In the Dialog's form Unload event:
Public pAllowUnload as Boolean
Private Sub Form_Unload(Cancel As Integer)
If Not pAllowUnload Then
Cancel = 1
Me.Hide
End If
End Sub
' And in the calling form:
Dialog.txtDateInfo.Text = dMyDateInfo
Dialog.Show 1, Me
MyDateInfo = CDate(Dialog.txtDateInfo.Text)
Dialog.pAllowUnload = True
Unload Dialog
Set Dialog = Nothing ' required now, or set Dialog.pAllowUnload
' to False before showing the dialog
There are lot of ways of doing this. Some more sophisticated, some simpler.
Some suggestions other made here are somehow more proffesional but
require a couple more lines of code.
Do what you prefer.
In cases likes this, I sometimes wrote functions (as other suggested)
and sometimes I did something like I said here.
Just to add to the pile (or to the confusion): since you used the phrase
"test the validity of the info", you might consider moving your business
rules to an object, and let that object manage the rules and any other data
collection mechanism (eg, a dialog) that might be necessary. The object
could communicate with any Form using Events. (as well as the dialog with
its business wrapper.)
-ralph
All ways of returning a value, to me seems a lot of overhead to avoid a
global variable ;)
I, for one, even use global variables, or global UDT's, to reduce the need
to pass multiple values to/from routines.
/Henning
Several of my projects go back many years, as I was writting them at
the same time learning the A B C's of VB (as I continue to do).
What I find in these, as I continue to play around with them, is that
they are filled to the hilt with Global/Public (module level)
variables. I used them for anything and everything!
After awhile, I may delete code that contained them and not realize I
need to clean up the unused variables.
It just seems cleaner to me to use as many variables that go out of
scope when done with the routine than to have a bunch of them that
never go out of scope.
This is why my questions lean toward these types of solutions, so that
it sort of, to a point, cleans up after itself.
But I hear ya. :)
Webbiz
> Put a flag to allow the unload at the line 'Unload Dialog'.
>
> I usually use a Public variable at form's module level, but you could also
> use the Tag property.
So what you are saying is for him to avoid using a public variable to return
data from the dialog, he should have a different public variable to control
unloading the same dialog.
Hmm, there seems to be logical inconsistency here. If he is going to have a
public or global variable he might just as well skip all the clever stuff
and use it to return data from the dialog. Equally well he could (rather
tackily) use some otherwise unused tag.
I've never understood the hatred towards judicious use of global/public
variables after all there are stacks of hidden ones in every program such as
every property of every control.
Regards
Dave O.
You can still access form variable data after it is unloaded.
It will only be "cleared" when you set the reference to nothing.
Think of forms as extended classes and the form can be instantiated but
not loaded. Even after unloading, the class still exists until you
release/terminate it.
The only exception is that accessing form properties that access the UI
causes it to be loaded, after which, you have to unload it before you
can release it again.
--
Dee Earley (dee.e...@icode.co.uk)
i-Catcher Development Team
iCode Systems
No, I didn't say that.
In fact, that was my first suggestion in the thread.
> he should have a different public variable to control
> unloading the same dialog.
They are two ways of doing the same thing (two ways with public module
variables).
>
> Hmm, there seems to be logical inconsistency here. If he is going to have a
> public or global variable he might just as well skip all the clever stuff
> and use it to return data from the dialog. Equally well he could (rather
> tackily) use some otherwise unused tag.
There are perhaps thousands of ways of doing this.
>
> I've never understood the hatred towards judicious use of global/public
> variables after all there are stacks of hidden ones in every program such as
> every property of every control.
They are also in the options pool. But it's what he didn't want.
They are not my choice on cases like this either.
The problem could be if you reuse them, you have to remember that they
could have and old value already, or clear them after use.
>
> Regards
> Dave O.
Regards.
Yes, I know.
>
> The only exception is that accessing form properties that access the UI
> causes it to be loaded, after which, you have to unload it before you
> can release it again.
>
I suggested to hide the form instead of unload so he could use controls
properties to get the values. It was just an alternative.
Aha, the objection isn't to public variables per se, but the combination of
public variables and sloppy programming. That seems reasonable.
If used carefully a public variable that is reset immediately after and/or
before use and is only used to span a few lines between forms can simplify
this sort of messaging greatly.
Regards
Dave O.
As well as the reasons Eduardo gave, consider that the simple expedient of
using a Global may work well in one scenario, but becomes awkward in
another. For example, communicating with one object instance compared to a
future need to communicate to multiple instances.
The value of avoiding globals is never appreciated until one has to go back
and modify or expand a program that has made extensive or even casual use of
them. This is only a personal observation, so take with a grain of salt, but
over the years I've never applied a solution dependent on Globals that
didn't come back to bite me.
There are some items in any application which are naturally 'global', eg ...
gbVerboseLoggingOn
gbLogPath
gbWarningLevel
etc. But even then, I find placing them in Objects or at the very least as
Properties greatly simplifies the initialization and tracking of this
information.
-ralph
All very reasonable, that's why I said if one does use them the scope should
be limited to no more than a few lines, otherwise you're correct to say it
may well bite you on the bum should you need to revisit the code a few years
down the line.
Dave O.
What I really gained from this is the fact that while the form may be
unloaded, it's variables that are Public/Global are still accessible
to the rest of the application. This was something I didn't think
about.
So as long as I load those variables with the data I wish to retrieve
later by the calling routine (or any others), and have not cleared out
those variables, then that is one way to pass info back.
There was also the technique of simply creating a Function within the
called form that also returns information, and allowing that function
to put the form into vbModal mode. Thus, the value will not return
UNTIL the form has served its purposes and is unloaded. That turned
out to be the way I went with this particular task I was trying to
solve.
There is, however, one thing not quite clear in my head. It has been
mentioned that the Public/Global variables will continue to hold the
values stored there after the form has been unloaded, UNLESS the form
is set = Nothing. If the Global/Public variables of a form is much
like those in a Module or Class, why are they cleared when the 'form'
itself is set = Nothing? If this is the case, then it suggests to me
that you have to have an instance of a form object before you can use
the variables, but this is not the case with a module itself. Here I'm
a bit confused.
Webbiz
Because Forms are kinda like Classes, but ain't the same thing.
"Life Cycle of Visual Basic Forms"
http://msdn.microsoft.com/en-us/library/aa242139(VS.60).aspx
-ralph
Perhaps didn't answer question completely. As I'm not sure what you mean by
"module" - Class or Basic?
You always have to have an instance of a Form or Class before you can use
its Global or Private variables. All variables (and function/subs) in .BAS
modules are "pre-instanced" or available since they are loaded into memory
at the start of a program. (The 'Private' attribute for .BAS modules is only
honored at 'Parse/Compile" time.)
Members of a Form or Class can not be accessed unless the Form or Class is
instanced. In fact all "Global/Public" variables in Forms or Classes are
converted to Properties, with a hidden private store, and become a part of
the Form or Class's Public or Default Interface.
So given that - what is confusing about "a module itself"?
-ralph
> There is, however, one thing not quite clear in my head. It has been
> mentioned that the Public/Global variables will continue to hold the
> values stored there after the form has been unloaded, UNLESS the form
> is set = Nothing. If the Global/Public variables of a form is much
> like those in a Module or Class, why are they cleared when the 'form'
> itself is set = Nothing? If this is the case, then it suggests to me
> that you have to have an instance of a form object before you can use
> the variables, but this is not the case with a module itself. Here I'm
> a bit confused.
Its all about the 'lifetime' of a form. You have 3 different types of
modules, the standard module, the class module, and the form module.
The class and form are objects and must be created, the standard module
is not.
When you first call something contained in a standard module (a method,
a public variable, etc) the module is loaded into memory and stays loaded
until the app ends (for all practical purposes).
When you create an instance of a class, its module is loaded into memory
and stays in memory all while the reference to the class remains in scope.
You get two events that give you an opportunity to act on these transitions.
Initialize fires when the class is being loaded into memory, and Terminate
fires when the class is being unloaded from memory. Between these two
events, the public variables and methods you add to the code module of
the class are available for use.
When you create an instance of a form, its module is loaded into memory
and stays in memory all while the reference to the form remains in scope.
You get two events that give you an opportunity to act on these transitions.
Initialize fires when the form is being loaded into memory, and Terminate
fires when the form is being unloaded from memory. Between these two
events, the public variables and methods you add to the code module of
the form are available for use.
Note that with respect to memory, a form is exactly like a class.
But a form also has a visual component. When you cause a form to be
visible, its visual component is loaded into memory and stays in memory
until it is unloaded. You get two events that give you an opportunity to act
on these transitions. Load fires when the visual component is being loaded
into memory and Unload fires when the visual component is being
unloaded from memory. There is also the state where the visual component
is loaded, but hidden from view (Hide was called).
If you put debug statements into the different events, you'll find a form
goes through the transitions in this order:
Form_Initialize
Form_Load
Form_QueryUnload
Form_Unload
Form_Terminate
Between Load and Unload, all the controls and properties of the form are
available. Between Initialize and Terminate, all the public variables and
methods you add to the code module are available.
Code executing between Initialize and Load, or between Unload and
Terminate that references a control or property of the form will cause
the visual component to load so that the control or property can be
accessed.
That means care has to be taken to avoid undesired effects. Example:
Unload Me
Me.Caption = "Unloading"
Here, the Unload event fires, but the very next statement accesses a
property of the form, causing the visual component to be reloaded into
memory. In that case the form's code module would also remain in
memory.
Perhaps now you can see why your form's public variables retain their
values after the visual component has been unloaded. That is because
the form's code module is still in memory waiting for the reference to
fall out of scope (eg: Set to Nothing).
Thus, if you want to track when a form is being loaded and unloaded
from memory, put debug statements in its Initialize and Terminate events.
If you want to track when a form's visual component is being loaded
and unloaded from memory, put debug statements in its Load and
Unload events.
HTH
LFS
> There is, however, one thing not quite clear in my head. It has been
> mentioned that the Public/Global variables will continue to hold the
> values stored there after the form has been unloaded, UNLESS the form
> is set = Nothing. If the Global/Public variables of a form is much
> like those in a Module or Class, why are they cleared when the 'form'
> itself is set = Nothing? If this is the case, then it suggests to me
> that you have to have an instance of a form object before you can use
> the variables, but this is not the case with a module itself. Here I'm
> a bit confused.
You always need an instance of something to hold its variables.
The standard modules are loaded (just one instance that doesn't need to
be referenced) when you first access something of the module.
This is how I understand it, perhaps someone else can explain it further.
> This is how I understand it, perhaps someone else can explain it further.
Emmm, I haven't scrolled the window, and I see now that the question had
many responses
This is a comment found on the above linked page:
---------------------------------------------
Dim frm As New Form1
frm.ANewMethod
Set frm = Nothing ' Form is destroyed.
A form used in this fashion is no better than a class module, so the
vast majority of forms pass on to the next state.
---------------------------------------------
Here it states that a form that has been set to "Nothing" is no better
than a class module. With a class module, the module level variables
that are Public are always available, right?
The section that deals with setting the form to Nothing states that it
completely reclaims the memory and resources (releases it). But would
that mean ridding the module level Global variables it contains, since
you don't have to reference the form (or any module) when using Global
variables, right?
Looking up everything that "Nothing" is suppose to do, it seems to be
all about removing the 'reference' to something. Global variables do
not need object referencing to begin with, no?
The writeup was illuminating though. Thanks.
Webbiz
>Perhaps didn't answer question completely. As I'm not sure what you mean by
>"module" - Class or Basic?
>
>You always have to have an instance of a Form or Class before you can use
>its Global or Private variables. All variables (and function/subs) in .BAS
>modules are "pre-instanced" or available since they are loaded into memory
>at the start of a program. (The 'Private' attribute for .BAS modules is only
>honored at 'Parse/Compile" time.)
Now THAT answered my question! I understand now. Form modules and
class modules as opposed to .bas modules.
Thank you. It's much clearer now.
Webbiz
<snip>
>When you create an instance of a class, its module is loaded into memory
>and stays in memory all while the reference to the class remains in scope.
>You get two events that give you an opportunity to act on these transitions.
>Initialize fires when the class is being loaded into memory, and Terminate
>fires when the class is being unloaded from memory. Between these two
>events, the public variables and methods you add to the code module of
>the class are available for use.
<snip>
Larry,
Nice writeup. Appreciate the explanation and it's understood.
:-)
Webbiz
Yes, it decreases reference count by one, and once the reference count
reaches zero, the object is destroyed.
You may also want to check these posts, which covers showing forms using
"Form1" or "frm" declared as New Form1, and when Terminate is called.
http://groups.google.com/group/microsoft.public.vb.general.discussion/msg/53214c5d7cbc46d1
http://groups.google.com/group/microsoft.public.vb.general.discussion/msg/a1abb49991d5d854