Separate Sets of Variables? [Solved]

Thanks @tiffle

Yes, that's what I was suspecting and probably why I've been going in circles...

Fortunately it's not too difficult to make a copy of the the two Macros and bulk rename all the Variables with a different value at the front (WSA__Application1 renamed to WSB___Application1 and so on) using @JMichaelTX's excellent Variable renaming Macro found here:

1 Like

Yes, @JMichaelTX is some kind of magician :wink:

2 Likes

There is another option that might work ok for you. I think you could leverage it to at least minimize the number of variable renames you have to do.

Dictionaries allow you to group related values together. So you could have a Set1 containing Size, Position, Area and Weight values, and Set2 containing different values for the same name. Then anywhere you want to use those values you could set a regular variable to contents of the Dictionary. You can use a variable for the set number to decide which dictionary to use.

https://wiki.keyboardmaestro.com/manual/Dictionaries

So, an example of creating a dictionary where the user enters a Set number:

Then in any other macro where you wanted to use that set of values, set a variable to contain the set number, then assign the values to the variables:

Thank you @kvanh for putting all the time in to help me with this. I will try Dictionaries tomorrow as it looks like that is going to be the way forward.

I generally don't like KM Dictionaries, but I think this is a great use case for them. I was going to suggest using a KM Global Variable that contains tab-delimited data for each set, and retrieve using RegEx.

Just for comparison, here's my approach of using a RegEx Table Lookup:

You store ALL of the set data in one KM global variable, which is a lookup table:

image

Example Output

image

Below is just an example written in response to your request. You will need to use as an example and/or change to meet your workflow automation needs.

Please let us know if it meets your needs.

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

MACRO:   How To Use Different Sets of Data [Example]

-~~~ VER: 1.0    2021-05-26 ~~~
Requires: KM 8.2.4+   macOS 10.11 (El Capitan)+
(Macro was written & tested using KM 9.0+ on macOS 10.14.5 (Mojave))

DOWNLOAD Macro File:

How To Use Different Sets of Data [Example].kmmacros
Note: This Macro was uploaded in a DISABLED state. You must enable before it can be triggered.


ReleaseNotes

Author.@JMichaelTX

PURPOSE:

  • Demo How to Use Sets of Data using RegEx Table Lookup

HOW TO USE

  1. First, make sure you have followed instructions in the Macro Setup below.
  2. See the below "How to Use" Comment Action
  3. This macro is just an example written in response to your request. You will need to use as an example and/or change to meet your workflow automation needs.

MACRO SETUP

  • Carefully review the Release Notes and the Macro Actions
    • Make sure you understand what the Macro will do.
    • You are responsible for running the Macro, not me. ??
      .
      Make These Changes to this Macro
  1. Assign a Trigger to this Macro .
  2. Move this macro to a Macro Group that is only Active when you need this Macro.
  3. ENABLE this Macro, and the Macro Group it is in.
    • For more info, see KM Wiki article on Macro Activation
      .
  • REVIEW/CHANGE THE FOLLOWING MACRO ACTIONS:
    (all shown in the magenta color)
    • CHANGE To Your Set Data
      • Format:

REQUIRES:

  1. KM 9.0+ (may work in KM 8.2+ in some cases)
  2. macOS 10.12.6 (Sierra)+

TAGS: @Example @RegEx @TableLookup

==USE AT YOUR OWN RISK==

  • While I have given this a modest amount of testing, and to the best of my knowledge will do no harm, I cannot guarantee it.
  • If you have any doubts or questions:
    • Ask first
    • Turn on the KM Macro Debugger from the KM Status Menu, and step through the macro, making sure you understand what it is doing with each Action.

This looks very good - and not too many steps.

So, I am assuming the approach could be to first gather all the individual bits of Data to Variables and then use those Variables to build the Monster DND_Object_Sets Variable? And then from there call the individual Sets as needed using a version of your Example Macro.

What I am tying to figure out is how to build DND_Object_Sets Variable on the fly for each of the Sets.

I can see how I could incorporate this at the start of a Macro 2 to choose between say 3 Sets of Data. For example, at the head of Macro 2 I choose Set02 and that Set of Data is used for the rest of the Macro.

But how would I tell Macro 1 to overwrite the Data for just Set02 when I run it without also overwriting Set01 and Set03?

And this sounds like it should work too. The Dictionary being a kind of version of DND_Object_Sets - a single file with all the Data in, broken down into Sets of Data?

But I just can't understand the logic of how these Dictionaries work.

Again, I think I am creating confusion for myself by not uploading examples of my actual Macro elements. I didn't do that because the Macros are quite long.

But I have now uploaded the Group of Macros to the Macro Library on the Forum as they are stable and working as they are.

They save Workspaces on the fly that I might need to restore at a later date. In their present form they work well (for me at least) and have have been very useful. But they only Save and Restore a Single Workspace. To have them store and restore Multiple Workspaces I have been copying the Group and bulk changing the Variable names (as I mentioned earlier). This allows me to have my Sets of Workspaces to Save and Restore to - but it does mean if I edit any one of the Macros I have to edit it in all the Groups.

The ideal would be to have just one Macro that does the Saving and tell it at the start which Set to Save to. And just one Restore Macro and tell it at the start which Set to Restore.

Dictionaries work very similarly to Arrays (this is in programming in general) except instead of having a number as the index into the values you have a name. This is called a key-value pair. The dictionary name groups the keys and values together.

So in a traditional array you have multiple values like so:
array_name = (value1,value2,value3)
and can access individual values with
new_var1 = array_name(1)
new_var2 = array_name(2)
new_var3 = array_name(3)
(note, arrays in most languages are zero indexed (first value is at index 0, not 1) so this example isn't exact for them)

In a dictionary instead you name each entry and assign it's value to that name.
dict_name[key1]=value1
dict_name[key2]=value2
dict_name[key3]=value3

then you use the same dictionary/key name to recover the value
new_var1 = dict_name[key1]

In KM accessing dictionaries as a token via:
%Dictionary[dict_name,key1]%

One of KM's super powers is the ability to expand tokens in a variable name then use the result as new variable name, the % can make it hard to read, but it is absolutely a fabulous feature.

varDictName = "Set1"
%Dictionary[%Variable%varDictName%,key1]%

Now your token can refer to multiple dictionaries just by changing the varDictName to be the name of the dictionary you want to use. Or if you just want to embed a number:

varDictNum = 2
%Dictionary[Set%Variable%varDictNum%,key1]%

You can do the same with key names and use variable substitution to change which key you're looking at (I rarely use this).

If in KM you ever need a "true" array, just make your key names into numbers:
secretArray[1] = array_value_1
secretArray[2] = array_value_2
secretArray[3] = array_value_3

This is closer to a true array but can have differences like the numbers don't have to be consecutive and deleting an item leaves a hole, the indexes aren't renumbered.

1 Like

So, I think I am beginning to get this. When I thought of a "Dictionary" I was thinking all the Variables in my Macro would end up stored in one big Dictionary.

But it looks like I can make a "Dictionary" for each Variable I want to store and "Key" number for what actual Data Sets I want them to store or reference?

So, for my Macros I might set up:

"Dictionary Left" to store the left coordinate of a Windowas a number.
"Dictionary Top" to store the top coordinate of a Windowas a number.
"Dictionary Width" to store the width of a Windowas a number.
"Dictionary Height" to store the height of a Window as a number.

And then use the "key" number to allow me to store different values to each Dictionary.

So "Dictionary Left" would have a choice via the "key" number.

Something like "Dictionary Left" "Key 1" (or "Key 2" etc)

I know the syntax is not right for Keyboard Maestro but is this the concept?

Yes, that would work. It's more like the traditional array you were looking at to begin with.

Another option is to group all the related coordinates together in a single dictionary and have multiple dictionaries for each window.

Let's suppose you want to save the coordinates for 2 window both the methods work.

Method 1 dictionary per coordinate, key name is window name:
dict_left[Win1] = window_1_left_coordinate
dict_left[Win2] = window_2_left coordinate

Now your dict_left can store the left coordinate for as many windows as you want. Just add a new Key name for the new window. Expand by creating a dictionary for each of the other coordinates and use the same key name:

dict_top[Win1]=Window_1_top_coordinate

Method 2: Dictionary per window, all coordinates in that dictionary:
dict_Win1[Left]=Window_1_left_coordinate
dict_Win1[Top]=Window_1_top_coordinate
dict_Win1[Width]=Window_1_width_value
dict_Win1[Height]=Window_1_height_value

Now to store a new window just create a new dictionary name:
dict_Win2[Left]=Window_2_left_coordinate

Which ever method makes the most sense to you should work.

1 Like

Yes. If you will give us an example of how you get your source data for each object maybe we could make some suggestions.

Add Set

You can use the Set Variable to Text action with the "Append" option (set in the Gear menu).

Assuming that you have set the "Local__..." variables from your source object:
image
NOTE: The variables are separated by TAB character. Everything is on one line. The KM Editor shows a soft word wrap that will NOT be in the data.

Update Set

You would use a KM Search and Replace action

Assuming that Local__SetID_ is "Set02"
image

I have several Macros that use this design and they work very well.

Questions?

Thank you @kvanh and @JMichaelTX
I can see two solutions here both equally promising. Is there any way to mark both as "the solution" in this thread?

Eureka! I have it now.

For my use this approach works (in this example to Save and Recall the name of the Front Application).

(VAR__ and DCT__ at the start of the Variable and Dictionary names are purely for my own annotation so that I can clearly see what is a Variable and what is a Dictionary.)

To Set a Value

To Recall a Value

The moment it became clear, was linking the method of creating a Dictionary Value to the method of Recalling a Value from it. And the fact that the Key could be a Variable is the solution to my problem.

So, the Dictionary becomes a fancy Variable that allows different values to be saved and recalled governed by a Key - which is what my question at the start of this thread was asking.

The Wiki page confused me because the example it uses for Storing is different to the example it uses for Recalling:

I'm trying to work out Shop Prices and Drink types and Costs that are saved in a Dictionary and then given First Names and Persons as the Recall Example :thinking:

Anyway thank you so much to @kvanh, @tiffle and @JMichaelTX I think I am there now.

3 Likes

Yes, that isn’t very helpful. It should end with the same example it started with. Maybe the wiki can be tidied up?

Anyway - good job getting your head around it :smiley:

1 Like

Congrats to finding a solution that works for you.
:+1:

1 Like

At present the Wiki says this:

I think I would have been a lot less confused if the Wiki had said something more like this:

3 Likes

I agree, that would be clearer.

@peternlewis @JMichaelTX - can the wiki be updated along these lines please?

That will have to be a job for @peternlewis, since I barely understand KM Dictionaries, and almost never use them.

Keyboard Maestro's dictionaries are an extreme PITA to create and maintain.

I'd much rather use a plain text table or a JSON object.

-Chris

2 Likes

I would be more than happy to make the small suggested edit changes to the Wiki myself (but I don't think I have the privileges needed to do that?) as I have found the Dictionaries to be genuinely useful in the last week - having never tried them before. I am sure others would find uses for Dictionaries too and that many have probably given up at the first hurdle.

1 Like

If you would like to post a Topic in the Wiki Category (sub-forum) with your proposed changes, I would be happy to apply them to the actual KM Wiki.

1 Like