Page 1 of 4 1234 LastLast
Results 1 to 15 of 46
  1. #1
    twgonder is online now Expert
    Windows 10 Access 2021
    Join Date
    Jun 2022
    Location
    Colombia
    Posts
    652

    Forms and parent/child forms guilty of incest with module variables

    This problem is somewhat a corollary of the problem in Thread :


    https://www.accessforums.net/showthread.php?t=87614

    I’m having a problem with two different forms calling the same module, when the module has a module variable. It seems that one form is stomping on the module variable of another form. As it works for me, this makes module declared variables useless and untrustworthy.
    Some have claimed I don’t understand global and module variables (despite using them just fine in db programs other than Access for thirty years). So, I'm happy to learn the Access super-progressive-jet-aircraft method ,compared to my old-sailing-ship db.

    In other systems, this kind of programming never gave me a problem, because if a procedure called a subroutine (old school name), then the module variables were kept in a separate work-space for each calling procedure. Quite common when spawning tasks (thread mentioned earlier) or calling procedures. This, I know, is different than a global, which doesn’t do that, as all modules/procedures share it.

    This little demo shows some incest between forms that call the same procedure, and use a module variable to store some control information for later use in each form.

    In Access, is it documented that module variables are shared between calling procedures? Does this make sense? If so, what is the solution to not having contaminated module variables between forms?

    The only solution I see is to pass the variable back-and-forth between the procedures, but since I have dozens of these control variables being set in formload, the overhead for all this is a bit cumbersome. That’s supposed to be the job of the programming language (at least well written ones). Then, passing back and forth possibly becomes a problem with multiple instances of one form contaminating another instance, as we saw in the thread mentioned at the top (#87614).

    Or, maybe there is some trick in Access I just haven’t found yet to avoid this kind of problem?

    To test this in the attached demo db:
    1. Open Form1, move forward and back a record. Look at the results.
    2. Open Form2 move forward and back a record. Look at the results.
    3. Go back to Form1 and move to the second record
    Barney should not think he is a child.

    If the argument is that one shouldn’t run more than one form at a time (which is pure hogwash in a Windows environment), then you can see the same behavior in the parent/child forms:
    1. Open FormP
    2. Move the parent portion of the form forward one record.
    Bamm-Bamm shouldn’t think he is an adult.

    Related to some of my previous posts, if you work in the VBA editor some, on this simple .accdb, you might get Accesss to crash, as it did for me about five times while writing it (Using Access 2021).
    Attached Files Attached Files

  2. #2
    June7's Avatar
    June7 is online now VIP
    Windows 10 Access 2010 32bit
    Join Date
    May 2011
    Location
    The Great Land
    Posts
    52,822
    It is call to fFrmLoad function causing issue. Last form loaded sets the mWhat global variable. That variable is used in fFrmCurrent function and that returns value to tbxIam.

    Reverse the first set of instructions you provided. You will then get Bamm-Bamm and Pebbles as parent.

    In form/subform arrangement, main form loads after subform (yes, weird but true).

    Set breakpoint. Follow code as it executes.

    The mWhat variable is useless.
    How to attach file: http://www.accessforums.net/showthread.php?t=70301 To provide db: copy, remove confidential data, run compact & repair, zip w/Windows Compression.

  3. #3
    kd2017 is offline Well, I tried at least.
    Windows 10 Access 2016
    Join Date
    Jul 2017
    Posts
    1,142
    Maybe you want a class module instead of a regular module? I honestly havn't explored vba's (quasi?) OOP features.

    Perhaps the word 'module' is misleading. A regular module in vba is just a flat code file, there is nothing special about it, it isn't used to contain a scope like you might expect in other languages. The only thing 'modular' about it is that you can save the file and import it into other projects.

    The mWhat variable is a 'global' variable that's declared within the 'module'.

    By the way, the 'Access super-progressive-jet-aircraft method' is very outdated. Half the time I start working on a solution in excel vba I talk myself into doing it in python instead.

  4. #4
    twgonder is online now Expert
    Windows 10 Access 2021
    Join Date
    Jun 2022
    Location
    Colombia
    Posts
    652
    Quote Originally Posted by kd2017 View Post
    ...The only thing 'modular' about it is that you can save the file and import it into other projects.

    The mWhat variable is a 'global' variable that's declared within the 'module'..
    I tried exporting a Mod and then importing it the other day. That had some serious problems! Lost the day's work...again!

    I had to go back and check the code, mWhat isn't a global, it's a scope of module. The problem is one call to a module corrupts another. I worked on systems that were 15 years old some 35 years ago that didn't exhibit this odd behavior. But then again, they had figured out protected workspace logic, something we see MS is still struggling with.

  5. #5
    twgonder is online now Expert
    Windows 10 Access 2021
    Join Date
    Jun 2022
    Location
    Colombia
    Posts
    652
    Quote Originally Posted by June7 View Post
    ... Last form loaded sets the mWhat global variable. That variable is used in fFrmCurrent function and that returns value to tbxIam.

    ....
    mWhat isn't global. That's the point.

  6. #6
    kd2017 is offline Well, I tried at least.
    Windows 10 Access 2016
    Join Date
    Jul 2017
    Posts
    1,142
    Quote Originally Posted by twgonder View Post
    I had to go back and check the code, mWhat isn't a global, it's a scope of module. The problem is one call to a module corrupts another.
    VBA isn't other languages. A module doesn't define a class or an object. A call to a function within a module is not expected to create separate instances of the module.

    I don't know what your trying to accomplish but maybe look into 'vba class modules'.

  7. #7
    twgonder is online now Expert
    Windows 10 Access 2021
    Join Date
    Jun 2022
    Location
    Colombia
    Posts
    652
    Quote Originally Posted by kd2017 View Post
    VBA isn't other languages. A module doesn't define a class or an object. A call to a function within a module is not expected to create separate instances of the module.

    I don't know what your trying to accomplish but maybe look into 'vba class modules'.
    I guess I just figured that out. It hadn't been a problem until I had a parent and child (or sub form) using the same routine. I'm really concerned about instances not getting it correct either, as seen with simple closing of forms in my other thread.

    As to classes, I'll have to look into that now I suppose. But if MS can't get the BASICs correct, then I'm equally concerned about their ability to create class code that works properly. Every day I put a new dent in the wall (with my head) thanks to poorly designed tools (that several have told me I'm just not understanding, and that my old way is a dinosaur (but somehow it can get module scoped variables to work properly).

    I'm testing now a new version, but I shudder to think at the work to move all those module scoped variables (dozens of them) back and forth between the two modules and figuring out which procedures need which.

    I understand the basics of what a class module should be, but has anyone taken a regular VBA module, and just made it a Class module somehow? Does it work the same?

  8. #8
    twgonder is online now Expert
    Windows 10 Access 2021
    Join Date
    Jun 2022
    Location
    Colombia
    Posts
    652

    A sobering solution

    I've modified the original to use the solution I mentioned, of moving what should be a module scoped variable back to the VBA code for the form.

    I'm a bit bleary-eyed, and tired from tramping through hundreds of lines in my big code to find this error, and even more flummoxed at considering the work to move all those variables and pass them where needed.

    Anyways, if you care, you can try all three forms at the same time, and unless I missed something, everything should work okay.. meaning kids will be kids that aren't violated by their parents.
    Attached Files Attached Files

  9. #9
    June7's Avatar
    June7 is online now VIP
    Windows 10 Access 2010 32bit
    Join Date
    May 2011
    Location
    The Great Land
    Posts
    52,822
    Okay, it's not global, just public in general module. My explanation of behavior still applies and should be expected. Code in each form's Load event passes value to Module1 procedure which sets mWhat variable. It can only retain value from last from loaded.
    How to attach file: http://www.accessforums.net/showthread.php?t=70301 To provide db: copy, remove confidential data, run compact & repair, zip w/Windows Compression.

  10. #10
    Edgar is online now Competent Performer
    Windows 8 Access 2016
    Join Date
    Dec 2022
    Posts
    271
    Hi, twgonder

    I did not find an issue other than the order in which you expect things to happen. Whenever one of the forms Loads, you are changing the global variable you set up in Module1. So, in that same Load event, you can "grab" the variable you just set for your form and keep it private for that form. To demonstrate that, please take a look at the attached database.

    How to use this version of your database:
    1. frmCurrentFormType should be open, it just keeps track of the mWhat variable and displays it whenever a form Loads.
    2. Reproduce the steps that are changing the mWhat variable, but take a look at the fields, I added the private variable between parentheses.

    Edit:
    The variable is not global, the function that changes it is.
    Attached Files Attached Files
    Last edited by Edgar; 03-22-2023 at 12:26 PM.

  11. #11
    twgonder is online now Expert
    Windows 10 Access 2021
    Join Date
    Jun 2022
    Location
    Colombia
    Posts
    652

    Already solved, but I'll look

    Quote Originally Posted by Edgar View Post
    Hi, twgonder ...I did not find an issue other than the order in which you expect things to happen. ....
    Thanks for taking the time to look. I (post #8) probably did the same as you, I'll have to dig into your solution to know.

    The first point is that a user can jump in any direction, and the developer in Access has very little control, other than to make everything modal, which kind of defeats the purpose. The second point is that MS in the 1990s, when they started with VBA, didn't take the time to look around and understand the difference between code and work space and when to protect either in a multi-tasking environment. And here we are 30 years later, still struggling with that laziness on their part.

    Now, I'm guessing that some developers have gone ahead and relied on this quirk in Access, confusing global and module scope. As yet, I haven't found a bug in local variable leaks (but I won't bet the farm on that yet). I'm still holding out hope (and desperately needing) that there is an option that can be turned on in a module to make the module scoped variables truly private for the multi-task/multi-instance environment that Access finds itself in.

  12. #12
    twgonder is online now Expert
    Windows 10 Access 2021
    Join Date
    Jun 2022
    Location
    Colombia
    Posts
    652
    @Edgar, #10 I looked at your file, you must have a very high-resolution setup, as I couldn't find the frmCurrentFormType at first, it was off the screen. That's why I develop in a lower resolution, especially for testing purposes.

    I tried your Form1 and Form2, same problem. Barney still thinks he is a child.

  13. #13
    moke123's Avatar
    moke123 is offline Me.Dirty=True
    Windows 11 Office 365
    Join Date
    Oct 2012
    Location
    Ma.
    Posts
    1,643
    I understand the basics of what a class module should be, but has anyone taken a regular VBA module, and just made it a Class module somehow? Does it work the same?
    No. two different animals.

    The main difference between classes and modules is that classes can be instantiated as objects while standard modules cannot. Because there is only one copy of a standard module's data, when one part of your program changes a public variable in a standard module, any other part of the program gets the same value if it then reads that variable. In contrast, object data exists separately for each instantiated object.
    If this helped, please click the star * at the bottom left and add to my reputation- Thanks

  14. #14
    Minty is offline VIP
    Windows 10 Office 365
    Join Date
    Sep 2017
    Location
    UK - Wiltshire
    Posts
    3,001
    This describes variables and their effective scope perfectly well in my opinion:
    https://learn.microsoft.com/en-us/of...and-visibility

    If you expect them to work differently to this then you will no doubt encounter problems.
    DLookup Syntax and others http://access.mvps.org/access/general/gen0018.htm
    Please use the star below the post to say thanks if we have helped !
    ↓↓ It's down here ↓↓

  15. #15
    isladogs's Avatar
    isladogs is offline MVP / VIP
    Windows 10 Office 365
    Join Date
    Jan 2014
    Location
    Somerset, UK
    Posts
    5,954
    @twgonder
    I found your example interesting but probably not for the reasons you intended.

    The scope of a module variable value will of course persist whilst you keep open another form that uses the variable.
    As that is the whole basis of your example, it of course leads to the results that you report.

    Consider taking your process a stage further to 3 or more generations so people can be listed as both a parent and a child.
    What type of results would you expect to see?

    With your permission, I'd like to use your example as part of a web article explaining why you should never try to use module level variables in this way.
    Understanding the scope of variables is an essential part of using Access successfully.
    Colin, Access MVP, Website, email
    The more I learn, the more I know I don't know. When I don't know, I keep quiet!
    If I don't know that I don't know, I don't know whether to answer

Page 1 of 4 1234 LastLast
Please reply to this thread with any new information or opinions.

Similar Threads

  1. Variable Child forms
    By renovator in forum Forms
    Replies: 5
    Last Post: 09-11-2016, 08:21 AM
  2. Replies: 1
    Last Post: 09-03-2014, 01:36 PM
  3. Replies: 3
    Last Post: 07-03-2013, 01:20 PM
  4. Replies: 1
    Last Post: 01-04-2011, 05:04 AM
  5. Variables in Forms
    By NewDeveloper in forum Forms
    Replies: 1
    Last Post: 06-20-2010, 08:04 AM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Other Forums: Microsoft Office Forums