Jump to content
Macro Express Forums

rberq

Members
  • Posts

    1,203
  • Joined

  • Last visited

  • Days Won

    61

Posts posted by rberq

  1. 2 hours ago, Cliff S said:

    Bruce, I tried your suggestion. The Macro failed completely. It does look like it your method won't work on Windows 10. Tnx

     

    Rberg. I duplicated your macro for creating a list of windows. The macro failed to find any windows, or even an empty list. Tnx 

     

    The macro works fine for me on both Windows 7 and 10.  Note that the macro writes a temporary file into folder C:\Temp, then reads the file back in.  If you don't have such a folder, I don't know what it will do. 

    I think something got lost in my copying-and-pasting from the direct editor.  I can't recreate the macro by copying the above.  Here's the full text, if you want to do all the work of entering it:

    Log Message to Default Error Log
    Log Errors
    //  
    // Display all open windows
    //  
    // Clear T50 which will be used to hold previous window title, and N50 counter
    Variable Set String %T50% ""
    Variable Set Integer %N50% to 0
    // ....    set up CR-LF in T98
    Variable Set %T98% to ASCII Char of 13
    Variable Set %T99% to ASCII Char of 10
    Variable Modify String: Append %T99% to %T98%
    //  
    Variable Set String %T1% ""
    Variable Set String %T2% ""
    //  
    // Get all window names and populate text file "windowlist.txt", adding end-of-file record all nines after the last window name.
    // Nines record will be ignored when the file is read back, due to logic that displays prior record only when next record is different,
    // and by virtue of the nines being the last record and the only one of its kind.
    Delete File or Files: "windowlist.txt"
    Repeat with Windows: Place title in %T1%
      Variable Modify String: Trim %T1%
      Variable Modify String: Append %T1% to Text File
    Repeat End
    Variable Set String %T1% "999999999999"
    Variable Modify String: Append %T1% to Text File
    //  
    //  
    //  
    // First time through repeat loop (or after new value), initialize T50 window title save area
    Text File Begin Process: "windowlist.txt"
      If Variable %N50% = 0
        Variable Modify String: Copy %T1% to %T50%
      End If
      //  
      If Variable %T1% = variable %T50%
        Variable Modify Integer: Inc (%N50%)
      Else
        // ....    (use T30 to hold window name before appending instance count and "on-top" indicator.
        Variable Modify String: Copy %T50% to %T30%
        If Variable %N50% > 1
          Variable Modify String: Append " (%N50% instances)" to %T50%
        End If
        If Window Title "%T30%" is on top
          Variable Modify String: Append "   *** This window is on top ***" to %T50%
        End If
        Variable Modify String: Append %T50% to %T2%
        Variable Modify String: Append %T98% to %T2%
        //  
        Variable Modify String: Copy %T1% to %T50%
        Variable Set String %T1% ""
        Variable Set Integer %N50% to 1
      End If
    Text File End Process
    //  
    //  
    Text Box Display: List of open windows
    //  
    //  
    // Done - exit
    Macro Return

  2. Here is a ME Version 3 macro that displays an alphabetic list of all current windows that it can find.  It may be helpful to you.  I have found with Windows 7 -- probably with Windows 10 also -- that there are many, many "windows" that you never ever see.  The same window title may appear many times; the macro only lists it once, with a counter of how many times it occurs.  The macro also tries to determine which window is "on top", though sometimes it finds more than one on-top, and sometimes none -- I don't know why, ask Bill Gates.    

     

    <LOGFILE:YY:Macro name: 0_Display_Open_Windows><LOGERR:N><REM2: ><REM2:Display all open windows><REM2: ><DIS:<REM2:Save variables used by this macro><DIS:<TMVAR2:19:01:00:000:000:WIN_DISPLAY_SAVE_T1><DIS:<TMVAR2:19:02:00:000:000:WIN_DISPLAY_SAVE_T2><DIS:<TMVAR2:19:98:00:000:000:WIN_DISPLAY_SAVE_T98><DIS:<TMVAR2:19:99:00:000:000:WIN_DISPLAY_SAVE_T99><REM2:Clear T50 which will be used to hold previous window title, and N50 counter><TVAR2:50:01:><IVAR2:50:01:0><REM2:....    set up CR-LF in T98><ASCIIC:98:1:13><ASCIIC:99:1:10><TMVAR2:08:98:99:000:000:><REM2: ><TVAR2:01:01:><TVAR2:02:01:><REM2: ><REM2:Get all window names and populate text file "windowlist.txt", adding end-of-file record all nines after the last window name.><REM2:Nines record will be ignored when the file is read back, due to logic that displays prior record only when next record is different,><REM2:and by virtue of the nines being the last record and the only one of its kind.><DOFILE:08:NN:c:\temp\windowlist.txt>><REPEATWIN:1:1:2><TMVAR2:01:01:00:000:000:><TMVAR2:20:01:00:000:000:c:\temp\windowlist.txtT><ENDREP><TVAR2:01:01:999999999999><TMVAR2:20:01:00:000:000:c:\temp\windowlist.txtT><REM2: ><REM2: ><REM2: ><REM2:First time through repeat loop (or after new value), initialize T50 window title save area><BTFBEG:001:000001:000000:C:\Temp\windowlist.txt><IFVAR2:2:50:1:0><TMVAR2:09:50:01:000:000:><ENDIF><REM2: ><IFVAR2:4:01:1:T50><NMVAR:08:50:0:0000001:0:0000000><ELSE><REM2:....    (use T30 to hold window name before appending instance count and "on-top" indicator.><TMVAR2:09:30:50:000:000:><IFVAR2:2:50:4:1><TMVAR2:07:50:00:000:000: (%N50% instances)><ENDIF><IFOTH:03:1:%T30%><TMVAR2:07:50:00:000:000:   *** This window is on top ***><ENDIF><TMVAR2:08:02:50:000:000:><TMVAR2:08:02:98:000:000:><REM2: ><TMVAR2:09:50:01:000:000:><TVAR2:01:01:><IVAR2:50:01:1><ENDIF><BTFEND><REM2: ><REM2: ><TBOX4:T:4:CenterCenter000632000703:000:List of open windows%T2%><REM2: ><DIS:<REM2:Restore variables used by this macro><DIS:<TVAR2:01:11:WIN_DISPLAY_SAVE_T1><DIS:<TVAR2:02:11:WIN_DISPLAY_SAVE_T2><DIS:<TVAR2:98:11:WIN_DISPLAY_SAVE_T98><DIS:<TVAR2:99:11:WIN_DISPLAY_SAVE_T99><REM2: ><REM2:Done - exit><MRETURN>

  3. OK, here’s the macro I originally suggested to you.  I added a TRIM statement for the T1 variable, because in copying your test data I accidentally added some trailing blanks in the CSV file.  Also I corrected one line where I had put “T99” instead of %T[99]% - but I think you had already caught that error.  Since I was testing with output to Notepad, I have inactivated a few lines where you get to the data entry screen and tab.  You will have to activate those lines, to test whether I have them in the right place.  When I run your test data typing into Notepad, it does this.  The macro code is at the end, after the Notepad sample.   Give it a try and see what happens. 
    ALS BLS ALIMED
    1
    7806
    ALS BLS ARMSTRG
    1
    2796
    2
    2797
    ALS BLS BTBULBS
    1
    10695
    2
    10696
    3
    10697
    4
    10698
    5
    10699
    ALS BLS BNDTREE
    1
    1717
    2
    2702
    3
    2703
    4
    2786
    5
    2787
    6
    2800
    7
    2801
    8
    2949
    9
    3967
    10
    7756
    11
    7758
    12
    7759
    13
    7761
    14
    7780
    15
    7852
    16
    7886
    17
    7887
    18
    8516
    19
    8630
    20
    8671

     

    <VARIABLE SET INTEGER Option="\x00" Destination="%N[99]%" Value="1" _COMMENT="first-time-through switch"/>
    <VARIABLE SET STRING Option="\x00" Destination="%T[99]%" NoEmbeddedVars="FALSE" _COMMENT="clear save area for last-processed-record's mnemonic"/>
    <ASCII FILE BEGIN PROCESS Filename="C:\\Temp\\testfile.csv" Format="CSV" Start_Record="1" Process_All="TRUE" Variable="%T%" Start_Index="1" Parse_Blank_Lines="FALSE" Clear_Array="TRUE"/>
    <VARIABLE MODIFY STRING Option="\x00" Destination="%T[1]%"/>
    <IF VARIABLE Variable="%N[99]%" Condition="\x00" Value="1" IgnoreCase="FALSE" _COMMENT="First time through, save mnemonic of first record"/>
    <VARIABLE MODIFY STRING Option="\x08" Destination="%T[99]%" Variable="%T[1]%" NoEmbeddedVars="FALSE" _COMMENT="save mnemonic"/>
    <TEXT TYPE Action="0" Text="%T[1]%<ENTER>" _COMMENT="Get screen for first mnemonic"/>
    <TEXT TYPE Action="0" Text="<F8>E<TAB>" _ENABLED="FALSE" _COMMENT="Enter Edit Tab"/>
    <END IF/>
    <IF VARIABLE Variable="%T[1]%" Condition="\x01" Value="%T[99]%" IgnoreCase="FALSE" _COMMENT="Still working on the same mnemonic?"/>
    <TEXT TYPE Action="0" Text="<F12>" _ENABLED="FALSE" _COMMENT="close out previous mnemonic"/>
    <TEXT TYPE Action="0" Text="%T[1]%<ENTER>" _COMMENT="Get screen for next mnemonic"/>
    <TEXT TYPE Action="0" Text="<F8>E<TAB>" _ENABLED="FALSE" _COMMENT="Enter Edit Tab"/>
    <END IF/>
    <COMMENT Value="Type in details for current mnemonic"/>
    <TEXT TYPE Action="0" Text="%T[2]%<ENTER>" _COMMENT="Line#\r\n"/>
    <TEXT TYPE Action="0" Text="%T[3]%<ENTER>" _COMMENT="Item Number\r\n"/>
    <TEXT TYPE Action="0" Text="<ENTER><ENTER><ENTER><ENTER><ENTER><ENTER><ENTER>" _ENABLED="FALSE"/>
    <VARIABLE SET INTEGER Option="\x00" Destination="%N[99]%" Value="0" _COMMENT="clear first-time-through switch"/>
    <VARIABLE MODIFY STRING Option="\x08" Destination="%T[99]%" Variable="%T[1]%" NoEmbeddedVars="FALSE" _COMMENT="save mnemonic"/>
    <ASCII FILE END PROCESS/>
    <TEXT TYPE Action="0" Text="<F12>" _ENABLED="FALSE" _COMMENT="close out previous (last) mnemonic"/>
    <MACRO RETURN/>
    <COMMENT Value="  "/>
    <COMMENT Value="  "/>
    <COMMENT Value="  "/>

     

  4. Since I can't see the form you are typing into, it's hard for me to debug the overall script.  I notice in your revised script that ASCII FILE BEGIN PROCESS is set to process only 1 record rather than all the records -- maybe that's why you don't get to the second record?  Fix that first.  Also, you are typing T2 and T3 only on the first pass through the script.  Move that first END IF up about three lines??? 

  5. I can reproduce the problem on my PC, which is running ME 3.9.0.1 and Windows 7.  But I don't know the solution.  If I type in the program name and checkmark the box "Bypass File Existence Check" in the Program Launch command, then the macro fails with "program not found" when I run the macro. 

    ME 3.11.1.1 on Windows 10 behaves the same. 

     

    Somewhere along the way, I believe Windows introduced some freaky cataloging/registering technique for executables, where they couldn't be run by the customary methods.  I never did understand it and still don't, and in fact I may have dreamed it but I don't think so.  Do a google search???

     

  6. if moving the mouse relative to the window, you don't need to know the coordinates of that window.  x=0, y=0 are automatically the coordinates of the top left corner of the window.  The four lines of code below click on the X at the upper right to close just about any window, full screen or partial screen.  Even for this, you don't need to know the location of the window, just its width.  Of course, if you move the mouse to a position greater than either window height or window width, it will be outside of the window.     

     

      Variable Set Integer %N30% from Width of Window
      Variable Modify Integer: %N30% = %N30% - 14
      Mouse Move Window %N30%, 9
      Mouse Left Button Click

  7. What you are trying to do is kind of tricky.  I don't think the Repeat loop is doing any good, because additional ASCII file records are NOT arriving each time through the Repeat. 

     

    The following code is probably closer to what you want.  I haven't tested it, so there may be errors and omissions.  Also depending on timing, you may have to put brief delays between some of the typing, to give the application time to respond. 

    <VARIABLE SET INTEGER Option="\x00" Destination="%N[99]%" Value="1" _COMMENT="first-time-through switch"/>
    <VARIABLE SET STRING Option="\x00" Destination="%T[99]%" NoEmbeddedVars="FALSE" _COMMENT="clear save area for last-processed-record's mnemonic"/>
    <ASCII FILE BEGIN PROCESS Filename="xxx" Format="CSV" Start_Record="1" Process_All="TRUE" Variable="%T%" Start_Index="1" Parse_Blank_Lines="FALSE" Clear_Array="FALSE"/>
    <IF VARIABLE Variable="%N[99]%" Condition="\x00" Value="1" IgnoreCase="FALSE" _COMMENT="First time through, save mnemonic of first record"/>
    <VARIABLE MODIFY STRING Option="\x08" Destination="%T[99]%" Variable="%T[1]%" NoEmbeddedVars="FALSE" _COMMENT="save mnemonic"/>
    <TEXT TYPE Action="0" Text="%T[1]%<ENTER>" _COMMENT="Get screen for first mnemonic"/>
    <TEXT TYPE Action="0" Text="<F8>E<TAB>" _COMMENT="Enter Edit Tab"/>
    <END IF/>
    <IF VARIABLE Variable="%T[1]%" Condition="\x01" Value="T[99]" IgnoreCase="FALSE" _COMMENT="Still working on the same mnemonic?"/>
    <TEXT TYPE Action="0" Text="<F12>" _COMMENT="close out previous mnemonic"/>
    <TEXT TYPE Action="0" Text="%T[1]%<ENTER>" _COMMENT="Get screen for next mnemonic"/>
    <TEXT TYPE Action="0" Text="<F8>E<TAB>" _COMMENT="Enter Edit Tab"/>
    <END IF/>
    <COMMENT Value="Type in details for current mnemonic"/>
    <TEXT TYPE Action="0" Text="%T[2]%<ENTER>" _COMMENT="Line#\r\n"/>
    <TEXT TYPE Action="0" Text="%T[3]%<ENTER>" _COMMENT="Item Number\r\n"/>
    <TEXT TYPE Action="0" Text="<ENTER><ENTER><ENTER><ENTER><ENTER><ENTER><ENTER>"/>
    <VARIABLE SET INTEGER Option="\x00" Destination="%N[99]%" Value="0" _COMMENT="clear first-time-through switch"/>
    <VARIABLE MODIFY STRING Option="\x08" Destination="%T[99]%" Variable="%T[1]%" NoEmbeddedVars="FALSE" _COMMENT="save mnemonic"/>
    <ASCII FILE END PROCESS/>
    <TEXT TYPE Action="0" Text="<F12>" _COMMENT="close out previous (last) mnemonic"/>

     

  8. 15 minutes ago, acantor said:

    Not sure this code will help, but I use routines like this to search for pixel colours along a user-specified horizontal line starting from the right side of the window. So it might help for vertical scroll bars, which are on the right edge of windows. 

     

    Yes, I was using similar code to scan along a vertical line (the scroll bar area), though being south of the border I searched for colors rather than colours.😉

    I just tried your trick of taking a screen shot and pasting it into Paint to look at the scroll bar.  The slider is consistently a gray shade, but the slot the slider moves in is a combination of the same gray with a lot of white pixels mixed in, for shading -- same problem as when working with the original screen rather than a snapshot.  I just did a little more testing, and found if I scan half a dozen pixels vertically, without finding any color variation, then I have reliably found the slider rather than the slot.  Perhaps I will try that technique next time I want to use the scroll bar. 

     

    Oops!  Seems I have hijacked this thread.  I hope the original poster got his answers. 

  9. 8 minutes ago, terrypin said:

    For macros working on the scroll bar I usually first drag it to either top or bottom, and then further move it if necessary from that known position. In practice I've found that the 'guess' of its initial, unknown position works reliably. 

     

    Right.  But with a short but unpredictable scroll bar length, AND unknown top-to-bottom position, how to you move the mouse to the middle of it?  Best workaround I have found is to move the mouse to the very top or bottom of the scroll area, click it a bunch of times, and by then the grab-able part IS under the mouse.  It would be more elegant and emotionally satisfying🤗 to be able to do a quick pixel-color scan to find it. 

  10. It is not really kludgy, and in fact can work pretty fast.  I have a number of macros that use CTRL-a to highlight a whole web page, look for specific text, then do something.  Below is a snippet of code that checks an email and either deletes it or saves it in a mail folder depending on text.  

     

    The key to making the macro very fast is to set the Macro Express clipboard delay (preferences) to zero and use a different technique to assure the clipboard command has completed – see text of the clipboard macro following this code snippet.  My fear, when I created the clipboard macro, was that it would return a partially-filled clipboard to the calling macro.  In other words, the test for "something" in the clipboard would be satisfied before "everything" was in the clipboard.  That did not happen, however, and the macro has worked flawlessly for years.  

     

        // ....    Amazon not in window title, so see if "Amazon.com order" is in the text somewhere.
        Mouse Move Screen 1300, 700 (somewhere within the body of the email text)
        Mouse Left Button Click             (click provides focus for CTRL-a to work properly)  
        Delay 200 Milliseconds
        Text Type: <CTRLD>a<CTRLU>
        Delay 200 Milliseconds
        Macro Run: 0_Generic_Copy_To_Clipboard
        Variable Set String %T1% from Clipboard
        Mouse Left Button Click  (clears the highlighting)
        Delay 200 Milliseconds
        If Variable %T1% contains "amazon.com order" 


    Macro 0_Generic_Copy_To_Clipboard
    // Set clipboard to nulls -- check to make sure it happens
    Clipboard Empty
    Repeat Start (Repeat 10000 times)
      If Clipboard Text Equals ""
        Repeat Exit
      Else
      End If
    Repeat End
    // Copy to clipboard (CTRL-c)
    Clipboard Copy
    // Loop until clipboard is non-null, that is, copy to clipboard has completed.  Since the value
    // to be copied may in fact BE null, we limit the loop to a nominal 1 second, then quit, leaving it null.
    // (Due to overhead, the maximum loop time will be more like 2 seconds than 1.)
    Repeat Start (Repeat 100 times)
      Delay 10 Milliseconds
      If Clipboard Text Equals ""
      Else
        Repeat Exit
      End If
    Repeat End
    // Return to caller
    Macro Return

     

  11. Another variant on pixel checking:  I had an application with several forms, each with the same screen title, and each form contained a dozen or more spots for entering data.  The problem was for the macro to know which form it was dealing with.  The entry slots were in different locations, and/or were different widths, on the several forms.  The data-entry space was a light color and the non-entry space was a gray background.  So the macro read a table of pixel locations, with an indicator for each location whether it should be the light or dark color.  If all locations matched what was expected, the form identity was known.  If a location did not match, then the next table (for the next form) was loaded and testing continued until a form was identified.  It was pretty fast since only a few dozen pixels had to be tested for each form.  When a form changed due to an application update, it was simple to update the corresponding table, with no changes to the macro itself.  In fact, I had a separate macro to build the tables, where I manually moved the mouse to an area to be tested, then triggered the macro with a hot key to record mouse location and pixel color. 

     

    Incidentally, it is MUCH faster to check pixel colors at specific locations, than to move the mouse and get the color at mouse location. 

  12. Are you sure the web page is completely (or sufficiently) loaded before the search?  You could try Wait for Web Page before searching for text. 

    That might explain why you can't reproduce the problem manually -- it takes you a lot longer to type in the search than it takes the macro, so by the time you finish typing the browser is ready for you. 

  13. Here's a typical loop I use to determine when a screen has changed, so the macro can proceed to its next step.  As the comment lines note, I know where on the screen a green button is, so the macro moves the mouse to the button, then loops waiting for button color to change.  Once color changes the macro clicks on the button.  Nominally the loop waits for 20 seconds (200 repeats with 1/10 second delay after each repeat).  Of course if the button DOESN'T change the loop ends anyway, the macro clicks the mouse, and things go all to hell -- that's not serious in this case since it's just working with a signon screen.

    This sort of waiting is excellent for web-based applications, because the macro will wait pretty long if the web is slow, or click almost instantaneous if the web is fast. With an application running directly on your own computer, waits are usually pretty consistent and you can get by with simple Delay commands.     


      // wait for switch to name/password screen (monitor for green Submit button to change to dark blue with
      // mouse hovering, and white to right of button)
      Mouse Move Screen 780, 540
      Repeat Start (Repeat 200 times)
        Get Pixel: Under Mouse into %N1%
        Get Pixel: Screen Coords: 840,540 into %N2%
        If Variable %N1% = 6567680
          AND
        If Variable %N2% = 16777215
          Repeat Exit
        Else
          Delay 100 Milliseconds
        End If
      Repeat End
      //
      Mouse Left Button Click

  14. Is it possible that you have introduced a blank space or unprintable character at the beginning or end of variable T4?  Try a TRIM of T4 (Variable Modify String:Trim) before the If File Exists command. 

    Also I see you are using the Clipboard, which can sometimes have timing issues.  For debugging, put a one-second delay after each clipboard command.  I know one second is excessive, but it's just for testing at this point, to see if that clears up the problem. 

  15. Your Macro Express version 3 should be fine.  I do a fair amount of extracting like this, and I prefer ME 3 for its relative simplicity.  

    You could probably have your macro:
    1.    Type Ctrl-a to highlight the entire email.
    2.    Copy highlighted text (entire email) to clipboard.
    3.    Save the clipboard into a text variable and work with it there.  (Manually, while developing the macro, copy and paste the clipboard into Notepad so you can see what you are working with.)
    4.    Find the position of “Ship to:” within the text, and delete all text up to and including “Ship to:”.
    5.    Copy one line at a time into text variables and do with it what you want.
    Of course the last step is where it starts to get sticky.  There is probably a carriage return and/or new line character at the end of each line.  If you can figure out what it is, you can use various string variable commands to copy up to the delimiter (into another variable), then delete it from the full text, go on to the next line, etc.  

    For example, the macro snippet below extracts a dollar amount that I know is in the text, sandwiched between the literals “balance” and “transact”.   You would be extracting a line delimited by “Ship to:” or carriage-return/new-line.   

    // Find target literal “balance” and delete everything to the left of it and including “balance”
    Variable Set Integer %N46% from Position of Text in Variable %T45% [look for “balance”]
    Variable Modify Integer: Dec (%N46%) [add 7 to include the word “balance” itself]
    Variable Modify String: Delete Part of %T45% [delete everything up to and including “balance”]
    // Find "transact" literal and delete it and everything to the right of it, then trim trailing blanks
    Variable Set Integer %N46% from Position of Text in Variable %T45% [look for “transact”]
    Variable Modify String: Delete Part of %T45% [delete “transact” and everything to the right]
    Variable Modify String: Right Trim %T45%
    // Back up 11 bytes from end of remaining data -- should be at or before the dollar amount we want
    Variable Set Integer %N46% from Length of Variable %T45%
    Variable Modify Integer: %N46% = %N46% - 11
    // Copy target amount, 12 characters, into variable T50 for return to calling macro
    Variable Modify String: Copy Part of %T45% to %T50%

     

×
×
  • Create New...