I worked this scheme up as a solution for a project that needs a way to move back and forth between different batches of variable values in a manageable way. There may be better ways to handle this but here is what I have been experimenting with…
Using Dictionaries to Retain Multiple States of Several Variables
There may be situations where you would like to revert back to some previous state when a batch of variables contained different values than they currently have. Here is a method to move multiple variable values back and forth via dictionaries en masse.
Create a dictionary in the .Initialize procedure containing the future variables as keys along with their starting values:
letfileglobal dVariables=initializedictionary( "First", "Something","Second", "Another thing", "Third", 254)
Note: You can also make them permanent variables using letpermanent
instead of letfileglobal
.
Now you can create all the actual variables along with their starting values directly from the dVariables dictionary using dumpdictionaryquoted(
and changing the carriage returns to commas:
execute "makefileglobals "+replace(dumpdictionaryquoted(dVariables),cr(),",")
This code will execute as:
makefileglobals First="Something",Third=254,Second="Another thing"
Note: That the dictionary does not return the keys in any particular order.
At any point we can change the dictionary key values or the actual variables. To change one or more key values use this standard code:
setdictionaryvalue dVariables, "First", "Nada", "Second", "Mucho", "Third", 389
Then to transfer these values to the actual variables in forms, execute the standard output of dumpdictionaryquoted(
:
execute dumpdictionaryquoted(dVariables)
☞ This executes the following statements:
First="Nada"
Third=389
Second="Mucho"
Now execute showvariables along with the listdictionarykeys(
output which is also a list of the variable names (changing the cr()'s to commas):
execute "showvariables "+replace(listdictionarykeys(dVariables),cr(),",")
☞ This execute this statement:
showvariables First,Third,Second
You can also first change the variables and then transfer those values to the dictionary:
setdictionaryvalue dVariables, "First", First, "Second", Second, "Third", Third
Note: The key values above are not quoted and thus use the actual variable values.
So why bother with all this? In my case I wanted to have a way to step back in the recent history of the various variable values taken at different points. I can have multiple versions of the variable dictionaries so I can choose a previous version and populate the actual variables to those past values at any time. I created a fileglobal variable I name dicVersion and set that to 1. I can capture the current state of the variables to a new dictionary with this:
execute "letfileglobal dVariables"+str(dicVersion)+"=dVariables"
dicVersion = dicVersion +1
☞ This creates a new dictionary named dVariables1 set to the
values of the dVariables dictionary and increments the
dicVersion variable.
Additional dictionaries can be created along the way using:
execute "letfileglobal dVariables"+str(dicVersion)+"=dVariables"+str(dicVersion-1)
dicVersion = dicVersion +1
☞ This would create a new dictionary named dVariables2 with the same
values as dVariables1.
To update all the variables to match a chosen dictionary and update forms you only need to run this (using dVariables1 in this case):
execute dumpdictionaryquoted(dVariables1)
execute "showvariables "+replace(listdictionarykeys(dVariables1),cr(),",")
If you want to eliminate any later dictionary versions you only need to reset the dicVersion variable back to an earlier number and optionally undefine the dictionaries you no longer need. For only a few variables as used in my example this is overkill but it is handy if you have to keep a handle on ten, twenty or more variables along the way.
Additional Idea: Record to Dictionary
This code will copy the current record to a dictionary retaining all the original data types (i.e. text, numeric, date or binary) unlike the exportline( function which converts everything to text.
Local recordDictionary
looparray info("fields"),cr(),element,index
field element+""
If index=1
initializedictionary recordDictionary,
quoted(element+""),fieldvalue("",element+"")
else
setdictionaryvalue recordDictionary,
quoted(element+""),fieldvalue("",element+"")
endif
endloop
Now the dictionary contains the quoted field names along with the values for each one. I don’t know what you could use something like this for but it seemed interesting to me at the time.