Jump to content
Macro Express Forums

rberq

Members
  • Posts

    1,195
  • Joined

  • Last visited

  • Days Won

    61

Everything posted by rberq

  1. Close enough for gummint work. And if you send to a few invalid addresses, what's the harm? The mail will just go into the big bit bucket in the clouds and be flushed out with the next rain storm.
  2. Also: I see "Restore Integer Variables" at the beginning of your script. Should there be a corresponding "Save Integer Variables" at the end? Passing variable values in this way is handy, but a little bit risky. A totally unrelated macro, running between two iterations of your macro, could potentially "save" an N1 value GREATER than 4, in which case your macro would continue to increment N1 more or less forever. It would be safer to say If Variable %N1% Is Greater Than or Equal To "4"
  3. The process is one list at a time in the web interface, set various parameters on several pages Feasibility would depend on whether the lists all have roughly the same parameters. You could perhaps develop one macro per web page, to tab from one field to the next and "type" the data in each field. Then you would manually switch to the next web page, trigger the next macro to fill out that page, and so on. Macro Express is good at typing into standard forms. It's a lot harder if you have to worry about timing, waiting for the web site to respond, switching web pages, and so on -- so those things can be done manually. It sounds like this is a one-time project, so if you have macros to do, say, 80% that would be a big step. read a batch of text files, or a csv Macro Express can do both pretty easily. I think your biggest problem would be the learning curve for Macro Express. At 3 minutes per list, 900 lists is 45 hours of drudgery. If you look at this as a one-shot deal, it's maybe simpler to suffer the drudgery. But if you learn Macro Express, you will doubtless find more uses for it in the future.
  4. Clever. Makes sense to use tools that already exist. But I had more fun. 🙂
  5. Bubble sort an array // // Sort array of process names Get Array Length (%ProcessNames%) => %arraylength% Variable Set Integer %sortindex1% to 0 Variable Set Integer %sortindex2% to 0 Variable Set Integer %sortlimit% to %arraylength% Variable Modify Integer %sortlimit%: Decrement Repeat Until %sortindex1% Equals "%sortlimit%" Variable Modify Integer %sortindex1%: Increment Variable Modify Integer: %sortindex2% = %sortindex1% + 1 If Variable %ProcessNames[%sortindex1%]% Equals "" Repeat Exit End If Repeat Until %sortindex2% Is Greater Than "%arraylength%" If Variable %ProcessNames[%sortindex2%]% Equals "" Repeat Exit End If If Variable %ProcessNames[%sortindex1%]% Is Greater Than "%ProcessNames[%sortindex2%]%" Variable Modify String: Copy Text from %ProcessNames[%sortindex1%]% to %tempname% Variable Modify String: Copy Text from %ProcessNames[%sortindex2%]% to %ProcessNames[%sortindex1%]% Variable Modify String: Copy Text from %tempname% to %ProcessNames[%sortindex2%]% End If Variable Modify Integer %sortindex2%: Increment End Repeat End Repeat //
  6. Logically your macro is very similar to mine -- substitute for invalid characters, split into short strings based on the substitution character, check the individual strings for valid email format. I started out like you did, with an array, just because I wanted to play with the Split command which I had never used before. But then I didn't want to worry about how big to make the array, so I went directly from separating the strings, to placing the valid ones in the output list, rather than stage them in an array in the interim. But if the customer looks at the result and says, "By the way, did mention that I want the email list in alphabetical order," then you are way ahead having the array all ready to sort.
  7. Damn! Nobody ever said that to me when I was keeping track of which hospital patients we killed, or didn't.😉
  8. I wasn't intending to clean up the data. I did that ONLY because I have this command later in the code: Variable Modify String %text%: Append Text ( @@) // Append space and double @@ to text being processed -- serves as end of text delimiter As an "end-of-text" marker, it is used to finally break out of the REPEAT loop. On the chance that @@ was embedded elsewhere in the data, it would have represented a false "end-of-text". So you are correct, a longer string of @@@@@@ would still leave a false end-of-text. I should have used some much-longer random string like "!#$#%$^&*)(*%^+_~#" to serve as a marker, which would be unlikely to appear in valid data. This end-of-data trick goes back to the olden days of matching up account records while processing multiple sequentially-ordered files, usually from magnetic tape. With only two tapes, it is not bad. But when you get three, four, or more tapes, the logic of which one to read next becomes horrendous once one or more has reached its end, unless you plug a dummy account number (high -- all nines) at that point. I am anxious to see your macro since you say your approach is much different.
  9. This is working pretty well with Notepad text. It relies on the fact that an email address will 1) Be a contiguous string of characters 2) Contain no embedded blanks 3) Contain one embedded @ sign 4) Be followed by a blank, or end of line. There are very likely more tweaks needed that I haven't discovered. About 20 lines, if you don't count setting up miscellaneous variable values. I ignored your idea of minimizing number of instructions, until my original brute-force method got too elaborate. Then I changed approach to make a macro considerably smaller than the original. So good idea, up to a point. I knew a programmer, back in 1968, who wrote assembly-language code, then would write code that actually overlaid the generated machine language during execution, in order to avoid putting additional IF logic in multiple places. Saved a few bytes, which maybe was useful in 1968 (NOT!) -- but boy it was a bear to debug if he wasn't around. So I'm not a big believer in saving instructions at the expense of clarity. // Log Messages to "C:\Temp\MacroExpressProLogFiles\MacroExpressPro_Macro_Log_File.txt" "Macro executed: (0_A_eMail_Scraper)" Log Errors to "C:\Temp\MacroExpressProLogFiles\MacroExpressPro_Macro_Log_File.txt" // // Extract email addresses from text // Program Launch: "challenge.txt" (Normal) Parameters: // Get test file of text // // Set miscellaneous constants // Tab character ascii 9 Variable Set to ASCII Char 9 to %TAB% // Line Feed (New Line) character ascii 10 Variable Set to ASCII Char 10 to %LINEFEED% // Carriage Return character ascii 13 Variable Set to ASCII Char 13 to %CARRIAGERETURN% // Carriage Return / Line Feed combination characters ascii 13 + ascii 10 Variable Set to ASCII Char 13 to %CRLF% Variable Modify String %CRLF%: Append Text String Variable (%LINEFEED%) // // Save all text in a variable Text Type (Simulate Keystrokes): <CTRLD>a<CTRLU> // Highlight all text and copy to clipboard Delay: 250 milliseconds Text Type (Simulate Keystrokes): <CTRLD>c<CTRLU> Delay: 250 milliseconds Text Type (Simulate Keystrokes): <END> Variable Set String %text% from the clipboard contents // Save initial text in variable // // Remove periods and @ not emmbedded in email addresses, also others Variable Modify String %text%: Trim // Trim left and right ends of text Variable Modify String: Replace "@@" in %text% with " " // Replaceany double-@, with single space Variable Modify String: Replace "@ " in %text% with " " // Replace all @ followed by space, with single space Variable Modify String: Replace " @" in %text% with " " // Replace all @ precedded by space, with single space Variable Modify String: Replace "%CARRIAGERETURN%" in %text% with " " // Replace all carriage returns, with single space Variable Modify String: Replace "%LINEFEED%" in %text% with " " // Replace all linefeeds, with single space Variable Modify String: Replace "%TAB%" in %text% with " " // Replace all tab characters with single space Variable Modify String: Replace ". " in %text% with " " // Replace all periods followed by space, with single space Variable Modify String: Replace " ." in %text% with " " // Replace all periods preceded by space, with single space // Variable Set String %emails% to "" // set email list null Variable Modify String %text%: Append Text ( @@) // Append space and double @@ to text being processed -- serves as end of text delimiter // // Extract email addresses, stack in variable "emails" Repeat Until %text% Equals "@@" Variable Set Integer %index% to the position of " " in %text% // Find space delimiting first word Variable Modify String: Copy part of text in %text% starting at 1 and %index% characters long to %subtext% // Copy text up to and including first space If Variable %subtext% Contains "@" // If extracted "word" contains @, assume it is an email address Variable Modify String %emails%: Append Text String Variable (%subtext%) // Append the email address to the list we are building Variable Modify String %emails%: Append Text String Variable (%CRLF%) // Append carriage return / line feed to the email address End If Variable Modify String: Delete part of text from %text% starting at 1 and %index% characters long // Delete text up to and including first space End Repeat // Text Box Display: Extracted Email Addresses // Macro Return // ******************************************************************************************* ******************************************************************************************* ******************************************************************************************* <COMMENT Value=" "/> <LOG MESSAGES Filename="C:\\Temp\\MacroExpressProLogFiles\\MacroExpressPro_Macro_Log_File.txt" Message="Macro executed: (0_A_eMail_Scraper)" Stamp="TRUE"/> <LOG ERRORS Filename="C:\\Temp\\MacroExpressProLogFiles\\MacroExpressPro_Macro_Log_File.txt" Hide_Errors="FALSE"/> <COMMENT Value=" "/> <COMMENT Value="Extract email addresses from text"/> <COMMENT Value=" "/> <PROGRAM LAUNCH Path="c:\\temp\\challenge.txt" Mode="\x00" Default_Path="TRUE" Wait="1" Get_Console="FALSE" _COMMENT="Get test file of text"/> <COMMENT Value=" "/> <COMMENT Value="Set miscellaneous constants "/> <COMMENT Value="Tab character ascii 9"/> <VARIABLE SET TO ASCII CHAR Value="9" Destination="%TAB%"/> <COMMENT Value="Line Feed (New Line) character ascii 10"/> <VARIABLE SET TO ASCII CHAR Value="10" Destination="%LINEFEED%"/> <COMMENT Value="Carriage Return character ascii 13"/> <VARIABLE SET TO ASCII CHAR Value="13" Destination="%CARRIAGERETURN%"/> <COMMENT Value="Carriage Return / Line Feed combination characters ascii 13 + ascii 10"/> <VARIABLE SET TO ASCII CHAR Value="13" Destination="%CRLF%"/> <VARIABLE MODIFY STRING Option="\x07" Destination="%CRLF%" Variable="%LINEFEED%" NoEmbeddedVars="FALSE"/> <COMMENT Value=" "/> <COMMENT Value="Save all text in a variable"/> <TEXT TYPE Action="0" Text="<CTRLD>a<CTRLU>" _COMMENT="Highlight all text and copy to clipboard"/> <DELAY Flags="\x12" Time="250"/> <TEXT TYPE Action="0" Text="<CTRLD>c<CTRLU>"/> <DELAY Flags="\x12" Time="250"/> <TEXT TYPE Action="0" Text="<END>"/> <VARIABLE SET STRING Option="\x02" Destination="%text%" NoEmbeddedVars="FALSE" _COMMENT="Save initial text in variable\r\n"/> <COMMENT Value=" "/> <COMMENT Value="Remove periods and @ not emmbedded in email addresses, also others"/> <VARIABLE MODIFY STRING Option="\x00" Destination="%text%" _COMMENT="Trim left and right ends of text"/> <VARIABLE MODIFY STRING Option="\x0F" Destination="%text%" ToReplace="@@" ReplaceWith=" " All="TRUE" IgnoreCase="TRUE" NoEmbeddedVars="FALSE" _COMMENT="Replaceany double-@, with single space"/> <VARIABLE MODIFY STRING Option="\x0F" Destination="%text%" ToReplace="@ " ReplaceWith=" " All="TRUE" IgnoreCase="TRUE" NoEmbeddedVars="FALSE" _COMMENT="Replace all @ followed by space, with single space"/> <VARIABLE MODIFY STRING Option="\x0F" Destination="%text%" ToReplace=" @" ReplaceWith=" " All="TRUE" IgnoreCase="TRUE" NoEmbeddedVars="FALSE" _COMMENT="Replace all @ precedded by space, with single space"/> <VARIABLE MODIFY STRING Option="\x0F" Destination="%text%" ToReplace="%CARRIAGERETURN%" ReplaceWith=" " All="TRUE" IgnoreCase="TRUE" NoEmbeddedVars="FALSE" _COMMENT="Replace all carriage returns, with single space"/> <VARIABLE MODIFY STRING Option="\x0F" Destination="%text%" ToReplace="%LINEFEED%" ReplaceWith=" " All="TRUE" IgnoreCase="TRUE" NoEmbeddedVars="FALSE" _COMMENT="Replace all linefeeds, with single space"/> <VARIABLE MODIFY STRING Option="\x0F" Destination="%text%" ToReplace="%TAB%" ReplaceWith=" " All="TRUE" IgnoreCase="TRUE" NoEmbeddedVars="FALSE" _COMMENT="Replace all tab characters with single space"/> <VARIABLE MODIFY STRING Option="\x0F" Destination="%text%" ToReplace=". " ReplaceWith=" " All="TRUE" IgnoreCase="TRUE" NoEmbeddedVars="FALSE" _COMMENT="Replace all periods followed by space, with single space"/> <VARIABLE MODIFY STRING Option="\x0F" Destination="%text%" ToReplace=" ." ReplaceWith=" " All="TRUE" IgnoreCase="TRUE" NoEmbeddedVars="FALSE" _COMMENT="Replace all periods preceded by space, with single space"/> <COMMENT Value=" "/> <VARIABLE SET STRING Option="\x00" Destination="%emails%" NoEmbeddedVars="FALSE" _COMMENT="set email list null\r\n"/> <VARIABLE MODIFY STRING Option="\x06" Destination="%text%" Value=" @@" NoEmbeddedVars="FALSE" _COMMENT="Append space and double @@ to text being processed -- serves as end of text delimiter"/> <COMMENT Value=" "/> <COMMENT Value="Extract email addresses, stack in variable \"emails\""/> <REPEAT UNTIL Variable="%text%" Condition="\x00" Value="@@"/> <VARIABLE SET INTEGER Option="\x0E" Destination="%index%" Text_Variable="%text%" Text=" " Ignore_Case="FALSE" _COMMENT="Find space delimiting first word"/> <VARIABLE MODIFY STRING Option="\x09" Destination="%subtext%" Variable="%text%" Start="1" Count="%index%" NoEmbeddedVars="FALSE" _COMMENT="Copy text up to and including first space"/> <IF VARIABLE Variable="%subtext%" Condition="\x06" Value="@" IgnoreCase="FALSE" _COMMENT="If extracted \"word\" contains @, assume it is an email address"/> <VARIABLE MODIFY STRING Option="\x07" Destination="%emails%" Variable="%subtext%" NoEmbeddedVars="FALSE" _COMMENT="Append the email address to the list we are building"/> <VARIABLE MODIFY STRING Option="\x07" Destination="%emails%" Variable="%CRLF%" NoEmbeddedVars="FALSE" _COMMENT="Append carriage return / line feed to the email address"/> <END IF/> <VARIABLE MODIFY STRING Option="\x0A" Destination="%text%" Start="1" Count="%index%" _COMMENT="Delete text up to and including first space"/> <END REPEAT/> <COMMENT Value=" "/> <TEXT BOX DISPLAY Title="Extracted Email Addresses" Content="{\\rtf1\\ansi\\ansicpg1252\\deff0\\deflang1033{\\fonttbl{\\f0\\fnil Tahoma;}}\r\n\\viewkind4\\uc1\\pard\\f0\\fs20 %emails%\r\n\\par }\r\n" Left="Center" Top="Center" Width="541" Height="637" Monitor="0" OnTop="TRUE" Keep_Focus="TRUE" Mode="\x00" Delay="0"/> <COMMENT Value=" "/> <MACRO RETURN/> <COMMENT Value=" "/>
  10. At the bottom of the Macro Explorer screen.
  11. It's hard to offer advice when you don't say WHAT is not working. Perhaps you could take a screen shot of your entry screen, and upload it to this forum thread. Here are a couple shot-in-the-dark suggestions. 1. Initially, try using the (Simulate Keystrokes) method for all your Text Type commands. Pasting from clipboard usually works, but not always. Once you have the Text Type working with simulated keystrokes, you can go back and test the paste option to speed things up. 2. Your typing commands will zip along very fast, regardless whether or not the application is ready to receive the next type-in. Try putting a delay after each <ENTER>, if the application needs time to position to the next input field. Even better, for testing, put a Wait for Key Press command after each <ENTER>, so the macro won't proceed until you can see with your own eyes that it is time for the next field to be typed.
  12. From your examples, a delay after Activate Window might be needed, but probably not. Anywhere that the macro has to wait for Windows or an application to react, may require a delay. But sometimes the delay is implied by the command, such as Wait for Web Page, in which case you should not need to explicitly code a delay command. Delays after Text Type should rarely be needed. Use the command Keystroke Speed if the typing outruns the ability of Windows or the application to accept keystrokes. I insert "Keystroke Speed: 30 milliseconds" at the beginning of most macros, as a default. Delays should never be needed after most "routine" or "internal" macro commands, like setting or modifying variables, logic commands, and so on. Not only are you working harder than necessary, inserting all those delays, but your macros must run excruciatingly slowly.
  13. I have to add to my remarks (above) about Environment Variables within ME. In addition to the standard variables maintained by Windows, Environment variables can also be created on-the-fly within a macro, using Variable Modify String; and retrieved with Variable Set String: Variable Modify String: Save %text% to Environment Variable, %sav_env_var% [save value] Variable Set String %text% to Environment Variable, %sav_env_var% [retrieve value] It is a bit confusing, because the Variables tab of the Editor does not allow you to define an environment variable, and an on-the-fly environment variable is not listed as such by the Editor. An on-the-fly environment variable apparently does NOT survive a shutdown of Macro Express. Sorry for the confusion -- I found a macro where I have been doing this for years, since way back in ME3!
  14. I can not discount acantor's theory. However, Google led me to this confusing statement: "I wrote Notepadex because ... I wanted a Notepad look-alike without the 32KB file size limitation and with a fast text search and replace function, and not much more." Confusing because standard Notepad does not seem to have a 32KB file size limit, and it does have a "Replace all" function. You might find it fun to take the standard Notepad, and write macros to add the features you are missing.
  15. I went from 4.9.1.1. to 6, fairly recently. Maybe I didn't do something right, maybe I'm not observant enough -- but I found nothing at all to learn or adapt to. I saw no significant changes, and had to check several ways to make sure the new release was even installed. I think you can leave the old version 4 installed in case you don't like 6. I finally converted because I figured there had been time to resolve any bugs in version 6, and because I didn't want to get too far behind in releases.
  16. MACRO STOP stops the macro that contains it. I don't think there is a command you can execute in Macro ABC that will stop Macro XYZ. If XYZ is a long-running macro, I assume it has some kind of REPEAT loop. You could have XYZ check "something" each time through the loop -- for example, check for whether file XYZSTOP exists. If the file exists, XYZ does a MACRO STOP to kill itself. When Macro ABC starts running, the first thing it does is create file XYZSTOP.
  17. Speaking of nothing to do with macros, or with ME -- more about dinosaurs. 😋 Go to before the Windows-compatible keyboard, and before the PC, and read about the key functions on IBM bi-sync cathode-ray-tube terminals. Some keys would transmit all the data on the screen back to the central computer. Some keys, if I recall correctly, would transmit only fields that had been changed, with changeable fields defined by what had been transmitted originally FROM the central computer. Some keys would transmit no screen data at all, only a one-byte "attention" indicator. Network speeds were so excruciatingly slow that it was an important programming consideration how to reduce character transmission to the bare minimum. As for magicians, I KNOW I am being misdirected but I NEVER detect how it is done. I'm a wonderful, gullible audience!
  18. Yes! My right-side Ctrl key has a little "list" symbol in the corner. When I press it along with the Function key, it acts as a right-click. I'm one of the 999 in a thousand who never noticed it before. Or if I did, I assumed it was a misprint.
  19. Well, you have gone through al most every method! Interesting about the "Misc Keys". I have rarely looked at them, but now I notice there is a <BROWSERBACK> which seems to work in Firefox the way BackSpace used to work, to take you to the previous web screen. Firefox discontinued BackSpace some months ago, so I wrote a macro triggered by INSERT instead, to click the browser back arrow. It seems I can change my macro to use <BROWSERBACK>, or ALT + LeftArrow, which should be simpler and more reliable. But what I really want to know is, how did you know that <APP> is equivalent to a right-click? It is not intuitively obvious ...😮 Incidentally, I have noticed that the Macro Run command will successfully run a disabled macro -- unless that has been changed in later versions of ME.
  20. It is pretty straightforward if you routinely enable / disable one particular macro or set of macros. For example, the snippet below toggles the state of a single macro and briefly displays a text box confirming which action is being taken. If Macro "11_keep_computer_awake" is disabled Text Box Display: Information [enabling] Macro Enable: 11_keep_computer_awake Else Text Box Display: Information [disabling] Macro Disable: 11_keep_computer_awake End If Delay: 3 seconds Macro Return To do this for any macro, highlighted in Macro Explorer, I think I would -- ENTER to open the macro in the Editor, -- use keystrokes to navigate to the Nickname, -- copy Nickname into clipboard, -- save Nickname in a variable, -- close the Editor, and -- use the variable in the Enable and Disable commands. I disable / enable just often enough that the clumsiness irritates me every time I have to do it. Now that you have inspired me perhaps I will finally generalize the snippet above and add it to my toolbox. Or I will adopt your message after you share it.
  21. In your example, you don't know if VAR3 will have a blank space or will be null. I don't know either. Try your prompt in a test macro, then use TEXT BOX to display >>>%VAR3%<<<. If the display shows as >>> <<<, you know it is blank. If the display shows as >>><<< then VAR3 is null. If VAR3 is blank after the prompt, you can use VARIABLE SET STRING to set it null -- just enter nothing in the value field of VARIABLE SET STRING. Next thing to check, in a test macro, is what happens when you say (with VAR3 null) IF CLIPBOARD CONTAINS %VAR3% .... Again, display your result with a text box. IF CLIPBOARD CONTAINS %VAR3% TEXT BOX DISPLAY "Contains null" ELSE TEXT BOX DISPLAY "Does not contain null" Sometimes it is not obvious how Macro Express will work, and if you can't find your situation in the Help section, testing like this is the quickest way to figure it out.
  22. "Alt + d" works reliably in my Firefox -- according to this link, should work in other browsers as well. https://www.computerhope.com/jargon/a/alt-d.htm
  23. Edit: Oops! I see acantor has already replied. Do not define URL1, URL2, URL3 within the macro. Instead, use the Variables tab of the Editor to define (add) text variable URL as an array -- a dozen entries, or however many maximum tabs you may have open. Use an integer variable %indx% as shown in this code sample, to store clipboard into successive entries of the array. There is an option of Repeat Start that you could use to increment the counter (%indx%) each time through the Repeat loop, instead of using Variable Modify Integer to do it. The hard part is getting all the % signs in the right places when referring to elements of the array.😋 Variable Set Integer %indx% to 0 Repeat Start (Repeat %qtyTABS% times) [get the data into the clipboard] Variable Modify Integer %indx%: Increment Variable Set String %URL[%indx%]% from the clipboard contents End Repeat
  24. 1. Open spreadsheet (manually or by macro commands) 2. Save spreadsheet (manually or by macro commands) as a CSV or other file format that can be processed by the ASCII FILE BEGIN PROCESS through ASCII FILE END PROCESS macro commands 3. As the ASCII file process returns individual lines to the macro, do the processing you outlined for each line This is accomplishing the same thing as Cory's elegant technique. His method brings the entire spreadsheet into a variable -- all the lines at once into a single variable -- then uses macro commands to split out individual lines and parse the several columns of each line. My suggested method relies on Excel / Macro Express to parse / store / retrieve the columns, one line at a time, into an array. Cory's method is more fun. Mine is more plodding and perhaps easier to visualize for your specific project.
×
×
  • Create New...