A Safer Way to Use TempVars

KitaYama

Well-known member
Local time
Today, 12:29
Joined
Jan 6, 2022
Messages
1,859
Still in new year holidays and having nothing to do, I'm trying to understand what Mike Wolfe's trying to achieve in this article:

https://nolongerset.com/a-safer-way-to-use-tempvars/

It seems that he adds a tempvar and then in the class, he sets a property to read the value of a tempvar and then get its value when needed.
It's 3 steps:
1-Adding a tempVar
2- Using Let property in the class to fill the property's value.
3- Using Get Property to read it

SQL:
Public Property Let MyVar(Value As Currency)
    TempVars("MyVar") = Value
End Property

Public Property Get MyVar() As Currency
    MyVar = TempVars("MyVar")
End Property

What I can't understand is : If there's a class to be used, why using tempvars at all.
Why not simply using the class Let/Get properties without tempvars?
I think the following will do the same, in only 2 step. Setting a value into the property and then reading it when necessary.

SQL:
Private m_MyVar As Currency

Public Property Get MyVar() As Currency
    MyVar = m_MyVar
End Property

Public Property Let MyVar(ByVal iNewValue As Currency)
    m_MyVar = iNewValue
End Property

Thanks for any insight on this.
 
Last edited:
my opinion is that if it is not in Standard (like ISO standard), then it is only an opinion or recommendation.
it is up to you if you want to consume it or not.
 
The name TempVars is ironic as they are more persistent than any VBA variable, holding their value after a VBA reset.

Some people think this is an advantage. I've never used them and never will.
 
The name TempVars is ironic as they are more persistent than any VBA variable
I'm sorry but I don't get your point.
Tempvars are normally used instead of global variables and are meant to keep a value as long as the application is running.
What's wrong with them being persistent?
 
The fact that TempVars hold their values after a VBA reset can be useful but also a mixed blessing.
It masks the fact that an error occurred that may need fixing. Global variable failures can be traced back.
 
If a VBA runtime error is not handled, the VBA variables are reset. TempVar would remain.
One advantage could be that TempVar elements can be used more easily in macros.

BTW: The property procedure does not necessarily have to be in a class, it can also be in a standard module.
 
Last edited:
I also think this is just a gimmick. I've never used TempVars myself.

When considering TempVars compared to global variables, global variables lose their value upon the occurrence of unhandled runtime errors, TempVars do not. However, in a proper application that is passed on, you will find error handling. Or you programmed without errors (= big claim).

If I remember correctly, TempVars were introduced with Access 2007 to improve the work in Macros and, from Access 2010, in DataMacros and to enable value transfer and propagation there. However, since macros and data macros lead a shadowy existence in real applications, TempVars share this role.
Of course, there are always some who believe that if something is available, it must be used. You can already see this with lookup fields in tables.
 
What I can't understand is : If there's a class to be used, why using tempvars at all.
Why not simply using the class Let/Get properties without tempvars?
I think the following will do the same, in only 2 step. Setting a value into the property and then reading it when necessary.
You missed the total point. You can do what you are saying but that would be a lot more work, and you have to re-read the whole article to get the big picture. This takes out a lot of extra work, because he wrote code to write the class from a table and bring in attributes. Now you can modify the table and add properties to your code without writing all the properties. Imagine you wanted 100 tempvars with specific names and data types. You would have to write 100 properties. In this method you put that in a table and it builds your class.

To understand the value of doing this then you would have to implement the whole solution with the described Table. I saw the example was super confusing because of things like myVar, OtherVar and coolbar. I will demo with real useable names.

The idea is in your table would be to define all the "tempvars" you want to store with their data type and if necessary a default value. The beauty is that you can add to the table and regenerate the class. It uses code to build code.

examples in table
VarName, VarType, VarValue

Account_Number String
Payment Currency
UserID long
StartDate Date
PendingApproval Boolean True
ex.

Then you would actually use that to generate/regenerate the class.
now you would have a property for each specific

Now to use it
TV.Account_Number = "ABC"
TV.Payment = 100.00
TV.StartDate = Now

And
msgbox TV.Account_Number

The huge benefit unlike Tempvars is that you know exactly what values are stored using intellisense. With tempvars you do not know how many you have and what their names are.

As stated another benefit is that you cannot provide an incorrect data type
TV.Payment = "ABC"

More importantly you get intellisense so you have visibility
Debug. Print TV. (all values appear)

If you were just using temp vars
TempVars("Payment") = "DOG" would work and not what you want
and No intellisense
TempVars! ' gives you nothing

Your example would work if you added all the of those properties for each value you want to store and a Function to be able to use that class in a query. However, the class would not persist (which is good or bad). His solution provides the big benefit of creating the class based on the values in the table. He could have done this same solution without tempvars by also adding via his code class variables for each property he wrote. (Not sure why he did not go that route instead).

There is also a subtle benefit and this is why you have to import the class not copy and paste. By importing it you can set attributes for that class that you cannot set in VBE. See article

By setting the attribute Predeclared in your code you do not have to set an instance of the class
Say What??? Yep.
you do not have to do something like
set myTV as New TV
then use the myTV instance
myTV.payment = 100

you can immediately do
TV.Payment = 100.00

This is because it created a predeclared global instance. These attributes can only be imported in unfortunately and not written in code. I have no idea why that is.
 
TempVars came from the short-lived attempt to webify Access in 2013. Access Web Apps had no VBA, so all actions needed to be done in Macros. Macros were enhanced to support that purpose. TempVars were introduced as part of that. They live on now, as TempVars in VBA.

Use them or not, they can have a role to play if you want them. I like them in queries, where they replace form references in criteria. I have done so for, well it's 2024, so nearly 10 years I guess. Never had a problem in that time, but as the saying goes YMMV.

With regard to what I think Mike is doing, it sounds to me like a variation on what I've heard called "Self Healing Properties". I suggest you read Mike's article to find out why he suggests it.

Here's another example:

Public Property Get TWIPPI() As Integer

Static lngTWIPPI As Integer

lngTWIPPI = DLookup("AppStringValue", AppString, "AppStringName ='TWIPPI'")
TWIPPI = lngTWIPPI

End Property
 
You missed the total point. You can do what you are saying but that would be a lot more work, and you have to re-read the whole article to get the big picture. This takes out a lot of extra work, because he wrote code to write the class from a table and bring in attributes. Now you can modify the table and add properties to your code without writing all the properties. Imagine you wanted 100 tempvars with specific names and data types. You would have to write 100 properties. In this method you put that in a table and it builds your class.

To understand the value of doing this then you would have to implement the whole solution with the described Table. I saw the example was super confusing because of things like myVar, OtherVar and coolbar. I will demo with real useable names.

The idea is in your table would be to define all the "tempvars" you want to store with their data type and if necessary a default value. The beauty is that you can add to the table and regenerate the class. It uses code to build code.

examples in table
VarName, VarType, VarValue

Account_Number String
Payment Currency
UserID long
StartDate Date
PendingApproval Boolean True
ex.

Then you would actually use that to generate/regenerate the class.
now you would have a property for each specific

Now to use it
TV.Account_Number = "ABC"
TV.Payment = 100.00
TV.StartDate = Now

And
msgbox TV.Account_Number

The huge benefit unlike Tempvars is that you know exactly what values are stored using intellisense. With tempvars you do not know how many you have and what their names are.

As stated another benefit is that you cannot provide an incorrect data type
TV.Payment = "ABC"

More importantly you get intellisense so you have visibility
Debug. Print TV. (all values appear)

If you were just using temp vars
TempVars("Payment") = "DOG" would work and not what you want
and No intellisense
TempVars! ' gives you nothing

Your example would work if you added all the of those properties for each value you want to store and a Function to be able to use that class in a query. However, the class would not persist (which is good or bad). His solution provides the big benefit of creating the class based on the values in the table. You would simply have to do it all manually.

There is also a subtle benefit and this is why you have to import the class. It defines a property of the class that for some reason can only happen if you import the class. See article

By setting the attribute Predeclared in your code you do not have to set an instance of the class
Say What???
you do not have to do something like
set myTV as New TV
then use the myTV instance
myTV.payment = 100

you can immediately do
TV.Payment = 100.00

This is because it created a predeclared global instance. These attributes can only be imported in unfortunately and not written in code. I have no idea why that is.
I was hoping that was what Mike was on about.
 
The value of this code really has little to do with temp vars IMO. In truth you could get rid of the tempvars all together by writing some additional code to create local class variables for each property you create. Re-read it.
The real value is now you have a way to use a table to define all the properties, data types, and default values of a class. Then run the code to create the class.

However, I will admit the articles are poorly written and very confusing. I had to re-read to get the point. It would be a lot better if he started with the table showing the properties to add to code and use real names instead of myvar, othervar, coolvar.
 
The example I posted is table driven, although I'm not sure it's done the same way.

lngTWIPPI = DLookup("AppStringValue", AppString, "AppStringName ='TWIPPI'")
 
The example I posted is table driven, although I'm not sure it's done the same way.
Kind of the same idea, but again you just have to write all of the properties yourself. Not a big trade-off for a few properties. Then, you could get rid of the tempvars and instead use this method in your class. You could also write extensibility to read all your values in the table and create the property in your class, like he did. That is why I am saying the benefit is more about the table used to write the code then Tempvars in general.

I assume you have the setters of the correct datatype that converts the correct data type into a string to store in your table. If not that defeats the type check at runtime. In your table you are saving all values as strings and then converting on the get, let which should give the same benefits.

Also I would do the conversion explicitly not implicitly. VBA does a pretty good job of implicit conversions but I would be safe.
TWIPPI = lngTWIPPI
but I would do it explicitly
TWIPPI = Cint(lngTWIPPI)

Which seems to be a bad name, because your property was designed to handle an integer not a long.

However, your class can lose instantiation if a runtime error. Again, good or bad.
 
His solution provides the big benefit of creating the class based on the values in the table. He could have done this same solution without tempvars by also adding via his code class variables for each property he wrote.
@MajP I think you didn’t read my question carefully or I failed to explain myself clearly.
I’m aware of the way the author used a function to create the class from a table. My question was why he does NEED tempvars at all. As you yourself explained in above statement, it can be done without Templars.

I just thought there maybe a reason behind the scene that the author have. used Tempvars even if it can be done without them.
 
I just thought there maybe a reason behind the scene that the author have. used Tempvars even if it can be done without them.
The big thing, and that is why I asked about if @GPGeorge had Setters.
if doing George's way
1. You would have to have a local table in each front end to store the values of the "temporary variables".
2. You would have to have setters that write to the table
3. You have to clear the table values at load or exit of the db.

If not using a table to store the values and not using tempvars:
1. The author would need additional code to write local class variables for each property
I guess it was just easier not to do that, but they sure could have done that and did away with tempvars. May have made the point more clear.
 
The big thing, and that is why I asked about if @GPGeorge had Setters.
if doing George's way
1. You would have to have a local table in each front end to store the values of the "temporary variables".
2. You would have to have setters that write to the table
3. You have to clear the table values at load or exit of the db.

If not using a table to store the values and not using tempvars:
1. The author would need additional code to write local class variables for each property
@MajP I think this answers all my questions.
I really appreciate the time.
 
Kind of the same idea, but again you just have to write all of the properties yourself. Not a big trade-off for a few properties. Then, you could get rid of the tempvars and instead use this method in your class. You could also write extensibility to read all your values in the table and create the property in your class, like he did. That is why I am saying the benefit is more about the table used to write the code then Tempvars in general.

I assume you have the setters of the correct datatype that converts the correct data type into a string to store in your table. If not that defeats the type check at runtime. In your table you are saving all values as strings and then converting on the get, let which should give the same benefits.

Also I would do the conversion explicitly not implicitly. VBA does a pretty good job of implicit conversions but I would be safe.
TWIPPI = lngTWIPPI
but I would do it explicitly
TWIPPI = Cint(lngTWIPPI)

Which seems to be a bad name, because your property was designed to handle an integer not a long.

However, your class can lose instantiation if a runtime error. Again, good or bad.
I think I first wrote that 10 + years ago, so, yeah, it's not great. Thanks for noting that.
 
The big thing, and that is why I asked about if @GPGeorge had Setters.
if doing George's way
1. You would have to have a local table in each front end to store the values of the "temporary variables".
2. You would have to have setters that write to the table
3. You have to clear the table values at load or exit of the db.

If not using a table to store the values and not using tempvars:
1. The author would need additional code to write local class variables for each property
I guess it was just easier not to do that, but they sure could have done that and did away with tempvars. May have made the point more clear.
No, there are no setters and the values are in a USysTable that is delivered in each front end. I see no reason to empty and reload it. It carries things like the value of a twip, the name of the application, the version number, contact info for the developer supporting it, etc. Those things are a mix of values unique to that application and those values, like the twip, for which a constant is useful.

I think a lot of developers use such tables.

I do not see a lot of value in using tempvars in that situation either, but what I am learning--now that it's too late--is that there are a lot smarter ways to develop in Access than those I learned as a consultant.
 

Users who are viewing this thread

Back
Top Bottom