Solved How to re-declare a public variable? (1 Viewer)

KitaYama

Well-known member
Local time
Today, 19:08
Joined
Jan 6, 2022
Messages
1,489
I have the following public variable declared in a module:
Code:
Option Explicit
Public OrdersRibbon As IRibbonUI

Then I have a function that runs from AutoExec and creates a xml statement and sets it as the default ribbon for the database:
Code:
Public Function LoadRibbons()
    .....
    ' create the xml
    .....
    Application.LoadCustomUI "OrdersRibbon", strXML
    .....
End Function

Then every now and then I use the following to re-assign the ribbon, hide/show/enable/disable buttons & controls:
Code:
OrderRibbon.Invalidate
OrderRibbon.InvalidateControl (MyControlID)

This is working, not even a single problem.

But if an unhandled error occurs, the public variable is destroyed (if it's the correct terminology) and the next time the code tries to invalidate the ribbon, it returns the following error:
Object variable or With block variable not set

Now my question:
  1. Is there any other way than a public variable to use in above case? I mostly use tempVars. But I've never set an object to a tempVar nd I'm not sure how to use it in above case.
  2. Is there any way to re assign a public variable once it's been destroyed? (at present we have to close and re-open the database)

Any kind of insight is much appreciated.
 
Last edited:
Solution
You can also save the memory address of the ribbon, and if it breaks, re-reference it from that address, because obviously the ribbon is not destroyed, just the variable that points to it. Consider...
Code:
Private ui_ As IRibbonUI

Function RibbonLoad(ui As IRibbonUI)
'   callback function from ribbon when it loads
    Set ui_ = ui               ' save to local variable
    TempVars!ui = ObjPtr(ui)   ' save address to temp var as backup
End Function

Property Get MainRibbon() As IRibbonUI
'   global property that automatically rebuilds
'   the ribbon if the ui_ variable is Nothing
    If ui_ Is Nothing And Not IsNull(TempVars!ui) Then Set ui_ = GetObjectFromPointer(TempVars!ui)
    Set MainRibbon = ui_
End Property

And the...

sonic8

AWF VIP
Local time
Today, 11:08
Joined
Oct 27, 2015
Messages
998
still error (k) exists, so my conclusion is that when error occurs, ui_ (the Ribbon) is not set to Nothing, but is damaged (it's pointer to public subs like getVisible, getLabel, etc. are lost.)
What do you mean by "it's pointer to public subs like getVisible, getLabel, etc. are lost."?
There are no pointers to these procedures. They are resolved by name at runtime. There is nothing that could get lost.
 

The_Doc_Man

Immoderate Moderator
Staff member
Local time
Today, 05:08
Joined
Feb 28, 2001
Messages
26,996
(A) "Is there any other way than a public variable to use in above case? I mostly use tempVars. But I've never set an object to a tempVar nd I'm not sure how to use it in above case."

TempVars do not accept object definitions. They are only for simple scalar variables of Short Text or some numeric format.

(B) "Is there any way to re assign a public variable once it's been destroyed? (at present we have to close and re-open the database)"

The variable isn't destroyed - but its contents are wiped. The error message is responding to the presence of Nothing (as an object address) rather than the absence of the variable itself.

Look at it this way: You had a PUBLIC object. You declared the object to be defined as a complex entity, i.e. DIM rs AS DAO.Recordset, in a certain way, then instantiated it using a SET object-variable = some-object - and once that happens, the object-variable becomes a pointer to the actual, much more complex object.

After the error that messes up the works, a program RESET occurs. Once it does, the object-variable is reset to Nothing, which for any simpler type of variable would be called a Null. The effect is that the address that is actually stored in the object variable is no longer valid. This next part is a guess, but the address is probably now 0, which is an illegal address in any normal Windows task. I don't know, but wouldn't be surprised to find out, that an internal and unreachable VBA status flag also exists that would confirm the object as "currently unassigned."

You can go back and repopulate the variable at any time, but what WAS there is now either destroyed (if internal to the Access process) or dangling and unreachable (if external to the Access process.) You can see dangling external processes from Task Manager. You can see them - but you can't connect to them. In essence, all you can do is kill any dangling external processes. Any internal structures (like recordsets or file system objects or other types of in-memory structures) are probably erased and unrecoverable.

I know you are desperate to find a solution because there is another thread related to this exact topic. But you can ask ten thousand times and still come up with the same answer. You CANNOT recover the objects. You can re-declare them, but it will be the same as if you had just closed and restarted Access. The old data is lost if that error handler doesn't intercept the error causing you grief.
 

GPGeorge

Grover Park George
Local time
Today, 03:08
Joined
Nov 25, 2004
Messages
1,775
"...They are only for simple scalar variables of Short Text or some numeric format."
And dates.

?TempVars!dtFromDate
4/10/2022

?Isdate(TempVars!dtFromDate)
True
 

Galaxiom

Super Moderator
Staff member
Local time
Today, 21:08
Joined
Jan 20, 2009
Messages
12,849
Unhandled errors are passed up the call stack until they encounter an error handler. Just adding a few handlers would make a big difference.

V-tools Access Add In has an automated function to insert error handlers.
 

KitaYama

Well-known member
Local time
Today, 19:08
Joined
Jan 6, 2022
Messages
1,489
The variable isn't destroyed - but its contents are wiped. .......

You can go back and repopulate the variable at any time, .....
@The_Doc_Man Your explanation is too complicated for my simple mind. I have to read it at least several times to digest it. But it won't be until this evening, when the heat of my Monday job is a little lower.

But for now, let's talk about the above section.
I have OrdersRibbon declared as a public variable. While opening the database, the following assigns a value to the variable:

Code:
Public Sub onRibbonLoad(ribbon As IRibbonUI)
      
    Set OrdersRibbon = ribbon
    
End Sub

The database resets and as you explained the variable still exists. but it's empty or null.
Is there anyway to set re-assign or re run the above procedure? I mean how I can pass the ribbon as a parameter to the sub?

thank you.
 

KitaYama

Well-known member
Local time
Today, 19:08
Joined
Jan 6, 2022
Messages
1,489
V-tools Access Add In has an automated function to insert error handlers.
Does it add the handler to all existing subs and functions without error handling?
As I explained earlier, the database is huge and it takes a life time to go through all functions and add one by one.

thank you.
 

The_Doc_Man

Immoderate Moderator
Staff member
Local time
Today, 05:08
Joined
Feb 28, 2001
Messages
26,996
"...They are only for simple scalar variables of Short Text or some numeric format."
And dates.

?TempVars!dtFromDate
4/10/2022

?Isdate(TempVars!dtFromDate)
True
Date is a typecast (interpretation) of type DOUBLE so counts as numeric.
 

The_Doc_Man

Immoderate Moderator
Staff member
Local time
Today, 05:08
Joined
Feb 28, 2001
Messages
26,996
Is there anyway to set re-assign or re run the above procedure? I mean how I can pass the ribbon as a parameter to the sub?

The same way you originally assigned it, by calling the sub with the correct actual argument. BUT if the thing being passed itself has been wiped, you have to rebuild that first.

I'm going to be honest with you. It is certainly possible to create code to reconstitute almost everything. BUT you will never fully recover EXACTLY what was lost due to the failed error trap. I hate to use the word "impossible" but realistically, this is a case where I would decline any bet, even a mere USA penny, on a successful reconstitution of everything. I wouldn't take the bet even if I were doing it for my own code with which I am intimately familiar. In YOUR case, you said the code was developed through multiple hands. Sorry, but not good odds.

You can probably reconstitute SOME things. Maybe even a lot of things. But there WILL be objects you will miss. I really don't want to be a buzz-kill on this topic but if I don't tell you the truth, I will mislead you. If someone else sees this differently, I would be overjoyed to admit I might have been a pessimist - but I just don't see it happening without getting in there and populating things with error handling so that you don't end up having your errors trapped by Access itself.
 

The_Doc_Man

Immoderate Moderator
Staff member
Local time
Today, 05:08
Joined
Feb 28, 2001
Messages
26,996
As I explained earlier, the database is huge and it takes a life time to go through all functions and add one by one.

This is the source of the problem, but here is a thought... you don't need error handling in EVERY itty-bitty function. If you can pick a place or situation in each form where these errors will stop something, put your error handling there and have the handler code restore usability without erasing everything. The up side is that this might be quicker. The down side is that you need to judiciously pick places to do this (and pick WHAT to do) with a lot of skull sweat. There is no easy way out of this pile of spaghetti.
 

sonic8

AWF VIP
Local time
Today, 11:08
Joined
Oct 27, 2015
Messages
998
upload your db, then.
You should be able to fix you own compile errors yourself. Just add a RichBox function with the required signature and comment out all other compile errors. - I'm not even sure if this would have been strictly necessary. I just refuse to analyze unexpected runtime behavior in code that doesn't even compile.
 

KitaYama

Well-known member
Local time
Today, 19:08
Joined
Jan 6, 2022
Messages
1,489
Is there any specific reason you ignore @MarkK's suggestion for restoring the variable?
I'm not ignoring him. I'm doing my best to follow him. But for me, it's a whole new world to what I know about Access. So it takes a little time.
Further more @arnelgp confirmed it doesn't behave as expected.

About the error in sample file, it was a copy/paste of our database. So some parts were remained. The main database is compiled and we don't see any errors there. Still the problem persists (if an unhandled error occurs the ribbon shows error on invalidating)
I'll try to put up another error free sample and hopefully you can test it.

This is from @theDBguy and shows he had experienced the same problem. So I don't think I'm alone here.
Hi. I am responding now just to subscribe to this thread and get a reminder later to look in my archives for a solution I came up a while back for the same problem.

Sent from phone...
 

KitaYama

Well-known member
Local time
Today, 19:08
Joined
Jan 6, 2022
Messages
1,489
You should be able to fix you own compile errors yourself. Just add a RichBox function with the required signature and comment out all other compile errors. - I'm not even sure if this would have been strictly necessary. I just refuse to analyze unexpected runtime behavior in code that doesn't even compile.
@sonic8 Check this sample file to see what we mean.

When you open the file you'll see a form. Click the button.
The button first invalidate the ribbon. and give you a messagebox to see the ribbon was invalidated successfull, no errors at all.
Then it cause an error. It tries to assign a string to an integer variable. Click END button to end the on-click event.

Now click the second button. This button tries to invalidate the ribbon again. But this time it doesn't succeed.
You'll receive the error that I explained in my first post above.
 

Attachments

  • testRibbon.accdb
    768 KB · Views: 89

KitaYama

Well-known member
Local time
Today, 19:08
Joined
Jan 6, 2022
Messages
1,489
@MarkK I have the same problem as @arnelgp
Compile error on ZEROPOINTER
And also when should I run your RibbonLoad Function? After loading the my customized ribbon?

Thank you.
 

sonic8

AWF VIP
Local time
Today, 11:08
Joined
Oct 27, 2015
Messages
998
@sonic8 Check this sample file to see what we mean.
Did you accidentally upload the wrong file? Your sample file does not include any code to reset the ribbon variable.
@arnelgp's sample includes MarkK's code to restore the variable and works (after fixing the compile errors, as mentioned). - That is what I was referring to.

Now click the second button. This button tries to invalidate the ribbon again. But this time it doesn't succeed.
You'll receive the error that I explained in my first post above.
Yes, sure. If you don't restore the variable for the ribbon, it will become Nothing after an error and the code will no longer work. - I never expressed the slightest doubt of that.
 

sonic8

AWF VIP
Local time
Today, 11:08
Joined
Oct 27, 2015
Messages
998
No it will not.
You step through the code and it will ignore the code:

If ui_ Is Nothing...
You haven't looked at the sample provided by @KitaYama. There is no single line of code containing "If ui_ Is Nothing" in the whole sample file.

As for your example, you are correct. ui_ is not Nothing after the error because you handled that error using "On Error Resume Next", so the variables are not reset.
 

Users who are viewing this thread

Top Bottom