Jump to content
Macro Express Forums

acantor

Members
  • Posts

    1,532
  • Joined

  • Last visited

  • Days Won

    18

Posts posted by acantor

  1. Hi Cory,

     

    Avoiding keyboard and mouse interactions with the Outlook user interface would be an advantage. I tried to implement your idea, but couldn't figure out how to create a rule to output a message to a text file. Please elaborate!

     

    Your idea did give me an idea for a second method to extract the sender's email address, but the method involves sending keystrokes to the user interface! (I was able to use Window Controls for parts of the script, but in the end, I got more consistent results when I sent keystrokes.)

  2. This morning I realized I spend time almost every day, when using Outlook, copying sender's email addresses and pasting them elsewhere. Copying email addresses is a fiddly, multi-step process.

     

    For example, when I manually select the email address from the field that contains the sender's information, the field displays this:

     

    sandysmith@mail.com

     

    But when I select and copy the line, this is what ends up in the clipboard:

     

    Sandy Smith  <sandysmith@mail.com>

     

    I don't want the person's name or the braces in the clipboard. Just the email address. And why should I navigate to fields, select text, and copy when a macro can do all three? :)

     

    My first attempt to automate the process using Macro Express seemed to work. But then I discovered the script failed with Plain Text messages. Back to the drawing board!

     

    I think I now have a solution. Scripting was trickier than I thought it would be. But I can see already this macro is going to be a great time-saver.

     

    The challenge: In whatever email application you use, write a Macro Express script to automatically copy the sender's email address from a message, without the need for you to manually navigate to a field, move the cursor, select text, or copy. The macro should do all the heavy lifting.

    I'll post a solution for Outlook soon.

  3. Variable Set Integer %x% to 5
    Variable Set Integer %x%: Prompt

     

    It's also possible to set the default value to whatever it was the last time the macro ran. If you do this, I don't think it's possible (or perhaps would be easy) to specify the default value the first time you run the macro.

     

    Variable Restore: Restore All Variables
    Variable Set Integer %x%: Prompt
    Variable Save: Save All Variables

     

    • Like 1
  4. If a web browser is open, insert something like this on the Address line:

     

    https://www.timeanddate.com/date/dateadded.html?m1=1&d1=26&y1=2024&type=add&ay=00&am=&aw=&ad=10&rec=

     

    This will find a day ten days in the future from January 26. 2024.

     

    m1=1 is the month: January is 1, December is 12.

    d1=26 is the day of the month.

    y1=2024 is the year.

     

    To extract the calculated date from the web page, you'd need to do something like this:

     

    Control A  // Select the page

    Copy C    // Copy

    Set %Clip% from Clipboard

    Set AnswerPosition to "Result:"

    Copy the next ?? characters to a variable

    Extract/calculate the values of the day, month, and year into variables.

    Replace the values in the variable that contains the URL.

     

    Still a lot of work!!

     

     

  5. Cory: I got stumped when I tried to express a date in decimal. Is there a way to do the transformation from within Macro Express?

     

    rberq: I didn't realize one could do that in Excel! It might be flashy, but it might be the ticket in the event there isn't a method built into Macro Express.

     

    Perhaps there's a web-based app to do the magic rather than using Excel. Since the problem is about renaming URLs, maybe a browser is already open.

  6. Unless Macro Express has built-in functions that I'm not finding, it's going to be challenging to subtract from an arbitrary date. It could be a fun project, though. The logic might look something like this:

     

    To subtract 2 days from the current date:

     

    If Day > 3 Then  Day = Day - 2

    (No need to modify Month or Year)

     

    If Day = 2 Then...

     

    Case Month = January

    Month = December

    Day = 31

    (No need to modify Year)

     

    Case Month = February

    Month = December

    Day = 31

    (No need to modify Year)

     

    Case Month = March

    Month = February

    Day = 28 .... (unless it's a leap year... :()

    (No need to modify Year)

     

    etc.

     

    I'm not sure how to proceed without writing a lot of code!

     

    Hopefully there's a less onerous solution.

  7. This code might get you started. The task would be much easier if the Start Day and End Day were based on today's date!

     

    I haven't messed with the code enough to massage the variables into a form that will allow dates to be subtracted and added.

     

    All this code does is extract the Start Date from the URL and place the day, month, and year into variables.

     

    // Get URL
    Variable Set String %Url% to "www.example.com/12341/2fjj/StartDate=12/25/2023&EndDate=12/23/2023/Blablabla"
     
    // Extract %StartDate% from the URL
    Variable Set Integer %StartDatePos% to the position of "StartDate=" in %Url%
    Variable Modify Integer: %StartDatePos% = %StartDatePos% + 10
    Variable Modify String: Copy part of text in %Url% starting at %StartDatePos% and 10 characters long to %StartDate%
     
    // From %StartDate%... extract Day, Month, and Year
    Variable Modify String: Copy part of text in %StartDate% starting at 1 and 2 characters long to %StartDateMonth%
    Variable Modify String: Copy part of text in %StartDate% starting at 4 and 2 characters long to %StartDateDay%
    Variable Modify String: Copy part of text in %StartDate% starting at 7 and 4 characters long to %StartDateYear%
     
    // Display results so far
    Text Box Display: Display components of "%StartDate%"
    
    <COMMENT Value="Get URL" _BACK="0080FFFF"/>
    <VARIABLE SET STRING Option="\x00" Destination="%Url%" Value="www.example.com/12341/2fjj/StartDate=12/25/2023&EndDate=12/23/2023/Blablabla" NoEmbeddedVars="FALSE"/>
    <COMMENT/>
    <COMMENT Value="Extract %StartDate% from the URL" _BACK="0080FFFF"/>
    <VARIABLE SET INTEGER Option="\x0E" Destination="%StartDatePos%" Text_Variable="%Url%" Text="StartDate=" Ignore_Case="TRUE"/>
    <VARIABLE MODIFY INTEGER Option="\x00" Destination="%StartDatePos%" Value1="%StartDatePos%" Value2="10"/>
    <VARIABLE MODIFY STRING Option="\x09" Destination="%StartDate%" Variable="%Url%" Start="%StartDatePos%" Count="10" NoEmbeddedVars="FALSE"/>
    <COMMENT/>
    <COMMENT Value="From %StartDate%... extract Day, Month, and Year" _BACK="0080FFFF"/>
    <VARIABLE MODIFY STRING Option="\x09" Destination="%StartDateMonth%" Variable="%StartDate%" Start="1" Count="2" NoEmbeddedVars="FALSE"/>
    <VARIABLE MODIFY STRING Option="\x09" Destination="%StartDateDay%" Variable="%StartDate%" Start="4" Count="2" NoEmbeddedVars="FALSE"/>
    <VARIABLE MODIFY STRING Option="\x09" Destination="%StartDateYear%" Variable="%StartDate%" Start="7" Count="4" NoEmbeddedVars="FALSE"/>
    <COMMENT/>
    <COMMENT Value="Display results so far" _BACK="0080FFFF"/>
    <TEXT BOX DISPLAY Title="Display components of \"%StartDate%\"" Content="{\\rtf1\\ansi\\ansicpg1252\\deff0\\deflang1033{\\fonttbl{\\f0\\fnil\\fcharset0 Courier;}}\r\n\\viewkind4\\uc1\\pard\\b\\f0\\fs40 Month = [%StartDateMonth%]\r\n\\par Day   = [%StartDateDay%]\r\n\\par Year  = [%StartDateYear%]\r\n\\par }\r\n" Left="821" Top="417" Width="638" Height="267" Monitor="0" OnTop="TRUE" Keep_Focus="TRUE" Mode="\x00" Delay="0" _BACK="00FFFFFF"/>

     

  8. This is not a "bullet-proof" solution, but the code might give you ideas of how to solve it.

     

    Variable Set Integer %Value%: Prompt
    Variable Set Integer %Interval%: Prompt
     
    Repeat Until %Value% Is Less Than "1"
      Text Type (Simulate Keystrokes): %Value%
    
      Variable Modify Integer: %Value% = %Value% - %Interval%
    End Repeat
    
    <VARIABLE SET INTEGER Option="\x01" Destination="%Value%" Prompt="What is the highest value?" Mask="FALSE" OnTop="TRUE" Left="Center" Top="Center" Monitor="0" Lines="\x00"/>
    <VARIABLE SET INTEGER Option="\x01" Destination="%Interval%" Prompt="Count down by what value?" Mask="FALSE" OnTop="TRUE" Left="Center" Top="Center" Monitor="0" Lines="\x00"/>
    <COMMENT/>
    <REPEAT UNTIL Variable="%Value%" Condition="\x02" Value="1"/>
    <TEXT TYPE Action="0" Text="%Value%\r\n"/>
    <VARIABLE MODIFY INTEGER Option="\x01" Destination="%Value%" Value1="%Value%" Value2="%Interval%"/>
    <END REPEAT/>

     

  9. A good naming convention goes a long way toward reducing the need to type quickly, or to type multiple characters. I try to use unique, single characters at the start of each list item:

     

    1  Single-spaced

    2  Double-spaced

    a  Auto-correct

    b  Bullets

    c  Crop

    ...

    k  Columns

     

    (Notice I used K for columns to avoid a conflict with C for crop.)

     

    My macro locates the location of the first space in the string, copies the string to a variable, and then uses the value to decide what to do...

     

    Variable Set String %x%: from List
    
    Variable Set Integer %SpacePosition% to the position of " " in %x%
    Variable Modify Integer: %SpacePosition% = %SpacePosition% - 1
    
    Variable Modify String: Copy part of text in %x% starting at 1 and %SpacePosition% characters long to %y%
     
    Switch( %y% )
    Case: a // AutoCorrect
    // [Do something]
    End Case
     
    Case: b // Bullets
    // [Do something]
    End Case
     
    Case: c // Crop
    // [Do something]
    End Case
    
    etc.

     

  10. There's another way to navigate directly to the desired list item:

     

    The list supports incremental searches. These searches always start from the leftmost character on each line of the list. For example, if this is the list:

     

    Almond

    Apple

    Apricot

    Avocado

     

    You can reach "avocado" by typing its first two letters: "av". This is less work than pressing "a", then Down three times.

     

    Similarly, you can reach "apricot" by typing "apr". This works because the third letter is what distinguishes "apricot" from "apple".

     

    A good naming convention makes choosing a list item efficient and intuitive. A list like the following will never require more than two key presses to choose any item, even if the list contains hundreds or thousands of items:

     

    aa

    ab

    ac

    ad

    ...

    az

    ba

    bb

    ...

    zy

    zz

     

    I have a Macro Express script to automate tasks in Word. The start of the list looks something like this:

     

    a  AutoCorrect

    b  Bullets

    c  Crop

    cc Center-center align

    cl  Center-left align

    co Columns

    cu Customize

    ...

     

    Therefore, commands are activated by pressing sequences of either only three or four keys:

     

    1. The hotkey to start the macro

    2. The first one (or two) letters of the list item I want.

    3. Enter.

     

    Incremental searches rock! :)

  11. Other thoughts:

     

    1. It sounds like you are invoking the "Open" dialog to open specific documents. Good on you for entering the full path into the File name field, rather than the clunky alternative of using Macro Express to navigate through the Open dialog box to choose the folder. 

     

    It takes time for the Open dialog to appear and be ready to accept input. You can either slip in a short delay, or monitor the presence of the Open dialog:

     

    Variable Set Bool %IsOpenReady% to "False"
     
    Text Type (Simulate Keystrokes): <CONTROL>o
     
    Repeat Start (Repeat 10 times)
      Delay: 200 milliseconds
      If Window "Open" is focused
        Variable Set Bool %IsOpenReady% to "True"
        Repeat Exit
      End If
    End Repeat
     
    If Variable %IsOpenReady% Equals "False"
      MessageBox: The "Open" dialog did not appear!
      Macro Stop
    End If
     
    Text Type (Simulate Keystrokes): %FullPathToFile%

     

    But this approach might be overkill, since a half-second delay will likely accomplish the same.

    • Like 1
  12. Try inserting longish (500 ms?) pauses before and after each Text Type instruction.

     

    If it works, reduce the length of the pauses.

     

    You might also try breaking up the Text Types, from this:

     

    Text Type (Simulate Keystrokes): %dirNG%%T[1]% 

     

    To this... at least until you sort out what's causing truncation.

     

    Text Type (Simulate Keystrokes): %dirNG% 
    Text Type (Simulate Keystrokes): %T[1]% 

     

    • Like 1
  13. A few years ago, Insight added "Set Value from List" to the "Variable Set String" instruction:

     

    List.thumb.jpg.370058b9ad8f937e15be4c9dbac2087b.jpg

     

    Variable Set String %Item%: from List

     

    So far, I've found one practical use of this: to quickly invoke the commands I use most often in Word and PowerPoint. For me, this is a better option than the alternatives: click-click-click through endless menus and ribbons; press unwieldy sequences of keys to navigate through menus and ribbons; or memorize hotkeys. (And not every action I perform is assigned a hotkey.)


    I made two versions of the same macro, one for Word, the other for PowerPoint. Each script makes it easy to choose one of about 20 commands by pressing as few as two keystrokes.

     

    (Another alternative would be to use Macro Express to create hotkeys for each action. But with 20 * 2 = 40 commands, that's a lot to memorize.)

     

    Is anyone else using Set Value from List? And if so, how are you using it?

  14. You may be able to use Macro Express to decide when to copy a file -- without using File Explorer. Macro Express can determine the size of a file.

     

     

    // Assign the name of a file to variable %FileName% (not sure how to do this, but I think it's possible!)
    // (You'll need to figure out how to do this.)
    
    Variable Set Integer %SizeOfFile% to the size of %FileName%
    
    If Variable %FileSize% Is Greater Than "1000"
      Copy File/Files: "%FileName%" to "c:\Temporary\%FileName%"
    End If

     

  15. I wonder if something like this might do what you need to do:

     

    Repeat Start (Repeat 10 times)
      Window Activate: tamamlandi
      Delay: 500 milliseconds
      If Window "tamamlandi" is focused
        Continue
      Else
        Power Off Computer
        Macro Stop
      End If
    End Repeat
    MessageBox: "tamamlandi" did not appear within 5 seconds
    
    
    <REPEAT START Start="1" Step="1" Count="10" Save="FALSE"/>
    <WINDOW ACTIVATE Title="tamamlandi" Exact_Match="FALSE" Wildcards="FALSE"/>
    <DELAY Flags="\x02" Time="500"/>
    <IF WINDOW Option="\x00" Title="tamamlandi" Partial="TRUE" Wildcards="FALSE"/>
    <CONTINUE/>
    <ELSE/>
    <POWER OFF COMPUTER/>
    <MACRO STOP/>
    <END IF/>
    <END REPEAT/>
    <MESSAGEBOX Caption="\"tamamlandi\" did not appear within 5 seconds" Message="Try again!" Icon="4"/>

     

  16. Cory, I just changed my solution based on two ideas I borrowed from you.

     

    1. Use F5 in Excel. I previously used Ctrl+G to do the same thing, but F5 might be more reliable. Sometimes, although rarely, sending modifier keys via Macro Express causes the modifier key to get "stuck" in the down position. Using F5 should minimize the problem.

     

    2. Use F5 to select a range of cells to copy. I didn't know about selecting  ranges via the Go To dialog! My previous version outputted Ctrl+G to go to cell A1. Then, the macro repeated Shift+right arrow nine times to select the range. Doing both operations at once should make the macro more reliable... faster too, if that's important.

     

    Although my solution expects the RoboForm to be open, it does locate the first field on the page by searching for its label and tabbing.

     

    One of my first efforts stored the ten values in an array. But the solution turned out to be a bit ponderous. In time, I came to realize that after copying a range of cells to the clipboard, there was, by default, a carriage return after each of the ten values. My macro replaces the carriage returns with tabs. When the macro outputs the ten values, it does so as one operation. The Text Type instruction outputs each value followed immediately by a TAB. The Tab advances to the next field on the web page.

     

    // Try to cancel whatever process may be started in Excel, e.g., an open dialog box
    Text Type (Simulate Keystrokes): <ESC>
     
    // Select Cells A1 through J1
    Text Type (Simulate Keystrokes): <F5> // Shortcut to "Go To" dialog, which we use to select A1 through J1
    Delay: 200 milliseconds
    Text Type (Simulate Keystrokes): A1:J1<ENTER>
     
    // Copy the ten cells to the Clipboard, and assign to %Clip%
    Text Type (Simulate Keystrokes): <CONTROL>c
    Delay: 500 milliseconds // This short delay gives time for clipboard to populate
    Variable Set String %Clip% from the clipboard contents
     
    // By default, each cell ends with a Carriage Return character
    // Replace each Carriage Return character with a Tab character
    Variable Set to ASCII Char 13 to %CR%
    Variable Set to ASCII Char 9 to %Tab%
    Variable Modify String: Replace "%CR%" in %Clip% with "%Tab%"
     
    // Switch to the RoboForm Tutorial, which must be open
         (https://www.roboform.com/filling-test-all-fields)
    Window Activate: RoboForm Tutorials - Form Filler
     
    // Give focus to "Title" field by searching and tabbing
    Text Type (Simulate Keystrokes): <CONTROL>f // Search on page
    Delay: 50 milliseconds
    Text Type (Simulate Keystrokes): Title
    Text Type (Simulate Keystrokes): <ESC> // Cancel search
    Delay: 200 milliseconds
    Text Type (Simulate Keystrokes): <TAB> // Tab to the adjacent "Title" field
     
    // Output the ten values. Each value ends with Tab, which advances to the next field on the web page
    Text Type (Simulate Keystrokes): %Clip%
    
    <COMMENT Value="Try to cancel whatever process may be started in Excel, e.g., an open dialog box"/>
    <TEXT TYPE Action="0" Text="<ESC>"/>
    <COMMENT/>
    <COMMENT Value="Select Cells A1 through J1"/>
    <TEXT TYPE Action="0" Text="<F5>" _COMMENT="Shortcut to \"Go To\" dialog, which we use to select A1 through J1"/>
    <DELAY Flags="\x02" Time="200"/>
    <TEXT TYPE Action="0" Text="A1:J1<ENTER>"/>
    <COMMENT/>
    <COMMENT Value="Copy the ten cells to the Clipboard, and assign to %Clip%"/>
    <TEXT TYPE Action="0" Text="<CONTROL>c"/>
    <DELAY Flags="\x02" Time="500" _COMMENT="This short delay gives time for clipboard to populate"/>
    <VARIABLE SET STRING Option="\x02" Destination="%Clip%" NoEmbeddedVars="FALSE"/>
    <COMMENT/>
    <COMMENT Value="By default, each cell ends with a Carriage Return character"/>
    <COMMENT Value="Replace each Carriage Return character with a Tab character"/>
    <VARIABLE SET TO ASCII CHAR Value="13" Destination="%CR%"/>
    <VARIABLE SET TO ASCII CHAR Value="9" Destination="%Tab%"/>
    <VARIABLE MODIFY STRING Option="\x0F" Destination="%Clip%" ToReplace="%CR%" ReplaceWith="%Tab%" All="TRUE" IgnoreCase="FALSE" NoEmbeddedVars="FALSE"/>
    <COMMENT/>
    <COMMENT Value="Switch to the RoboForm Tutorial, which must be open\r\n(https://www.roboform.com/filling-test-all-fields)"/>
    <WINDOW ACTIVATE Title="RoboForm Tutorials - Form Filler" Exact_Match="FALSE" Wildcards="FALSE" _IGNORE="0x0006"/>
    <COMMENT/>
    <COMMENT Value="Give focus to \"Title\" field by searching and tabbing"/>
    <TEXT TYPE Action="0" Text="<CONTROL>f" _COMMENT="Search on page"/>
    <DELAY Flags="\x02" Time="50"/>
    <TEXT TYPE Action="0" Text="Title"/>
    <TEXT TYPE Action="0" Text="<ESC>" _COMMENT="Cancel search"/>
    <DELAY Flags="\x02" Time="200"/>
    <TEXT TYPE Action="0" Text="<TAB>" _COMMENT="Tab to the adjacent \"Title\" field"/>
    <COMMENT/>
    <COMMENT Value="Output the ten values. Each value ends with Tab, which advances to the next field on the web page"/>
    <TEXT TYPE Action="0" Text="%Clip%"/>

     

  17. Quote

    First thing I'd do is to export the table to a tab delimited file and use the ASCII Text File Process command.

     

    Interesting!

     

    There would be advantages to adding a tab-delimited file into the mix, especially if there is a lot of data to transfer. But in this case, there are only ten cells, the cells are contiguous, and the fields the data gets transferred into are also contiguous.

     

    Using an intermediary file might help reduce the number of interactions between Macro Express and Excel, and between Macro Express and the web page when transferring data between two windows. I say "might help" because there may be ways to minimize the number of interactions without introducing an intermediary file.  I say "there may be ways" because I'm working on it!

×
×
  • Create New...