Jump to content
Macro Express Forums
acantor

Challenge: Automate Macro Express with macros!

Recommended Posts

THE CHALLENGE

The challenge is to create a set of hotkeys for the Macro Express Script Editor that insert the instructions you use most often without the need to touch the mouse. For example:

 

- Press a hotkey to insert the "Text Type" command

- Press another hotkey to insert the "Mouse Left Click" command

- Press a third hotkey to insert the "Repeat Start" command

 

SUGGESTED REQUIREMENTS

1.    Solutions for Windows 7 and 10 may be different. So make your hotkeys function in whatever operating system you currently use.

 

2.    The hotkeys work in all Script Editor panels: In other words, if you press a hotkey while the "Activations" (or "Variables" or "Scope"…) panel has focus, the macro inserts the instruction in the "Script" panel.

 

3.    The hotkeys work regardless of the size and position of the Script Editor window.

 

4.    The hotkeys work regardless of display resolution settings, custom scaling settings, etc. For example, if you change the resolution from [1,920 x 1080] to [800 x 600] pixels, your hotkeys still work.

 

BACKGROUND

There are dozens of built-in hotkeys in the Macro Express Script Editor, including:

 

Alt + I = Open "Script" panel

Alt + Down arrow = Go to the "Search for Command" text box

Alt + Left arrow = Go to left pane

Alt + Right arrow = Go to right pane

 

Ctrl + D = Duplicate selected command(s)

Ctrl + N = Enable / Disable the selected line(s) of code


ALTERNATIVE APPROACHES

 

This challenge is, above all, a practical exercise. After I defined 13 hotkeys for the Script Editor, the time I spent developing MEP scripts dropped in half.

 

I prefer hotkeys over the Macro Express "Favorites" and "Snippets" features, but I acknowledge the hotkey approach may not jive well for others! Nevertheless, I hope you find this an interesting Macro Express problem with wide applicability.

 

By the way, some of my hotkeys DON’T insert a Macro Express instruction. Instead, they give focus to groups of related commands.


For example, there are 17 items in the "Mouse" group in the left pane. When I press my hotkey, the 5th item in the "Mouse" group ("Mouse Left Click") gains focus. Then I select the mouse command I want by pressing up and down arrow keys, and insert it by pressing Enter.

 

This challenge may seem easy, but when I tried, I had to put in time before I got consistent and reliable results.

Share this post


Link to post
Share on other sites

Clever idea, to automate the insertion of often-used commands.  There's one thing I would like to have, and I wrote macros for in my last job, and that is bookmarking places in the code.  I often will copy a block of code, and want to insert it elsewhere in the same macro.  Lots of time is spent finding the code to be copied, then lots more time to re-find the insertion point and paste in the code.  It is not unknown for me to paste it in the wrong place. 😧  

So I will work on two macros: 

(1) Insert a "bookmark" comment into the script.

(2) Copy to clipboard, re-find the bookmark, delete it, and in its place paste from the clipboard. 

After macro (1), of course, one would manually locate and highlight the block of code to be cloned, then run macro (2).

Share this post


Link to post
Share on other sites

Looking forward to seeing your solution. It's exactly the kind of thing I had in mind: Let's automate some of the repetitive, time-consuming, physically- and/or cognitively-demanding tasks we do every day.

 

Here's another example. One of my macros inserts the "Delay" command. By default, the delay is in seconds. But I always want my delays in milliseconds. So the hotkey that I use to insert a delay automatically changes seconds to milliseconds and puts focus in the "Delay Time" field:

 

image.png.851889ad607d8f486866be4e5ece9ec1.png

Share this post


Link to post
Share on other sites

Here is a solution. I recently discovered a more elegant method, but this (and similar methods) have been working for years. (The more elegant solution has an undesirable side-effect that I haven’t been able to resolve.)

 

It's a two-step process:

 

1. Reset the tree-view of All Commands so that all branches are collapsed.

2. Send the sequence of keystrokes to select the instruction you want.

 

1. Resetting the tree-view

There are several ways to reset the tree-view to collapse all of the nodes, including this one:

 

1.1    Press <ALT>i // Make sure the "Script" tabbed page has focus

1.2    Short delay

1.3    Press <ALT><DOWN> // Move focus to the "Search for command" field

1.4    Press <TAB> // Move focus to the drop-down list (below "Script" on the tabbed page)

1.5    Press <END><HOME> // Reset the tree-view by switching away from, and back to, "All Commands" in the drop-down list

1.6   Press <TAB>           // Tab to the list of all commands

 

2. Navigating to a command in the tree-view

My solution relies on the incremental search built into standard tree-views to do the heavy lifting. For example, to reach "Variables" (beginning with all nodes closed) type “Variables” (or even “V” as no other node starts with that letter). Navigate to the “Repeat” node by typing “Repeat” (or even "Rep").

 

To expand a node, press the Right arrow key.

 

It’s also possible to press {Up} and {Down} arrow keys to move up and down the list, {Home} to jump to the top, and {End} to jump to the bottom.

 

{Enter} inserts a command into the script.

 

When the tree-view has keyboard focus, and if all nodes are collapsed, here are three different key sequences that insert "Repeat Start"…

 

repeat{Right}rrr{Enter}

 

or

 

rep{Right}{Down}{Down}{Down}{Down}{Down}{Enter}

 

or

 

{Home}{Down}{Down}{Down}{Down}{Down}{Down}{Down}{Down}{Down}{Down}{Down}{Down}{Down}{Down}{Down}{Right}{Down}{Down}{Down}{Down}{Down}{Enter}

 

The first and second key sequences are easier to understand than the third, so I’d say are better solutions. But all work.

 

So here is a command that inserts Repeat Start. To insert other Macro Express instructions, reuse the first section for each -- or use "Macro Run" to eliminate the need to edit each script.

 

Text Type (Simulate Keystrokes): <ALT>i // Navigate to the "Script" tabbed page using the built-in accelerator
Delay: 20 milliseconds

Text Type (Simulate Keystrokes): <ALT><ARROW DOWN> // Move focus to the "Search for command" field using the built-in hotkey
Text Type (Simulate Keystrokes): <TAB> // Move focus to the drop-down list (just below the word "Script" on the tabbed page)
Text Type (Simulate Keystrokes): <END><HOME> // Reset the treeview of commands by quickly switching away from, and back to, "All Commands" in the drop-down list

Text Type (Simulate Keystrokes): <TAB> // Tab to the list of all commands

Text Type (Simulate Keystrokes): repeat<ARROW RIGHT>
Text Type (Simulate Keystrokes): rrr<ENTER>
 

<TEXT TYPE Action="0" Text="<ALT>i" _COMMENT="Navigate to the \"Script\" tabbed page using the built-in accelerator"/>
<DELAY Flags="\x02" Time="20"/>
<COMMENT/>
<TEXT TYPE Action="0" Text="<ALT><ARROW DOWN>" _COMMENT="Move focus to the \"Search for command\" field using the built-in hotkey"/>
<TEXT TYPE Action="0" Text="<TAB>" _COMMENT="Move focus to the drop-down list (just below the word \"Script\" on the tabbed page)"/>
<TEXT TYPE Action="0" Text="<END><HOME>" _COMMENT="Reset the treeview of commands by quickly switching away from, and back to, \"All Commands\" in the drop-down list"/>
<COMMENT/>
<TEXT TYPE Action="0" Text="<TAB>" _COMMENT="Tab to the list of all commands"/>
<COMMENT/>
<TEXT TYPE Action="0" Text="repeat<ARROW RIGHT>"/>
<TEXT TYPE Action="0" Text="rrr<ENTER>"/>

 

Share this post


Link to post
Share on other sites

Here are my solutions to the copy-and-paste I described above:
(1) Insert a "bookmark" comment into the script.
(2) For a highlighted block of code, copy to clipboard, re-find the bookmark, delete it, and in its place paste from the clipboard.

 

The bookmark is inserted by duplicating the command at the insertion point, and adding a "bookmark" comment to the duplicated command.  This is a little bit crude, because if the bookmark doesn't get deleted we end up with a duplicated command which might or might not cause problems.  I might rewrite it to use your command-panel navigation method, to insert a standalone comment rather than modify a "live" command.  I couldn't quite figure out that navigation when I originally worked on this a few days ago.  

 

// Macro bookmarks a place in the script by duplicating the current line and adding a "BOOKMARK" comment to it

// (Works only if the Editor is set to insert commands AFTER the current command)
//  
// Duplicate the line of code at the insertion point
Text Type (Simulate Keystrokes): <CTRLD>d<CTRLU>
// Ctrl-Alt-c shortcut to insert comment
Text Type (Simulate Keystrokes): <CTRLD><ALTD>c<ALTU><CTRLU>
Delay: 250 milliseconds
// Type special recognizable "bookmark" text, then tab to "OK" and press ENTER to insert the bookmark comment
Text Type (Use Clipboard and Paste Text): !@#$%*** BOOKMARK ***!@#$%
Text Type (Simulate Keystrokes): <TAB><ENTER>
//  
Macro Return

 


// Macro copies highlighted macro script lines, pastes them into bookmarked location in script
//  
Macro Run: 0_Generic_Copy_To_Clipboard
//  
// Ctlr-HOME to top of script, locate bookmark, paste copied text, arrow up to bookmark line, remove bookmark
Text Type (Simulate Keystrokes): <CTRLD><HOME><CTRLU>
Text Type (Simulate Keystrokes): <CTRLD>f<CTRLU>
Text Type (Simulate Keystrokes): !@#$%*** BOOKMARK ***!@#$%<ENTER><ESC>
Text Type (Simulate Keystrokes): <CTRLD>v<CTRLU>
Text Type (Simulate Keystrokes): <ARROW UP>
Text Type (Simulate Keystrokes): <DELETE>
//  
Macro Return

 

 

Share this post


Link to post
Share on other sites

This simple macro , written years ago, has proved very useful. When writing macros I use many Text Display commands, temporarily showing variable values. The macro makes their identification unambiguous.

 

One day I'll get around to trying to improve it in a few ways, such as by automatically sizing the TBD. (But if anyone feels like tackling that for me...! )

 

<DELAY Flags="\x02" Time="100"/>
<COMMENT Value="Assumes a Text Box Display command dialog window is open."/>
<COMMENT Value="Assumes text cursor is at RH end of target line.\r\nActivation is l-click in small area to left of entries."/>
<KEYSTROKE SPEED Delay="50"/>
<TEXT TYPE Action="0" Text="<ARROW LEFT>" _COMMENT="Prepare to select all but the last percent sign."/>
<DELAY Flags="\x02" Time="100"/>
<TEXT TYPE Action="0" Text="<SHIFT><HOME>" _COMMENT="Select"/>
<DELAY Flags="\x02" Time="100"/>
<TEXT TYPE Action="0" Text="<CONTROL>c" _COMMENT="Copy to clipboard"/>
<DELAY Flags="\x02" Time="100"/>
<TEXT TYPE Action="0" Text="<HOME>"/>
<DELAY Flags="\x02" Time="100"/>
<TEXT TYPE Action="0" Text="<CONTROL>v" _COMMENT="Paste"/>
<DELAY Flags="\x02" Time="100"/>
<TEXT TYPE Action="0" Text="<SPACE>=<SPACE>"/>
<DELAY Flags="\x02" Time="100"/>
<TEXT TYPE Action="0" Text="<HOME>"/>
<DELAY Flags="\x02" Time="100"/>
<TEXT TYPE Action="0" Text="<DELETE>"/>
<DELAY Flags="\x02" Time="100"/>
<TEXT TYPE Action="0" Text="<END>"/>
<DELAY Flags="\x02" Time="100"/>
<TEXT TYPE Action="0" Text="<ENTER>" _COMMENT="Move to next line."/>
<DELAY Flags="\x02" Time="100"/>

EditTextBox-MacroSteps.thumb.jpg.c6580ca6ffaba68fdbd6c1c7d509c637.jpg

 

 

EditTextBox-ScopeActivation.jpg

Share this post


Link to post
Share on other sites
On 7/13/2020 at 6:52 AM, terrypin said:

One day I'll get around to trying to improve it in a few ways, such as by automatically sizing the TBD. (But if anyone feels like tackling that for me...! )

 

Hi Terry,

 

Maybe something like this?

 

Text Type (Simulate Keystrokes): <ALT>i // Go to Script tab
 
Variable Set String %Header%: Prompt // Get values for Text Box
Variable Set String %BoxContent%: Prompt
Variable Set Integer %FontSizeBox%: Prompt
Variable Set Integer %Width%: Prompt
Variable Set Integer %Height%: Prompt
 
Text Type (Simulate Keystrokes): <ALT><ARROW DOWN> // Search for a command...
Text Type (Simulate Keystrokes): Text Box Display<ENTER> // Exact name of command to search for
Delay: 20 milliseconds
Text Type (Simulate Keystrokes): <TAB> // Populate the fields...
Text Type (Simulate Keystrokes): %Header%<TAB><TAB><TAB><TAB>
Text Type (Simulate Keystrokes): %FontSizeBox%<TAB>
Text Type (Simulate Keystrokes): %BoxContent%<TAB><TAB><TAB><TAB><TAB><TAB><TAB><TAB><TAB>
Text Type (Simulate Keystrokes): %Width%<TAB><TAB>
Text Type (Simulate Keystrokes): %Height%

<TEXT TYPE Action="0" Text="<ALT>i" _COMMENT="Go to Script tab"/>
<COMMENT/>
<VARIABLE SET STRING Option="\x01" Destination="%Header%" Prompt="What is the header?" Mask="FALSE" OnTop="TRUE" Left="Center" Top="Center" Monitor="0" _COMMENT="Get values for Text Box"/>
<VARIABLE SET STRING Option="\x01" Destination="%BoxContent%" Prompt="What is the box content?" Mask="FALSE" OnTop="TRUE" Left="Center" Top="Center" Monitor="0"/>
<VARIABLE SET INTEGER Option="\x01" Destination="%FontSizeBox%" Prompt="Font size" Mask="FALSE" OnTop="TRUE" Left="Center" Top="Center" Monitor="0"/>
<VARIABLE SET INTEGER Option="\x01" Destination="%Width%" Prompt="Width of the box" Mask="FALSE" OnTop="TRUE" Left="Center" Top="Center" Monitor="0"/>
<VARIABLE SET INTEGER Option="\x01" Destination="%Height%" Prompt="Height of the box" Mask="FALSE" OnTop="TRUE" Left="Center" Top="Center" Monitor="0"/>
<COMMENT/>
<TEXT TYPE Action="0" Text="<ALT><ARROW DOWN>" _COMMENT="Search for a command..."/>
<TEXT TYPE Action="0" Text="Text Box Display<ENTER>" _COMMENT="Exact name of command to search for"/>
<DELAY Flags="\x02" Time="20"/>
<TEXT TYPE Action="0" Text="<TAB>" _COMMENT="Populate the fields..."/>
<TEXT TYPE Action="0" Text="%Header%<TAB><TAB><TAB><TAB>"/>
<TEXT TYPE Action="0" Text="%FontSizeBox%<TAB>"/>
<TEXT TYPE Action="0" Text="%BoxContent%<TAB><TAB><TAB><TAB><TAB><TAB><TAB><TAB><TAB>"/>
<TEXT TYPE Action="0" Text="%Width%<TAB><TAB>"/>
<TEXT TYPE Action="0" Text="%Height%"/>

 

Share this post


Link to post
Share on other sites

Hi Terry, I read the description of your macro more carefully. I wonder whether this approach might be of interest. Instead of activating the script from within the "Text Box Display" dialog, activate it from the Script Editor. But make sure the variable name is already in the clipboard, and then use the content of the clipboard to generate the message for the text box display.

 

This version relies on an alternative way to insert Macro Express commands into a script: press Alt + down arrow to activate the search box, and then specify the exact command name you want to insert:

 

// Ensure a variable name is in the clipboard before running the script
 
// What the script does...
 
// 1. Search for the "Text Box Display" command and insert it into the script
// 2. Navigate to the "Box Content" field in the Text Box Display dialog
// 3. Generate the text to insert in this format: 
//     VariableName = %VariableName%
// 4. Insert it into the field
 
Text Type (Simulate Keystrokes): <ALT><ARROW DOWN> // Hotkey to search for a Macro Express command...
Text Type (Simulate Keystrokes): Text Box Display // Exact name of command to search for
Text Type (Simulate Keystrokes): <ENTER> // Insert the "Text Box Display" command into the script
Delay: 20 milliseconds
Text Type (Simulate Keystrokes): <TAB><TAB><TAB><TAB><TAB><TAB> // Navigate to the "Box Content" field
 
Variable Set String %x% from the clipboard contents // Generate the text
Variable Set String %y% to "%x%"
Variable Modify String: Replace "%" in %y% with ""
Text Type (Simulate Keystrokes): %y% = %x%
  
<COMMENT Value="Ensure a variable name is in the clipboard before running the script"/>
<COMMENT/>
<COMMENT Value="What the script does..."/>
<COMMENT/>
<COMMENT Value="1. Search for the \"Text Box Display\" command and insert it into the script"/>
<COMMENT Value="2. Navigate to the \"Box Content\" field in the Text Box Display dialog"/>
<COMMENT Value="3. Generate the text to insert in this format: "/>
<COMMENT Value="    VariableName = %VariableName%"/>
<COMMENT Value="4. Insert it into the field"/>
<COMMENT _ENABLED="FALSE"/>
<TEXT TYPE Action="0" Text="<ALT><ARROW DOWN>" _COMMENT="Hotkey to search for a Macro Express command..."/>
<TEXT TYPE Action="0" Text="Text Box Display" _COMMENT="Exact name of command to search for"/>
<TEXT TYPE Action="0" Text="<ENTER>" _COMMENT="Insert the \"Text Box Display\" command into the script"/>
<DELAY Flags="\x02" Time="20"/>
<TEXT TYPE Action="0" Text="<TAB><TAB><TAB><TAB><TAB><TAB>" _COMMENT="Navigate to the \"Box Content\" field"/>
<COMMENT/>
<VARIABLE SET STRING Option="\x02" Destination="%x%" NoEmbeddedVars="FALSE" _COMMENT="Generate the text"/>
<VARIABLE SET STRING Option="\x00" Destination="%y%" Value="%x%" NoEmbeddedVars="FALSE"/>
<VARIABLE MODIFY STRING Option="\x0F" Destination="%y%" ToReplace="%" All="TRUE" IgnoreCase="FALSE" NoEmbeddedVars="TRUE"/>
<TEXT TYPE Action="0" Text="%y% = %x%"/>

 

Share this post


Link to post
Share on other sites

Here is a slight refinement. Test if the clipboard contains a valid variable name. If it does, use it. Otherwise, prompt the user to input a variable.

 

// If the clipboard contains a valid variable name, use it. Otherwise, prompt user for a variable name
 
// What the script does...
 
// 1. Search for the "Text Box Display" command and insert it into the script
// 2. Navigate to the "Box Content" field in the Text Box Display dialog
// 3. Checks if clipboard contains a variable name. If not, prompt for one
// 4. Generate the text to insert into the field, in this format: 
//     VariableName = %VariableName%
// 5. Insert it into the field
 
Text Type (Simulate Keystrokes): <ALT><ARROW DOWN> // Hotkey to search for a Macro Express command...
Text Type (Simulate Keystrokes): Text Box Display // Exact name of command to search for
Text Type (Simulate Keystrokes): <ENTER> // Insert the "Text Box Display" command into the script
Delay: 20 milliseconds
Text Type (Simulate Keystrokes): <TAB><TAB><TAB><TAB><TAB><TAB> // Navigate to the "Box Content" field
 
Variable Set String %x% from the clipboard contents
 
If Variable %x% Does not Contain "%" // If %x% does not contain "%" or contains a space, it isn't a valid variable name. So ask for one.
  OR
If Variable %x% Contains " "
  Variable Set String %x% to "" // Get rid of existing non-variable name
  Variable Set String %x%: Prompt
End If
 
Variable Set String %y% to "%x%"
Variable Modify String: Replace "%" in %y% with ""
Text Type (Simulate Keystrokes): %y% = %x%

<COMMENT Value="If the clipboard contains a valid variable name, use it. Otherwise, prompt user for a variable name"/>
<COMMENT/>
<COMMENT Value="What the script does..."/>
<COMMENT/>
<COMMENT Value="1. Search for the \"Text Box Display\" command and insert it into the script"/>
<COMMENT Value="2. Navigate to the \"Box Content\" field in the Text Box Display dialog"/>
<COMMENT Value="3. Checks if clipboard contains a variable name. If not, prompt for one"/>
<COMMENT Value="4. Generate the text to insert into the field, in this format: "/>
<COMMENT Value="    VariableName = %VariableName%"/>
<COMMENT Value="5. Insert it into the field"/>
<COMMENT _ENABLED="FALSE"/>
<TEXT TYPE Action="0" Text="<ALT><ARROW DOWN>" _COMMENT="Hotkey to search for a Macro Express command..."/>
<TEXT TYPE Action="0" Text="Text Box Display" _COMMENT="Exact name of command to search for"/>
<TEXT TYPE Action="0" Text="<ENTER>" _COMMENT="Insert the \"Text Box Display\" command into the script"/>
<DELAY Flags="\x02" Time="20"/>
<TEXT TYPE Action="0" Text="<TAB><TAB><TAB><TAB><TAB><TAB>" _COMMENT="Navigate to the \"Box Content\" field"/>
<COMMENT/>
<VARIABLE SET STRING Option="\x02" Destination="%x%" NoEmbeddedVars="FALSE"/>
<COMMENT/>
<IF VARIABLE Variable="%x%" Condition="\x07" Value="%" IgnoreCase="FALSE" _COMMENT="If %x% does not contain \"%\" or contains a space, it isn't a valid variable name. So ask for one."/>
<OR/>
<IF VARIABLE Variable="%x%" Condition="\x06" Value=" " IgnoreCase="FALSE"/>
<VARIABLE SET STRING Option="\x00" Destination="%x%" NoEmbeddedVars="FALSE" _COMMENT="Get rid of existing non-variable name"/>
<VARIABLE SET STRING Option="\x01" Destination="%x%" Prompt="Enter the variable name" Mask="FALSE" OnTop="TRUE" Left="Center" Top="Center" Monitor="0"/>
<END IF/>
<COMMENT/>
<VARIABLE SET STRING Option="\x00" Destination="%y%" Value="%x%" NoEmbeddedVars="FALSE"/>
<VARIABLE MODIFY STRING Option="\x0F" Destination="%y%" ToReplace="%" All="TRUE" IgnoreCase="FALSE" NoEmbeddedVars="TRUE"/>
<TEXT TYPE Action="0" Text="%y% = %x%"/>

 

Share this post


Link to post
Share on other sites

Many thanks Alan, those look very interesting. Garden chores all day today so will try them tomorrow morning.

Share this post


Link to post
Share on other sites

I did modify my book-marking macro to insert a comment via the command list panel.  It's nice knowing how to navigate the list with just keystrokes.

Also finally wrote a macro that does nothing but simulate the DELETE key.  It's either my keyboard or my clumsy fingers, but frequently when I try to delete something, it ends up deleting twice. 

Share this post


Link to post
Share on other sites

Hi Alan,

 

Still yet to get to my PC (tomorrow) but reading your three posts more carefully in bed now on my iPad, with a glass of Chardonnay for inspiration.

 

I don’t see anything that automatically changes the size of the TBD? With several variables listed, varying in width, I’m wondering if there’s some way to resize it appropriately based on the length of the longest one? Of course, it’s easy enough to do manually, but....

 

Terry

Share this post


Link to post
Share on other sites

Hi Terry,

 

Two questions.

 

1. Are you referring to the dialog box with title "Text Box Display"? Or to the text box that ultimately gets displayed as a result of executing the instruction?

 

2. On what basis should the window be sized? Should the width and height be constants? Or a ratio of the two values? Or something else?

Share this post


Link to post
Share on other sites

Morning Alan,

 

1. The latter.

2. I think a fixed width of say 120 chars would be OK (including 'xxx...xxx = ', with word wrap if then necessary.

 

Terry

 

EditTextBox-MacroSteps#4.jpg

Share this post


Link to post
Share on other sites

I wonder whether the width of the box could be calculated by applying some formula. This version multiplies the length of the string that is inserted into the "Box Content" field by ten.

 

My guess is that is approach will lead to poor approximations, but maybe a better solution is possible. A better formula might account for the font size, whether the variable is a string or a number, etc.

 

(But given the variability for the width of the box, perhaps automating this aspect of the macro is not worthwhile!)

 

Here's an example of multiplying ten by the length of text inserted into the Box Content field...

 

// If the clipboard contains a valid variable name, use it. Otherwise, prompt user for a variable name
 
// What the script does...
 
// 1. Search for the "Text Box Display" command and insert it into the script
// 2. Navigate to the "Box Content" field in the Text Box Display dialog
// 3. Checks if clipboard contains a variable name. If not, prompt for one
// 4. Generate the text to insert into the field, in this format: 
//     VariableName = %VariableName%
// 5. Insert it into the field
// 6. Change width of Message Box to a multiple of the number of characters
 
Text Type (Simulate Keystrokes): <ALT><ARROW DOWN> // Hotkey to search for a Macro Express command...
Text Type (Simulate Keystrokes): Text Box Display // Exact name of command to search for
Text Type (Simulate Keystrokes): <ENTER> // Insert the "Text Box Display" command into the script
Delay: 20 milliseconds
Text Type (Simulate Keystrokes): <TAB><TAB><TAB><TAB><TAB><TAB> // Navigate to the "Box Content" field
 
Variable Set String %x% from the clipboard contents
 
If Variable %x% Does not Contain "%" // If %x% does not contain "%" or contains a space, it isn't a valid variable name. So ask for one.
  OR
If Variable %x% Contains " "
  Variable Set String %x% to "%%" // Replace existing non-variable name with "%%"
  Variable Set String %x%: Prompt
End If
 
Variable Set String %y% to "%x%"
Variable Modify String: Replace "%" in %y% with ""
Variable Set String %z% to "%y% = %x%"
Text Type (Simulate Keystrokes): %z%
 
Text Type (Simulate Keystrokes): <TAB><TAB><TAB><TAB><TAB><TAB><TAB><TAB><TAB> // Navigate to "Width" field
 
Variable Set Integer %Lengthz% to the length of variable %z%
Variable Modify Integer: %FudgeFactor% = %Lengthz% * 10 // Experiment with multiplier to find a value that gives good results
Text Type (Simulate Keystrokes): %FudgeFactor%
  
<COMMENT Value="If the clipboard contains a valid variable name, use it. Otherwise, prompt user for a variable name"/>
<COMMENT/>
<COMMENT Value="What the script does..."/>
<COMMENT/>
<COMMENT Value="1. Search for the \"Text Box Display\" command and insert it into the script"/>
<COMMENT Value="2. Navigate to the \"Box Content\" field in the Text Box Display dialog"/>
<COMMENT Value="3. Checks if clipboard contains a variable name. If not, prompt for one"/>
<COMMENT Value="4. Generate the text to insert into the field, in this format: "/>
<COMMENT Value="    VariableName = %VariableName%"/>
<COMMENT Value="5. Insert it into the field"/>
<COMMENT Value="6. Change width of Message Box to a multiple of the number of characters"/>
<COMMENT _ENABLED="FALSE"/>
<TEXT TYPE Action="0" Text="<ALT><ARROW DOWN>" _COMMENT="Hotkey to search for a Macro Express command..."/>
<TEXT TYPE Action="0" Text="Text Box Display" _COMMENT="Exact name of command to search for"/>
<TEXT TYPE Action="0" Text="<ENTER>" _COMMENT="Insert the \"Text Box Display\" command into the script"/>
<DELAY Flags="\x02" Time="20"/>
<TEXT TYPE Action="0" Text="<TAB><TAB><TAB><TAB><TAB><TAB>" _COMMENT="Navigate to the \"Box Content\" field"/>
<COMMENT/>
<VARIABLE SET STRING Option="\x02" Destination="%x%" NoEmbeddedVars="FALSE"/>
<COMMENT/>
<IF VARIABLE Variable="%x%" Condition="\x07" Value="%" IgnoreCase="FALSE" _COMMENT="If %x% does not contain \"%\" or contains a space, it isn't a valid variable name. So ask for one."/>
<OR/>
<IF VARIABLE Variable="%x%" Condition="\x06" Value=" " IgnoreCase="FALSE"/>
<VARIABLE SET STRING Option="\x00" Destination="%x%" Value="%%" NoEmbeddedVars="FALSE" _COMMENT="Replace existing non-variable name with \"%%\""/>
<VARIABLE SET STRING Option="\x01" Destination="%x%" Prompt="Enter the variable name" Mask="FALSE" OnTop="TRUE" Left="Center" Top="Center" Monitor="0"/>
<END IF/>
<COMMENT/>
<VARIABLE SET STRING Option="\x00" Destination="%y%" Value="%x%" NoEmbeddedVars="FALSE"/>
<VARIABLE MODIFY STRING Option="\x0F" Destination="%y%" ToReplace="%" All="TRUE" IgnoreCase="FALSE" NoEmbeddedVars="TRUE"/>
<VARIABLE SET STRING Option="\x00" Destination="%z%" Value="%y% = %x%" NoEmbeddedVars="FALSE"/>
<TEXT TYPE Action="0" Text="%z%"/>
<COMMENT/>
<TEXT TYPE Action="0" Text="<TAB><TAB><TAB><TAB><TAB><TAB><TAB><TAB><TAB>" _COMMENT="Navigate to \"Width\" field"/>
<COMMENT/>
<VARIABLE SET INTEGER Option="\x0D" Destination="%Lengthz%" Text_Variable="%z%"/>
<VARIABLE MODIFY INTEGER Option="\x02" Destination="%FudgeFactor%" Value1="%Lengthz%" Value2="10" _COMMENT="Experiment with multiplier to find a value that gives good results"/>
<TEXT TYPE Action="0" Text="%FudgeFactor%"/>

 

Share this post


Link to post
Share on other sites

Thanks Alan, much appreciate your nice work on this. But your macro means abandoning my existing familiar one, which I'd not want to do. At present it achieves the task of adding the 'unpercented name', in the logical place, namely within each such TBD, at the time they are inserted, where the variables can be reliably entered. If I've understood correctly your approach requires searching for them later, to add the 'unpercented name' and also do the sizing work, yes? On a specific, how and when do you expect the clipboard to capture the name of each variable? As I'm having some trouble testing it, would you mind sending me whatever files make up your own test environment please.

 

If indeed it's possible at all I'd want any sizing to be either done in an add-on to my macro, or to follow it immediately in a fresh macro. The only ideas I had were to somehow (!) use either the complex Run macro in variable command, or the registry to manage the variable data.

 

In practice, I guess the width and height and then change it after the first run. So I'm ready to conclude that this is one of those 'nice-to-have' macros that are not really worth the effort, apart admittedly for the intellectual satisfaction!

 

Terry

 

 

 

Share this post


Link to post
Share on other sites

Hi Terry,

 

I tested my script in the Macro Express Scripting Editor, so there are no files and no testing environments, other than Macro Express. You can copy my script and paste it directly into the Scripting Editor. Set the scope to the Scripting Editor, add an activation, and hopefully you're good to go.

 

My approach may not be applicable for how you use Macro Express. For example, I don't know where variable names are coming from, so I opted to use the clipboard. (I almost always copy the names of variables from one place in the code and paste it in other places. I almost never choose the variable name I want from a list, although I imagine this is how many people do it.) 

 

As I read your descriptions, I'm getting a stronger picture of what you're after. You don't need a way to open a new "Text Box Display" dialog. (Which is the primary purpose of my script.) Instead, your goal is to modify existing "Text Box Display" dialogs: you want to add data to the end of the "Box Content" field, like this?

 

Hello = %Hello%

World = %World%

IsThisCorrect = %IsThisCorrect%

 

I think we agree that automating the sizing of the box would be nice addition, but would not easy to accomplish. But I wouldn't put it past you do come up with a workable solution!

Share this post


Link to post
Share on other sites

Hi Alan,

 

Yep, you’re right on the mark there. I may return to it but meanwhile so much other stuff to do.

 

Not least drastically culling my 2,300 macros! A key obstacle to that is avoiding removal of sub macros. MX Pro has no reliable way to identify which of these gets used in ‘main’ macros.

Share this post


Link to post
Share on other sites
Quote

MX Pro has no reliable way to identify which of these [sub macros] gets used in ‘main’ macros.

 

I guess that's because Macro Express does not consider a called macro as having been run. So its "Last Run Time" doesn't get updated.

 

In the "Miscellaneous" tab you can check "Log All Commands." This will generate a log file of every step when a macro is run, even if the macro has been called from another. The name of he file will contain the nickname of the macro. Perhaps it would be a good practice to ensure this check box is always checked.

 

Hope you manage to sift through all of those macros without accidentally culling ones you really need to keep!

Share this post


Link to post
Share on other sites
7 hours ago, terrypin said:

MX Pro has no reliable way to identify which of these gets used in ‘main’ macros.

 

I have these two commands at the beginning of every macro.  (I wrote a macro to put them there.)  The result is a single log file, rather than a separate log for each macro.    Because "Log Messages" explicitly logs each macro, called macros are just as easy to identify as main macros.  The single log is especially useful for complicated applications where you want to see the sequence and timing that related macros ran.  Also, for trace and/or diagnostic purposes you can scatter "Log Messages" commands throughout your macro and examine them later at your leisure.  I generally inactivate the diagnostic logging after a macro is debugged, but leave the commands in place so they are easy to reactivate if later problems appear.  

 

A very short sample of my log is below.  Macro Express inserts the "Macro Completed" lines, so between that and the "Log Messages" at the beginning you know when and for how long a macro ran.  Notice in the last log sample that "0_Generic_Copy_To_Clipboard" is a called macro; it's beginning is indicated by the explicit "Log Messages" command within the macro, but Macro Express does NOT tell us when it ended, same as macro explorer says last run time was "Never."  If you needed to know how long the called macro took to run, you could put your own time-stamped "Log Messages" command at the end of it. 

 

Commands:

     Log Messages to "C:\Temp\MacroExpressProLogFiles\MacroExpressPro_Macro_Log_File.txt"
       "Macro executed: 0_Generic_Copy_To_Clipboard"
     Log Errors to "C:\Temp\MacroExpressProLogFiles\MacroExpressPro_Macro_Log_File.txt"

 

7/16/2020 12:32:41 PM: Macro executed: Kybd_Paste_Solitaire_Hint
Thursday, July 16, 2020 12:32:42 PM: Macro Completed (Kybd_Paste_Solitaire_Hint)

 

7/16/2020 12:33:18 PM: Macro executed: 1_Type_gmail_eMail_Address
Thursday, July 16, 2020 12:33:19 PM: Macro Completed (1_Type_gmail_eMail_Address)

 

7/16/2020 12:34:26 PM: Macro executed: 1_Close_Application_or_Browser_Window
Thursday, July 16, 2020 12:34:26 PM: Macro Completed (1_Close_Application_or_Browser_Window)

 

7/16/2020 12:34:27 PM: Macro executed: 1_Close_Application_or_Browser_Window
Thursday, July 16, 2020 12:34:27 PM: Macro Completed (1_Close_Application_or_Browser_Window)

 

7/16/2020 12:36:12 PM: Macro executed: 1_GoToForumLink_or_eMail
7/16/2020 12:36:12 PM: Macro executed: 0_Generic_Copy_To_Clipboard
Thursday, July 16, 2020 12:36:13 PM: Macro Completed (1_GoToForumLink_or_eMail)

 

 

 

Share this post


Link to post
Share on other sites
8 hours ago, terrypin said:

MX Pro has no reliable way to identify which of these gets used in ‘main’ macros.

 

Alternative to the logging method above: Write a macro to step through Macro Explorer, opening each macro and looking for "Macro Run" commands and appending them to a text file.  At your leisure you can look at the text file to see the called macros that are not to be deleted. 

Share this post


Link to post
Share on other sites
Quote

Write a macro to step through Macro Explorer, opening each macro and looking for "Macro Run" commands and appending them to a text file. 

 

Another Macro Express Challenge!

Share this post


Link to post
Share on other sites

Excellent posts, thanks! I’ve plainly neglected error logging for far too long and those will be a great help.

 

But the last recommendation gets the seegar, thanks so much @rberq. Of course, embarrassingly obvious once you see it suggested!

 

And, thanks to Cory, I already I have his brilliant macro ‘Search and report on macro text’ which will do the job nicely.

Share this post


Link to post
Share on other sites

So, I finally got around to your suggestion for automating insertion of commands.  The more I thought about it, the more I agreed with you that it could save a lot of time.  Instead of using separate hot keys for each inserted command, I used a single hot key to start the “insert” macro.  The macro displays a menu of commands to be inserted, with the ampersand (&) to make each menu item keyboard-selectable.  

 

There is more code for most commands to select generic options, so what is inserted is really a “dummy” command that must be modified afterwards.  For example, the inserted “Variable Set String” sets a dummy variable to null.  

 

In addition, certain menu selections insert multiple dummy commands: selecting “Repeat Start” results in a skeleton loop:
     Repeat Start
         Repeat Exit
     End Repeat
Selecting “If Variable” results in a skeleton
     If %T[99]% Equals “”
          Else
     End If

//  
Log Messages to "C:\Temp\MacroExpressProLogFiles\MacroExpressPro_Macro_Log_File.txt"
  "Macro executed: 2x_Insert_Common_Macro_Commands"
Log Errors to "C:\Temp\MacroExpressProLogFiles\MacroExpressPro_Macro_Log_File.txt"
Keystroke Speed: 30 milliseconds
Mouse Speed: 30 milliseconds
//  
// Macro displays a multiple-choice box, inserts selected command into macro
//  
If Not Window "Macro Express Pro - Script Editor" is focused
  Macro Return
End If
//  
// Multiple-choice box
Multiple Choice Menu: Command List
Variable Modify String: Replace "&" in %command% with ""
If Variable %command% Equals "" // On null selection, end macro

  OR
If Variable %command% Equals "X - Exit, No Command" // On null selection, end macro

  Macro Return
End If
//  
// Prepare command panel to insert the chosen instruction
Text Type (Simulate Keystrokes): <ALTD><ARROW DOWN><ALTU> // Alt-DownArrow to move to "Search for command" field
// Select the chosen command from the list
Text Type (Simulate Keystrokes): %command%
Text Type (Simulate Keystrokes): <ENTER> // ENTER to insert the command
//  
// For some commands, do extra keystrokes and/or inserts
If Variable %command% Equals "Comment" // COMMENT
  Text Type (Simulate Keystrokes): <SPACE><TAB><ENTER> // One blank space and ENTER to insert the comment
End If
//  
If Variable %command% Equals "Delay" // DELAY
  Text Type (Simulate Keystrokes): <ARROW DOWN><TAB>250<TAB><TAB><SPACE><TAB><ENTER> // Set 250ms, ignore macro speed factor, ENTER command
End If
//  
If Variable %command% Equals "If Variable" // IF VARIABLE For If Variable, also enter Else and End If
  Delay: 250 milliseconds
  Text Type (Simulate Keystrokes): <TAB><TAB>%T[99]<TAB><TAB><TAB><TAB><TAB><ENTER> // ENTER to insert the command
  Delay: 250 milliseconds
  Text Type (Simulate Keystrokes): <ALTD><ARROW DOWN><ALTU>
  Text Type (Simulate Keystrokes): Else
  Text Type (Simulate Keystrokes): <ENTER> // ENTER to insert the command
  Delay: 250 milliseconds
  Text Type (Simulate Keystrokes): <ALTD><ARROW DOWN><ALTU>
  Text Type (Simulate Keystrokes): End If
  Text Type (Simulate Keystrokes): <ENTER> // ENTER to insert the command
End If
//  
If Variable %command% Equals "Mouse Move" // MOUSE MOVE
  Text Type (Simulate Keystrokes): <TAB><TAB><TAB><TAB><TAB><TAB><ENTER> // Set 250ms, ignore macro speed factor, ENTER command
End If
//  
If Variable %command% Equals "Repeat Start" // REPEAT START For Repeat Start, also enter a Repeat Exit and End Repeat
  Text Type (Simulate Keystrokes): <ENTER> // ENTER to insert the command
  Delay: 250 milliseconds
  Text Type (Simulate Keystrokes): <ALTD><ARROW DOWN><ALTU>
  Text Type (Simulate Keystrokes): Repeat Exit
  Text Type (Simulate Keystrokes): <ENTER> // ENTER to insert the command
  Delay: 250 milliseconds
  Text Type (Simulate Keystrokes): <ALTD><ARROW DOWN><ALTU>
  Text Type (Simulate Keystrokes): End Repeat
  Text Type (Simulate Keystrokes): <ENTER> // ENTER to insert the command
End If
//  
If Variable %command% Equals "Text Type" // TEXT TYPE
  Macro Return
End If
//  
If Variable %command% Equals "Text Box Display" // TEXT BOX DISPLAY
  Macro Return
End If
//  
If Variable %command% Equals "Variable Set String" // VARIABLE SET STRING
  Delay: 250 milliseconds
  Text Type (Simulate Keystrokes): <TAB><TAB>
  Variable Set String %T[99]% to "%T[99]%"
  Text Type (Simulate Keystrokes): %T[99]%
  Text Type (Simulate Keystrokes): <TAB><TAB><TAB><TAB><ENTER>
End If
//  
If Variable %command% Equals "Variable Modify String" // VARIABLE MODIFY STRING
  Delay: 250 milliseconds
  Text Type (Simulate Keystrokes): <TAB><TAB>
  Variable Set String %T[99]% to "%T[99]%"
  Text Type (Simulate Keystrokes): %T[99]%
  Text Type (Simulate Keystrokes): <TAB><TAB><ENTER>
End If
//  
//  
//  
Macro Return
//  ////////////////////////////////////////////////////////////

 


<COMMENT Value=" "/>
<LOG MESSAGES Filename="C:\\Temp\\MacroExpressProLogFiles\\MacroExpressPro_Macro_Log_File.txt" Message="Macro executed: 2x_Insert_Common_Macro_Commands" Stamp="TRUE"/>
<LOG ERRORS Filename="C:\\Temp\\MacroExpressProLogFiles\\MacroExpressPro_Macro_Log_File.txt" Hide_Errors="FALSE"/>
<KEYSTROKE SPEED Delay="30"/>
<MOUSE SPEED Delay="30"/>
<COMMENT Value=" "/>
<COMMENT Value="Macro displays a multiple-choice box, inserts selected command into macro"/>
<COMMENT Value=" "/>
<IF NOT WINDOW Option="\x00" Title="Macro Express Pro - Script Editor" Partial="TRUE" Wildcards="FALSE"/>
<MACRO RETURN/>
<END IF/>
<COMMENT Value=" "/>
<COMMENT Value="Multiple-choice box"/>
<MULTIPLE CHOICE MENU Style="\x00" Result="\x01" Dest="%command%" Title="Command List" Prompt=" Choose command to insert" Options="&Comment\r\n&Delay\r\n&If Variable\r\nMacro R&eturn\r\n&Mouse Move\r\nMouse &Left Click\r\n&Repeat Start\r\n&Text Type\r\nText &Box Display\r\nVariable Set &String\r\nVariable M&odify String\r\n&X - Exit, No Command" Left="Center" Top="Center" Monitor="0" Width="443" Height="226" OnTop="FALSE" Columns="Auto"/>
<VARIABLE MODIFY STRING Option="\x0F" Destination="%command%" ToReplace="&" All="TRUE" IgnoreCase="FALSE" NoEmbeddedVars="FALSE"/>
<IF VARIABLE Variable="%command%" Condition="\x00" IgnoreCase="FALSE" _COMMENT="On null selection, end macro\r\n"/>
<OR/>
<IF VARIABLE Variable="%command%" Condition="\x00" Value="X - Exit, No Command" IgnoreCase="FALSE" _COMMENT="On null selection, end macro\r\n"/>
<MACRO RETURN/>
<END IF/>
<COMMENT Value=" "/>
<COMMENT Value="Prepare command panel to insert the chosen instruction"/>
<TEXT TYPE Action="0" Text="<ALTD><ARROW DOWN><ALTU>" _COMMENT="Alt-DownArrow to move to \"Search for command\" field"/>
<COMMENT Value="Select the chosen command from the list"/>
<TEXT TYPE Action="0" Text="%command%"/>
<TEXT TYPE Action="0" Text="<ENTER>" _COMMENT="ENTER to insert the command"/>
<COMMENT Value=" "/>
<COMMENT Value="For some commands, do extra keystrokes and/or inserts"/>
<IF VARIABLE Variable="%command%" Condition="\x00" Value="Comment" IgnoreCase="FALSE" _COMMENT="COMMENT"/>
<TEXT TYPE Action="0" Text="<SPACE><TAB><ENTER>" _COMMENT="One blank space and ENTER to insert the comment"/>
<END IF/>
<COMMENT Value=" "/>
<IF VARIABLE Variable="%command%" Condition="\x00" Value="Delay" IgnoreCase="FALSE" _COMMENT="DELAY"/>
<TEXT TYPE Action="0" Text="<ARROW DOWN><TAB>250<TAB><TAB><SPACE><TAB><ENTER>" _COMMENT="Set 250ms, ignore macro speed factor, ENTER command"/>
<END IF/>
<COMMENT Value=" "/>
<IF VARIABLE Variable="%command%" Condition="\x00" Value="If Variable" IgnoreCase="FALSE" _COMMENT="IF VARIABLE For If Variable, also enter Else and End If"/>
<DELAY Flags="\x12" Time="250"/>
<TEXT TYPE Action="0" Text="<TAB><TAB>%T[99]<TAB><TAB><TAB><TAB><TAB><ENTER>" _COMMENT="ENTER to insert the command"/>
<DELAY Flags="\x12" Time="250"/>
<TEXT TYPE Action="0" Text="<ALTD><ARROW DOWN><ALTU>"/>
<TEXT TYPE Action="0" Text="Else"/>
<TEXT TYPE Action="0" Text="<ENTER>" _COMMENT="ENTER to insert the command"/>
<DELAY Flags="\x12" Time="250"/>
<TEXT TYPE Action="0" Text="<ALTD><ARROW DOWN><ALTU>"/>
<TEXT TYPE Action="0" Text="End If"/>
<TEXT TYPE Action="0" Text="<ENTER>" _COMMENT="ENTER to insert the command"/>
<END IF/>
<COMMENT Value=" "/>
<IF VARIABLE Variable="%command%" Condition="\x00" Value="Mouse Move" IgnoreCase="FALSE" _COMMENT="MOUSE MOVE"/>
<TEXT TYPE Action="0" Text="<TAB><TAB><TAB><TAB><TAB><TAB><ENTER>" _COMMENT="Set 250ms, ignore macro speed factor, ENTER command"/>
<END IF/>
<COMMENT Value=" "/>
<IF VARIABLE Variable="%command%" Condition="\x00" Value="Repeat Start" IgnoreCase="FALSE" _COMMENT="REPEAT START For Repeat Start, also enter a Repeat Exit and End Repeat"/>
<TEXT TYPE Action="0" Text="<ENTER>" _COMMENT="ENTER to insert the command"/>
<DELAY Flags="\x12" Time="250"/>
<TEXT TYPE Action="0" Text="<ALTD><ARROW DOWN><ALTU>"/>
<TEXT TYPE Action="0" Text="Repeat Exit"/>
<TEXT TYPE Action="0" Text="<ENTER>" _COMMENT="ENTER to insert the command"/>
<DELAY Flags="\x12" Time="250"/>
<TEXT TYPE Action="0" Text="<ALTD><ARROW DOWN><ALTU>"/>
<TEXT TYPE Action="0" Text="End Repeat"/>
<TEXT TYPE Action="0" Text="<ENTER>" _COMMENT="ENTER to insert the command"/>
<END IF/>
<COMMENT Value=" "/>
<IF VARIABLE Variable="%command%" Condition="\x00" Value="Text Type" IgnoreCase="FALSE" _COMMENT="TEXT TYPE"/>
<MACRO RETURN/>
<END IF/>
<COMMENT Value=" "/>
<IF VARIABLE Variable="%command%" Condition="\x00" Value="Text Box Display" IgnoreCase="FALSE" _COMMENT="TEXT BOX DISPLAY"/>
<MACRO RETURN/>
<END IF/>
<COMMENT Value=" "/>
<IF VARIABLE Variable="%command%" Condition="\x00" Value="Variable Set String" IgnoreCase="FALSE" _COMMENT="VARIABLE SET STRING"/>
<DELAY Flags="\x12" Time="250"/>
<TEXT TYPE Action="0" Text="<TAB><TAB>"/>
<VARIABLE SET STRING Option="\x00" Destination="%T[99]%" Value="%T[99]%" NoEmbeddedVars="TRUE"/>
<TEXT TYPE Action="0" Text="%T[99]%"/>
<TEXT TYPE Action="0" Text="<TAB><TAB><TAB><TAB><ENTER>"/>
<END IF/>
<COMMENT Value=" "/>
<IF VARIABLE Variable="%command%" Condition="\x00" Value="Variable Modify String" IgnoreCase="FALSE" _COMMENT="VARIABLE MODIFY STRING"/>
<DELAY Flags="\x12" Time="250"/>
<TEXT TYPE Action="0" Text="<TAB><TAB>"/>
<VARIABLE SET STRING Option="\x00" Destination="%T[99]%" Value="%T[99]%" NoEmbeddedVars="TRUE"/>
<TEXT TYPE Action="0" Text="%T[99]%"/>
<TEXT TYPE Action="0" Text="<TAB><TAB><ENTER>"/>
<END IF/>
<COMMENT Value=" "/>
<COMMENT Value=" "/>
<COMMENT Value=" "/>
<MACRO RETURN/>
<COMMENT Value=" "/>

 

macro.JPG

Share this post


Link to post
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...