How to Cancel Specific (Nested) Macro but not Top Level Macro?

I have created macros to download bills and statements from their websites. Part of the routine for each is to call other macros that check if the date the bill/statement appears on the websites hasn't occurred yet, or if the bill/statement has already been downloaded.

I accomplish this by having at the start of each bill/statement macro an action that sets the variable Calling_Macro to %ExecutingInstance%. Inside the macros that check the date and/or if it is already downloaded I have an action to Cancel a Specific Macro of the instance: %Variable%Calling_Macro% if the date isn't current yet or the bill/statement has already been downloaded.

That works great if I run the macros for each bill or statement one at a time. However, I have also created a master macro that calls each of the bill/statement macros in turn. (i.e. each bill/statement macro is now a nested/child macro of the master macro). The very first one it came to wasn't ready to run yet and I saw it got cancelled. However, that also cancelled the master macro. That doesn't seem like it should have happened as the action is called Cancel a Specific Macro. I purposely did not run Cancel All Macros inside my sub-macros. I know I could work around this by setting variable in my sub-macros and then check them in each bill/statement macro, and then run Cancel Just This Macro from the particular bill/statement, but this is not elegant and seems contrary to the whole purpose of Cancel a Specific Macro.

So, the bottom line is: 1) Why is Cancel a Specific Macro also cancelling the parent/master macro and 2) Is there a way to cancel just that child macro from inside the 3rd macro? (the 3rd macro being the ones that check the date and if it was already downloaded).

Thank you,

You might need to creat loop and have “break from the loop” kinda of action.

Thanks for the reply, but that doesn't answer the question as to why Cancel a Specific macro (in my example invoking that in Macro #3 to cancel Macro #2) was also cancelling the topmost macro (Macro #1) also?

As I mentioned I could do, I did away with trying to use it and just set a variable I called (cleverly :-)) "Stop" to True and and then put a command to Cancel Just This macro right after it in Macro #3. Then back in Macro #2 after I execute Macro #3 I test if Stop = True to reset Stop to False and then the action to Cancel Just this Macro. It wasn't hard to due, but certainly wasn't as elegant as having Macro #3 stop Macro #2, and only Macro #2, if desired (which, after all, seems the entire raison d'ĂŞtre of having an action called Cancel Specific Macro).

1 Like

See the Cancel a Specific Macro action on the Wiki.

“Cancel a Specific Macro (v9.0+) — Cancels a specific macro instance (from the %ExecutingInstance% or %ExecutingInstances% tokens).”

Look here for an explanation:

How Do We Use %ExecutingInstance% token? - #4 by kvanh

Wow just coming across this unexpected quirk.

Sorry for digging this topic up again, I just had to comment because the functionality of this surprised me as I was expecting a dropdown of all Macros that I could choose from, regardless of whether they're running or not. Having to set a var seems a bit convoluted. Though I guess cause KM is checking which macros are currently active, as opposed to letting you cancel of your entire list of dormant macros? (what would be the harm in that anyway?).

@ccstone I'm not sure if the other people in here and in the post you linked are discussing the same thing I'm trying to do, so I'll just explain my scenario:

  • Macro1 has a 60sec pause before it moves onto further actions, which then triggers Macro2, which then both macros 1+2 end.
  • If I trigger Macro3 during that 60s pause, I want to tell it to Cancel Macro1.

Am i correct in understanding the solution is:
In Macro1 I set a new var Macro1_instance = %ExecutingInstance%. And Macro3 calls Cancel a Specific Macro (%Macro1_instance%)
?

Thanks
and sorry if it's been repeated

(I gotta say the wiki barely goes into this. The various flavours of %ExecutingInstance% are pretty cryptic. Some real examples of the whole array of tokens would be v helpful to see somewhere. Though i guess it is a wiki and not a manual)

That would be impossible for KM to do, because how would KM know which running copy of Macro1 would be the one to cancel. The very design of KM allows for multiple copies of the same macro to be running. This is not a bug, it's a very powerful feature. For this reason, you need to specify the instance of Macro1 that you want Macro3 to cancel.

Perhaps KM could add a new option to the Cancel action that would say "Cancel all instances of the macro with the name "<Macro1>". I suppose you could ask for this feature to be added to the Cancel action. Who knows, you might find this request to get implemented. But the problem with this request is that you can have multiple macros with the exact same name, so how would KM know which one to cancel? In fact, you can have all your macros in the same KM Group with the same name. Do you see the problem? How would you specify which macro to cancel?

Thanks for explaining this!! Multiple instances of the same macro is what I was missing from my lil brain. Now understanding. But yes, would be so nice to say kill all pesky instances of <Macro 1>. It would've certainly saved me this headache i'm having right now, I just can't seem to locate the instance and there's something causing issues.

I might be posting is as a new post in the forum so not to hijack this topic, as it might be due to something else caused by multiple macros and subroutines being called with some Pauses thrown into the mix.

The result is that, during the 60s pause that is inside <Macro 1>, if I try to trigger <Macro 3>, it won't actually trigger until Macro 1 has resumed from the pause. As if Pause is applied globally? (it's not, right?)

Thing is that I had it working almost fine at some point, because I used to have Cancel All Other Macros at the beginning of each macro, but then I realised that it was interfering with some of the automated calls of other Macros and Subroutines, so instead of Canceling ALL other macros I just wanted the ability to delete the ONE that I knew had a Pause inside it... even just to debug and see if it was indeed the cause of the log jam of other macros (it certainly plays out that way).

I wonder if this rings any bells?


EDIT: Found the culprit!

As if Pause is applied globally? (it's not, right?)

All my triggers are coming from the Stream Deck via KM-Link. During the Pause from Macro 1, if I trigger Macro 3 with a key command, it works fine! If I trigger it from the Stream Deck, any [Cancel Macro] action gets ignored and queued up until the pause ends. :frowning:

Right there, that sounds to me like an inelegant approach. There are ways to "pause for X seconds" and still let you cancel Macro1 without needing Macro3 to cancel it. For example, you can have Macro1 perform a loop for 60 seconds, and it could quit if the user does something (eg, press the Shift key, or move the mouse to the top of the screen) and if the user does one of those things, the macro quits early, but if the user does not do those things, the macro will continue. This way you can get rid of external macros and variables that store instance UUIDs.

I'm afraid I'm not sure what that means.

Well, you've made a step in diagnosing the problem. That's great. I'm afraid I can't see why triggering from the Stream Deck would "ignore and queue up" the request. I suspect there's something wrong in your macro. But you haven't shared your macro, so I can't troubleshoot it.

Roger. I'm going to do some digging first and if I'm still stuck I'll post in a new thread and will tag you if that's OK. I seem to remember youre familiar with stream deck workflows. Thank u

Good idea. Indeed, I'm moderately familiar with Stream Deck, but mostly the mobile version with the standard plug in. There are several people on this site with more experience than me.

  • There's a token that gets all executing instances
  • There's a token that get the name of the macro of an executing instance
  • There's an action that cancels a specific executing instance

See if you can put those together to do what you want.

KM can't provide discrete actions for every single thing you might ever want to do. But it does give you a big toolbox that you can use to build your own solution.

Most of the time, anyway...

Great point. I had forgotten about the token in your second bullet. It's doable that way as long as he uses unique names for every macro.

Minor nit-pick -- unique names for every potentially concurrently executing macro. You could for example, have macros in mutually exclusive Groups without much of a problem.

But, IMO, you're better off with unique names anyway. KM may not care too much, but it'll save a lot of head scratching later on!

1 Like