OpenArgs (my) class way (1 Viewer)

B
I jumped in because there was a lot of esoteric speculation going on. The tools are available for everyone to use when figuring out when you need to set objects to "nothing". It’s certainly not about memorizing specific cases. That’s just my take on it, anyway, and, to clarify, apologies if I came across that way. I’ve actually tried a few times to encourage more developers to use the tools, but maybe I didn’t explain things clearly enough. It's possible that it wasn’t compelling enough, or maybe my low post count didn't help.

Regardless, I encourage more people to use a wider range of tools to avoid being misled by those who act like their post count or status makes their opinions unchallengeable. If I’m part of that group, then fair enough. Let’s rely on the tools and the facts to find the truth, not on post count, titles, or blind peer respect.
But I have no idea what these tools even are. I use MZ-Tools, and have for decades. I would absolutely love something that scanned code and said "This might need to be manually set to null". I believe I have rubber duck too but don't actively use it. OTOH I don't actively develop any more.
 
I just went through MZ Tools and didn't see anything like this.

1749335875955.png
 
You could use the Watch window, I use that thing all the time.
1. Add a watch
2. Write an expression such as Not myObj Is Nothing
3. Choose a procedure where myObj should be Nothing
4. Choose a module
5. Choose Break When Value Is True
6. Run your code, use your class or form or whatever and, if at some point the condition is met, it will break
7. Debug the thing

Here's an example, and a file
1749348404913.png


Tweak the expression in the image above by writing doc Is Nothing using the rest of the configuration as is, when you run the form it will break at the beginning of the procedure, walk the code and see how it changes from True to False. Once it's false, the doc variable exists and can be used.

You don't have to be that specific, but I wanted to use the whole Watch. You can also track value changes and the contents of a watched variable. Pretty handy.
 

Attachments

You could use the Watch window, I use that thing all the time.
1. Add a watch
2. Write an expression such as Not myObj Is Nothing
3. Choose a procedure where myObj should be Nothing
4. Choose a module
5. Choose Break When Value Is True
6. Run your code, use your class or form or whatever and, if at some point the condition is met, it will break
7. Debug the thing

Here's an example, and a file
View attachment 120162

Tweak the expression in the image above by writing doc Is Nothing using the rest of the configuration as is, when you run the form it will break at the beginning of the procedure, walk the code and see how it changes from True to False. Once it's false, the doc variable exists and can be used.

You don't have to be that specific, but I wanted to use the whole Watch. You can also track value changes and the contents of a watched variable. Pretty handy.
@Edgar_ I like it! I mean I REALLY like it. I have done this a bit, but not to the level I should .
Having said that, would you consider starting a separate thread for this. "Debug tools, how to debug our code" or something like that. This post is buried deep down in a thread which really has nothing to do with the subject of debugging. I believe that a thread about how to debug code is worth our time. And I believe that others chipping in can really produce results for the community.
 
would you consider starting a separate thread for this. "Debug tools, how to debug our code" or something like that.
I'll consider it. I'm glad you could find some use in it. The devs gave us some handy stuff, it's just not talked about much, but it's there. On top of writing your expressions, you can explore what the contents of an entire object looks like throughout the procedure and add all kinds of conditions for your breaks without modifying your code. That may not be like the automatic tool you were referring to, but I don't doubt that given the right conditions, it would help spot circular references as soon as they appear. You can have as many watches as you need, so that's a plus.

I'll try to post a tutorial one of these days.
 
Last edited:
I do not get it. This is standard debugging, and yes many people are not well versed in that. But this seems irrelevant to the conversation of when you "need" to set an object to nothing. Or at least I am not seeing how this would be used. Lets say I want to do a test which I do not think the example is enlightening. This example does not show a case where objects should be set to nothing and where and object does not "need" to be set to nothing. So it does not really show me anything.

Lets say I purposely create a circular reference which is something where I would set objects to nothing. I could not use this idea easily to see if I am causing a circular reference nor do I think I could even prove if i did. Even If I did, the problems are created are often intermittent. Maybe I am not seeing what you are saying. But I still have no idea how the average user could use this idea to show when they really should set an object to nothing and when the risk is not there.

I do agree that an advanced debugging thread would be nice. I point people to these as a start
and plenty of videos.
 
I do not get it. This is standard debugging, and yes many people are not well versed in that. But this seems irrelevant to the conversation of when you "need" to set an object to nothing. Or at least I am not seeing how this would be used. Lets say I want to do a test which I do not think the example is enlightening. This example does not show a case where objects should be set to nothing and where and object does not "need" to be set to nothing. So it does not really show me anything.

Lets say I purposely create a circular reference which is something where I would set objects to nothing. I could not use this idea easily to see if I am causing a circular reference nor do I think I could even prove if i did. Even If I did, the problems are created are often intermittent. Maybe I am not seeing what you are saying. But I still have no idea how the average user could use this idea to show when they really should set an object to nothing and when the risk is not there.

I do agree that an advanced debugging thread would be nice. I point people to these as a start
and plenty of videos.
@MajP - I do not get it. This is standard debugging,

Is OffPutting. It gives you an "I'm superior because" sound. Folks come in all shapes and sizes and what is "standard" to you has never even been looked at by others. Access is hugely complex, just learning about the non-vba side of things can take a non-programmer months or years to adequately figure out. And IMO the vast majority of "access programmers" came from there and slid sideways into programming.

Just sayin...

The bigger question is what is a discussion about "when you need to set an object to nothing" doing buried deep (4 pages) down in "my" thread about a class pair I wrote to do a particular thing.
 
Last edited:
@MajP Thanks for the links to the subject.

  1. The pearson software link is good but basic. I will say that I created a Locals window docked next to and on the right of the debug window.
  2. I do not even bother clicking off to anything for Excel developers.
  3. If I am going to be reading in Access-Programmers, clicking off to anywhere else is likely to get me sidetracked from what I am wanting to read / write about. I have pretty extreme ADHD, which coupled with the fact that I am old, makes getting sidetracked just way too easy.
  4. Plus if it is in Access-Programmers I can just respond if I so desire.
So for me, a discussion native to Access-Programmers just works better.
 
Last edited:
Is OffPutting. It gives you an "I'm superior because" sound. Folks come in all shapes and sizes and what is "standard" to you has never even been looked at by others. Access is hugely complex, just learning about the non-vba side of things can take a non-programmer months or years to adequately figure out. And IMO the vast majority of "access programmers" came from there and slid sideways into programming.
I think you might be reading to much tone that is not intended. That was not meant to sound superior in any way. It is clearly not a criticism and specifically reiterated that more understanding of debugging is good and not understood by many. But I truly do not understand how you would use this as @Edgar_ described.
You guys wouldn't have this discussion if you used more debugging tools than just the immediate window
I think that is a pretty broad statement, kind of "offputting and superior" implying we do not know how to debug. And maybe you and other get it, but I just do not see it. I am asking for some better explanation and potentially a better example.

  1. I do not even bother clicking off to anything for Excel developers.
  2. If I am going to be reading in Access-Programmers, clicking off to anywhere else is likely to get me sidetracked from what I am wanting to read / write about. I have pretty extreme ADHD, which coupled with the fact that I am old, makes getting sidetracked just way too easy.
  3. Plus if it is in Access-Programmers I can just respond if I so desire.
OK, I guess. But I am almost certain that debugging VBA in Excel, Access or any other Office Product is the same.
 
Last edited:
Well that works.

First I made the clsOpenArgs up in the form's header public so that I could see it from outside the form.
Code:
Option Compare Database
Option Explicit

Public mclsOpenArgs As clsOpenArgs
Of course the correct way to do this is to create a property in the form to expose the clsOpenArgs but this is just test code.

I had not created the method to apply the properties to the form so I did that.

Code:
Function fApplyFormProperties()
    On Error GoTo fApplyFormProperties_Error
Dim lclsOpenArg As clsOpenArg
    For Each lclsOpenArg In mcolOpenArg
        mfrm.Properties(lclsOpenArg.pName) = lclsOpenArg.pVal
    Next lclsOpenArg
   
   
Exit_fApplyFormProperties:
    On Error GoTo 0
    Exit Function

fApplyFormProperties_Error:
Dim strErrMsg As String
    Select Case Err
    Case 0      'insert Errors you wish to ignore here
        Resume Next
    Case Else   'All other errors will trap
        strErrMsg = "Error " & Err.Number & " (" & Err.Description & ") in procedure EDPDemoDB.clsOpenArgs.fApplyFormProperties, line " & Erl & "."
        Beep
#If boolELE = 1 Then
        WriteErrorLog strErrMsg
#End If
        assDebugPrint strErrMsg
        Resume Exit_fApplyFormProperties
    End Select
    Resume Exit_fApplyFormProperties
    Resume 0    'FOR TROUBLESHOOTING
End Function

I then created a function out in a test module to get a pointer to that specific form so that I could play around.

Code:
Function frmOpenArgsDemo() As Form_frmOpenArgsDemo
    Set frmOpenArgsDemo = Forms("frmOpenArgsDemo")
End Function

I then opened the form as follows (in the debug window):
docmd.OpenForm "frmOpenArgsDemo",acNormal,,,,acWindowNormal,"Visible=false;Color=Blue"

passing in two open args, visible=false and color=blue

I then called the method in the debug window to apply the OpenArgs to the form's properties (in the debug window):

frmOpenArgsDemo.mclsOpenArgs.fApplyFormProperties


The form went invisible due to the first OpenArg. Then the second OpenArg threw an error as shown.

Error 2455 (You entered an expression that has an invalid reference to the property Color.) in procedure EDPDemoDB.clsOpenArgs.fApplyFormProperties, line 0.

So the concept works.

The code is up on GitHub in my demo database. frmOpenArgsDemo for the form, basTest for the module with the code to get a pointer to the open form. It has to be open obviously.

This has been a post to demonstrate a little more about classes
I haven't read the whole thread. Maybe this has been dealt with. surely rather than colour=blue you would use colour=cstr(vbblue), (or more simply just the numeric string, and then dereference the string back to the numeric value in your class.
 
I haven't read the whole thread. Maybe this has been dealt with. surely rather than colour=blue you would use colour=cstr(vbblue), (or more simply just the numeric string, and then dereference the string back to the numeric value in your class.
Sorry but this is so far away from whatever we were discussing that I am totally lost. As for colors... I normally just use the vbCyan kind thing. Why it is not that is lost in the mists of an overly long thread about things totally unrelated to the original subject.
 
I think you might be reading to much tone that is not intended. That was not meant to sound superior in any way. It is clearly not a criticism and specifically reiterated that more understanding of debugging is good and not understood by many. But I truly do not understand how you would use this as @Edgar_ described.

I think that is a pretty broad statement, kind of "offputting and superior" implying we do not know how to debug. And maybe you and other get it, but I just do not see it. I am asking for some better explanation and potentially a better example.


OK, I guess. But I am almost certain that debugging VBA in Excel, Access or any other Office Product is the same.
I might be reading too much tone into your statements. I am just trying to make you aware of how I hear you sometimes. If I hear tone do others too? You are a very knowledgeable and helpful guy, and thinking about how you might sound may make you more approachable to some of us.

I do want to know how I sound, I try to be aware of how I sound. If I come off as sharp or sarcastic... it's because I intend that. Though perhaps I use that sound a bit too often?:oops:

Yes, debugging in excel is the same except that all too often they launch into putting stuff into sheets or cells etc. And I am in Access. And I am not going to do whatever that stuff is. So I have learned to just not bother.
 
Sorry but this is so far away from whatever we were discussing that I am totally lost. As for colors... I normally just use the vbCyan kind thing. Why it is not that is lost in the mists of an overly long thread about things totally unrelated to the original subject.
I thought you said that the colour element of the openargs failed, and I thought it might be connected with the fact that openargs is a string.

I have sometimes passed multiple openargs elements with a string separator, and parsed the string accordingly, but without using a class.
 
I thought you said that the colour element of the openargs failed, and I thought it might be connected with the fact that openargs is a string.

I have sometimes passed multiple openargs elements with a string separator, and parsed the string accordingly, but without using a class.
"the color element failed" - No, color was the name of an open arg passed in, with an associated color value. I used "Color" Intentionally, knowing that it was not going to work as a property of the form. Form's don't have a color property, at least that I can find with an OpenArg named "Color".

I was demonstrating how I can pass in OpenArgs and tell the OpenArgs class to try and "poke" the OpenArgs into form properties named the same thing. "The color OpenArg failed". Which was an expected thing of course. Testing the one that shouldn't work.

>>>I have sometimes passed multiple openargs elements with a string separator, and parsed the string accordingly

I used to do it just that way. One day I had a specific "framework" behavior I wanted to make broadly available to my forms as they opened. For this reason I created the clsOpenArgs which I then made a variable up in the header of my clsFrm. And clsFrm instantiates clsOpenArgs and tells it to do it's thing, parsing the Openargs (if any) . That makes it available to any form which uses OpenArgs, but of equal importance, it means it is done once and Ya! Now every form has that! I am not coding it over and over in specific places where I decide to use it. What I call "the framework way".
 
Last edited:
I do not get it. This is standard debugging
Ideally, the debugger should be your go-to tool when a bug occurs, unless you're following a strict test-driven development approach. It sounds like you might have been expecting a more automated solution that can catch all scenarios. I've come across some tools that aim to do that, vbWatch, for instance, looks promising, though I haven't tested it myself. Personally, I find the built-in debugging tools reliable enough to catch the kinds of issues where something needs to be explicitly set to Nothing. It's not about guessing, you don't need to memorize any case, it's about having the right tools in place when things go wrong.

Or at least I am not seeing how this would be used.
The engine would usually notify you when there's a problem. From there, you can add watches to pinpoint when and where it happens, and then continue debugging. That's what the debugger is for. Do not go around thinking you know all cases, the engine helps you detect the problems as they occur. When it does not, there are side effects and unintended consequences, that's also a good indicator of the presence of memory leaks and what not. So, again, Watches and other tools may help a lot.

This example does not show a case where objects should be set to nothing and where and object does not "need" to be set to nothing. So it does not really show me anything.
The example clearly shows when a variable's value changes, and you can use conditions to check if it's pointing to something it shouldn't at a given point in time or procedure. For instance, if it isn't Nothing at the start of a process when it should be, you can scope the watch specifically to that process.

But I still have no idea how the average user could use this idea to show when they really should set an object to nothing and when the risk is not there.
Kind of off topic but take a look at LLMs. They reflect on what your average user does. Ask them to debug something and they will suggest Debug.Print statements instead of the tools that offer greater control and reduced guess work, that's statistics. And then we're pointed to articles that are 30 or 40? years old, barely scratching the surface of the topic, if at all. It's as if the community hasn't produced anything more substantial or up-to-date since then. It demands new and better approaches to code in general. Thank the universe for the existence of twinBasic, but that also needs more support. Anyway, the average user is, sadly, not using the debugger. Apparently, savvy ones aren't either.

I am asking for some better explanation and potentially a better example
Some day. You can track the doc variable in the example. It's going to be very didactic.

By the way, debugging Excel, Word, PowerPoint, Access, even AutoCAD is all the same. You just work with different objects.
 
Last edited:
What I call "the framework way".
And that's a great thing. All other development kits are using frameworks for everything, saving thousands of hours, but nothing is really out there yet for every day Access development, save for a few classes and modules here and there to handle very specific scenarios.
 
By the way, debugging Excel, Word, PowerPoint, Access, even AutoCAD is all the same. You just work with different objects.
This is true. I have done work in Excel, Word, Access and Outlook. The biggest issue there is that the environment is completely different from Access. We really do have the "best" environment for easily and quickly writing code. And also re where the code is stored. In a worksheet? Really?

I used to use the Excel widget that recorded keystrokes and such (a really powerful and useful tool), but then pull that code back into Access to store. Wrap it and call it and get stuff done.

I recently used events in outlook, sunk in Access, to capture Outlook email, check the from / to and subjects to catch orders coming in to a small business where they used emails in that manner. It worked quite well, I could grab an email and pull the stuff out of the email message to create orders in the order table. Events raised in Outlook, sunk in a class in Access. In theory one could do the same in any of the office apps.
 
And that's a great thing. All other development kits are using frameworks for everything, saving thousands of hours, but nothing is really out there yet for every day Access development, save for a few classes and modules here and there to handle very specific scenarios.
I was around before windows, and back then DOS was the "ultimate framework". In the end it is really about the bios handling the very low level stuff, disks, serial ports, interrupts, memory managemt (at the very basic level) and then building up on that to give us devs hard drives, displays, keyboards, mice, memory etc. I remember when we had to understand that stuff.

Now I just open Access and Windows handles all the underneath stuff for Access. And now I just open Access and Access handles all the minute details of tables, fields, indexes, forms, controls and so forth. Access is a database framework on top of the Windows framework.

And so why not build a framework on top of Access to handle a bunch of stuff when an App opens, When a form opens. Get the Sysvars which run the framework loaded out of various sysvars tables and cached into memory in classes. I had a sysvar table for the framework itself, for the application and for the client info. The framework sysvars had default values in my Framework library, which were pulled into the FE the very first time that I initialized the framework for a new FE. I could then override the framework sysvars in the fe if this specific fe needed to do something different from the default.

Get logs set up and working. An error log to log errors into tables if the framework sysvars said it was going to go into a table, or a file if the framework sysvars said it was going to log to file.

Then the form side of the house. clsFrm to manage forms as they loaded. Get the various behaviors ready for the form as it loaded.

A framework for me, written by me, to make my Access development easier. It took a couple of years, as I worked on client apps, but it got done and it made my life as a dev in Access much easier.
 
It would be nice if we could have all those classes and modules made by others in one place where we can simply select and bring into our development environment. Sort of like npm for NodeJS or nugget within .Net, you would not even need to classify them, you would just search for them and with simple gesture you'd be ready to use them. Such a thing would require an add-in, perhaps, but it would be a useful add-in, for sure.
 
[OT: "npm" for Access]
... have all those classes and modules made by others in one place where we can simply select and bring into our development environment ...
The same would also be useful for add-ins etc.
Ideas have already been introduced in prominent place (Access DevCon 2023):

If there were a "catalog" of these code modules, an add-in could be developed with a manageable amount of effort. (I already use an add-in for importing code modules including their dependencies, which could be expanded or parts of it could be used).
Since I also consider this to be useful, I would be happy to discuss ideas/conceptions about such an add-in + catalog in more detail.
However, I suggest an extra thread for this so that John's thread is not totally hijacked. :)
 
Last edited:

Users who are viewing this thread

Back
Top Bottom