Link to home
Start Free TrialLog in
Avatar of patrickab
patrickabFlag for United Kingdom of Great Britain and Northern Ireland

asked on

Simple User Forms

Good evening Experts,

Here's yet another very basic question!

I have a User Form with two Text boxes and a 'Proceed' button.

The text boxes are called TextBox1 and TextBox2 and the button is called CommandButton1.

I have two variables, height and width, both declared as Doubles.

Can you give me the correct code that will do the following (I know it's incorrect and that's why I'm asking this question):

    UserForm1.Show 'This does display UserForm1 and it allows data entry
    If UserForm1.CommandButton1 clicked Then
        height = UserForm1.TextBox1.Value
        width = UserForm1.TextBox2.Value
    End If

Then when you've corrected my VBA can you tell me whether I can place this in an ordinary module to get it to work.

Many thanks

Patrick
Avatar of zorvek (Kevin Jones)
zorvek (Kevin Jones)
Flag of United States of America image

   UserForm1.Show
    height = UserForm1.TextBox1.Value
    width = UserForm1.TextBox2.Value

The above code must be outside the form module.

Kevin
Hi Patrick, double click the command button... that will open a code pane..

Private Sub CommandButton1_Click()

End Sub

in that, put

        height = UserForm1.TextBox1.Value
        width = UserForm1.TextBox2.Value

so that the code reads

Private Sub CommandButton1_Click()
        height = UserForm1.TextBox1.Value
        width = UserForm1.TextBox2.Value
End Sub


To show the form, you can put UserForm1.Show in any module

---
Harish
When you display a user form you can do so modally or non-modally. Modal is the default. When displayed modally only event code in the form module is run until the form is closed. Then the next line of code after the Show command is executed. When shown non-modally, your code just keeps going after the form is displayed.

If you want to do something specific when a command button is clicked, put the event handling code in the user form module.

Kevin
Patrick, here is a sample workbook:

http://mgharish.5gigs.com/ee/patrickab.xls

Note the code in the module as well as the userform
SOLUTION
Avatar of Harisha M G
Harisha M G
Flag of India image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of patrickab

ASKER

Kevin and Harish,

Thanks to you both for those v quick responses.

You see I had hoped it could all go in one module and not have to have daft little subs to take care of button presses. I had of course seen the CommandButton1_Click() sub but had thought it a clumsy way to do it.

Now before I finish, does it transfer the data back to the main module automatically for the two variables or is something more needed to achieve that?

Patrick
Patrick, the code transfers the data. But to resume the code, the form should be closed (That's why I put another command button)
That depends on where your variables are declared. If your variables are declared locally to the sub in which you display the form (as they should be in well-structured code) then you need to capture the field values after the form has closed:

    UserForm1.Show
    height = UserForm1.TextBox1.Value
    width = UserForm1.TextBox2.Value

The code within the form module will not able to access variables local to another module or sub.

Kevin
And if Harish returns and tells you to just make your variables global, please don't listen. That is considered one of the cardinal sins of good structured programming.

Kevin
Kevin, I know global variables should not be used in excess. But when he says
"does it transfer the data back to the main module automatically"
it should be global (in most cases)

What else can be the case ?
See my example code. That is how it should be done. There is no need to use globals in this or most other cases.

Kevin
Have you tested your code ? ( I am 99.9 % sure, you haven't ;) )

How does that assign the value ?

1) If immediately when the form is shown, H & W should be blank
2) If when the form is closed, then there is no need for the form.

But unfortunately, both of them do not happen.
Kevin,

I noticed that Harish has put 'Public gHeight, gWidth' above Module1. That looks pretty global to me - but then what do I know.

I'm not there yet as 'then you need to capture the field values after the form has closed:'

and how do I do that, please. Without that my problem is not solved!

Also can I close the form without a button in the Sub CommandButton1_Click() sub with:

Unload Userform1

Patrick

Harish,

When you show a form modally and then hide the form once the use input is complete, the form and all of the associated form objects remain intact. You can access any form object by referencing the form object and then the control:

   UserForm1.TextBox1.Value

Only when you Unload a form is the form and all of the associated objects destroyed. Therefore, when showing a form modally, all you have to do is reference the form controls after the form is hidden:

   height = UserForm1.TextBox1.Value

This is the proper method to use when showing a modal form.
]
Patrick,

To hide a form so that it's objects remain available use the Me.Hide method:

Sub CommandButton1_Click()
   Me.Hide
End Sub

Kevin
> then you need to capture the field values after the form has closed:

You can't do that because when the form is unloaded, all the controls are destroyed.
>   Me.Hide

It will not unload the form at all !! A big memory leakage
When you use Me.Hide from a command button code, the form is permanently hidden. (Unless you have a timer or use APIs)

In that case, even if the form is hidden, it is still in memory. AND IT IS THE MOST INEFFECIENT WAY OF GETTING THE VALUES FROM A FORM
>It will not unload the form at all !! A big memory leakage
Not at all. The amount of memory consumed by a form is fixed and quite small compared to the entire memory footprint of the Excel application and the workbook. When you re-show a hidden form it used the same objects. And all you have to do if you ARE concerned about memory (which no one really is any more) is to unload the form after recovering the values:

    UserForm1.Show
    height = UserForm1.TextBox1.Value
    width = UserForm1.TextBox2.Value
    Unload UserForm1

But I never unload forms because it hurts performance. I like my forms to be peppy and hiding them versus unloading them makes them real peppy. Haven't had a problem with memory in, oh, about 10 years.

>AND IT IS THE MOST INEFFECIENT WAY OF GETTING THE VALUES FROM A FORM
Actually, it is the most efficient way. Unloading the form means you have to use globals which has been frowned upon for years by OO engineers. And unloading a form is actually much more inefficient than hiding them as the entire form has to be recreated each time you display it. Ever since I can remember engineers have relied on leveraging memory to make applications run faster - it's called caching.

Kevin
Kevin,

I'm making this unnecessarily difficult for you! Here's my pathetic file...

http://www.asdy88.dsl.pipex.com/Experts%20Exchange/Userform_trials.xls

Patrick
Remove the lines

    Dim gheight As Double
    Dim gwidth As Double

ASKER CERTIFIED SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
When you have both global (Public) and local (Dim) variables of the same name, the local variable gets the precedence. Hence the message box is showing the local variables, which have 0 as the value. When you delete those values, global variables are used and you will get the correct result.
Patrick, as you can see, if you run Kevin's module code more than once, the previously entered value is shown, which means that the form was still in memory. This is a nasty memory leakage and SHOULD NOT be used !

The cases when .Hide are much necessary are when you temporarily want something else to be shown. In that case, you might use

UserForm1.Hide
UserForm2.Show
UserForm1.Show

In this case, the first form is hidden and the second is shown. And immediately when the second form is closed by the user, the first one is shown again, and the previously entered values will be intact.
Kevin,

Thank you for that. At some stage this pm I got all of it except:

Private Sub CommandButton1_Click()
    UserForm1.Hide
End Sub

Not realising that it had to be hidden for it to work.

I didn't like the globals as they then become inflexible. I always avoided that sort of thing in the past.

Patrick
Harish,

Forms hidden do not cause memory leakage - where did you pick up that crazy idea? Trust me on this. I have been coding Excel applications since you were in diapers.

If you want the text fields initialized to empty just use the Form_Activate event:

Private Sub UserForm_Activate()
TextBox1 = ""
TextBox2 = ""
End Sub

Memory leaks are lost handles and pointers that remain after the code moves on. This is clearly not the case here. This is just an initialized control valule that is remaining intact which, believe it or not, is exactly what we want so that we can access it after the form is hidden.

Kevin
>I didn't like the globals as they then become inflexible. I always avoided that sort of thing in the past.
Right on! Be a good OO (Object-Oriented) engineer and avoid them like the plague!

Kevin
> Forms hidden do not cause memory leakage
Where do you think the previous values of the textbox are stored ? On the hard disk ?

> I have been coding Excel applications since you were in diapers
Thanks for reminding.
Glad to have been on the sidelines during that debate. I did read in someone's contribution that forms that are not unloaded in Excel ca cause it to crash. Not my words but I can't honestly remember whose - but it was recent - last 2 to 3 weeks.
Kevin & Harish - Thanks to you both - Patrick
> forms that are not unloaded in Excel ca cause it to crash.

Did you mean can or can't ? :)
can
Thanks :)
Patrick,

I spent some time searching for evidence that hiding forms increases the risk of crashes or corrupted workbooks and found nothing. All I found was advice suggesting that hiding improves performance. What you may have seen is discussion about hiding and showing ActiveX controls on a sheet which IS prone to crashes. There is ample evidence that  activities such as excessive formatting, use of controls on sheets, and VBA manipulation of those controls causes workbook corruption as well as crashes.

In any event, if one desires to unload a form after hiding for the purposes of recovering local form variables, issue the unload command after the form has been hidden and the post-show code executed:

    UserForm1.Show
    height = UserForm1.TextBox1.Value
    width = UserForm1.TextBox2.Value
    Unload UserForm1

Another way to think about a user form is as a class object that is instantiated. In fact, it is very much a class object except that it inherits the generic form properties and methods. But all other behavior is the same as a class. And any good programmer knows that you don't put code in a class to set a global variables just to pass a value to another routine. The correct technique is to pass/instantiate the class and pull the class values out before destroying the class object. The user form should be and can be treated the same way.

Kevin
And to correct another misconception stated above, a memory leak is when an application allocates memory and then forgets about it. If the code that does this is executed repeatedly then memory will be consumed over the course of the application instance's lifecycle. But VBA/VB is managed code meaning that memory among many other things is very well managed and it is virtually impossible to "lose" memory. Any form shown will either remain in memory and be reused if hidden, or destroyed and rebuilt if unloaded. In either case memory leakage will not occur.

Kevin
>> if one desires to unload a form after hiding for the purposes of recovering local form variables, issue the unload command after the form has been hidden

You don't have to hide the form before unloading. Unloading implicitly hides the form and .Show method implicitly loads the form
>You don't have to hide the form before unloading. Unloading implicitly hides the form and .Show method implicitly loads the form
If you don't hide your modal form it remains visible and the code following the Show command will never run. Unloading does not hide a form, it unloads it and destroys any context with it. Hiding a form moves it down in the z-order and allows resumption of the next statement after the Show. They are two completely different actions with very different results.

Kevin
>> Unloading does not hide a form
wrong.
Harish,

Interesting. This should be good...post an example of how you unload a form and the form is hidden at the same time. For the demonstration to be successful, you have to be able to access any form control after unloading.

Kevin
Unloading automatically hides the form. How can you access it after unloading ?
>How can you access it after unloading ?
Exactly - you can't. Unloading is NOT the same as hiding. As I explained above, when you unload a form you destroy it and all of it's associated objects. When you hide a form the form objects remain intact but the form is hidden from view. They are therefore two completely different actions and two completely different results.

Kevin
>> Unloading is NOT the same as hiding.

Yes. I know. I never told Unload means hiding. I told that Unload implicitly means hiding. That is, when you call Unload UserForm1,

Controls are hidden
Form is hidden          <--- This is important
Resources are freed
Handles are freed
Harish,

>I never told Unload means hiding. I told that Unload implicitly means hiding.
But that's what "implicit" means: Implied or understood though not directly expressed.

>Form is hidden
You are using the word "hide" or "hidden" incorrectly. An unloaded form is not a hidden form. To hide means you still exist but can't be seen. There is no implicit hiding going on when you unload. If the form was truely hidden you would still be able to access it's objects.

Kevin
Without hiding, you can't unload a form.

Let me see a form that is already unloaded, but not hidden (visible)
>Let me see a form that is already unloaded, but not hidden (visible)
Read the following very, very carefully. Take your time.

When you unload a form it is destroyed, not hidden. When you hide a form it is hidden, not destroyed. To hide means that the form still exists but is not visible. And if it still exists that means I can do things with it even though it is hidden. When you unload a form it is gone, expired, destroyed, bye bye...but not hidden.

Is it still visible? Of course not. But that doesn't mean it is hidden.

If I came over to your town, tied you up, put you in a crate, and put the crate on a rocket that took you to the Sun you would be destroyed. If I then went to your parents and when they asked where you where if I said Harish was hidden or hiding, would I be telling the truth?

Kevin
> When you unload a form it is destroyed, not hidden.
Before destroying, it is hidden

> When you hide a form it is hidden, not destroyed.
Yes. I never told no.

> To hide means that the form still exists but is not visible.
Yes. When using Unload, for a moment, the form exists, but not visible. Then the form is destroyed

> And if it still exists that means I can do things with it even though it is hidden.
Yes. A hidden form CAN be manipulated

> When you unload a form it is gone, expired, destroyed, bye bye...but not hidden.
Controls are hidden, form is hidden, then form is destroyed

> Is it still visible? Of course not. But that doesn't mean it is hidden.
Does that mean visible ? I thought hidden/visible are antonyms.

> If I came over to your town, tied you up, put you in a crate, and put the crate on a rocket that took you to the Sun you would be destroyed.
Unrelated

> If I then went to your parents and when they asked where you where if I said Harish was hidden or hiding, would I be telling the truth?
Unrelated.
>for a moment, the form exists, but not visible. Then the form is destroyed
And this is what your side of the discussion has come down to? OK.

And when that dude with the explosives strapped to his body presses the button and blows up a bus he is, just for a moment, hiding. I suppose you're right. Problem is, you can't use that information for anything. "Gee, Bob forgot to give me the grocery list before he pressed the detination button. Wait a nanosecond, let me see if he is still hiding! Maybe if I reach in his pocket really quick before he vaporizes..."

I know, unrelated.

So try this...Execute an Unload statement and then get the control values before the form is destroyed. You know, in that happy place right after you have executed the Unload statement but before the form is destroyed...when it is hidden. You show me how to do that then I'll agree the form is hidden. I'll also agree that humans do not need meat and they never walked on the moon.

Kevin
> So try this...Execute an Unload statement and then get the control values before the form is destroyed. You know, in that happy place right after you have executed the Unload statement but before the form is destroyed...when it is hidden. You show me how to do that then I'll agree the form is hidden. I'll also agree that humans do not need meat and they never walked on the moon.

Let me clarify this:

Think of Unload as a function: (pseudo code)

Sub Unload()
    Me.Hide
    '***'
    Me.Destroy
End Sub

Then can you interrupt the function while it is executing (i.e, can you do something when the instruction near '***' is being executed ? In my system, No
That's pretty cool! So how would you use that information to capture the form's controls into some variables after you execute the Unload statement?

Kevin
You can't get the form's controls after "Unload"ing. However, you can do it after ".Hide"ing
Ahhh, so they are different. Which means that hiding is not implied by unloading. That's what I thought.

Kevin
I don't think I can make you understand what I mean..

But I will try:
Unload is a superset of Hide
If I execute a Hide the form is hidden and I can access the form controls.

If I execute an Unload the form is destroyed and I can't access the form controls.

If an Unload is also a Hide or a superset as you say, then how do I get the form controls if I execute an Unload versus a Hide? Can you demonstrate this for me?

From Excel VBA Help under the section describing the Hide statement: "When an object is hidden, it's removed from the screen and its Visible property is set to False. A hidden object's controls aren't accessible to the user, but they are available programmatically to the running application, to other processes that may be communicating with the application through Automation, and in Windows, to Timer control events."

From Excel VBA Help under the section describing the Unload statement: "When an object is unloaded, it's removed from memory and all memory associated with the object is reclaimed. Until it is placed in memory again using the Load statement, a user can't interact with an object, and the object can't be manipulated programmatically."

Kevin
Re-read these, and take more time than I did:

> When you unload a form it is destroyed, not hidden.
Before destroying, it is hidden

> When you hide a form it is hidden, not destroyed.
Yes. I never told no.

> To hide means that the form still exists but is not visible.
Yes. When using Unload, for a moment, the form exists, but not visible. Then the form is destroyed

> And if it still exists that means I can do things with it even though it is hidden.
Yes. A hidden form CAN be manipulated
Kevin, does this make it any better:

When you use .Show, do you explicitly need to use Load userform ? No.
(However it doesn't mean that you should never use Load before .Show, as in the cases where you need to set the form controls' properties before presenting it before the user)

Similarly, when you use Unload, you don't have to explicitly call .Hide
>Before destroying, it is hidden...When using Unload, for a moment, the form exists, but not visible.
Hmmm...and if I flap my arms wildly while jumping in the air I suppose I am flying too. So, your entire case has boiled down that fraction of a nanosecond when, you believe, the form is actually in a hidden state before being destroyed. Dispite the fact that this has absolutely nothing to do with VBA and Hiding versus Unloading, I'll correct you here as well. The windows GDI does not hide a window or graphic object before destroying it. It simply removes the handle from the list of window objects and sends a window update event to each window which the recently destroyed window was covering. To hide a window object requires addtional resources and time which I am sure a mature operating system such as Windows does not do.

>When you use .Show, do you explicitly need to use Load userform ? No.
That's because Show does, in fact, do a Load if the form is not already loaded.

>Similarly, when you use Unload, you don't have to explicitly call .Hide
Of course not. But Unload does not Hide as Hide is, by definition, existing but hidden from view. These are two completely different results.

Kevin
How come you agree with .Show, but not with Unload ?
Because Show actually does do a Load if the form is not already loaded. But Unload does not do a Hide or anything like it. And, even if it did, it's completely irrelevant since whatever transitory state the form might be in is outside the scope of VBA and the question at hand. To say the form is hidden when the topic concerns hiding for the purposes of retreiving control values makes no sense. To say the form is loaded when showing does make sense because you can't show a form that is not loaded.

Kevin
> But Unload does not do a Hide or anything like it

It DOES hide.


> To say the form is loaded when showing does make sense because you can't show a form that is not loaded.

Similarly, you can't have an unloaded form that is visible
>It DOES hide.
No, it does not. If it was hidden you would be able to access it's control while hidden.

You need to look up "hide" and "hidden" in your English dictionary. You also need to consider the concept of "state" and how it relates to our perception of reality. You keep insisting that, because an object ceases to exist it is also hidden. Hidden means that the object exists but is not visible, and it has to maintain that state long enough for someone to notice and take advantage of that state. When you use the Unload statement the object is destroyed. When you use the Hide method the object continues to exist but is no longer visible. It is not destroyed. It is placed in the hidden state that is observable and relevant.

There is no Hide in Unload, implied or otherwise. Firstly, the discussion is about VBA and what can and can't be done. Therefore anything happening behind the scenes between the execution of an Unload and the next statement is irrelevant. If the OS did, in fact, hide the form before destroying it then that fact is as relevant to the conversation as what I had in my diapers was relevant to the Russian's launching Sputnik. Secondly (although completely irrelevant to the discussion), when the OS hides a graphic object it does specific actions to do so that consume resources. When the OS is asked to destroy a graphic object it is not going to hide it and then destroy it because that is wasting resources, it just destroys it.

Kevin
> If it was hidden you would be able to access it's control while hidden.

As you have noted, it is hidden only for a few microseconds.


> Hidden means ... of that state.

Not necessary for it to be long enough. Is it documented somewhere that it should be invisible for so many milliseconds/microseconds to call it as hidden ?


> When you use the ... is observable and relevant.

I agree.

Have this code for a form:

When you close a form, according to you, only Terminate should have been called. Who calls QueryClose ?
_____________
Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer)
    MsgBox "QueryClose"
End Sub

Private Sub UserForm_Terminate()
    MsgBox "Terminate"
End Sub
_____________

And here is my final word:

Check it in VB.NET if you have...

_____________
    Private Sub Form1_Closed(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Closed
        MsgBox("Closed")
    End Sub

    Private Sub Form1_Closing(ByVal sender As Object, ByVal e As System.ComponentModel.CancelEventArgs) Handles MyBase.Closing
        MsgBox("Closing")
    End Sub

    Private Sub Form1_VisibleChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.VisibleChanged
        MsgBox("VisibleChanged")
    End Sub

    Private Sub Form1_Leave(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Leave
        MsgBox("Leave")
    End Sub
_____________

The message boxes that are shown are:

VisibleChanged                        (During Form Load)
Closing
Closed
VisibleChanged                        (During Form Unload)


Now, if you still have problems like .NET and VBA are different, it can work diffrently in India and US, or may be.. released in different years, or anything else, I really can't help.

If you think I am lying, please ask a question in VB.NET area for someone to tell whether the sequence shown above is true or not.
Jeez, you just won't give up. The fact that the visible state of the form changes from True to False does not mean it is hidden. It means it is no longer visible. It is going away, bye bye, gone. VB.NET, like VB and VBA, is a highly managed environment and events are triggered to make our coding easier. The above does not prove that the form is hidden. All it proves is that during the destruction of the form, those events are called. And the events are not called by the form, they are called by the VB and VB.NET managed environments which is omni-present and never goes away until your application quits.

Kevin
Wow fellars - I am left speechless. I still can't help wondering why you both haven't answered my implicit question of how many fairies dance on the head of a pin. Surely you both realise that my VBA skills cannot progress without that fundamental fact being clear to me. If can see them but can't count them, and you can count them but not see them then perhaps they aren't there in the first place. And yet I have seen them so in my mind's eye they are visible even though I cannot show them to you. I do not know how to convince you both just how important this belief is to me. I have seen them so they exist. I think, so perhaps I am.

After that, my head hurts, so I'm going to bed.
Yes. I won't give up.

> The fact that the visible state of the form changes from True to False does not mean it is hidden.

Then what does it mean ? How is the Visible property changed ? According to you, if the form is destroyed without calling visible property, who triggers this event ?

> It means it is no longer visible.

Even a child can understand that "no longer visible" means hidden

> And the events are not called by the form, they are called by the VB and VB.NET managed environments which is omni-present and never goes away until your application quits.

Perhaps not your day Kevin... unfortunately, .NET provides the "sender" as the argument for every event handler..

___________
    Private Sub Form1_Closed(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Closed
        MsgBox("Closed by " & sender.GetType.ToString)
    End Sub

    Private Sub Form1_Closing(ByVal sender As Object, ByVal e As System.ComponentModel.CancelEventArgs) Handles MyBase.Closing
        MsgBox("Closing by " & sender.GetType.ToString)
    End Sub

    Private Sub Form1_VisibleChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.VisibleChanged
        MsgBox("VisibleChanged by " & sender.GetType.ToString)
    End Sub

    Private Sub Form1_Leave(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Leave
        MsgBox("Leave by " & sender.GetType.ToString)
    End Sub
___________

This time, the messages are:

VisibleChanged by WindowsApplication1.Form1
Closing by WindowsApplication1.Form1
Closed by WindowsApplication1.Form1
VisibleChanged by WindowsApplication1.Form1

Do you still need any other proofs on who called the event handler ?

>> I have been coding Excel applications since you were in diapers.

That's been 20 years since I was in diapers. You must have forgotten the basics... go and study them again.
Patrick,

I thought you would be amused by this banter between friends. You should see our offline discussions - much more bizarre. Like the one where he tried to convince me that humankind never walked on the moon. For me it's a little more like the Little Engine that Could: "I think I can, I think I can, I think I can..."

Harish,

>Then what does it mean ? How is the Visible property changed ? According to you, if the form is destroyed without calling visible property, who triggers this event ?
It means simply that the VB.NET managed code calls those various events to trigger your event handlers. If I add code to the VisibleChanged event handler and the VB.NET code manager did NOT call it when the form was unloaded I would be a little disappointed, wouldn't you? Has nothing to do with the "hiding" of a form.

>Even a child can understand that "no longer visible" means hidden
Really? Interesting. Visible = Not Hidden and Not Visible = Hidden. So that form I displayed a year ago is no longer visible therefore it must be hidden. I wonder if I can access it's objects...And that guy who vaporized himself blowing up that subway in London - he's no longer visible so he must be hiding too.

>Perhaps not your day Kevin... unfortunately, .NET provides the "sender" as the argument for every event handler..
Still doesn't mean that the form has been hidden in the sense that we have been discussing above. And, remember, despite the fact that you keep making a claim that the form is really hidden, if even for a nanosecond, it still has absolutely nothing to do with VBA and accessing form objects. Remember, for it to be hidden it has to be in that state long enough to be observed. The VB.NET may simulate a "hidden" form for the benefit of VB.NET application code so that such an event handler can be used.

>That's been 20 years since I was in diapers. You must have forgotten the basics... go and study them again.
Coming from someone who is having difficulty accepting the fact that a hidden form and unloaded form are two different things? Someone who still uses globals because it makes programming easier?

It is interesting that the only point you have left to argue is that, in a language and environment unrelated to the Excel VBA environment, you have found evidence that a form might not be visible yet still accessible - actually hidden. And this is to prove to me that somehow the VBA Unload statement actually creates a hidden form, just as if one were to use a Hide method. Can I conclude that since you are now focused only on this rather arcane and unrelated aspect of VB.NET that all of the other points I have made above are accepted?

Kevin
Not wanting to come between friends I suggest that it might be useful for one of you to write a simple sub that illustrates the difference or lack of difference between hiding and unloading a VBA form. Then we can all see for ourselves and judge for ourselves.

It's intriguing that the area that I avoided as much as possible in C was memory management even though I only had 640k RAM available. I hated malloc(), calloc(), free() and realloc(). Even then I left it to C to allocate memory dynamically as it saw fit. I thought to a large extent direct memory management by application programs was now a thing of the past as it was/is handled by the OS and all it's myriad systems or is that just my total lack of knowledge on the whole subject area. However I can report that I recently crashed Excel as it ran out of stack space. I was only messing around with huge numbers of calculations in VBA and it wouldn't accept it.

All I do know is that my present machine has about 800 times more memory than the machine I used when I wrote progs in C, so these days if I was programming in say Visual C I don't believe I would need to think about memory managment at all. But then what do I know.
You're right...except maybe for the memory management stuff in C...but that was then. VBA is a highly managed environment which means you really don't have to worry about memory at all. There are those that suggest VBA and VB still have memory issues and that the managed cleanup process is lacking in some cases and so deliberately setting object pointers to Nothing is a good precaution. I believe same but I also believe that the cases are rare and so I default to not setting my objects to Nothing.

Harish and I went down a long rat hole that really had nothing to do with the subject matter. The bottom line in VBA is that if you Unload a form it's gone - it is never in a hidden state. If you Hide a form it is hidden from view and remains accessible for code further downstream. If you want the form re-initialized upon re-showing then you can use the Unload statement on the form after recovery of the form controls.

Since a form is normally displayed in a modal fashion which disallows any other activity until the form is closed, the code that closes the form upon completion of any form related activity has to hide the form versus unload the form:

Private Sub CommandButton1_Click()
   Me.Hide
End Sub

This allows the statements after the Show method to execute while the form still exists allowing the form controls to be accessed. The form can be unloaded then if desired:

   UserForm1.Show
   MyVariable = UserForm1.TextBox1
   Unload UserForm1

Using this technique avoids the necessity for global variables.

Sometimes it is necesary to capture a more complex piece of information in the form module before it is hidden. This information can be placed in a public module-level variable inside the form module:

Public MyComplexAnswer As Boolean

which is then accessible after the form is hidden in the same way the form controls are accessed:

   UserForm1.Show
   MyVariable = UserForm1.MyComplexAnswer
   Unload UserForm1

Despite the various esoteric and unrelated statements Harish made along the way which really boiled down to issues of semantics and the meanings of English words, that's the whole story.

Kevin
  UserForm1.Show
   MyVariable = UserForm1.TextBox1
   Unload UserForm1

is never going to work if you don't use Hide there in the form. If you use Unload, before the control is sent back to the calling module (above code), the form is hidden, and then control and form are destroyed.

>> in a language and environment unrelated to the Excel VBA environment, you have found evidence that a form might not be visible yet still accessible - actually hidden.

It is niether .NET nor Excel VBA nor VB Runtime, which does this, but Windows.

Those environments will only manage the issues while debugging. Once the standalone executable is created, there is nothing except Windows to manage the things.
 
Kevin, I didn't know you are so adament, and cant simply accept the truth ;-)
>is never going to work if you don't use Hide there in the form. If you use Unload, before the control is sent back to the calling module (above code), the form is hidden, and then control and form are destroyed.

I'm glad you finally agree...except this part looks a little suspicious: "before the control is sent back to the calling module (above code)" - what above code? Are you speaking about your code?

>I didn't know you are so adament, and cant simply accept the truth

The truth is here - very plain, very simple, and back on topic: http:Q_21735008.html#15961365.

The other stuff was just fun and games with a dose of abuse of the English language.

Kevin
  UserForm1.Show
   'Now the control is transfered to UserForm1 and unless it is hidden/unloaded, the code won't go on any further

   MyVariable = UserForm1.TextBox1
   'This will work only if the form is Hidden, not when Unloaded. When you Unload, eventhough the form is hidden, the control is yet in the Userform1
   
I'm not sure where you are going now...everything you have stated is covered in plain and simple verbiage here: http:Q_21735008.html#15961365. Did you read it?

Kevin
Hmm. You are compelling me to reply for that too...

> VBA is a highly managed environment which means you really don't have to worry about memory at all.

>> Then why do you get many questions on topics like "Excel is closed, but still visible in Task Manager" ?

> There are those that suggest VBA and VB still have memory issues and that the managed cleanup process is lacking in some cases and so deliberately setting object pointers to Nothing is a good precaution. I believe same

>> Good to hear :)

> but I also believe that the cases are rare and so I default to not setting my objects to Nothing.

>> Again a bad practice

> The bottom line in VBA is that if you Unload a form it's gone - it is never in a hidden state.

>> If you can't believe the message boxes, then who can tell you what is being done ? What exactly does VisibleChanged mean ? Everyone can tell that the form is being hidden, why did MS implement such a event there ?

> If you Hide a form it is hidden from view and remains accessible for code further downstream.

>> Yes

> If you want the form re-initialized upon re-showing then you can use the Unload statement on the form after recovery of the form controls.

>> Yes

Since a form is normally displayed in a modal fashion which disallows any other activity until the form is closed, the code that closes the form upon completion of any form related activity has to hide the form versus unload the form:

Private Sub CommandButton1_Click()
   Me.Hide
End Sub

>> OK,.. now you can show the form again, using Run command in VBA; But what if it is a EXE ? When you hide the form, it will never be visible again. Where will it be ?
In memory

> This allows the statements after the Show method to execute while the form still exists allowing the form controls to be accessed. The form can be unloaded then if desired:

   UserForm1.Show
   MyVariable = UserForm1.TextBox1
   Unload UserForm1

Using this technique avoids the necessity for global variables.

>> Yes, avoids globals, which are far more better than wasting memory.

> Sometimes it is necesary to capture a more complex piece of information in the form module before it is hidden. This information can be placed in a public module-level variable inside the form module:

Public MyComplexAnswer As Boolean

which is then accessible after the form is hidden in the same way the form controls are accessed:

   UserForm1.Show
   MyVariable = UserForm1.MyComplexAnswer
   Unload UserForm1

>> How can you ask for a Public variable in form module, but not in code module ?
>Then why do you get many questions on topics like "Excel is closed, but still visible in Task Manager" ?
Because the application itself and the UI are two different layers. Occasionally the UI layer can crash leaving the application layer and the object in the Taskbar. Did you know that when VBA was first introduced the Word, Excel, and PowerPoint UIs were written in VBA? You can also hide the Excel application:

   Application.Visible = False

>[not setting my objects to Nothing] Again a bad practice
Microsoft clearly states in their VB and VBA documentation that VB and VBA objects are destroyed upon exit from the scope in which they are declared. Behavior other than this is very rare and usually related to the use of Windows API calls. Here is one of many examples of experts writing about this subject: http://www.keysound.com/html/ch_15_much_ado_about_nothing.htm.

>If you can't believe the message boxes, then who can tell you what is being done ? What exactly does VisibleChanged mean ? Everyone can tell that the form is being hidden, why did MS implement such a event there ?
Please get out of that rat hole. I am no longer in there with you. The discussion has been brought back to VBA. My comment was "The bottom line in VBA is that if you Unload a form it's gone - it is never in a hidden state." I said nothing about any other language or environment.

>OK,.. now you can show the form again, using Run command in VBA; But what if it is a EXE ? When you hide the form, it will never be visible again. Where will it be ? In memory
It's time to enter the 21st century. Memory is currently about $100 a gig. It is a non-issue. No one cares any more. On top of that Windows uses virtual memory now. Disk space is running about $100 for 200 gigs. Again a non-issue. And we are talking about VBA, not compiled code.

>Yes, avoids globals, which are far more better than wasting memory.
Really? While true a number of years ago you are probably the only one left on the planet that believes this. Relational databases were once considered a pipe dream because of the unusually high CPU requirements, and storage systems like VSAM and ISAM were standard - now relational is the only way to go because CPU power is so cheap and abundant. Use of globals or rather the avoidance of globals is covered in any literature talking about cohesion and coupling, the basic goal of good object oriented design. Here is one example: http://www.kellen.net/Coupling%20and%20Cohesion.htm.

And, if that isn't enough, here is a list if responses from our peers when asked "Reasons for avoiding global variables?": http://discuss.joelonsoftware.com/default.asp?design.4.249182.18

You might also be interested to know that avoiding globals and adhering to good object design principles actually reduces memory consumption - if you really are worried about memory.

>How can you ask for a Public variable in form module, but not in code module ?
Because a public variable in a form module is the same a public variable in a class module. It is not the same as a global. It is local to the class and comes and goes with the class objects. And forms are just classes that inherit a form's properties.

Kevin
> I said nothing about any other language or environment.

But the forms are same in any language. They are created/destroyed using the same technique, not matter whether you wrote it in VB, Delphi, C++, .NET or whatever else


>>How can you ask for a Public variable in form module, but not in code module ?
>Because a public variable in a form module is the same a public variable in a class module. It is not the same as a global.

Well, very interesting. Then what do you reckon I used in my code ? Is it global variable or public variable ? :)

According to you it is a Public variable, and yes it is. But I was refering to the same as global because it is accessible from the form too.

You say that you don't need to use Nothing.. but why does VB include it ?
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/script56/html/6b868dc6-10f9-47c0-aede-1a578584a9a0.asp

When you use Dim statement, only the object is created, and when you use Set, it is assigned some value/data. When the function returns, if you have used Set x = New something, then you must use Set x = Nothing.

>But the forms are same in any language. They are created/destroyed using the same technique, not matter whether you wrote it in VB, Delphi, C++, .NET or whatever else

The underlying object model is the same but it's the environment in which the objects are used that is what we need to be talking about. Some of the events that you mentioned in VB.NET do not exist in VBA. Therefore why event bring it up? This was the problem earlier as you were adamant about taking us down that rat hole when it really had nothing to do with the subject at hand. All you wanted to do was to be able to prove some point that, in the end, is not relevant to the subject at hand.

>Well, very interesting. Then what do you reckon I used in my code ? Is it global variable or public variable ? According to you it is a Public variable, and yes it is. But I was referring to the same as global because it is accessible from the form too.

A public variable is an exposed member of a class available only to that class and within any scope in which an object of that class has been defined. A public variable is created once for each instance of the class instantiated while a global variable only occurs once. A global variable is a variable defined at the root scope of the application and therefore available to all other subordinate scopes. Your variables were therefore global variables. And remember that a form is a special class.

>You say that you don't need to use Nothing.. but why does VB include it ?

I never said that you don't need to use the Nothing keyword. What I said was that the cleanup process that is run when any scope is terminated does an excellent job of cleaning up any existing objects that were defined in that scope. The Nothing keyword is used primarily to test whether or not object variable contains an instantiated object. This is very useful for many different tasks such as pulling entries that might not exist from a collection. It is also the correct way to clear an object variable so that the object's reference counter can be properly maintained and the object destroyed if needed. If you write well structured object oriented code you will find that objects are there when you need them and destroyed when you don't.  

>When you use Dim statement, only the object is created, and when you use Set, it is assigned some value/data. When the function returns, if you have used Set x = New something, then you must use Set x = Nothing.

You kind of got it but you are misinformed on a few things. When you use Dim to define an object variable you allocate a long handle. The handle is initialized to Nothing. When you use the Set statement you assign an object reference to that object variable. The object to which you reference could be new using the New operator, or a reference to an existing object. Each object created has a reference counter that is incremented each time the reference to that object is stored in another variable. It is decremented any time you assign Nothing or a reference to another object in any variable originally containing a reference to the object in question. When the reference counter reaches zero the object is automatically destroyed. Note that you do not have to assign Nothing to destroy an object. It is destroyed when the reference counter reaches zero and the reference counter is decremented when either you change the object variable's value or you lose the object variable by leaving the scope in which it was declared.

Kevin
> Your variables were therefore global variables. And remember that a form is a special class.

No. There is another keyword, Global, which refers to the real global keyword.
Public means, as you told, accessible by other classes. A module does act as a class since it can have Public/Private variables/Subs/Functions.

> Some of the events that you mentioned in VB.NET do not exist in VBA.

Yes. But it doesn't mean that they are handled in different ways. VB doesn't have any property called AlwaysOnTop for a form. However Delphi has. Does this mean that a VB form cannot be made "Always On Top" ? No, you can use Windows API called SetWindowPos to do that. But you say VB and Delphi are different and hence they have different properties and events. Aren't you ?

Whatever may be the language, since the platform is same, the events triggered are same unless you override them as in C++. But since I have shown the code in .NET without any overriding, you have to admit that the form is hidden temporarily before it is destroyed.
Remember, I am not saying using global variables is the best way, but it is better than wasting memory (which you are calling caching) by hiding the form, which is of no use.
>No. There is another keyword, Global, which refers to the real global keyword. Public means, as you told, accessible by other classes. A module does act as a class since it can have Public/Private variables/Subs/Functions.

The Global keyword was created in VB to define a global variable. In VB4 the Public keyword was introduced along with classes. It was allowed at the module level as a replacement of the Global keyword. From that time on the use of Public in a general or regular module is synonymous with Global and vice versa. When used in a class module Public has a different meaning as described above.

>Yes. But it doesn't mean that they are handled in different ways. VB doesn't have any property called AlwaysOnTop for a form. However Delphi has. Does this mean that a VB form cannot be made "Always On Top" ? No, you can use Windows API called SetWindowPos to do that. But you say VB and Delphi are different and hence they have different properties and events. Aren't you ?

You need to get your head out of the rat hole and consider the context. We are talking about VBA, not VB.NET. It doesn't matter what happens at that level if there if is no impact on the environment in which we working. It is no more relevant to the conversation than the temperature of the air in your tires is to whether or not you will make it to the store on your bicycle. You keep losing sight that the topic concerns whether globals are required to capture form control values (they are not) and if a form assumes a hidden state when unloaded (it does not.)

>Whatever may be the language, since the platform is same, the events triggered are same unless you override them as in C++. But since I have shown the code in .NET without any overriding, you have to admit that the form is hidden temporarily before it is destroyed.
It boils down to perception. If you want to believe that the form is hidden for some fraction of an instant then you can believe that. I prefer to keep my mind on a more realistic plane of reality and I thus consider the context within which I am working. No, the form does not assume a hidden state and it is silly to even consider the notion when it makes no difference to the discussion whether it does or does not hide. If there is some boolean somewhere in the underlying Windows architecture that some engineer named "Hidden" and it is set to True before the object is destroyed then, technically, you would be right within that context. But extrapolating our day-to-day activities to such extremes is not only a waste of time, it leads to poor judgment. Ever here the phrase "see the forest through the trees"? You have not only lost sight of the forest, you can't see the trees, bushes, grass, or grains of dirt. You have managed to drop down into the fabled rabbit hole that Alice found. Reality as we know it is doomed thanks to entropy but do we let that impact our daily lives?

>Remember, I am not saying using global variables is the best way, but it is better than wasting memory (which you are calling caching) by hiding the form, which is of no use.
I have given you ample evidence that use of globals is not only bad program design and is prone to erroneous code, but it also is indicative of poorly managed memory. But, keeping things simple for simple minds, consider two scenarios. In the first scenario, the Harish program, you use globals to capture the control values. In the second scenario, the Kevin program, I hide the form, capture the control values in variables declared in the routine that calls the form, and then unload the form. When my routine exits I release the memory consumed by my variables and the form. When your routine exits you have released the memory used by the form but you still have the memory used by the globals.

But, of course, I prefer to keep the form in memory because I like to have a quicker load the second time around - makes for a better user interface and user experience. If memory usage was such a problem then no one would be caching and everything would have to be read from disk or rebuilt each time. Which is worse? If you have it, use it. If you aren't sure you have it, keep in memory anyway and let Windows figure it out - it will be flushed to the virtual memory disk cache if necessary - that's what it's there for.

Kevin
Hmm... some oxymorons:
_____________
> From that time on the use of Public in a general or regular module is synonymous with Global and vice versa.

> A public variable is an exposed member of a class available only to that class and within any scope in which an object of that class has been defined. A public variable is created once for each instance of the class instantiated while a global variable only occurs once. A global variable is a variable defined at the root scope of the application and therefore available to all other subordinate scopes.

Please be clear yourself which is correct
_____________
> Forms hidden do not cause memory leakage

> When my routine exits I release the memory consumed by my variables and the form.

First you said, Hidden will not cause memory wastage, and then you say, it is released when your routine exits (Note that your routine does contain Unload).
That means you are agreeing that it is still in the memory until you unload it manually
_____________
> VB.NET, like VB and VBA, is a highly managed environment and events are triggered to make our coding easier.

> We are talking about VBA, not VB.NET.

First you didn't care whether it is VBA or .NET, but when I demonstrated the form events using .NET, you started saying as if it is a completely different part
_____________
You are talking about everything, other than the problem at hand...

You said that the form is not hidden, and is directly destroyed. I have shown that the VisibleChanged event occurs.

Then you said that it is not called by the form. But I showed you that the "sender" object, indeed, contained WindowsApplication1.Form1 and then you left the subject forever, and started stating about rat hole.

Forms are handled in the same way in all cases... VB, VBA, VB.NET, C++, Delphi or any other that you may consider.

Don't know why you are assuming something like "Rat hole" which is not there at all.
>Please be clear yourself which is correct
Both are correct. Please do a little research and you will see for yourself. Use of Public to define a variable in a general VB/VBA module is the same a using Global. Use of public in a class module (includes ThisWorkbook, worksheets, and forms) defines a member of that class that is available to that class and the scope in which any class object is declared. A public class member is not a global variable.

>First you said, Hidden will not cause memory wastage, and then you say, it is released when your routine exits (Note that your routine does contain Unload).
That means you are agreeing that it is still in the memory until you unload it manually
I never said a hidden form wasted memory, you did. I also never stated it did not consume memory. I only included the Unload for you since you seem so concerned about memory. I never use Unload. I prefer to let Windows manage memory and I like faster user interfaces. The memory consumed by one form is insignificant compared to the VB/VBA/Excel runtime code and all the Windows supporting logic. It's a gnat on an elephant's ass so to speak.

>First you didn't care whether it is VBA or .NET, but when I demonstrated the form events using .NET, you started saying as if it is a completely different part
Still don't care. But you became so obsessed with the minutia of a form's existence I felt compelled to pull back and get the conversation back on track. It is clear to me now that you will stop at nothing to follow the rat. In other words, no matter how much I try to convince you that a form is not in a hidden state you will work equally as hard to prove to me that it is. It boils down to semantics and the use of the work "Hidden".

>You are talking about everything, other than the problem at hand...
The problem at hand is how to pull variables from form controls without resorting to globals. You took the conversation to the depths of insignificance while trying to prove that a form enters a hidden state even if the higher level language call asks to unload the form. Nobody but cares at this point but you.

>You said that the form is not hidden, and is directly destroyed. I have shown that the VisibleChanged event occurs. Then you said that it is not called by the form. But I showed you that the "sender" object, indeed, contained WindowsApplication1.Form1 and then you left the subject forever, and started stating about rat hole.
I can only go down a rat hole so far. When the discussion becomes irrelevant it is time to back out and regroup.

>Forms are handled in the same way in all cases... VB, VBA, VB.NET, C++, Delphi or any other that you may consider.
No, they are not. Consider: is there a VisibleChanged event handler in VB/VBA? No. That means, from the higher level language perspective, they are not. When having a discussion you need to consider the plane of reality in which the other members of a conversation are thinking, and in which the tools about which you are discussing exist. VB/VBA does not expose these subtleties of window management and thus it should not be part of the conversation. I know you believe a form has a moment of state when you think is hidden. I get that. But I don't believe it is relevant as it is too far removed from importance to even be considered. VB, we are talking about VB.

>Don't know why you are assuming something like "Rat hole" which is not there at all.
Yes, I believe it is: http://www.answers.com/rathole.

Kevin
> I know you believe a form has a moment of state when you think is hidden. I get that. But I don't believe it is relevant as it is too far removed from importance to even be considered.

It took me almost 60 posts to make you believe that.

OK, now back to the original problem.. in your case (your first code without Unload), the form is hidden and the control is transfered back to the module. Right ?

Then if the user doesn't run the code at all, the form is in memory without any need. Why do you need caching ? Isn't that a waste of memory ?

You say it is a waste of time to load/unload the form. You also say that the form takes very less memory. What amount of time would it take to load/unload the form ?

What do you loose if I use two global variables which take only 8 bytes, instead of keeping a whole form in memory which can take up to several hundreds of bytes ?

But yes, I still agree that global variables should not be used in excess, but it is also true that it can be used if it is easier and efficient than other ways.

It is just like avoiding "goto" statements in structured programming.. If you want to check for a critical condition inside nested loops, then I would simply use goto, and you use an extra boolean variable and check that in all the nested loops since it is not a good practice to use goto in a structured programming. Just like this:

My way:

While cond1 = True
    While cond2 = True
        While cond3 = True
            If(Condition4IsMet) Then Goto EndLoop
        Wend
    Wend
Wend

EndLoop:
...


Your way:

bFlag = True
While (cond1 = True And bFlag)
    While (cond1 = True And bFlag)
        While (cond1 = True And bFlag)
            If(Condition4IsMet) Then bFlag = False
        Wend
    Wend
Wend

You are checking for an extra condition in every loop, just because Goto should not be used. Right ?

Which is more effecient ?

(I know you will say that the code above is written by me, not you; but note that I am just saying how your coding technique is, which just sticks to one rule, without any rational thinking)

Now, if the form is loaded and used on mouse move or click, then I agree that caching can be beneficial. But in this case, it is run once, when user wants it to run.

Why do you waste memory ?
In "Your way" make corrections.. cond2 and cond3
>It took me almost 60 posts to make you believe that.
Believe what? That you believe that the form assumes a hidden state? I never said you didn't. I only acknowledged that you did. And I never agreed that it did. Still don't. It's you're perception that it does and, unfortunately, no one is going to be able to convince you otherwise. You are, essentially, stuck in the rat hole of obscurity and irrelevance. I am embarrassed that I followed you so far in. Although some might say I led or pushed you down there ;-)

>OK, now back to the original problem.. in your case (your first code without Unload), the form is hidden and the control is transferred back to the module. Right ?
Yes.

>Then if the user doesn't run the code at all, the form is in memory without any need. Why do you need caching ? Isn't that a waste of memory ?
No. A waste of memory is keeping something around you no longer need, or thinking you destroyed it when you really didn't. I need caching because I do want the form in memory because it displays more quickly and it does not consume enough memory for me to worry about. And I let Windows handle memory caching - it's much better at that than I am.

>You say it is a waste of time to load/unload the form. You also say that the form takes very less memory. What amount of time would it take to load/unload the form ?
Never said that. I said it slows down the user interface, makes it appear more sluggish. Amount of time depends on system resource availability. Sometimes it takes a second or so. It is usually perceptible. When the form is hidden it is virtually instantaneous.

>What do you loose if I use two global variables which take only 8 bytes, instead of keeping a whole form in memory which can take up to several hundreds of bytes ?
We'll do some math here. Eight bytes versus a few hundred bytes - say 500. I think you said you had 512 Megs of memory. So you are consuming 0.000001% of available memory and I'm consuming 0.000092%. That doesn't look very significant to me. And that doesn't even consider Windows virtual memory or the fact that globals in general are indicative of sloppy software design.

>But yes, I still agree that global variables should not be used in excess, but it is also true that it can be used if it is easier and efficient than other ways.
In excess? A well designed application should not need any globals at all. Easier? Maybe. But not in the long run. Globals have been an excuse to write sloppy code for years. Read up on good structured and object oriented programming techniques and you will see why.

>You are checking for an extra condition in every loop, just because Goto should not be used. Right ? Which is more efficient ?
Your new nickname is Rat Hole. I have never seen anyone come up with more sillier reasons for writing bad code than you. Of course you can write code with GoTos that will run faster than code without. Faster, smaller, less memory - this is the fodder of rat hole discussions. You are not increasing speed or saving memory nearly as much as you are being lazy and choosing the easy way out. For small chunks of code that only you will see that's fine. But when you start looking back at old code that you need to maintain it's a whole different story. I have managed engineering teams for 25 years and I have seen sloppy code and well-designed code. The sloppy code always ends up being a nightmare - full of bugs and extremely difficult to maintain.

Here is an example: I recently audited a software company that had about 250,000 lines of code. The vast bulk of the code was written by two engineers, about evenly distributed between the two. Engineer 1 is methodical and writes very structured and well designed object code while Engineer 2 writes sloppy code that is poorly designed. Engineer 1 is always done in about 1/3 to 1/2 the time that it takes Engineer 2 to do a similar task. Both Engineers produce the same quality in terms of the finished product - it works. The problem is that when they have to modify any of this code, they get lots of bugs and problems with Engineer 2's code and far fewer problems with Engineer 1's code. The percentages are approximately 10% of the bugs are in Engineer 1's code and 90% in Engineer 2's code. So, while Engineer 2 may finishe before Engineer 1, he ends up spending much more time by the end of the day to get everything working after all the maintenance and enhancements. Of course I identified this as a very high risk area with their product. This is the real world. This is how a business can succeed or fail.

If memory and performance was such a big deal then we wouldn't be using relational databases - we would be using the extremely fast and efficient ISAM/VSAM database technologies. Did you know that Windows requires in excess of 64 megs to run? Maybe you should switch back to DOS if you are so concerned about memory and performance. DOS was fast - think about how fast it would be on your 512 meg machine! And all that extra memory you can look at and know it is free, ready to be used!

Object oriented code consumes more resources than non object oriented code. The .NET support libraries are HUGE. And memory and CPU cycles are CHEAP. It isn't about memory any more, and speed just isn't that much of a problem in loops like the ones you illustrated above. It's much more about maintainability and reusability.

>Now, if the form is loaded and used on mouse move or click, then I agree that caching can be beneficial. But in this case, it is run once, when user wants it to run.
Yes, and, besides you, who cares if it is in memory? When was the last time you saw an out of memory message? I haven't seen one since I was coding on Macintoshes with fixed memory partitions - and then I just increased the partition size.

>Why do you waste memory ?
I don't waste memory. I use memory...because it's there. And worrying about the usage or non usage of a few hundred bytes here and there is a fool's errand. Do you wash your car every time you go on a road trip so you can get 0.001% better gas mileage because of slightly better wind resistance? Do you shave your head when you ride your bike so you can consume a wee bit less energy because of slightly better wind resistance?

Kevin
> And I never agreed that it did.

You don't agree with the .NET messageboxes ? or you don't agree with the fact that the forms are handled in the same way in both the cases ?

>> Then if the ** user doesn't run the code at all**, the form is in memory without any need.
>No.

Reread my question.

> Never said that.

What did you NOT say ?

> We'll do some math here.

I had told you that I had 1/8 Gigs of memory.. that equals 128 MB.. don't know how you came up with 512 MB.

If you can't calculate such a small thing, how did you perform the next calculations ? ;)

OK. I too will do math here:
Your system will, in most cases, be using only 1% of total CPU time. But at the same time, it consumes always full memory and virtual memory (May it be related to any application or not, it is refreshed at a constant rate, but only the part which is used by applications is shown in Task Manager).

So, if you use some time to load the form, the system may use some extra resource from the CPU (not the time, since it uses only CPU cycles).. say 2% or even 3% But at the same time, if you use Hide, that form will be there in RAM forever and will cause some wastage of RAM which could have been used by other application.

> who cares if it is in memory?

The whole discussion is about memory, and you are concluding like this ??
Huh, I can't believe it.

Please stop giving unrelated stories and examples.

I have replied for the good replys. Others are not answers for my questions. Please be precise so that I can stop searching for meanings and concentrate on the subject ;)
> When was the last time you saw an out of memory message?

Incidentally, see this: http://mgharish.5gigs.com/ee/vmm.png

It is about 10 minute old image.

Now tell me, who cares if it is in memory ? Harish, not Kevin; Since Kevin has enough memory, he doesn't care about memory. But Harish knows the value of memory, and hence, cares
>You don't agree with the .NET messageboxes ? or you don't agree with the fact that the forms are handled in the same way in both the cases ?
They are there, they are real. You are using them to prove something that is, at that level, just a matter of semantics and little more.

>Reread my question.
OK.

>> Then if the ** user doesn't run the code at all**, the form is in memory without any need.
I repeat...No. A waste of memory is keeping something around you no longer need, or thinking you destroyed it when you really didn't. I NEED caching because I DO want the form IN MEMORY because it DISPLAYS MORE QUICKLY and it DOES NOT consume enough memory for me to worry about. And I let Windows handle memory caching - it's much better at that than I am. This is, again, an indication of a failure to understand other's perceptions and realities. You are stuck in your own view of a world short on memory and somehow resilient to sloppy code.

>What did you NOT say ?
What was immediately above that text: "You say it is a waste of time to load/unload the form. You also say that the form takes very less memory.
Never said either. I said I don't unload a form because I want it to stay loaded (and in memory.) I think I have said that about 20 times now. And I never said it takes less memory. I said that I don't care about the memory.

>I had told you that I had 1/8 Gigs of memory.. that equals 128 MB.. don't know how you came up with 512 MB. If you can't calculate such a small thing, how did you perform the next calculations ?
Let's see... 8/(512*1028*1028)=0.000001% and 500/(512*1028*1028)=0.000092%
Of course, with only 128 Megs the percentages will be a lot higher:
8/(128*1028*1028)=0.000006% and 128/(512*1028*1028)=0.000370%
Oh my, we have a really serious memory issue here.

>OK. I too will do math here:
OK, let's see what you can do...

>Your system will, in most cases, be using only 1% of total CPU time. But at the same time, it consumes always full memory and virtual memory (May it be related to any application or not, it is refreshed at a constant rate, but only the part which is used by applications is shown in Task Manager). So, if you use some time to load the form, the system may use some extra resource from the CPU (not the time, since it uses only CPU cycles).. say 2% or even 3% But at the same time, if you use Hide, that form will be there in RAM forever and will cause some wastage of RAM which could have been used by other application.

Are you serious? Out of 128 Megs you really think a few hundred bytes is going to make that much difference? I don't see any math, just guesswork and speculation. Do you realize that the Excel memory footprint is about 20 megs? Do you realize that just showing any form Excel loads about 2 megs of support code? Do you realize that when you unload a form Excel keeps the 2 megs of support libraries in memory? Hmmm...I wonder why. You think maybe the Excel engineers have figured out that memory is cheap and abundant, that the Windows virtual memory system works, and that it is better have a snappy user interface than unload every code segment and data structure no longer in use?

> who cares if it is in memory?
The whole discussion is about memory, and you are concluding like this ?? Huh, I can't believe it.
No, the whole discussion is about good software design and whether or when and how to unload unused objects. You have the infatuation with memory. I don't.

>Please stop giving unrelated stories and examples.
Why? It's is one of the most common forms of debate. An analogy serves to offer perspective. You do appreciate perspective, do you not?

>I have replied for the good replys. Others are not answers for my questions. Please be precise so that I can stop searching for meanings and concentrate on the subject
And THAT is the very reason you are stuck in the rat hole. You cannot extract yourself long enough to see that a little memory usage is irrelevant to the bigger picture. It just does not matter any more. You are living in the dark ages of computing when memory was rare and expensive. It no longer is and no one except you cares any more. Analogies are used by most people to illustrate concepts. Your unwillingness to consider analogies is another indication of how stuck you are in the minutia of proving that a "few hundred bytes" of memory is somehow going to make a difference.

>Now tell me, who cares if it is in memory ? Harish, not Kevin; Since Kevin has enough memory, he doesn't care about memory.
That is not an "out of memory" message. That is the Windows virtual memory engine telling you it has run short of virtual memory and is increasing the size. The only reason you are being notified is that it consumes some time and makes the machine sluggish while the virtual memory cache on disk is increased. An out of memory message means you have run out of heap or stack, or the stack has collided with the heap, or you try to allocate a block of memory in the heap and there isn't enough to be had. The result is a crashed application or an application that can not continue. That is an out of memory condition and it just doesn't happen any more.

>But Harish knows the value of memory, and hence, cares
Well, if saving a few hundred bytes to you is worth using globals and unloading every form, then you really should consider DOS. It use much less memory than Windows and is a lot faster. You can save 10's of megs, maybe 100's of megs. Wait a minute, do you really like Windows and all the wonderful features? Is it worth the extra 100's megs of memory consumption to get all those cool features? You like all that new .NET stuff too? How many megs of memory do you think those support libraries take up? But you would rather use globals and unload forms, saving a few hundred bytes of memory, than write better code...

Hey, we all have our own quirks and priorities.

Kevin


> They are there, they are real. You are using them to prove something that is, at that level, just a matter of semantics and little more.

Your previous answer was contractory :)

> it DISPLAYS MORE QUICKLY

It displays more quickly only if you run the code. It seems that you didn't re-read the question

> I said I don't unload a form because I want it to stay loaded (and in memory.) I think I have said that about 20 times now. And I never said it takes less memory. I said that I don't care about the memory.

Well, then what does "displays more quickly" means ? Doesn't it mean fast ?

>Your system will, in most cases, be using only 1% of total CPU time. But at the same time, it consumes always full memory and virtual memory (May it be related to any application or not, it is refreshed at a constant rate, but only the part which is used by applications is shown in Task Manager). So, if you use some time to load the form, the system may use some extra resource from the CPU (not the time, since it uses only CPU cycles).. say 2% or even 3% But at the same time, if you use Hide, that form will be there in RAM forever and will cause some wastage of RAM which could have been used by other application.

> Out of 128 Megs you really think a few hundred bytes is going to make that much difference? I don't see any math, just guesswork and speculation. Do you realize that the Excel memory footprint is about 20 megs? Do you realize that just showing any form Excel loads about 2 megs of support code? Do you realize that when you unload a form Excel keeps the 2 megs of support libraries in memory? structure no longer in use?

Yes for all.

> Hmmm...I wonder why. You think maybe the Excel engineers have figured out that memory is cheap and abundant, that the Windows virtual memory system works, and that it is better have a snappy user interface than unload every code segment and data.

Because they are MS engineers, and Windows is a MS product, it is natural for them to think so, and Windows Virtual memory system is easily the worst of all.

> No, the whole discussion is about good software design and whether or when and how to unload unused objects. You have the infatuation with memory. I don't.

We started the discussion with Hide and Unload, and I stated that Hide uses more memory. What is the discussion about ?

> You do appreciate perspective, do you not?

Yes. But in your previous post, required content was only 25%.

> You are living in the dark ages of computing when memory was rare and expensive.

May be, but CPU cost at that time was also high, remember your childhood days ;)

> An out of memory message means you have run out of heap or stack, or the stack has collided with the heap, or you try to allocate a block of memory in the heap and there isn't enough to be had. The result is a crashed application or an application that can not continue. That is an out of memory condition and it just doesn't happen any more.

run this C++ code:

int *x;

x = new int[1024*1024*5];

Let me see what happens;


> Wait a minute, do you really like Windows and all the wonderful features?

Those "wonderful features" don't need so much memory at all. Linux, which can have the same/more amount of graphics, multiple desktops and much more security, can run on a 32 MB system.

> Hey, we all have our own quirks and priorities.

Yes. But you didn't say which way is better in loop code. That would have cleared some facts..
>Your previous answer was contractory
Do you mean contradictory? Nope. You just didn't read it.

>It displays more quickly only if you run the code. It seems that you didn't re-read the question
I think what you mean is if the form is shown only once...is that what you mean? I can't recall ever making a form that was designed to only display once. Not sure why you are focused on this rather obtuse aspect of form management. Since memory is so cheap I assume any and all forms can be redisplayed at any time in the future and only hide them. I don't pretend to know whether or not a user will request a form again. I write modeless applications the way most graphical window-based applications are written.

>Well, then what does "displays more quickly" means ? Doesn't it mean fast ?
Last time I checked the dictionary the two words are synonymous.

>and Windows Virtual memory system is easily the worst of all.
I have worked with many virtual memory systems starting with IBM and Burroughs mainframes to the Macintosh and Windows. The underlying Windows virtual memory system is probably the best on the planet, especially since NT. It offers a protected model that prevents one application from stepping on another and allows for a very dynamic memory environment so you don't have to worry about stacks and heaps. Consider that it has to support piles and piles of crappy software written by idiots and not crash. Pretty amazing.

>We started the discussion with Hide and Unload, and I stated that Hide uses more memory. What is the discussion about ?
Thank God! Finally back on track. That's it! And I stated that memory is cheap and you started down the path that the form is still hidden for a little while even when you unload it. And down the rat hole we went. There was some good discussion about globals and good programming techniques but the rest of it was mostly pointless.

>Yes. But in your previous post, required content was only 25%.
You missed the point again. Analogies are used to make a point by illustration through another perspective. Something you have not yet figured out how to appreciate, or leverage.

>May be, but CPU cost at that time was also high, remember your childhood days
When I was a child I had access to a GA mini with about 16K of core memory and which took three hours to boot from a paper tape. Memory was really expensive (you could actually see the bits - they were magnetic donuts with wires running through them) and there wasn't much of it. You thought in terms of lines of basic code - a few hundred and you were done. No more. Project complete. Talk about limited memory. But that was then and this is now. Memory is so stinking cheap that it just doesn't matter any more. Even with only 128 megs you are fretting over nothing.

>run this C++ code
Well, duh. You just allocated 20 megs of memory for an array, 40 megs if you are in .NET. Try this and your computer might catch on fire:

x = new int[1024*1024*128];

It's all relative. I could load an Excel workbook with 150 sheets each filled with 255*65536 cells of data and say "Look, that Excel workbook is HUGE!" But I don't because it is a silly exercise that doesn't prove anything except how much time I can waste. I could also take a sledge hammer to your computer and say "look, it can't handle the stress of a sledge hammer attack!" but I don't because it's a silly exercise that proves nothing.

>Those "wonderful features" don't need so much memory at all. Linux, which can have the same/more amount of graphics, multiple desktops and much more security, can run on a 32 MB system.
I advise you to switch immediately then. I don't want you to hurt yourself on Windows. Besides, your memory is probably getting pretty tired holding all those Windows bytes.

>Yes. But you didn't say which way is better in loop code. That would have cleared some facts..
But I did:
"Your new nickname is Rat Hole. I have never seen anyone come up with more sillier reasons for writing bad code than you. Of course you can write code with GoTos that will run faster than code without. Faster, smaller, less memory - this is the fodder of rat hole discussions. You are not increasing speed or saving memory nearly as much as you are being lazy and choosing the easy way out. For small chunks of code that only you will see that's fine. But when you start looking back at old code that you need to maintain it's a whole different story. I have managed engineering teams for 25 years and I have seen sloppy code and well-designed code. The sloppy code always ends up being a nightmare - full of bugs and extremely difficult to maintain."

I then went on with a story that illustrated the costs of such folly in the real world but you chose to ignore it because it didn't contain any event handlers or globals.

You see, thinking the way you do can get you into a heap of trouble. By focusing on one aspect of a problem - speed for example - you ignore other elements of the problem that can have an equal or greater impact on the success of the outcome. Call it the "Bush Syndrome". Bush decided that Saddam had some WMD that needed to be taken away from him and he went in and really buggered up the place. WMD turned into a war on terror and an even bigger mess. He didn't look at the bigger picture at the outset. If he had he probably would have realized that invading Iraq would cost much more than planned, make even more people hate us, and create an unstable situation in a country that will take yeas to work out. Ooops, an analogy you wouldn't understand...

How about some bits and bytes: In your version of the code you use a GoTo to make it faster. But at what cost? In that specific example you can easily argue the cost is negligible and the speed gain is measurable. But if you continue to use these bad habits in larger and larger projects you will end up with truly sloppy code that is a nightmare to maintain. That's the bigger picture. That's where my head is at. Use best practices at all levels and with all situations - and best practices is not just about keeping memory consumption to a minimum.

Kevin
You started from "Memory is not wasted" and ended up with "Who cares if memory is wasted"

> I think what you mean is if the form is shown only once...is that what you mean? I can't recall ever making a form that was designed to only display once.

What if the form is called only from Workbook_Open ? How many times does it run ?

> Last time I checked the dictionary the two words are synonymous.
Then you must understand that you are using oxymorons right from the beginning.

> I have worked with many virtual memory systems starting with IBM and Burroughs mainframes to the Macintosh and Windows.

But not Linux. I searched, and there is no single article saying that Windows VM is better than swap partition technique of Linux

> And I stated that memory is cheap and you started down the path that the form is still hidden for a little while even when you unload it.

And when the form is run only once, it is completely a waste

> Well, duh. You just allocated 20 megs of memory for an array, 40 megs if you are in .NET. Try this and your computer might catch on fire:

I know. But you told that memory is very cheap ! Put as many memory sticks as required and then run the code.

> But I don't because it's a silly exercise that proves nothing.

But to prove that memory is a valuable thing, you need to do that exercise.

> I advise you to switch immediately then.

I couldn't find an appropriate Linux driver for my modem on the modern Linux flavours. Had I obtained that, I would have told good-bye to Windows.

> Ooops, an analogy you wouldn't understand...

I do understand, but with some difficulties ;)

Tell your engineers to leave the job. If he can't maintain his own code, he is of no use.

> And best practices is not just about keeping memory consumption to a minimum.

I know, but sticking to one type of programming doesn't bring effeciency either. You should adopt the easy but powerful features when required.