VBA Check or un check Lib ref -Global variables are emptied

User avatar
Doc.AElstein
BronzeLounger
Posts: 1499
Joined: 28 Feb 2015, 13:11
Location: Hof, Bayern, Germany

VBA Check or un check Lib ref -Global variables are emptied

Post by Doc.AElstein »

VBA Check or un check a Library reference and your global variables get emptied?
Hello
I spent many hours trying to figure out why seemingly erratically my Global variable were being emptied.
I spent some more time preparing a Forum Post to ask for help … in the process of preparing the question, I found the cause and an initial workaround. :)

But as I had not found any help after a lot of internet searching, I thought I would briefly mention the issue out of passing interest and as it might help somebody else who is searching who has a similar problem in the future.
_.__
Background to the issue
So I have a large file with a lot of messy and complicated coding built up on and off over a year or so.
It is sometimes convenient to use a global variable declaration at the top of a code module so that I can use the value in it from different codes at different times.
A lot goes on when the file is open. ..What goes on is usually a bit different every day.
It gets passed on and opened and closed in different Excel versions and different computers..
( It is a pretty amazing and special file actually, .. corrupted with multiple ThisWorkbook code modules and other unique things like Worksheet code modules with no worksheets :) )

The current problem ( was)
From time to time a code failed as a global variable no longer seemed to have in it what it should have..

The causes
_ 1) Manually / Womanually uncheck or check any reference
If you manually or womanually check or uncheck any reference ( From VB Editor -- Tools -- References – scroll about and check or uncheck a small box https://imgur.com/hbsEg3Z" onclick="window.open(this.href);return false; ) , then all global variable in a file are emptied. It doesn’t matter where the global variable is or where the code is that you try to use the global variable.
So simple conclusion here: make any reference change manually or womanually and your Globals are buggered
_2) Programmatically uncheck or check any reference
The situation here is slightly more complicated.
As long as the code in which the reference has changed has not ended , then in that code or any called procedures , the global variable maintain their values
As soon as the code in which the reference is changed ends, then all global variables are emptied.

The workarounds.
Strangely it doesn’t help to refill your Globies after changing a reference check.- at least not in the code that does the reference change. ( They still work anyway in that procedure before it is closed )
One workaround is to do all your Globy filling in a procedure which you schedule to run just after any code which does any reference check changes.

As a “Belt and Braces” approach, I also call the Globy filling procedure, or fill a globy or two, in a few other codes, whether those codes need the globies or not. – Does no harm to refresh them when you have the time….. as the saying goes… “….top up your globy from time to time so its filled and ready for action ….”

_._
Demo Examples
I have uploaded 2 files, ( a drastically reduced version of my main file, and a fresh made file ) with a few demo codes for anyone is interested at looking at the problem:
The Files have some ThisWorkbook code modules, normal code modules and worksheet code modules, and a few others.. 4 Code modules are of relevance to the issue
In these 3 modules_....
_.. DiesesArbeitsmappe1 - the German version of This Workbook code module 1 ( DiesesArbeitsmappe in fresh uncorrupted file)
_.. Modul1 – normal code module
_.. Tabelle7 ( “Sheet1” ) – conventional worksheet code module for an existing worksheet.
_...I have simple codes like this

Code: Select all

' In Lis Workbook code module
Option Explicit
Public LisWkBkProWb As Workbook
Public LisWkBkGloby As Long
Sub FillLisWkBkGloby()
 Set LisWkBkProWb = ThisWorkbook
 Let LisWkBkGloby = 42
End Sub
' Run the code above, then the code below and all is well.
' Check or uncheck any reference and run code again below....
Sub HowLongsYourGloby()
 MsgBox LisWkBkGloby & vbCrLf & LisWkBkProWb.Name
End Sub
If you run both codes, then all is well. You can then run the second code as often as you like and all is well.
If you then change any reference manually, and just run the second code then it will error as the Globies have apparently been emptied as an unwanted by-product of changing any reference


In a second normal code module, DoItProgramatically, are some more complicated codes:

Sub ScrewAboutWithReferencesInRunningCodeIsOK()
This checks and un checks a few references programmatically. It demos that in this code and any called procedure there is no problem with using the Globies, ( which are filled at the start of the code ).

Sub TakeOffAReferenceScrewUpYourGlobies()
This demos the problem..
It initially fills the global variables. It then un checks a reference ( for Office ).
Just before this code, Sub TakeOffAReferenceScrewUpYourGlobies() , finishes, it schedules the code, Sub WhatsInMyGlobies( ), to start after a couple of seconds.
The code Sub WhatsInMyGlobies( ) errors because the global variables have been emptied as an unwanted by product of the un checking of the Office reference

The next code should then be run a few seconds after the last code
Sub WorkaroundFillYaGlobsAfterARefChange
This code does something similar to the last. This time it initially fills the globies again and re checks the Office reference.
It also schedules the code to Sub WhatsInMyGlobies( ) to start a few seconds after this code , Sub WorkaroundFillYaGlobsAfterARefChange , finishes. But it schedules a code Sub FillMeGlobsUpMate() to start a few seconds before the code Sub WhatsInMyGlobies( ) is scheduled to start. As a result of this, code Sub WhatsInMyGlobies( )does not error.

Finally….
Sub JustToCheck()
This code schedules 4 codes to start one after the other. These code do:-
1 Fills the Globies
2 Un checks a reference ( for Office )
3 tries to use the globies, and errors
( 4 – not part of the main demo, but just for tidiness re checks the reference to Office, as I suspect it is sensible to do that. )

Two uploaded demo Files:
_ A stripped down version of the File that first had all the problems : https://app.box.com/s/hqr8eytl0576o1kwvhv2g1ajpfetzle4" onclick="window.open(this.href);return false;
_ A fresh made file.: https://app.box.com/s/5ypovakgtaglqe8ztkh6q8az2tmsiurb" onclick="window.open(this.href);return false; ( Also attached )

Note: If you are using a version of Excel other than 2003, 2007 or 2010, then you will need to tweak for the correct Library GUIDs ( If you do that you might like to pass on the GUIDs to me – Here is a simple code to get those:
https://tinyurl.com/yb7ay2r9" onclick="window.open(this.href);return false;
I checked all in XL 2003, 2007 and 2010, so did my wife. Results r generally the same

Alan
( see you next Winter maybe :) )
You do not have the required permissions to view the files attached to this post.
I am having difficulty logging in with this account just now.
You can find me at DocAElstein also

User avatar
rory
5StarLounger
Posts: 817
Joined: 24 Jan 2010, 15:56

Re: VBA Check or un check Lib ref -Global variables are empt

Post by rory »

You're causing state loss by resetting the project, which is why the variables are reset.
Regards,
Rory

User avatar
Doc.AElstein
BronzeLounger
Posts: 1499
Joined: 28 Feb 2015, 13:11
Location: Hof, Bayern, Germany

It's a Bloody messmory state loss here. Lost In State

Post by Doc.AElstein »

Thanks Rory fürs info. . I expect it is reasonable to expect then that the resetting goes on when the code ends, which would explain my results I think. ( *** but sometimes some screwy things can go on when the check is made.. )

I think I just need to make sure that I do the programmatically checking stuff in isolation and preferably when the code opens and preferably just once.
_._______

***
I had some peculiar and inconsistent problems with some Application.Run codes going ape shit and causing weird recursions at the code line which changed a reference...

If I have code set off by a Application.Run that then changes a reference check, then at the point of the checking / unchecking the Application.Run goes a bit squatty sometimes starting off again and / or event codes shoot off erratically sometimes.

I could not get any consistent results on that yet.
But this little demo shows up something strange if you do it in debug F8 mode:

If you run this code _..
Sub ApplicableRunsInGlobyGoneBollox()
which is in this File
“NeuProAktuelleMakrosReferenceGoneBollox.xls” : https://app.box.com/s/hqr8eytl0576o1kwvhv2g1ajpfetzle4" onclick="window.open(this.href);return false;
_.. then that file , Sub ApplicableRunsInGlobyGoneBollox() , calls ( using Application.Run ) a code Sub TraschAOfficeTCheckRegysBox() , which is in another file.

That code, Sub TraschAOfficeTCheckRegysBox() , is in this file:
“GlobalVariableGoneBollox.xls” : https://app.box.com/s/5ypovakgtaglqe8ztkh6q8az2tmsiurb" onclick="window.open(this.href);return false;
That code, Sub TraschAOfficeTCheckRegysBox() , unchecks Office. When that happens the code springs back and forth and hangs up a bit.
In this simple situation it has no ill effects.
But in a larger more complicated File with a lot of event codes it sometimes causes a bit of fun.
Never mind
:)
I am having difficulty logging in with this account just now.
You can find me at DocAElstein also

User avatar
Jan Karel Pieterse
Microsoft MVP
Posts: 656
Joined: 24 Jan 2010, 17:51
Status: Microsoft MVP
Location: Weert, The Netherlands

Re: VBA Check or un check Lib ref -Global variables are empt

Post by Jan Karel Pieterse »

Some tips.

1. There are other causes for variable reset you may not be aware of:

- issuing an "End" statement
- A runtime error occurs and the user clicks "End"
- Clicking the Reset button on the VBE toolbar
- CLose the file with the code
- Close Excel .
- Add (or remove) an ActiveX control on a worksheet

My way of handlilng this is:

- Avoid global variables as much as possible
- Add a check global boolean variable which is set to True when globals are initialized which you can check in entry-subs for its value:

Code: Select all

Public gbVarsOK as Boolean
Sub SomeEntryRoutine()
    If gbVarsOK = False Then InitWorkbookVars
    'Other code
ENd Sub
Regards,

Jan Karel Pieterse
Excel MVP jkp-ads.com

User avatar
Doc.AElstein
BronzeLounger
Posts: 1499
Joined: 28 Feb 2015, 13:11
Location: Hof, Bayern, Germany

Focusing On My Globy Scopes, and in messying with States

Post by Doc.AElstein »

Thanks Jan for the extra info. - I think I and others have probably experienced the situations that you have listed of the Globies being emptied, but I wasn’t quite sure what was going on at the time, so that helps clarify things a bit, thanks.
(… “… A runtime error occurs and the user clicks "End"
- Clicking the Reset button on the VBE toolbar..“…
……
I expect I chased my tail a bit when I either did one of those two possibilities in a couple of situations….
For example At Error occurrence
Debug + then some how continued ‘ Globies not emptied
or
End. ‘ Globies Emptied
_ - I expect at the time I did not notice that one emptied the Globies and one didn’t
Another example at a Stop
_ - Similar thing goes for having a Stop in a code. – If at a Stop, when the code stops there, I hit
Reset ‘ Globies get emptied
or
Play (F5) or F8 ‘ Globies not emptied
_ - Once again, I expect at the time I did not notice that one emptied the Globies and one didn’t )


..”..Avoid global variables as much as possible…“..
It is nice to hear that from you. I was using Global variable a lot as it seemed “the thing to do” .. I do a lot of calculations in Arrays that call on the Globals that I put in the global variable, so it sort of seemed the logical thing to do at the time.
I keep finding odd little things that throw a spanner in the works, and I was recently thinking of going back to jotting things down on the back of a Bier Mat instead.
Possibly something in-between the extremes is the best approach:….
I usually avoid interaction as much as possible with the spreadsheet: But I don’t have thousands of global variables, and some of them are simple, … so maybe just storing values or values that I need to set a object or two could just be pasted out in a spare worksheet and accessed from there. That has the additional advantage that I can have a quick look from time to time if need be, when debugging etc, to help see what the state of things are.

…“.Add (or remove) an ActiveX control on a worksheet..“….
It does not surprise me that Adding (or removing) an ActiveX control on a worksheet clears the globies. It most likely screws up a lot else besides I expect… Active x controls in a worksheet I hear should probably be avoided like the plague anyway , ( - they wont insert in many of my Excel versions anyway ( http://www.excelfox.com/forum/showthrea ... nsert-them" onclick="window.open(this.href);return false; ) , and after weeks of trying the hundreds of published cures and workarounds they still wont insert for me , or if they do they don’t work and/ or break other stuff)..

_._____________________

For now, my current workaround..
Currently I have a code , Sub FillMeGlobsUpMate , which initialises the globies, and in the last few days I have been adding a quick Call of that in codes when the original problem crops up. With hindsight now I probably would have avoided using global variables in the first place.
(The idea of jotting things down on the back of a Bier mat doesn’t work at all well here... – When they bring the Bier, they scribble something on the back of the Bier Mat … , that makes it a bit difficult to decipher my notes from it later .. even when I’ve sobered up)


Alan

_.__________

P.s. 1 : Just to link something relevant to the general Theme of this Thread … from here:
http://eileenslounge.com/viewtopic.php? ... 79#p197065" onclick="window.open(this.href);return false;
http://eileenslounge.com/viewtopic.php? ... 79#p197085" onclick="window.open(this.href);return false;

If you do use Globies , then it might be wise to put them in a code module other than the one in which they are used, especially if you may be doing any adjustments to coding in the module. In other words, as Kevin said at those Posts,… in development it can be an extra nuisance having Globies in the same module in which you are working.
The reason for this is the following:
Try any of these 6 actions
add a code
delete a code ( ‘ comment out will do just as well)
add a global variable declaration line
delete a global variable declaration line ( or ‘ comment out)
add a API Declare thingy
delete a API Declare thingy ( or ‘ comment out)
If you do any of those 6 actions , then you will find that the globies in the code module in which you did that are emptied
( You can mess about within existing codes and there is no problem. The problem comes when you add or delete codes or declarations: Any of those 6 actions will cause the globies to be emptied but only in the module in which you take any of those 6 actions

Here’s a not very simple demo for this P.s. 1 thing that I am talking about.:
In this File: _.. ( “NeuProAktuelleMakrosReferenceGoneBollox.xls” )
https://app.box.com/s/hqr8eytl0576o1kwvhv2g1ajpfetzle4" onclick="window.open(this.href);return false;
_.. there are a few Globies, in 4 code modules.
This code will fill them up ( Initialatyizationing)

Code: Select all

Private Sub IniSchitMateYourGlobs()
 Call Modul1.FillModul1Globy ' In Normal Code Module
 Call DieseArbeitsmappe1.FillLisWkBkGloby ' Special ThisWorkbook code module
 Call Tabelle7.FillWs1Globy ' In a semi Normal Worksheets code Module
 Call HardGlobies.FillModul1Globy ' In another Normal Code Module
End Sub
Having run the above code, run this code, Private Sub OwdeToHardGlobies()
This code, Sub OwdeToHardGlobies() , will check the status of those globies by trying to use them. It will display the values or tell you which globies failed ( where empty )
Initially no fails will be indicated. If you try any of the 6 actions listed, then re run the code then the code will indicate that the globies in the code module in which the action was taken have been emptied, but those in the other 3 code modules have not been effected.


You can also experiment with taking one of those 6 actions in one of the other code modules,that is to say in a different code module to that with the code Sub OwdeToHardGlobies()
Then run that code .… The results are not quite as expected …
If you do that, then once again you will see that code will error for the code lines trying to use the globies from the module in which you did the change - that you may have expected- BUT also strangely the globies are emptied within the module in which you are running the code Sub OwdeToHardGlobies()

Clearly its quite tricky and messy playing with your globies. So maybe it is best to leave them alone or even don’t bother to use them.. or if you must use them, then it probably is a good idea to keep them topped up. .. – you never know when they might get emptied.
Last edited by Doc.AElstein on 13 Apr 2018, 06:06, edited 1 time in total.
I am having difficulty logging in with this account just now.
You can find me at DocAElstein also

User avatar
Doc.AElstein
BronzeLounger
Posts: 1499
Joined: 28 Feb 2015, 13:11
Location: Hof, Bayern, Germany

I wish I knew how t automate up/downloading my files to box

Post by Doc.AElstein »

Edit.. Oops
i forgot to re upload that demo file to the file sharing site, so it did not have all the codes I was talking about in it..
it does now
https://app.box.com/s/hqr8eytl0576o1kwvhv2g1ajpfetzle4" onclick="window.open(this.href);return false;
Sorry about that..
I am having difficulty logging in with this account just now.
You can find me at DocAElstein also

User avatar
Jan Karel Pieterse
Microsoft MVP
Posts: 656
Joined: 24 Jan 2010, 17:51
Status: Microsoft MVP
Location: Weert, The Netherlands

Re: VBA Check or un check Lib ref -Global variables are empt

Post by Jan Karel Pieterse »

The way I do this:

- Minimize use of Project scoped variables (Publicly declared in normal module)
- If we have to (i.e. variables that are expensive to fill up), declare them in one module reserved just for that (in my case called modGlobals)
- Use the gbVarsOK variable so you have a quick check if re-initialisation is needed
Regards,

Jan Karel Pieterse
Excel MVP jkp-ads.com

User avatar
Doc.AElstein
BronzeLounger
Posts: 1499
Joined: 28 Feb 2015, 13:11
Location: Hof, Bayern, Germany

Re: VBA Check or un check Lib ref -Global variables are empt

Post by Doc.AElstein »

Jan Karel Pieterse wrote:The way I do this:
I just made my first worksheet named “Globies”. I think that will do me for most stuff.
I will probably do something like you suggest for a few larger global arrays I have, ( or rather any arrays of 2 dimension: I find that single “ breadth” rows or single “breadth” columns load and paste out very quickly, or quick enough for anything I have needed)
Alan
P.s. I am not sure why something like referring like this
ThisWorkbook.Globvariable
Or
Sheet1.Globvariable
is not considered a “Project scoped variable”. I realise that technically it is a Property thing, but to all intents and purposes I think it can be considered a “Project scoped variable”

( For those to work as “Project scoped variable” , then they would need to be declared as Pubic in the respective class code module and not Private )
Pubic Globvariable As _____

I suppose it is just definitions .....
I am having difficulty logging in with this account just now.
You can find me at DocAElstein also