Jump to content
Macro Express Forums

Saving Variables - A Dead Horse? Or Still Hanging On?


Recommended Posts

Edited at the top for new-comers:

If you're having Save/Restore problems (as I was), please read through the helpful information provided by Cory, Jim, and Paul below. Their advice about using Registry Keys has been enlightening and has hopefully put me on the path to success. I'd been changing my Save/Restores to Save variable to file/Set variable from file contents. Which is essentially what Reading/Writing to reg. keys appears to be, but it's more hidden. Assuming I'm doing it right. So far, so good. My computers are still working :) Thanks guys!

 

I hate to beat them when they're dead... eh, I hate beating them when they're alive. But this sucker just keeps rearing its ugly head. And I know it's probably not the horse's fault, but I just can't seem to wrap my ugly head around this.

 

I have a variable that I set to, let's say Bank 001 while I'm working on Bank 001. This variable is called %PreviousBank%

 

When I finish working on Bank 001, my main application automatically starts loading Bank 002.

 

I have a macro (let's call it New Account Macro )that runs every time a new account enters the main application and it detects which bank that account belongs to and assigns that bank name to the variable %CurrentBank%.

 

The macro then compares the two variables. If they match, it moves on, finishes loading information so I can do my work. If they do not match, the macro runs a sub-macro which activates an assistant application and changes the bank it is set to from %PreviousBank% to %CurrentBank%. %PreviousBank% simultaneously gets updated with the new bank ID.

 

The macro works fine, mostly. But occasionally, when New Account Macro runs, it checks %PreviousBank% and finds the variable empty. I've tried adding a delay after the Restore Text Variable command, but that hasn't helped.

 

All I can figure is that I must be Restoring Text variables at some point in another macro, and then not saving them later, so the data is being lost. Does that sound likely? Is that how the Save/Restore functions are working against me? If so, I should be able to just track down which macros I'm using in between and find the hanging Restore that needs a closing Save... or eliminate the Restore altogether (I've found I just don't need them as much as I used to).

 

Thanks for any input.

Link to comment
Share on other sites

I think you're on the right track Steve. Something else is wiping out that variable. But beyond that here are my 4 cents.

 

First 2¢: You never need to use delays to wait for variables to be propagated. MEP will not move forward until the action is complete. IOW no matter how fast things go you can not be to quick in moving forward.

 

Second 2¢: IMHO with the new variables there is no more need for the variable save/restore commands. That is to say in the way we had been using them for sub-macros and such.

Link to comment
Share on other sites

I think you're on the right track Steve. Something else is wiping out that variable. But beyond that here are my 4 cents.

 

First 2¢: You never need to use delays to wait for variables to be propagated. MEP will not move forward until the action is complete. IOW no matter how fast things go you can not be to quick in moving forward.

 

Second 2¢: IMHO with the new variables there is no more need for the variable save/restore commands. That is to say in the way we had been using them for sub-macros and such.

Thanks Cory, I believe your first 2 cents, and I'm removing the delay (it wasn't helping anyway).

 

I just ran the macro in question 4 times in a row for the same account (it has a manual run option). The first two times it ran as though there were no contents within %PreviousBank%. The 3rd time it ran fine. The 4th time it failed to find any info in %PreviousBank%. Something is wrong with the Restore Variable function.

 

As for the second 2 cents: I have finally started to grasp that fact. But I do believe it is necessary for this particular set of macros.

 

Here's the why:

 

When New Account Macro runs it needs to compare the bank associated with the freshly loaded account against the bank loaded into my assistant application (attempting to access a Bank 002 account when Bank 001 is loaded results in a crushing headache). The only quick and consistantly reliable (or what used to be reliable) way of doing that is to have whichever bank is loaded into the assistant application stored in a variable.

 

Here's a dumbed-down version of the macro as it stands (all pertinent commands are shown, actual processes for making the change to the assistant application have been reduced to a "Change Bank" command)

Macro Start
Restore Text Variables
Set Text Variable %CurrentBank% from Title
If %CurrentBank% = %PreviousBank%
 Macro Stop
Else
 Activate Assistant Application
 Change Loaded Bank to %CurrentBank%
 Set %PreviousBank% to %CurrentBank%
 Save Text Variables
End If

 

The next time I run this macro, the Restore Variables command should put something into %PreviousBank%, whether it's Bank 001 or Bank 002 etc. is not the issue... the problem is that the variable is coming up empty.

 

It's very inconsistent about it, too. Sometimes there is something there, sometimes there isn't. Even when no other macros are being run between instances of running this macro.

 

Obviously, I need to build a simpler macro that I can duplicate these results with so that I have something concrete to report to ISS, because this is extremely annoying, and since it's inconsistent, and my actual macro relatively complex (and relies on various internal applications), my exact macro won't help them much.

 

 

 

EDIT -

I'm a single straw away from replacing the Save Text Variables with a Save Variable to File command, and replacing the Restore Variables with a Set Variable from File command. I'm sure that will work, but I was under the impression that the Save/Restore function was designed to help avoid such a bother.

 

Cory, if you have a way to work around the Save/Restore (other than the one I just mentioned) for macros such as the one described above, could you let me in on the secret, please?

Link to comment
Share on other sites

I also have difficulties wrapping my head around how to successfully pass Macro Express variables from one script to another in version 4. However, I have managed to get many of my scripts to work properly by (reluctantly) removing called macros that mess around with variable values. It means that my scripts are longer, more difficult to debug, and more awkward to modify... but at least they do exactly what I expect.

 

I will continue to experiment with macros that pass variables from one macro to another, but for the moment, I will live with this inconvenience.

Link to comment
Share on other sites

I've had some success with reading/writing essential variables into the Registry, especially if there are values I wish to retain between runs of a macro. I've manually created a key specific to my macros [HKEY_CURRENT_USER\MACROS\**Macro.Name**\**Key.Values**] then am able to use the same path to store many of my "important" variables. [i prefer to create the keys and values manually before writing my macro, and not bother MEP with "Create Registry Key/Value" commands.]

 

Joe Weinpert did a good job explaining the Registry commands in Macro Express Explained, and I started utilizing the Registry with ME3. MEP works the same way, and I haven't had any problems with corrupting the Registry in either ME3 or MEP.

 

 
Read Registry Value "HKEY_CURRENT_USER\MACROS\Bank\Previous Bank" into %Previous Bank%
Variable Set String %Current Bank% from title
If Variable %Previous Bank% Equals "%Current Bank%"
 Macro Stop
Else
// Change gears for the new bank.
 Write Registry Value "%Current Bank%" into HKEY_CURRENT_USER\MACROS\Bank\Previous Bank
End If

 

Still, it's the Registry, so tread lightly. ;)

Link to comment
Share on other sites

I find myself hesitating on how to explain how not to use the save/restore, you simply don't. The only potential problem is if they use the same variable names but even then that only applies to the variables you need to reference in each. Let's say I have 10 variable in the parent macro. In the parent macro I run a sub-macro that counts the number of PDF files in a folder. In this case I probably have 8 local vars in the parent and 2 global named, say, %Folder Name% and %File Count%. In the submarco I will have half a dozen local vars and a couple global, %Folder Name% and %File Count%. So if I have a local var for %Extension% or %Counter% in the parent macro and want to use those same names in the sub-macro it's all good.

 

Now for the life of me I can't figure out how all the local and global applies to your problem though and I've tried to figure out how it could even possibly work. When the macro starts there is no values in any of the vars. It look like you are using the Variable Restore to load variables form the previous session. I didn't know this was even possible but if that it what you're doing it's a real bad approach. What if you use the save/restore for something else? Will it not wipe out what you're doing? So I'm abandoning what you wrote and will tell you how I do things like this.

 

Often I keep track of things for users and one good example is the last Client they worked on and this sounds similar. My approach is that at the end of the macro I save the Client ID to a registry value. It's best to use the HKey Current User BTW. EG I save the string to HKEY_CURRENT_USER\Software\Insight Software Solutions\Macro Express 4\Misc\Last CID. Now the next time I run the macro the first thing I do is seed the %CID% var with the value from the registry. This is the most sensible way I can think of to accomplish this. I mean this is what the registry was designed to do.

 

And I believe the reg is the best place to do this as well since it's lightning fast since the OS has it loaded into memory at all times. It's a database and this is what databases do well. Much better than saving to a file even though with modern caching that's really fast too. Now one place I do use INI files instead is when that saved value needs to be shared between multiple machines or profiles. Let's say we're assigning new CIDs and we have 10 users doing so. Well in that case we need to keep the last CID issued in a common location so all can access and increment it.

Link to comment
Share on other sites

I've had some success with reading/writing essential variables into the Registry, especially if there are values I wish to retain between runs of a macro.
Steve, what Jim says is right on. I had not read it before I posted last. And he makes a good point that you do not need to create keys and values before using them, like directories with a file copy they will be created for you.

 

One important caveat however is that in some cases you do need to clear recycled variables. I just learned this one. Let's say I set the var %Temp% to "Ted" and then read a registry value that's supposed to contain a name. But in this case the value does not exist. %Temp% is not nulled out but rather remains "Ted".

Link to comment
Share on other sites

Steve, what Jim says is right on. I had not read it before I posted last. And he makes a good point that you do not need to create keys and values before using them, like directories with a file copy they will be created for you.

 

One important caveat however is that in some cases you do need to clear recycled variables. I just learned this one. Let's say I set the var %Temp% to "Ted" and then read a registry value that's supposed to contain a name. But in this case the value does not exist. %Temp% is not nulled out but rather remains "Ted".

Thank you both, Jim and Cory.

 

I hesitate to touch the Registry, as I'm far from a programmer (and I don't know that I could, even if I knew what I was doing, on my work computer... though maybe this is something I can do without admin rights; I really don't know). But I do have ME Explained, so I'll read through any info I can on how the Registry works with ME and how I might be able to make this function for me.

 

It look like you are using the Variable Restore to load variables form the previous session. I didn't know this was even possible

This is what I've always used Save/Restore for. It's what I thought the commands were designed to do (besides porting variables content from one macro to another).

 

From the ME Help pages: "The Variable Save command saves the values of variables set in the macro to system memory."

 

Is this not precisely what writing to the Registry does? Saves the content of the variable to the Registry so that on a follow-up run of the macro it would be able to pull the same information as was saved? I imagine saving it to the registry would allow it to still be there after a reboot or a termination of MEP, but still essentially the same content, right?

 

I never used to have this kind of problem with Save/Restore. I've been using this particular macro for well over a year in ME3. The PreviousBank variable was saved to %T96%, the CurrentBank variable was saved as %T95%. I never once had a problem with the Save/Restore making the comparisons. All I've really done, besides transferring the macro over to MEP is change the names of the variables.

 

For the time-being (while I research the Registry options), I'm converting my Save Variables command to a Modify Variable > Save to File and my Restore Variables command to a Set Variable from Contents of File. It's not elegant, but it works.

 

And if I've been misusing Save/Restore (which I may well have been), and it's real purpose was simply for moving the contents from Macro A to Macro B within a sub-macro routine, then I suppose it makes sense that it is no longer a worthwhile command-set, other than for use in un-modified ME3 conversions.

 

Again, thank you for your valuable input. I'll learn all I can about the registry options and see if I can't do what I've been doing, but via the correct tools.

Link to comment
Share on other sites

1) If you want to run a macro using MeProc.exe and pass parameters, then you must use Variables Restore in your macro.

 

2) If you want Macro1 to call Macro2 without waiting for Macro2 to finish, then any of Macro1's variables that Macro2 wants to use must be saved in Macro1 and restored in Macro2.

 

3) If you want to share variables beteen MacroA and MacroB without having MacroA call MacroB (waiting for it to finish), then the same considerations apply as in point 2 above.

 

Otherwise, I cannot see any reason to use Variables Save and Restore in MEP.

Link to comment
Share on other sites

Otherwise, I cannot see any reason to use Variables Save and Restore in MEP.

Well, in my case (which is similar to your reason 2).

 

While Macro A isn't calling Macro B, per se, Macro A does need to access information gathered during it's previous run, and compare it to the information being gathered in its current run.

 

This, to my mind, is a reason to use Save/Restore (which I have done successfully for years); but it is now coming to my attention that this is not what Save/Restore is intended for and I may need to write the 'previous' information to the computer's registry... which honestly seems dangerous and like over-kill when something as simple as Save/Restore has worked so well for so long.

 

Picture a red dot in the middle of the screen:

 

Restore Variables (the first time this macro runs: %Var1% = "" & %Var2% = "")

Get Pixel Color from the dot location

Set %var1% to pixel color at dot location (Red).

If %Var1%(Red) <> %Var2%("")

__Text Box Display: "Dot has changed colors!"

Else

__Macro Stop

End if

Set %Var2% to %Var1%

Save Variables

 

 

In this example, the next time the macro is run, %Var1% and %Var2% will both equal red. The macro will stop. However, if the dot changes to blue, then %Var1% will no longer = %Var2%, and the text box will display that the "Dot has changed colors!"

 

It's not complicated, and it has always worked until yesterday. I am surprised that nobody else on the board has thought to use Save/Restore in this fashion, but then I guess I've been using the back-side of an axe to hammer in nails... it mostly works, but it isn't the right tool for the job. In the mean-time, my work-around is to use a sledge-hammer while figuring out how to hold a regular one.

Link to comment
Share on other sites

In our PGM Library we save variables up to a maximum limit of 16 versions (akin to a stack 16 levels deep)! Thus, starting with n1=0, we can increment n1 16 times, each time saving our variables anew. On the 16th occasion, n1 will equal 16. The mere act of restoring to the previous level has the effect of decrementing n1 by 1.

This works well, one major reason being that the variables we can save and restore are known in advance, i.e. n1-n100, t1-t100 and d1-d100.

 

But today the sky's the limit. You can call your variables anything you like, and there are more variable types. This would make the task of rewriting the stack concept very difficult to accomplish if not impossible (unless, of course, we were to restrict such variables to a known set, e.g. n[1]-n[100], etc - this approach would impose constraints on our users which they would probably find unacceptable).

 

I can imagine it's quite hard for MEP to keep track of all the variables it needs to save and restore. Furthermore, relying on this single-set save and restore may tend to be very restrictive because a save done by one macro at a given point in time can easily be overwritten by another save done by the same, or a different, macro at another time. Don't forget - all variable saves and restores maintain only a single set of variable values, whcih are global to all macros at all times (I'm excluding consideration of local variables here).

 

I recommend you familiarise yourself with the registry (it is intended for precisely the sort of purpose we're discussing). If you reserve for yourself one or more keys within the HKCU section, you are unlikely to do any damage (I always think the warnings that accompany any registry edits are exaggerated and tend to put people off unnecessarily).

 

Alternatively, you might want to consider the use of .ini files because ME has quite a useful set of commands dealing with sections within such files.

Link to comment
Share on other sites

Otherwise, I cannot see any reason to use Variables Save and Restore in MEP.
Perfect examples Paul, I had not considered these but that's mainly because these are very esoteric applications not likely encountered by the casual users.
Link to comment
Share on other sites

Steve... Your killing me man. Please do me one little favor and just try saving a simple item to the registry and read it back. I guarantee you once you get over your phobia you will slap yourself in the head and thank me. Check out the attached file.

 

The registry is your friend and is no more dangerous than the file system. In fact they are very analogous with respect to risk. Would you start creating, and deleting files in the c:\windows\system32 folder? No way, danger zone. But if you created your own folder named c:\Temp4Steve you wouldn't be afraid now would you? Same with the registry. The registry is simply a database made up of several hives. Each hive has a separate purpose but to keep life simple for you look at HKLM (HKEY_Local_Machine) and HKCU (HKEY_Current_User). Use HKCU most of the time but if you ever need to save something for all users on one machine consider HKLM. Also if in Vista you might not be able to write to HKLM. There is a Miscellaneous key in the Macro Express 4 key I like to use because I know it will always be there and it's blank. Keep yourself in there and you can do no harm. Remember the registry was developed to replace INI files which is essentially what you're trying to do. It was meant for you, try it out!

 

Oh, click here and check out the Wiki on the reg, it's a good read. Also I would like to stretch my metaphor above. In the registry you have hives as the top level like HKLM and then under that keys are like directories and values are like files. That's not 100% right but I think it would help you initial understanding.

 

And there is no way variable save is like the registry. With the reg you can save singular or multiple vars but with the Variable save/restore it's the whole kit and caboodle. Also let's say your user is working away and logs off for the evening, if you use the reg the macro will remember when they start up again. Not something Var Restore will do. Also let's say you have 20 macros that like to remember things from day to day, this is impossible to manage with Variable Save/Restore.

 

Just give it a shot and if you don't slap your forehead with the realization of all the capabilities in the next coupe of days I'll buy you a beer.

Reg4Steve.mex

Link to comment
Share on other sites

Steve... Your killing me man. Please do me one little favor and just try saving a simple item to the registry and read it back. I guarantee you once you get over your phobia you will slap yourself in the head and thank me. Check out the attached file.

 

The registry is your friend and is no more dangerous than the file system. In fact they are very analogous with respect to risk. Would you start creating, and deleting files in the c:\windows\system32 folder? No way, danger zone. But if you created your own folder named c:\Temp4Steve you wouldn't be afraid now would you? Same with the registry. The registry is simply a database made up of several hives. Each hive has a separate purpose but to keep life simple for you look at HKLM (HKEY_Local_Machine) and HKCU (HKEY_Current_User). Use HKCU most of the time but if you ever need to save something for all users on one machine consider HKLM. Also if in Vista you might not be able to write to HKLM. There is a Miscellaneous key in the Macro Express 4 key I like to use because I know it will always be there and it's blank. Keep yourself in there and you can do no harm. Remember the registry was developed to replace INI files which is essentially what you're trying to do. It was meant for you, try it out!

 

Oh, click here and check out the Wiki on the reg, it's a good read. Also I would like to stretch my metaphor above. In the registry you have hives as the top level like HKLM and then under that keys are like directories and values are like files. That's not 100% right but I think it would help you initial understanding.

 

And there is no way variable save is like the registry. With the reg you can save singular or multiple vars but with the Variable save/restore it's the whole kit and caboodle. Also let's say your user is working away and logs off for the evening, if you use the reg the macro will remember when they start up again. Not something Var Restore will do. Also let's say you have 20 macros that like to remember things from day to day, this is impossible to manage with Variable Save/Restore.

 

Just give it a shot and if you don't slap your forehead with the realization of all the capabilities in the next coupe of days I'll buy you a beer.

Cory, Paul, and Jim,

 

Thank you for being patient with me. I really want to learn this stuff, and I have every intention of thoroughly reading up on this in ME Explained. I'm going to download and test out that .mex you provided, too, Cory, and play with the Registry (safely). I've seen so many threads discussing using the registry that I'm surprised I haven't looked more closely before now.

Link to comment
Share on other sites

I've had some success with reading/writing essential variables into the Registry, especially if there are values I wish to retain between runs of a macro. I've manually created a key specific to my macros [HKEY_CURRENT_USER\MACROS\**Macro.Name**\**Key.Values**] then am able to use the same path to store many of my "important" variables. [i prefer to create the keys and values manually before writing my macro, and not bother MEP with "Create Registry Key/Value" commands.]

 

Joe Weinpert did a good job explaining the Registry commands in Macro Express Explained, and I started utilizing the Registry with ME3. MEP works the same way, and I haven't had any problems with corrupting the Registry in either ME3 or MEP.

 

 
Read Registry Value "HKEY_CURRENT_USER\MACROS\Bank\Previous Bank" into %Previous Bank%
Variable Set String %Current Bank% from title
If Variable %Previous Bank% Equals "%Current Bank%"
 Macro Stop
Else
// Change gears for the new bank.
 Write Registry Value "%Current Bank%" into HKEY_CURRENT_USER\MACROS\Bank\Previous Bank
End If

 

Still, it's the Registry, so tread lightly. ;)

Thanks Jim,

 

This is almost exactly what I've ended up doing, and it seems to be working perfectly!

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
×
×
  • Create New...