Jump to content
Macro Express Forums
acantor

Challenge: hotkeys to move text without selecting

Recommended Posts

For anybody who writes and revises documents, there are two incredibly useful Microsoft Word commands that many (if not most) people don’t know. The hotkeys for these commands are:

 

Alt + Shift + Down arrow

Alt + Shift + Up arrow

 

The first hotkey selects the entire paragraph and moves it DOWN by one paragraph. The second hotkey does the same but in the opposite direction.

 

A cool thing about these two commands: they don’t involve the clipboard. The commands move entire paragraphs without the need to select, copy, cut, or paste.

 

I emphasize: These commands act on the entire paragraph that contains the insertion point (cursor), whether or not text is selected.

 

The same two hotkeys also work in PowerPoint text boxes, and in Outlook email messages (HTML and Rich Text only, not Plain Text).

 

The challenge is to create Macro Express scripts to add these two hotkeys to other programs. You can choose any program you like, but here are a few examples you might want to consider:

 

1.    WordPad: Move a paragraph up and down.

2.    Notepad: Move a line up and down . (I don’t think it’s possible with paragraphs, but prove me wrong if you can!)

3.    Excel: Move the entire row up and down.

4.    Excel: Move the entire column left and right. (Perhaps use Alt + Shift + Left and Alt + Shift + Right)

 

One hint:

Although the built-in commands for moving paragraphs don’t use the clipboard, your Macro Express commands probably will!

 

Share this post


Link to post
Share on other sites

I've used those and many more often. One thing I tell any aspiring macro writer to do first is find a reference for the application they're automating and evaluate all the keyboard shortcuts.

Sorry, no time to take up your challenge today. 

Share this post


Link to post
Share on other sites

I agree a ME macro will likely need the clipboard.  After all, an application like Word already HAS the document in memory, where ME does not.  And even though the Microsoft apps may not use the standard Windows clipboard, they must be using an internal equivalent.  I'm going to tackle the easy one first: Notepad. 

Share this post


Link to post
Share on other sites

In VBA (the underlying macro language for Word), in addition to being able to act on the contents of the clipboard, one can also act on the contents of the selection: the data that has been selected in a Word document. The selection can be text, formatting information, images, or, when nothing is selected, the text cursor itself. The selection is not so much a clipboard equivalent, but an entirely different way to handle data.

 

Because we don't have direct, programmatic access to the selection via Macro Express, we can have challenges like this...

Share this post


Link to post
Share on other sites

Well, I have a preliminary version working for Notepad.  It moves a paragraph down; moving it up would be similar.  It requires that the text be typed continuously in Notepad, using the ENTER key only to start a new paragraph.  That means the CR-LF sequence exists only at the end of a paragraph.  

 

Logic of the macro is first to type an oddball string at the insertion point – wherever the mouse is positioned within the paragraph to be moved down.  Then, get the whole document into a variable, and replace every CR-LF with an octal 02, an unprintable character that will never exist in normal text.  Replacing CR-LF with a single byte is done because Macro Express needs a single byte for splitting.  The text is then split on &02 into array %paragraph%.  Each item in the array is searched for the oddball string that the macro initially typed, and when found that array item is swapped with the subsequent one.  The items of array %paragraph% are then concatenated to an output string, with CR-LF appended after each paragraph, and the oddball marker string is removed.  

 

It works fine when the text follows the constraints I defined.  However, when I loaded the text of a book from Project Gutenberg, there was a CR-LF for every line, and paragraphs delineated by double-spacing.  More work needed to handle these real-world cases!  

 

<COMMENT Value=" "/>
<LOG MESSAGES Filename="C:\\Temp\\MacroExpressProLogFiles\\MacroExpressPro_Macro_Log_File.txt" Message="Macro name: Kbyd_Paragraph" Stamp="TRUE"/>
<LOG ERRORS Hide_Errors="FALSE"/>
<COMMENT Value="Line Feed (New Line) character ascii 10"/>
<VARIABLE SET TO ASCII CHAR Value="10" Destination="%LF%"/>
<COMMENT Value="Carriage Return character ascii 13"/>
<VARIABLE SET TO ASCII CHAR Value="13" Destination="%CR%"/>
<COMMENT Value="Carriage Return / Line Feed combination characters ascii 13 + ascii 10"/>
<VARIABLE MODIFY STRING Option="\x08" Destination="%CRLF%" Variable="%CR%" NoEmbeddedVars="FALSE"/>
<VARIABLE MODIFY STRING Option="\x07" Destination="%CRLF%" Variable="%LF%" NoEmbeddedVars="FALSE"/>
<COMMENT Value="Octal 01 and 02 "/>
<VARIABLE SET TO ASCII CHAR Value="1" Destination="%Octal01%"/>
<VARIABLE SET TO ASCII CHAR Value="2" Destination="%Octal02%"/>
<COMMENT Value="Pattern to flag paragraph (insertion point) "/>
<VARIABLE SET STRING Option="\x00" Destination="%pattern%" Value=")(*()(*()(*()(*()(*()][\\][p" NoEmbeddedVars="FALSE"/>
<COMMENT Value="Maximum number of paragraphs to be handled by macro"/>
<COMMENT Value="Clear %paragraph% array to hold up to 50 paragraphs "/>
<VARIABLE SET INTEGER Option="\x00" Destination="%max_paragraphs%" Value="50"/>
<CLEAR VARIABLES Type="Text Variables" Option="\x01" Variable="%paragraph%" Start="1" End="%max_paragraphs%" _COMMENT="clear storage array to hold paragraphs"/>
<COMMENT Value=" "/>
<COMMENT Value="Text file should be already open in Notepad, with mouse hovering over paragraph which is to be moved down.\r\nInsert funny pattern of characters at insertion point."/>
<MOUSE LEFT CLICK/>
<TEXT TYPE Action="0" Text="%pattern%"/>
<COMMENT Value=" "/>
<COMMENT Value="Get Notepad content into veriable %book%. "/>
<MACRO RUN Use_ID="FALSE" Name="0_Kybd_Copy_All" ID="-1" Wait="TRUE"/>
<VARIABLE SET STRING Option="\x02" Destination="%book%" NoEmbeddedVars="FALSE"/>
<DELAY Flags="\x11" Time="2" _ENABLED="FALSE"/>
<TEXT BOX DISPLAY Title="Debugging -- display book content with pattern inserted" Content="{\\rtf1\\ansi\\ansicpg1252\\deff0\\deflang1033{\\fonttbl{\\f0\\fnil\\fcharset0 Tahoma;}{\\f1\\fnil Tahoma;}}\r\n\\viewkind4\\uc1\\pard\\f0\\fs20 %book%\\f1 \r\n\\par }\r\n" Left="25" Top="114" Width="1289" Height="566" Monitor="0" OnTop="FALSE" Keep_Focus="TRUE" Mode="\x00" Delay="0" _ENABLED="FALSE"/>
<COMMENT Value=" "/>
<COMMENT Value="Make sure ESC character does not exist in the text, also no octal 01 or 02"/>
<VARIABLE MODIFY STRING Option="\x07" Destination="%book%" Variable="%Octal02%" NoEmbeddedVars="FALSE" _ENABLED="FALSE"/>
<IF VARIABLE Variable="%book%" Condition="\x06" Value="%Octal02%" IgnoreCase="FALSE"/>
<TEXT BOX DISPLAY Title="Error" Content="{\\rtf1\\ansi\\ansicpg1252\\deff0\\deflang1033{\\fonttbl{\\f0\\fnil\\fcharset0 Tahoma;}{\\f1\\fnil Tahoma;}}\r\n\\viewkind4\\uc1\\pard\\f0\\fs20 Error: ZIP macro -- text to be compressed already contains the ESC Escape character, or an octal 01 or 02.  These characters are not allowed, because they are used for special purposes within this macro.\r\n\\par \r\n\\par Macro aborted.  \\f1 \r\n\\par }\r\n" Left="Center" Top="Center" Width="278" Height="200" Monitor="0" OnTop="TRUE" Keep_Focus="TRUE" Mode="\x00" Delay="0"/>
<MACRO RETURN/>
<END IF/>
<COMMENT Value=" "/>
<COMMENT Value="Right-trim the overall text and add another copy of the marker pattern to the end,\r\npreceded by octal 02 so it will be split out as a (dummy) concluding paragraph. "/>
<VARIABLE MODIFY STRING Option="\x02" Destination="%book%"/>
<VARIABLE MODIFY STRING Option="\x06" Destination="%book%" Value="%Octal02%" NoEmbeddedVars="FALSE"/>
<VARIABLE MODIFY STRING Option="\x06" Destination="%book%" Value="%pattern%" NoEmbeddedVars="FALSE"/>
<VARIABLE MODIFY STRING Option="\x06" Destination="%book%" Value="%Octal02%" NoEmbeddedVars="FALSE" _ENABLED="FALSE"/>
<VARIABLE SET INTEGER Option="\x0D" Destination="%length_book%" Text_Variable="%book%"/>
<COMMENT Value=" "/>
<COMMENT Value="Replace all CRLF within text by octal 02."/>
<VARIABLE MODIFY STRING Option="\x0F" Destination="%book%" ToReplace="%CRLF%" ReplaceWith="%Octal02%" All="TRUE" IgnoreCase="FALSE" NoEmbeddedVars="FALSE"/>
<TEXT BOX DISPLAY Title="Diagnostics -- modified text with octal 02" Content="{\\rtf1\\ansi\\ansicpg1252\\deff0\\deflang1033{\\fonttbl{\\f0\\fnil\\fcharset0 Tahoma;}{\\f1\\fnil Tahoma;}}\r\n\\viewkind4\\uc1\\pard\\f0\\fs20 %book%\\f1 \r\n\\par }\r\n" Left="Center" Top="Center" Width="1348" Height="597" Monitor="0" OnTop="TRUE" Keep_Focus="TRUE" Mode="\x00" Delay="0" _ENABLED="FALSE"/>
<COMMENT Value=" "/>
<COMMENT Value="Split out text into paragraphs based on CRLF (which has been replaced by octal 02). "/>
<SPLIT STRING Source="%book%" SplitChar="%Octal02%" Dest="%paragraph%" Index="1"/>
<TEXT BOX DISPLAY Title="Diagnostics -- paragraphs 1 to 12" Content="{\\rtf1\\ansi\\ansicpg1252\\deff0\\deflang1033{\\fonttbl{\\f0\\fnil\\fcharset0 Tahoma;}{\\f1\\fnil Tahoma;}}\r\n\\viewkind4\\uc1\\pard\\f0\\fs20 %paragraph[1]%\r\n\\par \r\n\\par %paragraph[2]%\r\n\\par \r\n\\par %paragraph[3]%\r\n\\par \r\n\\par %paragraph[4]%\r\n\\par \\f1 \r\n\\par \\f0 %paragraph[5]%\r\n\\par \r\n\\par %paragraph[6]%\r\n\\par \r\n\\par %paragraph[7]%\r\n\\par \r\n\\par %paragraph[8]%\r\n\\par \r\n\\par %paragraph[9]%\r\n\\par \r\n\\par %paragraph[10]%\r\n\\par \r\n\\par %paragraph[11]%\r\n\\par \r\n\\par %paragraph[12]%\\f1 \r\n\\par \r\n\\par \r\n\\par \r\n\\par \r\n\\par \r\n\\par \r\n\\par }\r\n" Left="7" Top="89" Width="1352" Height="596" Monitor="0" OnTop="TRUE" Keep_Focus="TRUE" Mode="\x00" Delay="0" _ENABLED="FALSE"/>
<COMMENT Value=" "/>
<COMMENT Value="Scan paragraphs in array looking for special pattern that we inserted earlier.\r\nMake sure to take the first pattern, so as not to use the extra pattern that\r\nwe inserted at the end. "/>
<VARIABLE SET INTEGER Option="\x00" Destination="%paragraph_index%" Value="0"/>
<VARIABLE SET INTEGER Option="\x00" Destination="%index_of_paragraph_to_be_moved%" Value="0"/>
<REPEAT UNTIL Variable="%paragraph_index%" Condition="\x04" Value="%max_paragraphs%"/>
<VARIABLE MODIFY INTEGER Option="\x07" Destination="%paragraph_index%"/>
<IF VARIABLE Variable="%paragraph[%paragraph_index%]%" Condition="\x06" Value="%pattern%" IgnoreCase="FALSE"/>
<VARIABLE MODIFY INTEGER Option="\x06" Destination="%index_of_paragraph_to_be_moved%" Variable="%paragraph_index%"/>
<REPEAT EXIT/>
<END IF/>
<END REPEAT/>
<TEXT BOX DISPLAY Title="Diagnostics -- paragraph containing pattern" Content="{\\rtf1\\ansi\\ansicpg1252\\deff0\\deflang1033{\\fonttbl{\\f0\\fnil\\fcharset0 Tahoma;}{\\f1\\fnil Tahoma;}}\r\n\\viewkind4\\uc1\\pard\\f0\\fs20 Paragraph %index_of_paragraph_to_be_moved% contains the marker pattern\\f1 \r\n\\par \r\n\\par }\r\n" Left="Center" Top="Center" Width="543" Height="171" Monitor="0" OnTop="TRUE" Keep_Focus="TRUE" Mode="\x00" Delay="0" _ENABLED="FALSE"/>
<COMMENT Value=" "/>
<COMMENT Value="Switch the pattern-marked paragraph with the subsequent paragraph "/>
<VARIABLE MODIFY INTEGER Option="\x00" Destination="%index_of_subsequent_paragraph%" Value1="%index_of_paragraph_to_be_moved%" Value2="1"/>
<VARIABLE MODIFY STRING Option="\x08" Destination="%temporary_paragraph%" Variable="%paragraph[%index_of_paragraph_to_be_moved%]%" NoEmbeddedVars="FALSE"/>
<VARIABLE MODIFY STRING Option="\x08" Destination="%paragraph[%index_of_paragraph_to_be_moved%]%" Variable="%paragraph[%index_of_subsequent_paragraph%]%" NoEmbeddedVars="FALSE"/>
<VARIABLE MODIFY STRING Option="\x08" Destination="%paragraph[%index_of_subsequent_paragraph%]%" Variable="%temporary_paragraph%" NoEmbeddedVars="FALSE"/>
<COMMENT Value=" "/>
<COMMENT Value="Build output text by concatenating paragraphs.  \r\nAppend to each paragraph the octal 02 that was removed by the Strip command."/>
<VARIABLE SET STRING Option="\x00" Destination="%book1%" NoEmbeddedVars="FALSE"/>
<VARIABLE SET INTEGER Option="\x00" Destination="%paragraph_index%" Value="0"/>
<REPEAT UNTIL Variable="%paragraph_index%" Condition="\x04" Value="%max_paragraphs%"/>
<VARIABLE MODIFY INTEGER Option="\x07" Destination="%paragraph_index%"/>
<IF VARIABLE Variable="%paragraph[%paragraph_index%]%" Condition="\x00" IgnoreCase="FALSE"/>
<ELSE/>
<VARIABLE MODIFY STRING Option="\x07" Destination="%book1%" Variable="%paragraph[%paragraph_index%]%" NoEmbeddedVars="FALSE"/>
<VARIABLE MODIFY STRING Option="\x07" Destination="%book1%" Variable="%Octal02%" NoEmbeddedVars="FALSE"/>
<END IF/>
<END REPEAT/>
<VARIABLE SET INTEGER Option="\x0D" Destination="%length_book1%" Text_Variable="%book1%"/>
<TEXT BOX DISPLAY Title="Diagnostics -- output rebuilt, but without CRLFs" Content="{\\rtf1\\ansi\\ansicpg1252\\deff0\\deflang1033{\\fonttbl{\\f0\\fnil\\fcharset0 Tahoma;}{\\f1\\fnil Tahoma;}}\r\n\\viewkind4\\uc1\\pard\\f0\\fs20 Length of original book %length_book%\r\n\\par Length of modified book1 %length_book1%\r\n\\par \r\n\\par %book1%\\f1 \r\n\\par \r\n\\par }\r\n" Left="Center" Top="Center" Width="1345" Height="613" Monitor="0" OnTop="TRUE" Keep_Focus="TRUE" Mode="\x00" Delay="0" _ENABLED="FALSE"/>
<COMMENT Value=" "/>
<COMMENT Value="Put back the CRLF sequences that we previously converted to octal 02."/>
<VARIABLE MODIFY STRING Option="\x0F" Destination="%book1%" ToReplace="%Octal02%" ReplaceWith="%CRLF%" All="TRUE" IgnoreCase="FALSE" NoEmbeddedVars="FALSE"/>
<TEXT BOX DISPLAY Title="Diagnostics -- output rebuilt, CRLFs restored" Content="{\\rtf1\\ansi\\ansicpg1252\\deff0\\deflang1033{\\fonttbl{\\f0\\fnil\\fcharset0 Tahoma;}{\\f1\\fnil Tahoma;}}\r\n\\viewkind4\\uc1\\pard\\f0\\fs20 %book1%\\f1 \r\n\\par \r\n\\par }\r\n" Left="Center" Top="Center" Width="1345" Height="613" Monitor="0" OnTop="TRUE" Keep_Focus="TRUE" Mode="\x00" Delay="0" _ENABLED="FALSE"/>
<COMMENT Value=" "/>
<COMMENT Value="Remove the marker pattern from the text "/>
<VARIABLE MODIFY STRING Option="\x0F" Destination="%book1%" ToReplace="%pattern%" All="TRUE" IgnoreCase="FALSE" NoEmbeddedVars="FALSE"/>
<TEXT BOX DISPLAY Title="Diagnostics -- final output rebuilt, marker patterns removed" Content="{\\rtf1\\ansi\\ansicpg1252\\deff0\\deflang1033{\\fonttbl{\\f0\\fnil\\fcharset0 Tahoma;}{\\f1\\fnil Tahoma;}}\r\n\\viewkind4\\uc1\\pard\\f0\\fs20 %book1%\\f1 \r\n\\par \r\n\\par }\r\n" Left="Center" Top="Center" Width="1345" Height="613" Monitor="0" OnTop="TRUE" Keep_Focus="TRUE" Mode="\x00" Delay="0" _ENABLED="FALSE"/>
<COMMENT Value=" "/>
<COMMENT Value="Put the retructured text back into the Notepad area by highlighting all and pasting from clipboard"/>
<VARIABLE MODIFY STRING Option="\x10" Destination="%book1%" NoEmbeddedVars="FALSE"/>
<TEXT TYPE Action="0" Text="<CTRLD>a<CTRLU>"/>
<DELAY Flags="\x12" Time="500"/>
<TEXT TYPE Action="0" Text="<CTRLD>v<CTRLU>"/>
<COMMENT Value=" "/>
<COMMENT Value=" "/>
<MACRO RETURN/>
<COMMENT Value=" "/>

 

Share this post


Link to post
Share on other sites

My approach for Notepad (which swaps lines, not paragraphs; and only works if text wrap is toggled off) is entirely different. My two scripts output keystrokes for moving a line down or up. The macros mimic the behaviour of the Word commands that inspired this challenge by selecting the most recently moved text.

 

My scripts fail occasionally, probably due to timing issues. But I find them reliable enough to use when I am editing HTML files.

 

// Swap the current line with the line that's below it
Text Type (Simulate Keystrokes): <END><SHIFT><HOME> // Select current line, from end to start
Text Type (Simulate Keystrokes): <SHIFT><ARROW LEFT> // Extend the selection by one character to the left
Text Type (Simulate Keystrokes): <CONTROL>x
Text Type (Simulate Keystrokes): <ARROW DOWN><END> // Move down one line, go to end of it
Text Type (Simulate Keystrokes): <CONTROL>v
Text Type (Simulate Keystrokes): <SHIFT><HOME> // Re-select the line

<COMMENT Value="Swap the current line with the line that's below it"/>
<TEXT TYPE Action="0" Text="<END><SHIFT><HOME>" _COMMENT="Select current line, from end to start"/>
<TEXT TYPE Action="0" Text="<SHIFT><ARROW LEFT>" _COMMENT="Extend the selection by one character to the left"/>
<TEXT TYPE Action="0" Text="<CONTROL>x"/>
<TEXT TYPE Action="0" Text="<ARROW DOWN><END>" _COMMENT="Move down one line, go to end of it"/>
<TEXT TYPE Action="0" Text="<CONTROL>v"/>
<TEXT TYPE Action="0" Text="<SHIFT><HOME>" _COMMENT="Re-select the line"/>
// Swap the current line with the line that's above it
Text Type (Simulate Keystrokes): <HOME><SHIFT><END> // Select current line, from start to end
Text Type (Simulate Keystrokes): <SHIFT><ARROW RIGHT> // Extend the selection by one character to the right
Text Type (Simulate Keystrokes): <CONTROL>x
Text Type (Simulate Keystrokes): <ARROW UP><HOME> // Move up one line, go to start of line (just in case)
Text Type (Simulate Keystrokes): <CONTROL>v
Text Type (Simulate Keystrokes): <SHIFT><ARROW UP> // Re-select the line

<COMMENT Value="Swap the current line with the line that's above it"/>
<TEXT TYPE Action="0" Text="<HOME><SHIFT><END>" _COMMENT="Select current line, from start to end"/>
<TEXT TYPE Action="0" Text="<SHIFT><ARROW RIGHT>" _COMMENT="Extend the selection by one character to the right"/>
<TEXT TYPE Action="0" Text="<CONTROL>x"/>
<TEXT TYPE Action="0" Text="<ARROW UP><HOME>" _COMMENT="Move up one line, go to start of line (just in case)"/>
<TEXT TYPE Action="0" Text="<CONTROL>v"/>
<TEXT TYPE Action="0" Text="<SHIFT><ARROW UP>" _COMMENT="Re-select the line"/>
	

I'm working on versions of these commands for Outlook Plain Text messages. (The functionality for moving paragraphs up and down is built in for HTML and Rich Text messages, but not for Plain Text messages.) I initially tried to send keystrokes like my Notepad scripts, but the scripts got way too complex when I began uncovering one borderline situation after another, e.g., blank lines between paragraphs vs. none; first or last paragraph in the email message, etc.

 

So I (mostly) ditched keystrokes, and did something similar to you. My new version selects and copies two paragraphs, transfers the text to a variable, splits the string on the CRLF, and outputs the two paragraphs in reverse order. Hopefully I'll iron out the kinks soon. If I can't, I might borrow from your playbook and process the entire document in Variable Land!

Share this post


Link to post
Share on other sites
16 hours ago, acantor said:

My two scripts output keystrokes for moving a line down or up.

Often this approach works well for precisely-defined conditions, like what you used it for, and can be done in relatively-few keystrokes.  I used to have a wonderful keyboard where you just pressed one of twelve "program" keys, then entered whatever keystrokes you wanted.  Basically you could enter a keyboard macro in a matter of seconds, right within the keyboard.  My keyboard finally became obsolete because newer computers had no place to plug it in,😧 so I transitioned to Macro Express.  ME is vastly more powerful overall, but the programmable keyboard was vastly easier and faster for small keyboard-only sequences. 

 

Meanwhile, minor tweaks have made my Notepad macro work with more common document layouts that I mentioned above. 

Share this post


Link to post
Share on other sites

I hope you will share the latest version!

 

I thought that I had found a reliable method to select two paragraphs in Outlook plain text messages by sending keystrokes, but I may have hit a brick wall.  I haven't given up on the approach yet!

Share this post


Link to post
Share on other sites
23 hours ago, rberq said:

minor tweaks have made my Notepad macro work with more common document layouts that I mentioned above. 

Works well now with the more-common Notepad method of (1) using the ENTER key to start a new line, or just typing along and letting Notepad wrap the words; and (2) using two ENTERs in a row to start a new paragraph by double-spacing.  This involved simply scanning the text for two contiguous CRLFs, and if any is/are found, then all single CRLFs are removed.  Haven't really tested extensively with lots of documents -- it's fun but I don't envision much use for this macro. 

 

<COMMENT Value=" "/>
<LOG MESSAGES Filename="C:\\Temp\\MacroExpressProLogFiles\\MacroExpressPro_Macro_Log_File.txt" Message="Macro name: Kbyd_Paragraph" Stamp="TRUE"/>
<LOG ERRORS Hide_Errors="FALSE"/>
<COMMENT Value="Line Feed (New Line) character ascii 10"/>
<VARIABLE SET TO ASCII CHAR Value="10" Destination="%LF%"/>
<COMMENT Value="Carriage Return character ascii 13"/>
<VARIABLE SET TO ASCII CHAR Value="13" Destination="%CR%"/>
<COMMENT Value="Carriage Return / Line Feed combination characters ascii 13 + ascii 10"/>
<VARIABLE MODIFY STRING Option="\x08" Destination="%CRLF%" Variable="%CR%" NoEmbeddedVars="FALSE"/>
<VARIABLE MODIFY STRING Option="\x07" Destination="%CRLF%" Variable="%LF%" NoEmbeddedVars="FALSE"/>
<COMMENT Value="Octal 01 and 02 "/>
<VARIABLE SET TO ASCII CHAR Value="1" Destination="%Octal01%"/>
<VARIABLE SET TO ASCII CHAR Value="94" Destination="%Octal01%" _ENABLED="FALSE" _COMMENT="caret ^"/>
<VARIABLE SET TO ASCII CHAR Value="2" Destination="%Octal02%"/>
<VARIABLE SET TO ASCII CHAR Value="126" Destination="%Octal02%" _ENABLED="FALSE" _COMMENT="tilde ~"/>
<COMMENT Value="Pattern to flag paragraph (insertion point) "/>
<VARIABLE SET STRING Option="\x00" Destination="%pattern%" Value=")(*()(*()(*()(*()(*()][\\][p" NoEmbeddedVars="FALSE"/>
<COMMENT Value="Maximum number of paragraphs to be handled by macro"/>
<COMMENT Value="Clear %paragraph% array to hold up to 50 paragraphs "/>
<VARIABLE SET INTEGER Option="\x00" Destination="%max_paragraphs%" Value="500"/>
<CLEAR VARIABLES Type="Text Variables" Option="\x01" Variable="%paragraph%" Start="1" End="%max_paragraphs%" _COMMENT="clear storage array to hold paragraphs"/>
<COMMENT Value=" "/>
<COMMENT Value="Style_1 has one CRLF per paragraph.\r\nStyle_2 has a double-CRLF per paragraph, to double-space between paragraphs.\r\nStyle_2 may or may not have a CRLF for each line within a paragraph."/>
<COMMENT Value=" "/>
<COMMENT Value=" "/>
<COMMENT Value="Text file should be already open in Notepad, with mouse hovering over paragraph which is to be moved down.\r\nInsert funny pattern of characters at insertion point."/>
<MOUSE LEFT CLICK/>
<TEXT TYPE Action="0" Text="%pattern%"/>
<COMMENT Value=" "/>
<COMMENT Value="Get Notepad content into veriable %book%. "/>
<MACRO RUN Use_ID="FALSE" Name="0_Kybd_Copy_All" ID="-1" Wait="TRUE"/>
<VARIABLE SET STRING Option="\x02" Destination="%book%" NoEmbeddedVars="FALSE"/>
<DELAY Flags="\x11" Time="2" _ENABLED="FALSE"/>
<TEXT BOX DISPLAY Title="Debugging -- display book content with pattern inserted" Content="{\\rtf1\\ansi\\ansicpg1252\\deff0\\deflang1033{\\fonttbl{\\f0\\fnil\\fcharset0 Tahoma;}{\\f1\\fnil Tahoma;}}\r\n\\viewkind4\\uc1\\pard\\f0\\fs20 %book%\\f1 \r\n\\par }\r\n" Left="25" Top="114" Width="1289" Height="566" Monitor="0" OnTop="FALSE" Keep_Focus="TRUE" Mode="\x00" Delay="0" _ENABLED="FALSE"/>
<COMMENT Value=" "/>
<COMMENT Value="Make sure no octal 01 or 02 already exist in the text"/>
<IF VARIABLE Variable="%book%" Condition="\x06" Value="%Octal01%" IgnoreCase="FALSE"/>
<OR/>
<IF VARIABLE Variable="%book%" Condition="\x06" Value="%Octal02%" IgnoreCase="FALSE"/>
<TEXT BOX DISPLAY Title="Error" Content="{\\rtf1\\ansi\\ansicpg1252\\deff0\\deflang1033{\\fonttbl{\\f0\\fnil\\fcharset0 Tahoma;}{\\f1\\fnil Tahoma;}}\r\n\\viewkind4\\uc1\\pard\\f0\\fs20 Error: ZIP macro -- text to be compressed already contains the ESC Escape character, or an octal 01 or 02.  These characters are not allowed, because they are used for special purposes within this macro.\r\n\\par \r\n\\par Macro aborted.  \\f1 \r\n\\par }\r\n" Left="Center" Top="Center" Width="278" Height="200" Monitor="0" OnTop="TRUE" Keep_Focus="TRUE" Mode="\x00" Delay="0"/>
<MACRO RETURN/>
<END IF/>
<COMMENT Value=" "/>
<COMMENT Value="Right-trim the overall text and add another copy of the marker pattern to the end,\r\npreceded by octal 02 so it will be split out as a (dummy) concluding paragraph. "/>
<VARIABLE MODIFY STRING Option="\x02" Destination="%book%"/>
<VARIABLE MODIFY STRING Option="\x06" Destination="%book%" Value="%Octal02%" NoEmbeddedVars="FALSE"/>
<VARIABLE MODIFY STRING Option="\x06" Destination="%book%" Value="%pattern%" NoEmbeddedVars="FALSE"/>
<VARIABLE SET INTEGER Option="\x0D" Destination="%length_book%" Text_Variable="%book%"/>
<COMMENT Value=" "/>
<COMMENT Value="If text contains any double-CRLF, set Style_2 indicator.  Otherwise Style_1. \r\nIf Style_2, replace double-CRLFs by octal 01, so we know where to put back the\r\ndouble-CRLFs later on.  Then, if Style_2, get rid of single CRLFs (if any) that mark\r\nends of lines as opposed to paragraphs.  "/>
<IF VARIABLE Variable="%book%" Condition="\x06" Value="%CRLF%%CRLF%" IgnoreCase="FALSE"/>
<VARIABLE SET STRING Option="\x00" Destination="%style1%" Value="FALSE" NoEmbeddedVars="FALSE"/>
<VARIABLE SET STRING Option="\x00" Destination="%style2%" Value="TRUE" NoEmbeddedVars="FALSE"/>
<VARIABLE MODIFY STRING Option="\x0F" Destination="%book%" ToReplace="%CRLF%%CRLF%" ReplaceWith="%Octal01%" All="TRUE" IgnoreCase="FALSE" NoEmbeddedVars="FALSE"/>
<VARIABLE MODIFY STRING Option="\x0F" Destination="%book%" ToReplace="%CRLF%" ReplaceWith=" " All="TRUE" IgnoreCase="FALSE" NoEmbeddedVars="FALSE"/>
<VARIABLE MODIFY STRING Option="\x0F" Destination="%book%" ToReplace="%Octal01%" ReplaceWith="%CRLF%" All="TRUE" IgnoreCase="FALSE" NoEmbeddedVars="FALSE"/>
<ELSE/>
<VARIABLE SET STRING Option="\x00" Destination="%style1%" Value="TRUE" NoEmbeddedVars="FALSE"/>
<VARIABLE SET STRING Option="\x00" Destination="%style2%" Value="FALSE" NoEmbeddedVars="FALSE"/>
<END IF/>
<TEXT BOX DISPLAY Title="Diagnostics -- style" Content="{\\rtf1\\ansi\\ansicpg1252\\deff0\\deflang1033{\\fonttbl{\\f0\\fnil\\fcharset0 Tahoma;}{\\f1\\fnil Tahoma;}}\r\n\\viewkind4\\uc1\\pard\\f0\\fs20 style1 = %style1%\r\n\\par style2 = %style2%\\f1 \r\n\\par \r\n\\par }\r\n" Left="Center" Top="Center" Width="1348" Height="597" Monitor="0" OnTop="TRUE" Keep_Focus="TRUE" Mode="\x00" Delay="0"/>
<COMMENT Value=" "/>
<COMMENT Value="Replace all CRLF within text by octal 02."/>
<VARIABLE MODIFY STRING Option="\x0F" Destination="%book%" ToReplace="%CRLF%" ReplaceWith="%Octal02%" All="TRUE" IgnoreCase="FALSE" NoEmbeddedVars="FALSE"/>
<TEXT BOX DISPLAY Title="Diagnostics -- modified text with octal 02" Content="{\\rtf1\\ansi\\ansicpg1252\\deff0\\deflang1033{\\fonttbl{\\f0\\fnil\\fcharset0 Tahoma;}{\\f1\\fnil Tahoma;}}\r\n\\viewkind4\\uc1\\pard\\f0\\fs20 %book%\\f1 \r\n\\par }\r\n" Left="Center" Top="Center" Width="1348" Height="597" Monitor="0" OnTop="TRUE" Keep_Focus="TRUE" Mode="\x00" Delay="0" _ENABLED="FALSE"/>
<COMMENT Value=" "/>
<COMMENT Value="Split out text into paragraphs based on CRLF (which has been replaced by octal 02). "/>
<SPLIT STRING Source="%book%" SplitChar="%Octal02%" Dest="%paragraph%" Index="1"/>
<TEXT BOX DISPLAY Title="Diagnostics -- paragraphs 1 to 12" Content="{\\rtf1\\ansi\\ansicpg1252\\deff0\\deflang1033{\\fonttbl{\\f0\\fnil\\fcharset0 Tahoma;}{\\f1\\fnil Tahoma;}}\r\n\\viewkind4\\uc1\\pard\\f0\\fs20 %paragraph[1]%\r\n\\par \r\n\\par %paragraph[2]%\r\n\\par \r\n\\par %paragraph[3]%\r\n\\par \r\n\\par %paragraph[4]%\r\n\\par \\f1 \r\n\\par \\f0 %paragraph[5]%\r\n\\par \r\n\\par %paragraph[6]%\r\n\\par \r\n\\par %paragraph[7]%\r\n\\par \r\n\\par %paragraph[8]%\r\n\\par \r\n\\par %paragraph[9]%\r\n\\par \r\n\\par %paragraph[10]%\r\n\\par \r\n\\par %paragraph[11]%\r\n\\par \r\n\\par %paragraph[12]%\\f1 \r\n\\par \r\n\\par \r\n\\par \r\n\\par \r\n\\par \r\n\\par \r\n\\par }\r\n" Left="7" Top="89" Width="1352" Height="596" Monitor="0" OnTop="TRUE" Keep_Focus="TRUE" Mode="\x00" Delay="0" _ENABLED="FALSE"/>
<COMMENT Value=" "/>
<COMMENT Value="Scan paragraphs in array looking for special pattern that we inserted earlier.\r\nMake sure to take the first pattern, so as not to use the extra pattern that\r\nwe inserted at the end. "/>
<VARIABLE SET INTEGER Option="\x00" Destination="%paragraph_index%" Value="0"/>
<VARIABLE SET INTEGER Option="\x00" Destination="%index_of_paragraph_to_be_moved%" Value="0"/>
<REPEAT UNTIL Variable="%paragraph_index%" Condition="\x04" Value="%max_paragraphs%"/>
<VARIABLE MODIFY INTEGER Option="\x07" Destination="%paragraph_index%"/>
<IF VARIABLE Variable="%paragraph[%paragraph_index%]%" Condition="\x06" Value="%pattern%" IgnoreCase="FALSE"/>
<VARIABLE MODIFY INTEGER Option="\x06" Destination="%index_of_paragraph_to_be_moved%" Variable="%paragraph_index%"/>
<REPEAT EXIT/>
<END IF/>
<END REPEAT/>
<TEXT BOX DISPLAY Title="Diagnostics -- paragraph containing pattern" Content="{\\rtf1\\ansi\\ansicpg1252\\deff0\\deflang1033{\\fonttbl{\\f0\\fnil\\fcharset0 Tahoma;}{\\f1\\fnil Tahoma;}}\r\n\\viewkind4\\uc1\\pard\\f0\\fs20 Paragraph %index_of_paragraph_to_be_moved% contains the marker pattern\\f1 \r\n\\par \r\n\\par }\r\n" Left="Center" Top="Center" Width="543" Height="171" Monitor="0" OnTop="TRUE" Keep_Focus="TRUE" Mode="\x00" Delay="0" _ENABLED="FALSE"/>
<COMMENT Value=" "/>
<COMMENT Value="Switch the pattern-marked paragraph with the subsequent paragraph "/>
<VARIABLE MODIFY INTEGER Option="\x00" Destination="%index_of_subsequent_paragraph%" Value1="%index_of_paragraph_to_be_moved%" Value2="1"/>
<VARIABLE MODIFY STRING Option="\x08" Destination="%temporary_paragraph%" Variable="%paragraph[%index_of_paragraph_to_be_moved%]%" NoEmbeddedVars="FALSE"/>
<VARIABLE MODIFY STRING Option="\x08" Destination="%paragraph[%index_of_paragraph_to_be_moved%]%" Variable="%paragraph[%index_of_subsequent_paragraph%]%" NoEmbeddedVars="FALSE"/>
<VARIABLE MODIFY STRING Option="\x08" Destination="%paragraph[%index_of_subsequent_paragraph%]%" Variable="%temporary_paragraph%" NoEmbeddedVars="FALSE"/>
<COMMENT Value=" "/>
<COMMENT Value="Build output text by concatenating paragraphs.  \r\nAppend to each paragraph the octal 02 that was removed by the Strip command."/>
<VARIABLE SET STRING Option="\x00" Destination="%book1%" NoEmbeddedVars="FALSE"/>
<VARIABLE SET INTEGER Option="\x00" Destination="%paragraph_index%" Value="0"/>
<REPEAT UNTIL Variable="%paragraph_index%" Condition="\x04" Value="%max_paragraphs%"/>
<VARIABLE MODIFY INTEGER Option="\x07" Destination="%paragraph_index%"/>
<IF VARIABLE Variable="%paragraph[%paragraph_index%]%" Condition="\x00" IgnoreCase="FALSE"/>
<ELSE/>
<VARIABLE MODIFY STRING Option="\x07" Destination="%book1%" Variable="%paragraph[%paragraph_index%]%" NoEmbeddedVars="FALSE"/>
<VARIABLE MODIFY STRING Option="\x07" Destination="%book1%" Variable="%Octal02%" NoEmbeddedVars="FALSE"/>
<END IF/>
<END REPEAT/>
<VARIABLE SET INTEGER Option="\x0D" Destination="%length_book1%" Text_Variable="%book1%"/>
<TEXT BOX DISPLAY Title="Diagnostics -- output rebuilt, but without CRLFs" Content="{\\rtf1\\ansi\\ansicpg1252\\deff0\\deflang1033{\\fonttbl{\\f0\\fnil\\fcharset0 Tahoma;}{\\f1\\fnil Tahoma;}}\r\n\\viewkind4\\uc1\\pard\\f0\\fs20 Length of original book %length_book%\r\n\\par Length of modified book1 %length_book1%\r\n\\par \r\n\\par %book1%\\f1 \r\n\\par \r\n\\par }\r\n" Left="Center" Top="Center" Width="1345" Height="613" Monitor="0" OnTop="TRUE" Keep_Focus="TRUE" Mode="\x00" Delay="0" _ENABLED="FALSE"/>
<COMMENT Value=" "/>
<COMMENT Value="Put back the CRLF sequences that we previously converted to octal 02."/>
<IF VARIABLE Variable="%style1%" Condition="\x00" Value="TRUE" IgnoreCase="TRUE"/>
<VARIABLE MODIFY STRING Option="\x0F" Destination="%book1%" ToReplace="%Octal02%" ReplaceWith="%CRLF%" All="TRUE" IgnoreCase="FALSE" NoEmbeddedVars="FALSE"/>
<ELSE/>
<VARIABLE MODIFY STRING Option="\x0F" Destination="%book1%" ToReplace="%Octal02%" ReplaceWith="%CRLF%%CRLF%" All="TRUE" IgnoreCase="FALSE" NoEmbeddedVars="FALSE"/>
<END IF/>
<TEXT BOX DISPLAY Title="Diagnostics -- output rebuilt, CRLFs restored" Content="{\\rtf1\\ansi\\ansicpg1252\\deff0\\deflang1033{\\fonttbl{\\f0\\fnil\\fcharset0 Tahoma;}{\\f1\\fnil Tahoma;}}\r\n\\viewkind4\\uc1\\pard\\f0\\fs20 %book1%\\f1 \r\n\\par \r\n\\par }\r\n" Left="Center" Top="Center" Width="1345" Height="613" Monitor="0" OnTop="TRUE" Keep_Focus="TRUE" Mode="\x00" Delay="0" _ENABLED="FALSE"/>
<COMMENT Value=" "/>
<COMMENT Value="Remove the marker pattern from the text "/>
<VARIABLE MODIFY STRING Option="\x0F" Destination="%book1%" ToReplace="%pattern%" All="TRUE" IgnoreCase="FALSE" NoEmbeddedVars="FALSE"/>
<TEXT BOX DISPLAY Title="Diagnostics -- final output rebuilt, marker patterns removed" Content="{\\rtf1\\ansi\\ansicpg1252\\deff0\\deflang1033{\\fonttbl{\\f0\\fnil\\fcharset0 Tahoma;}{\\f1\\fnil Tahoma;}}\r\n\\viewkind4\\uc1\\pard\\f0\\fs20 %book1%\\f1 \r\n\\par \r\n\\par }\r\n" Left="Center" Top="Center" Width="1345" Height="613" Monitor="0" OnTop="TRUE" Keep_Focus="TRUE" Mode="\x00" Delay="0" _ENABLED="FALSE"/>
<COMMENT Value=" "/>
<COMMENT Value="Put the retructured text back into the Notepad area by highlighting all and pasting from clipboard"/>
<VARIABLE MODIFY STRING Option="\x10" Destination="%book1%" NoEmbeddedVars="FALSE"/>
<TEXT TYPE Action="0" Text="<CTRLD>a<CTRLU>"/>
<DELAY Flags="\x12" Time="500"/>
<TEXT TYPE Action="0" Text="<CTRLD>v<CTRLU>"/>
<COMMENT Value=" "/>
<COMMENT Value=" "/>
<MACRO RETURN/>
<COMMENT Value=" "/>

 

Share this post


Link to post
Share on other sites

Here is a "move paragraph down" command for Outlook plain text messages. It's not 100% yet, but close. I also have a move paragraph up command, but when I apply the same logic the macro is still doing a few odd things. (I'll post it when I've got it working better.)

 

I'm using the "Mouse Move: To the Text Cursor Position" instruction. The instruction fails in many programs, but works reliably in this context. After moving the mouse pointer to the cursor, the command triple clicks, which selects the entire paragraph. Then the macro sends keystrokes to extend the selection to the end of the following paragraph. The text is copied, assigned to a variable, split on the carriage return, and outputted in reverse order.

 

If you want to try it, set the scope to window, partial match, "- Message (Plain Text)"

 

Mouse Move: To the Text Cursor Position // Route the mouse pointer to the insertion point
Mouse Left Click // Triple click to select the paragraph
Mouse Left Click
Mouse Left Click
Text Type (Simulate Keystrokes): <CONTROL><SHIFT><ARROW DOWN> // Extend the selection to include the following paragraph
Text Type (Simulate Keystrokes): <CONTROL>c
Variable Set String %Clip% from the clipboard contents
Split String "%Clip%" on "%CR%" into %Paragraph%, starting at 1 // Split the two paragraphs at the Carriage Return
Text Type (Use Clipboard and Paste Text): %Paragraph[2]%
%Paragraph[1]%
Text Type (Simulate Keystrokes): <SHIFT><CONTROL><ARROW UP> // Reselect the paragraph that was selected first

  
  <MOUSE MOVE Option="\x00" X="0" Y="0" _PROMPT="0x000A" _COMMENT="Route the mouse pointer to the insertion point"/>
<MOUSE LEFT CLICK _COMMENT="Triple click to select the paragraph"/>
<MOUSE LEFT CLICK/>
<MOUSE LEFT CLICK/>
<TEXT TYPE Action="0" Text="<CONTROL><SHIFT><ARROW DOWN>" _COMMENT="Extend the selection to include the following paragraph"/>
<TEXT TYPE Action="0" Text="<CONTROL>c"/>
<VARIABLE SET STRING Option="\x02" Destination="%Clip%" NoEmbeddedVars="FALSE"/>
<SPLIT STRING Source="%Clip%" SplitChar="%CR%" Dest="%Paragraph%" Index="1" _COMMENT="Split the two paragraphs at the Carriage Return"/>
<TEXT TYPE Action="1" Text="%Paragraph[2]%\r\n%Paragraph[1]%"/>
<TEXT TYPE Action="0" Text="<SHIFT><CONTROL><ARROW UP>" _COMMENT="Reselect the paragraph that was selected first"/>
	

 

Share this post


Link to post
Share on other sites

Once I worked out a reliable way to select the current paragraph (i.e., the paragraph that contains the insertion point/text cursor), I realized I could ditch variables and string operations.

 

So for moving paragraphs up and down in plain text Outlook messages, these two macros function very much like the commands already available in HTML and RTF messages. (The built in commands don't involve the clipboard, but these commands do.)

 

For both command, set the scope to window, partial match, "- Message (Plain Text)"

 

Like the built-in commands for HTML and RTF messages, I use Alt + Shift + down and Alt + Shift + up as hotkeys.

 

Down:

Mouse Move: To the Text Cursor Position // Route the mouse pointer to the insertion point
Mouse Left Click // Triple click to select the paragraph
Mouse Left Click
Mouse Left Click
Text Type (Simulate Keystrokes): <CONTROL>x
Text Type (Simulate Keystrokes): <CONTROL><ARROW DOWN> // Select down one paragraph
Text Type (Simulate Keystrokes): <CONTROL>v
Text Type (Simulate Keystrokes): <ENTER>
Text Type (Simulate Keystrokes): <SHIFT><CONTROL><ARROW UP> // Reselect the originally selected paragraph 

<MOUSE MOVE Option="\x00" X="0" Y="0" _PROMPT="0x000A" _COMMENT="Route the mouse pointer to the insertion point"/>
<MOUSE LEFT CLICK _COMMENT="Triple click to select the paragraph"/>
<MOUSE LEFT CLICK/>
<MOUSE LEFT CLICK/>
<TEXT TYPE Action="0" Text="<CONTROL>x"/>
<TEXT TYPE Action="0" Text="<CONTROL><ARROW DOWN>" _COMMENT="Select down one paragraph"/>
<TEXT TYPE Action="0" Text="<CONTROL>v"/>
<TEXT TYPE Action="0" Text="<ENTER>"/>
<TEXT TYPE Action="0" Text="<SHIFT><CONTROL><ARROW UP>" _COMMENT="Reselect the originally selected paragraph"/>

Up:

 

Mouse Move: To the Text Cursor Position // Route the mouse pointer to the insertion point
Mouse Left Click // Triple click to select the paragraph
Mouse Left Click
Mouse Left Click
Text Type (Simulate Keystrokes): <CONTROL>x
Text Type (Simulate Keystrokes): <CONTROL><ARROW UP> // Select up one paragraph
Text Type (Simulate Keystrokes): <CONTROL>v
Text Type (Simulate Keystrokes): <ENTER>
Text Type (Simulate Keystrokes): <SHIFT><CONTROL><ARROW UP> // Reselect the originally selected paragraph

<MOUSE MOVE Option="\x00" X="0" Y="0" _PROMPT="0x000A" _COMMENT="Route the mouse pointer to the insertion point"/>
<MOUSE LEFT CLICK _COMMENT="Triple click to select the paragraph"/>
<MOUSE LEFT CLICK/>
<MOUSE LEFT CLICK/>
<TEXT TYPE Action="0" Text="<CONTROL>x"/>
<TEXT TYPE Action="0" Text="<CONTROL><ARROW UP>" _COMMENT="Select up one paragraph"/>
<TEXT TYPE Action="0" Text="<CONTROL>v"/>
<TEXT TYPE Action="0" Text="<ENTER>"/>
<TEXT TYPE Action="0" Text="<SHIFT><CONTROL><ARROW UP>" _COMMENT="Reselect the originally selected paragraph"/>

 

Share this post


Link to post
Share on other sites
On 6/20/2020 at 10:37 PM, acantor said:

I'm using the "Mouse Move: To the Text Cursor Position" instruction.

I have used the opposite approach in many macros, to establish the text cursor position.  Generally this is by positioning the mouse over an item, such as one of the titles in a list of emails, or a file name in Explorer, or a word within text.  Then hit the hotkey combination to start a macro, and the first thing the macro does is click the mouse to establish the cursor position.  Biggest problem with this is, when I move my hands to the keyboard to start the macro, the touch-pad detects the movement and slides the mouse pointer to somewhere else!  Perhaps the next ME release will have a brain-wave interface so I can just think "run macro now" without moving my hands.   

 

But I will have to keep in mind the possibilities for this command.  I experimented a bit this morning and it worked in most of the applications I tested with.

Share this post


Link to post
Share on other sites

Sometimes it's possible to take advantage of the "Mouse Move to the Text Cursor Position" in applications that don't support the command. For example, in some programs, the command moves the mouse cursor to the upper left corner of the active window rather than to the text cursor position.

 

But if clicking in that corner resets the tab order, then that's a useful navigation technique... something like this:

 

Mouse Move: To the Text Cursor Position // Jump the mouse cursor to the upper-left corner of the active window
Mouse Left Click // Clicking here resets the tab order
 
Repeat Start (Repeat 18 times) // Navigate to the "Surname" field
  Text Type (Simulate Keystrokes): <TAB>
End Repeat
 
Text Type (Simulate Keystrokes): %Surname%
 

Share this post


Link to post
Share on other sites



Perhaps the next ME release will have a brain-wave interface so I can just think "run macro now" without moving my hands.   

 

:)

 

But until that future day, there is something that can be done now that is a step in that direction. Use Dragon software, which is third-party speech recognition software for Windows. When Dragon is running on a system, voice-enabling Macro Express scripts is fairly straightforward. (It's less easy with the inexpensive "Home" edition than the Professional editions, but still do-able.) So instead of triggering a script with your thoughts, at least you can trigger a script by saying a few syllables.

Share this post


Link to post
Share on other sites
2 hours ago, acantor said:

Dragon software, which is third-party speech recognition software for Windows. When Dragon is running on a system, voice-enabling Macro Express scripts is fairly straightforward. (It's less easy with the inexpensive "Home" edition than the Professional editions, but still do-able.) So instead of triggering a script with your thoughts, at least you can trigger a script by saying a few syllables.

Yeah, but then my wife will know what I am up to, and offer her opinions.🙄  But that's a great idea.  I like my smartphone feature, where I can just say, "Hey, Google, what's the population of Paraguay, and where the heck is Paraguay, anyhow?" and it tells me.  I will look into Dragon.  Maybe I can just mumble and it will understand....

Share this post


Link to post
Share on other sites
Quote


Maybe I can just mumble and it will understand....


Ha!

 

Google's speech recognition products handle mumbling better than Dragon. On many measures of the usefulness of speech recognition, Google has surpassed Dragon. Since you're an Android user, take a glimpse of the future of speech recognition technology by downloading Google's "Live Transcribe" free app.

 

Nevertheless, Dragon is a remarkable product because of its versatility. It can be used to dictate text, revise text, control a small number of applications, and more -- hands-free. Dragon is most accurate when users speak in long, unbroken utterances (eight or more words without pausing), clearly spoken. No guarantees when mumbling!

 

Share this post


Link to post
Share on other sites
3 hours ago, acantor said:

On many measures of the usefulness of speech recognition, Google has surpassed Dragon. Since you're an Android user, take a glimpse of the future of speech recognition technology by downloading Google's "Live Transcribe" free app.

I have been astonished how well my Android phone understands my speech.  Not only Google searches, but the map application, too.  Instead of all that typing with fingers or a stylus, I can just say, "Hey, Google, navigate to Kalamazoo," and it comprehends.     

Share this post


Link to post
Share on other sites



I have used the opposite approach in many macros, to establish the text cursor position.

 

I'm wondering whether your macro for moving paragraphs in Notepad would be amenable to routing the mouse cursor to the text cursor position. I don't remember whether the instruction works in Notepad. I know it DOES NOT work in Word or any browser I've tested it with.

Share this post


Link to post
Share on other sites

Your finding is surprising, but you're right. I'm sure this was not the case in earlier versions of Word. (I'm using Word 2019).

 

So the instruction now works in Word, although not everywhere in Word.

 

1. In a document: yes.

 

2. In the ribbons, yes if the item is a field where the user can type (e.g., Home --> Font name drop-down, or to its right, the Font Size drop-down).

 

3. But apparently not when the focused item in a Ribbon is a button or similar control (e.g., Home -->  Bold, Italics, etc.)

 

4. In dialog boxes and panels: Same as 2 and 3 above.

Share this post


Link to post
Share on other sites

Here is a challenge within the challenge.

 

In the Macro Express Script Editor, there are two icons at the top of the vertical bar that runs along the right side of the screen. Click the top icon to move the current line upwards (without selecting it), and the icon beneath it to move the current line down.

 

If more than one line is selected, the icons act on the entire block of lines rather than one line.

 

These two commands parallel the paragraph-moving functionality in Word, PowerPoint, and Outlook. And like the Office commands, the Macro Express commands don't use the clipboard.

 

It turns out that there are keyboard equivalents in the Script Editor for performing these tasks. They appear to be undocumented. (At least, I couldn't find them... I discovered the keyboard shortcuts by accident.)

 

Through trial-and-error experimentation, can you figure out the two built-in keyboard shortcuts for moving text within the Script Editor?

 

And while you are at it, figure out the built-in keyboard shortcuts for the third and fourth icons, i.e., duplicate line (or several selected lines), and add a comment? (Hint: These two shortcuts are documented.)

Share this post


Link to post
Share on other sites

The icons along the right side are so subdued that I didn't even notice them (bear in mind I only started using ME Pro a couple weeks ago.)🙄

But I have for a long time used the keyboard equivalents ctrl-up-arrow, ctrl-down-arrow, and ctrl-d to move or duplicate highlighted lines. 

I haven't figured out the keyboard shortcut for adding a comment, but while experimenting I discovered that ctrl-x deletes highlighted line(s).

Share this post


Link to post
Share on other sites
1 hour ago, rberq said:

haven't figured out the keyboard shortcut for adding a comment, but while experimenting I discovered that ctrl-x deletes highlighted line(s).

 

Yep, you got it, Ctrl + Down and Ctrl + Up. So the keyboard shortcuts are similar to the similar Office commands (Shift + Ctrl + Down and Shift + Ctrl + Up).

 

The keyboard shortcuts for Duplicate Command (Ctrl + D) and Comment (Ctrl + Alt + C) are listed in the "Edit" menu of the Script Editor. Too bad "Comment" cannot be Ctrl + C because that's the standard Windows keyboard shortcut for Copy to the clipboard.

 

(On the other hand, if someone needs to sprinkle comments in their scripts more than they need to copy lines to the clipboard, they can create a window-specific Macro Express script triggered by Ctrl + C, that outputs Ctrl + Alt + C...

 

Text Type (Simulate Keystrokes): <CONTROL><ALT>c

As you observed, pressing Ctrl + X causes selected line(s) to vanish, but that's because the information is "Cut." This keyboard shortcut works almost everywhere in Windows. The cut text resides in the clipboard and is available for pasting.

Share this post


Link to post
Share on other sites

The challenge was to create two Macro Express scripts: one to move the current paragraph up, and the other to move the current paragraph down, without the need to (manually) select any text.

 

The inspiration for the challenge is Alt + Shift + up and down arrows in Word, which move the current paragraph without selecting it. (These built-in commands don't use the clipboard, but the Macro Express scripts likely will.)

 

Anyone want to give this challenge a shot for Excel? The task is to create two hotkeys that move the current ROW up or down.

 

 

I'll post a solution soon.

Share this post


Link to post
Share on other sites

This seems to work well with Excel 2010.  Before initiating the macro, hover the mouse over any cell in the row to be moved down.  Then keyboard shortcuts are used.  Though row X is to be moved down, the macro actually creates an empty row above X, then copies the row below X to the clipboard and pastes it into the empty row, then deletes the copied/pasted row.  The last step of the macro is to position the mouse over the row that has just been moved down, so that no manual repositioning is needed to move it down further – just initiate the macro again.  A macro to move a row up would be similar.  

//  
//  
// move excel row down -- mouse hovered over row to be moved
// select any cell in row to be moved, based on mouse hovering over it
Mouse Left Click
// keyboard select entire row to be moved
Text Type (Simulate Keystrokes): <SHIFTD><SPACE><SHIFTU>
// keyboard insert empty row above row to be moved
Text Type (Simulate Keystrokes): <CTRLD><SHIFTD>=<SHIFTU><CTRLU>
// keyboard arrow down to row below that to be moved down, keyboard select entire row, copy to clipboard
Text Type (Simulate Keystrokes): <ARROW DOWN><ARROW DOWN><SHIFTD><SPACE><SHIFTU><CTRLD>c<CTRLU>
// keyboard arrow up to the blank inserted row, keyboard select entire row, paste copied row from clipboard
Text Type (Simulate Keystrokes): <ARROW UP><ARROW UP><SHIFTD><SPACE><SHIFTU><CTRLD>v<CTRLU>
// keyboard arrow down to row below that to be moved down, keyboard select entire row, keyboard delete row
Text Type (Simulate Keystrokes): <ARROW DOWN><ARROW DOWN><SHIFTD><SPACE><SHIFTU><CTRLD>-<CTRLU>
// Keyboard arrow up to the row just moved, position mouse over row so we can repeat macro to move it down still more
Text Type (Simulate Keystrokes): <ARROW UP>
Mouse Move: To the Text Cursor Position
//  
Macro Return
//  
//  

 

 

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...