Need Assistance in making a Macro more efficient

Hello Maestros!

In my journey to be a stronger/wiser/more efficient user of Keyboard Maestro, I go back to many of my older macros and reconfigure/rethink them with better/slicker techniques that I've learned from this forum and from reading the wiki. There is a ton that I don't know even though I've been at this for a while. I was inspired by @JMichaelTX's post, several days ago, when he asked "What is the Best Method to Prepend a Few Lines of Text to a Large File?." At first, I was like "Hell, other than @peternlewis, @gglick, @DanThomas and a handful of other KM superstars - (shrug) I can't help him! - He knows much more than I know about KM and programming than I could help him with." I waited a day and since no one responded, I showed him how I had done it in hopes others would chime in. I figured, people had the same thoughts about helping him as I did or maybe they were afraid. I also thought, I help others, without delay, so why not throw my hand in the pot. What is he gonna do, ban my solution? :slight_smile: Anyway, I posted because as great a KM problem solver and Maestro that @JMichaelTX is, sometimes you just want another opinion. After that, others chimed in with great options. I was happy to break the ice.

Thinking about it later, I wonder if he had a technique that he just wanted to improve on.
Flash back -- I remember a few months ago, @gglick taught me how to select macros, using a prompt list, from a specific macro group. That technique changed 8 of my macros and boosted the efficiency tremendously.. I still owe Gabe a few beers for that one. I've never had or bought alcohol but his help was worth it.

That brings me to today. I have a working macro with nothing wrong with it functionally. It works just as I need it to. I just think there are other techniques, that can be implemented, to make it better and to add to the toolkit. The implementations would help me and others with future macros.

This macro is used for a specific meeting preparation, for work, when using Citrix. Long story but even cutting and pasting won't work for the back and forth.

The Macro does the following:

  1. Allows the selection of data (in this demo’s case, there are 4 selections associated with the macro. The real one has more) using the OCR feature and stores it into a local variable.

Sample data:

CHR0384757:  Make cookies
CHR03848357:  Make a smoothie
CHR0386657:  Bake a cake
CHR0381457:  Start veggie stir fry
  1. After each selection, it will provide a 3 second grace period to select the next line of data. The delay is in case I have to scroll down to another page. As mentioned, each selection saves to a local variable.

  2. Once completed with all four selections, the macro will type the output in a text document. (However, in this demo, it will display in a window)

The simple output looks like this even though it would be in an added to an ongoing work journal:

Meeting Title: Review 
Logged: Wednesday, July 22, 2020 @ 3:24 PM
CHRO384757: Make cookies 
CHRO3848357: Make a smoothie 
CHRO386657: Bake a cake 
CHRO381457: Start veggie stir fry 

That said, I want to know how I can do any of the following concerning the attached macro above. Take a look and please, please, please comment if you have time or suggestions.

My ask --- Here are the specific areas that I'd like to improve:

  1. Improve on the efficiency of steps/code.
  2. Can the variables, in the macro be dynamically created - Local_CR1 - Local_CR4 or even up to Local_CR10? In this macro there are 4 macros with the following sets. Basically, can a For Each action be created to reference a list of Local_CR variables 1 - 10 to plug into OCR save to variable area? Or do I have to declare the variable as I've done.
  3. I know there is a Repeat action and other looping actions but could this be done better.
  4. Any other specific techniques you would employ to make this better?

Snapshot of the actions in question - please expand the macro to see the same steps for the other variables:

Basically, I'd just like to know how I can make this more efficient and/or what would you do differently?

Sorry for the long post and Thanks for your time.

P.S. - Don't be afraid to please chime in!


1 Like

For #2, yes, the variables can be dynamically created. Check out this Wiki entry: About half-way down, see the section "How To Use Dynamic Variable Names".

Note that the examples are fairly complicated, because they show all sorts of scenarios. But if you're patient and work through them, you'll see how it works.

So in essence you could set a counter to 1, then do a "Repeat" loop and use the counter to construct the variable name. Then add 1 to the counter before the bottom of the "Repeat" loop.

Focus on building the variable names first. Then focus on setting them to something. Then reading their value. One step at a time.

Have fun!

My first rule with existing code: If it ain't broke, don't fix it..

I have plenty of new projects to work on without rewriting a macro or script that is working fine. Even if it was a bit slow, I would not mess with it until it really bugged me, or held me up in some material way.

Sorry, but TLDR.

If you want to provide a material problem with the Macro, then I'll take a look.
Please be succinct.

My advice: Do your learning/improvements on a new project. Then you'll be getting something for your efforts besides the knowledge. Once you have the new knowledge/technique, then you can decided whether or not it is worth it rewrite something.

Just so you know, I often have this experience: I'm reviewing some old code I wrote a few years ago, maybe looking for something specific. But as I read the code, I often think "What in the world was I thinking when I wrote that."

1 Like

Thanks for the kind words, KC! I'm not a big drinker myself, but if the opportunity ever presents itself, I'll be glad to take you up on those beers. At any rate, I found this an interesting exercise to work on, so I took a crack at modifying your macro (actions I added are in yellow and orange):

Review Checks - Forum 1.1.kmmacros (15.4 KB)

This version prompts you to take a screenshot or continue with the macro, then pauses until the mouse is clicked (unless you want to change it to a key, of course) to give you as much or as little time as you need to scroll the screen into position, which should eliminate the need to dynamically create variables or set arbitrary pause times. It also cuts down the redundancy of identical, repeated actions, as this is the sort of thing loops are made for. So instead of making CR1, CR2 variables for each capture, or trying to dynamically create variables, I used the same CR variable for each capture and just appended the results to a "master" variable of sorts. Hopefully the changes and usage should be fairly self explanatory, but of course, feel free to weigh in if anything is unclear or doesn't seem to work as it should.

1 Like

Yep, it can be done, but I recommend avoiding it if at all possible.
I wrote that section of the wiki (maybe not very well), and while I understood it at the time, I use it so rarely that everytime I do, I have to go back an restudy the subject all over again.

IMO, the introduction of Local and Instance Variables has eliminated a lot of the need for the. Instance variable in particular are useful for as pseudo parameters for Sub-Macros.

Instead of having a bunch of Variables named "Var1", "Var2", "Var3", etc, I prefer to append each result into a master Variable, separated by either lines or tabs, or both.

I think you may be right, but just to illustrate a way with separate variables:

Pretty straightforward.

1 Like

Maybe in your eyes, but not mine.

Question is the benefit worth the effort, and the loss of readability? Say 6-12 months later, you want to do something specific with a particular variable. How long will it take you to figure this out and debug it?

How long will it take you to figure this out and debug it?

No time at all, since I grabbed these examples from old code. :smile:

I have no problem with you doing it some other way - we're programmers, so we'll always disagree on specifics. But you'd have a hard time deciphering this code? I'm calling BS - you're better than that and we both know it. :joy::stuck_out_tongue_winking_eye:

Truth be told, I'd probably use the technique you mentioned, since I do it all the time - at least when I can count on being able to use KM's variable indexing, e.g. var[1]. But I was trying to answer the question of how to create variables dynamically.

Thanks all for sharing. Sorry for the initial long post. I wanted to give some specifics, of my mindset, on why I was asking . I’m simply trying to get better. I’m far from a programmer so I inquired. Thanks for the input.