And I absolutely understand and agree with you. That said... the novice programmer comes in and someone says... don't worry about it, the "garbage collector will clean it up.". And you know what, that is true because they are not doing anything complex. And now they have learned they don't need to worry about it. They don't know what a "garbage collector" is, or what it does.@MajP This is the exact reason I started setting all variables to nothing. Some people without having the correct understanding, start "Teaching" ((and yes @jwcolby54 I am using the quotes intentionally) their wrong methods of programing and saying vba doesn't clean after itself or such, and we follow them blindly, without being told the whys and whens. And their reasons be like : Novic users don't understand.
I really appreciate you for bringing it up, for the way you put it out and specially forthe link.
Thanks @MajP.
@jwcolby54 Taking time or not is not the problem. The important point is to learn to progrom correctly. Not to put a lot of walls and doors around our code for ifs and maybes. I prefer to be told why it's done. Not because you don't understand put a =nothing to everything.
LOL. So go start a thread about debugging tools. We need that! It sounds very "I'm superior because..."You guys wouldn't have this discussion if you used more debugging tools than just the immediate window
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.LOL. So go start a thread about debugging tools. We need that! It sounds very "I'm superior because..."
@Edgar_ I would say I am pretty savvy with debugging, but I have no idea how I would use this to determine if I need to set an object to nothing. Are you saying it can point out circular references? Is this available in standard IDE or something like MZ-tools? I have MZtools and used RubberDucks but cannot say I have seen this capability. But I will also say I have not dug into all the capabilities.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.
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 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.
Not myObj Is Nothing
myObj
should be Nothingdoc 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.@Edgar_ I like it! I mean I REALLY like it. I have done this a bit, but not to the level I should .You could use the Watch window, I use that thing all the time.
1. Add a watch
2. Write an expression such asNot myObj Is Nothing
3. Choose a procedure wheremyObj
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 writingdoc 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.
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.would you consider starting a separate thread for this. "Debug tools, how to debug our code" or something like that.
@MajP - I do not get it. This is standard debugging,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
Debugging VBA
www.cpearson.com
and plenty of videos.![]()
Debugging VBA Code in Excel - GeeksforGeeks
Your All-in-One Learning Portal: GeeksforGeeks is a comprehensive educational platform that empowers learners across domains-spanning computer science and programming, school education, upskilling, commerce, software tools, competitive exams, and more.www.geeksforgeeks.org
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.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 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.You guys wouldn't have this discussion if you used more debugging tools than just the immediate window
OK, I guess. But I am almost certain that debugging VBA in Excel, Access or any other Office Product is the same.
- I do not even bother clicking off to anything for Excel developers.
- 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.
- Plus if it is in Access-Programmers I can just respond if I so desire.
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.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.
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.Code:Option Compare Database Option Explicit Public mclsOpenArgs As clsOpenArgs
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
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 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 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 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 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.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.
"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 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.
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.I do not get it. This is standard debugging
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.Or at least I am not seeing how this would be used.
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.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.
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.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.
Some day. You can track the doc variable in the example. It's going to be very didactic.I am asking for some better explanation and potentially a better example