Results 1 to 10 of 10

Thread: [RESOLVED] Correct procedure for declaring variables

  1. #1

    Thread Starter
    New Member
    Join Date
    Jul 2008
    Posts
    10

    Resolved [RESOLVED] Correct procedure for declaring variables

    Hey guys. I was just wondering what exactly was the correct way to declare variables within a project. Obviously of course the best way to declare things is as private as you can, within procedures, then forms, then global if you absolutely must. However, I have a slight problem in that I have forms with (say) a dozen procedures which each have variables declared in them. If a certain error occurs, then I just want to quit to the desktop (my other thread in this forum deals with that particular problem), and therefore when that happens I need to wipe all my variables as I go (I think - if I unload all forms, I still need to set their variables to 'nothing', correct?). So, I plan to migrate all code nulling to my 'Terminate' event, to make sure all variables are killed. However, what happens if the application errors before a particular subroutine that declares variable 'foo' ever runs? Aka, I then try and "foo = Nothing", but foo doesn't exist.

    So, should I a: declare all of my variables at form level, so they all exist in case the app errors and has to quit in a hurry, or b: use an On Error Resume Next in the Terminate event so that any non-initialised variables are just skipped over? (Resume Next... *shudder*)

    Thanks,
    Edibles
    Last edited by ediblespread; Jul 15th, 2009 at 10:09 AM.

  2. #2
    Junior Member
    Join Date
    May 2007
    Posts
    27

    Re: Correct procedure for declaring variables

    Hi,

    If I understand correctly your problem, I think your real issue understands variable scope,

    Variables that were created inside subs and functions disappear once that functions end (or you exit it), releasing of objects should be done once you don’t need them or just before exiting the sub/function.

    Variables that were declared at form level, exists as long as the form exists, they should (usually) initialized (set new) on form load and released on form unload/terminate.
    (On that matter classes are just the same but you have Initialize and terminate instead of load and unload)

    Variables that were created as public/global in module lives throughout your code you need to decide when you first need them to initialize them and release them when you don’t need them (usually when application ends)

    now regarding "nulling", if a variable declared as object is declared at let say form level, setting it to null at any point of your form life will not cause any error and you can safely add set to null on terminate event,
    however, if a variable is declared at a sub/function level, the rest of the code does not aware of its existence, so you can't set it to null on your terminate because your form doesn't know what this variable is.

    Last thing, make sure you have Option Explicit in your code, this at least will tell you when you are "able" to "talk" to specific variable and when the function is not aware of it.

    Hope it helped and clarify things.

  3. #3
    Super Moderator si_the_geek's Avatar
    Join Date
    Jul 2002
    Location
    Bristol, UK
    Posts
    41,974

    Re: Correct procedure for declaring variables

    Quote Originally Posted by ediblespread View Post
    Hey guys. I was just wondering what exactly was the correct way to declare variables within a project. Obviously of course the best way to declare things is as private as you can, within procedures, then forms, then global if you absolutely must.
    That is what you should do.

    ... and therefore when that happens I need to wipe all my variables as I go (I think - if I unload all forms, I still need to set their variables to 'nothing', correct?).
    Most variables (those with simple data types such as Integer/String/Long/..) do not need to be tidied up, that will be done for you automatically.

    Object variables (basically ones where you use "Set", or "Dim .. as New") do need to be tidied up - and it should be done in the apt scope for the variable:
    • If it is declared in a procedure - it should be tidied up in the procedure too (including in the error handler, and before any "Exit Sub" etc).
    • If it is declared at form level - tidy up in Form_Unload of that form.
    • If it is declared in a module - tidy up in your 'ending program' routine.
    There is an explanation of this idea (including examples for objects like Recordsets) in the article How should I close my form/program/class? from our Classic VB FAQs (in the FAQ forum)


    edit: it seems I took a while to write this, corheart's post wasn't there before! ah well, I think I gave some useful extra info

  4. #4

    Thread Starter
    New Member
    Join Date
    Jul 2008
    Posts
    10

    Re: Correct procedure for declaring variables

    Right, that helps alot, thanks. A few questions, just to make sure I've got it completely, if you don't mind.

    Variables that were created inside subs and functions disappear once that functions end (or you exit it), releasing of objects should be done once you don’t need them or just before exiting the sub/function.
    So, if I had a sub like the following:

    Code:
    Sub subTest()
    Dim x as integer
    Dim y as integer
    
    x = 5
    y = x * 2
    
    End Sub
    Then what I would want to do is before the "End Sub" I should have "x = Nothing" and "y = Nothing", and then when "End Sub" runs, x and y would be garbaged, and thus no longer a problem? I assume this is therefore why (details in my other thread) when I try to unload lots of forms at once (to quit completely in case of a certain error) it finishes each subroutine before it quits, even after unloading the forms - the very problem that has been plauging me!

    Variables that were declared at form level, exists as long as the form exists, they should (usually) initialized (set new) on form load and released on form unload/terminate.
    Yup, so these I kill in the Terminate even, got that. What happens if I have a sub like the following:

    Code:
    Sub subCrash
    
    funCrashAndUnload
    
    mAVariable = "foo"
    
    End Sub
    Where funCrashAndUnload causes the program to crash and then unload all forms. Once all forms are unloaded, the function kicks back to this subroutine, which would then try to set mAVariable to "foo" - but when the form unloaded, mAVariable was set to "Nothing" in the terminate event, and then assumedly... destroyed? I'm a bit confused still as to how subroutines can finish running after I've unloaded their parent form...



    Thanks very much for your help, you were very informative. I hope you continue to help a poor bewildered newbie!

    -Edibles


    EDIT (in response to Si's post):

    Indeed, you did take your time - I'd already started replying! . Thanks for answering. So, when you say primitives (actually, we, is String a primitive in VBA? Anyway, let's say basic) data types are automatically tidied up, how does that happen? When the subroutine ends/form unloads/program quits they're just reset to Nothing and killed automatically?

    (Note, I use 'Dim' for basic data types too - or should I say the original code did, so I just continued - aka, Dim x as Integer. Is this wrong?)

    I see what you mean about procedures and tidying, thanks. I shall also have a look at that VB FAQ - I'll admit to not thinking, being lazy and forgetting to check it, sorry! >_<
    Last edited by ediblespread; Jul 15th, 2009 at 04:33 AM.

  5. #5
    Super Moderator si_the_geek's Avatar
    Join Date
    Jul 2002
    Location
    Bristol, UK
    Posts
    41,974

    Re: Correct procedure for declaring variables

    Quote Originally Posted by ediblespread View Post
    Then what I would want to do is before the "End Sub" I should have "x = Nothing" and "y = Nothing", and then when "End Sub" runs, x and y would be garbaged, and thus no longer a problem?
    They are Integer variables, so you do not set them to Nothing (as that only applies to object variables).

    I assume this is therefore why (details in my other thread) when I try to unload lots of forms at once (to quit completely in case of a certain error) it finishes each subroutine before it quits, even after unloading the forms - the very problem that has been plauging me!
    What happens if I have a sub like the following: ...
    That is perfectly normal behaviour, and dealing with it is covered by the article I linked to in my previous post.

    Yup, so these I kill in the Terminate even, got that.
    Rather than _Terminate, you should use _Unload. That is because the _Terminate event occurs after some things have already unloaded, and referring to them will cause the form to automatically re-load.

  6. #6
    Super Moderator si_the_geek's Avatar
    Join Date
    Jul 2002
    Location
    Bristol, UK
    Posts
    41,974

    Re: Correct procedure for declaring variables

    Quote Originally Posted by ediblespread View Post
    EDIT (in response to Si's post):

    Indeed, you did take your time - I'd already started replying! .
    It seems I've been fairly slow again!

    Thanks for answering. So, when you say primitives (actually, we, is String a primitive in VBA? Anyway, let's say basic) data types are automatically tidied up, how does that happen? When the subroutine ends/form unloads/program quits they're just reset to Nothing and killed automatically?
    They are automatically tidied as needed when their scope expires (the subroutine ends/form unloads/program quits).

    (Note, I use 'Dim' for basic data types too - or should I say the original code did, so I just continued - aka, Dim x as Integer. Is this wrong?)
    Dim is used for all variables (or at least should be!).

    The important point was the "as New", eg: Dim x as New y
    ...but using that isn't a good idea (there is an FAQ article which explains it), it is better to use a separate Set line.

  7. #7

    Thread Starter
    New Member
    Join Date
    Jul 2008
    Posts
    10

    Re: Correct procedure for declaring variables

    Yeah, sorry, I made that reply then went to read the linked thread. It was very informative, thank you very much. It is going to mean alot of work (basically, about a dozen forms with a dozen subroutines each can call the function at multiple points a subroutine which can crash if the network goes down (it's accessing an SQL database, and if the network goes properly down the program is to just quit right out.), so therefore I will have to check for an error after every single call to a form, subroutine or function =[. Oh well.)

    Ah right, okay. Thanks for all the help - I'm sure I'll be back to bother you soon! .

    -Edibles

    PS: Actually, one weird offhand thing. The OTM file is currently 6.5MB, and has been for the last few weeks. We have made multiple changes to it, removed vast amounts of coding and forms, and then added some more code... and it never changes from 6.5MB. Does the VBA IDE not actually 'delete' modules when you remove them or something? It's not a major problem at all, but when all of our users at once download the updated file it's a fair spike.

  8. #8
    Junior Member
    Join Date
    May 2007
    Posts
    27

    Re: Correct procedure for declaring variables

    Then what I would want to do is before the "End Sub" I should have "x = Nothing" and "y = Nothing", and then when "End Sub" runs
    Like si_the_geek said, native variables (i.e. integers, long, string, double, date etc.) does not need to be released/set to null, vb gracefully deal with them by itself, the only thing you need to warry about setting to null are variables you create as objects or were created with new or used set on it)

    Code:
    Private Sub foo()
         Dim fso As New FileSystemObject
         Dim x As Object
         Dim i As Integer
    
        <some code>
    
        Set fso = Nothing
        Set x = Nothing
    End Sub
    if your fun function funCrashAndUnload is releasing all forms including the form the function is declared in then you you do a simple check like to protect from error

    Code:
    If Not mAVariable IsNothing Then
           mAVariable = "foo"
    End If
    I'm a bit confused still as to how subroutines can finish running after I've unloaded their parent form...
    well i hope i am right and i manage to explain right : VB when you call the unload event, simply exceute all that is there mark the form to be relesed, then return to complete the rest of the code, once that function is finished the form reference to the form is cleared and destroyed.
    (i am sure its not the best explanation but i hope it help you understand)
    the only code that stop execution of code is "Exit Function"/"Exit Sub", "End" and err.Raise


    Edit: Ops took too long to type untill I see all was clarified

  9. #9
    Super Moderator si_the_geek's Avatar
    Join Date
    Jul 2002
    Location
    Bristol, UK
    Posts
    41,974

    Re: Correct procedure for declaring variables

    PS: Actually, one weird offhand thing. The OTM file is currently 6.5MB, ...
    I've got no idea what an OTM file is, but based on your use of the keyword VBA I assume it is something to do with whatever program your VBA editor is in. Based on the way that Access .mdb files work, I presume there will be an option somewhere to "compact" the file, but have no idea where, or what it would be called.


    It seems you have been posting in the wrong place, as VBA and VB6 are different in several ways (but everything in this thread is still valid, as those particular things are the same).

    Thread moved to Office Development/VBA forum

  10. #10

    Thread Starter
    New Member
    Join Date
    Jul 2008
    Posts
    10

    Re: Correct procedure for declaring variables

    Code:
    If Not mAVariable IsNothing Then
           mAVariable = "foo"
    End If
    This works for just one or two variables, but there may be quite a few in the program I am working with (consider - it creates an SQL query string, passes it to the funConnect function, then sets all sorts of userfields and variables based on the resulting recordset. funConnect is the function that can crash). I therefore probably am better off just checking for there having been an error on leaving every form/subroutine/function call in the program where a branched down form/subroutine/function could call funConnect and crash. Yay.

    well i hope i am right and i manage to explain right : VB when you call the unload event, simply exceute all that is there mark the form to be relesed, then return to complete the rest of the code, once that function is finished the form reference to the form is cleared and destroyed.
    I sort of get you, but it still seems odd - the 'Terminate' event does run before the subroutines are finished off - so much for the claim that 'Terminate' is the final stage where everything is destroyed...

    Thanks anyway.

    Yeah, sorry Si - I just noted that this may be the wrong forum, sorry! I was scanning the other forums and noticed that the Office Development forum is actually where VBA is meant to go >_<. Sorry!

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width