Jump to content
Macro Express Forums

rberq

Members
  • Posts

    1,200
  • Joined

  • Last visited

  • Days Won

    61

Everything posted by rberq

  1. Well worth while if the macro will run hundreds or thousands of times a day. Much ado about nothing if it runs rarely. Must make a note to myself to find out what methods are used to compress text, as in zip files. I have often wondered, but mostly back before I had Google to assist me.
  2. I did similar testing with a timer also. Much of the run time was moving the clipboard data into a variable before starting the whole operation; so I started the timer AFTER that move was completed. I found the same thing that you did -- all varieties of the script ran in about the same time, with one exception. One of my versions, before the replace-2-with-1 loop, changed all strings of 30 spaces to 1 space, then all strings of 29 spaces to 1, then all 28, then 27, and so on. When that was done, the loop usually had to run only once or twice and sometimes not at all. That version ran significantly faster when the entire string was all or mostly-all spaces; but it ran significantly longer with mostly-character text.
  3. If I understand the question, if the target "Page x of y" is always at the end, try this: move clipboard data to variable %work%, set integer %length% to length of %work%, set %position% to %length% minus 100, copy %work% from %position% for length of 100 to %shortwork%, use your existing logic to scan %shortwork% rather than scanning the whole PDF. 100 bytes pulled off the end of the file should be plenty, if the paging is always at the very end. If not, use 200 bytes, or whatever. The point is, scanning 100 bytes should be much quicker than scanning the whole PDF. If you want to speed it up even more, don't search specifically for "of 50", "of 49", etc. Rather, find the positions of "page " and "of ", then extract the next few characters beyond "of " and that should be the number of pages.
  4. I don't have a question, I have an answer. I put the information here in case it might be helpful to somebody else. It goes beyond what I found when querying the ME problem database, and when querying this forum.
  5. I/O error 103 The semaphore can not be set again. I got this error over and over last evening. I'm surprised it hadn't happened before. I was tinkering with a macro and made several changes to it, saving after each change. Then I couldn't save any more, just got the above error message. See attached screen shot -- the clue is at lower right in the system tray. I don't know the exact mechanism, but the PC was uploading a very large file to Dropbox. Meanwhile Dropbox apparently queued up the macro file to be uploaded, due to changes. Eventually Dropbox must have put some kind of lock on the macro file, preventing more file changes. Of course I panicked for a while, then made a guess that Dropbox was the problem. Waited until the Dropbox synchronizing finished, then everything was OK.
  6. Yes, that naming convention certainly makes your macro more readable! I don't think ME 3 supports Boolean variables, as such. My last job before I retired involved coding "medical logic modules" which were add-on customizations to a very large electronic patient care system in a hospital. It used a scripting language that seemed to be halfway between BASIC and COBOL. I liked its Boolean variables even better than what you are showing, because you didn't have to say IF ... EQUALS TRUE or IF ... EQUALS FALSE. It was more like, FALSE was equivalent to null; and TRUE was equivalent to anything else. So instead of Variable Set Bool %IsOrdinaryTextInClip% to "True" ... If Variable %IsOrdinaryTextInSelection% Equals "True"... you would both define the variable and set the condition by Clipboard_contains_ordinary_text = 1 (or = 7, or ="yes indeed it does", or any other value you felt like) or Clipboard_contains_ordinary_text = "" (null) Then in the logic you would test the condition by If Clipboard_contains_ordinary_text ... or If not Clipboard_contains_ordinary_text ... This did away with the unnecessary verbiage of "equals true" and "equals false". The variable was Boolean in the sense of having a value or being null; and the IF statement tested for existence or non-existence. Of course you could also test for specific values, for example If Clipboard_contains_ordinary_text equals "yes indeed it does" ...
  7. Great idea for a cartoon. I wish I could draw. First panel shows a man carrying the head end a long snake. Another man behind him carrying more of the snake. Second panel two more men carrying more and more of the snake. Third panel two more men with more snake, but one of the men is carrying a sign that says, "The End is Near." Last panel a man carrying the tail end. OK, I'll keep my day job. Besides, somebody's probably done it already.
  8. I give up. The only thing I can see is to eliminate the display of statistics at the end.
  9. Not necessarily. My macro runs in about a second on a 91K file with not too many long space strings. It runs in three seconds on a 335K file that is entirely spaces. When the ME script runs, the hard work must be done by a pre-compiled routine within ME, so it's not necessarily slower than a RegEx command which likewise (I assume) uses pre-compiled logic.
  10. We can cut your nine lines down to eight, if we eliminate Variable Set String %b% to "%a%" and then do all operations on %a%. That should help us finish before the universe either collapses or squirts through a black hole into somebody else's universe. I tried all day to figure out how to use Terry's CRLF idea, just because I wanted so badly to use the Strip feature. Couldn't come up with a reasonable way to deal with even-length space strings. I did find that my version runs considerably faster if I precede my Repeat loop with the following series -- but only if it's a VERY large string and contains VERY long strings of contiguous blanks. I realize this takes me out of contention for the fewest-statements prize, but you've now got me worried about the cosmic deadline so I feel it's a worthwhile addition. // Initial removal of long space strings Replace " " with " " in %T1% Replace " " with " " in %T1% Replace " " with " " in %T1% Replace " " with " " in %T1% Replace " " with " " in %T1% Replace " " with " " in %T1% Replace " " with " " in %T1% Replace " " with " " in %T1% Replace " " with " " in %T1% Replace " " with " " in %T1% Replace " " with " " in %T1% Replace " " with " " in %T1% Replace " " with " " in %T1% Replace " " with " " in %T1% Replace " " with " " in %T1% Replace " " with " " in %T1% Replace " " with " " in %T1% Replace " " with " " in %T1% Replace " " with " " in %T1% Replace " " with " " in %T1% Replace " " with " " in %T1% Replace " " with " " in %T1% Replace " " with " " in %T1% Replace " " with " " in %T1% Replace " " with " " in %T1% Replace " " with " " in %T1% Replace " " with " " in %T1% Replace " " with " " in %T1% Replace " " with " " in %T1%
  11. Yes, appears to be correct, and by calculating the minimum number of time you MUST go through the repeat loop, you very nicely minimize execution time. Well .... not really minimize, because you will always loop enough times to handle the worst-case condition where the entire string, or most of it, consists of spaces. Probably still faster than my version, which checks on every pass whether any double spaces still remain. My version potentially saves passes through the "Replace" command, but at the expense of re-scanning the string each time to see if it's time to quit.
  12. I'm thinking Terry has us both beat. Should be a two-line macro: Replace all spaces with CRLF. Variable Modify String [Strip CR/LF]. Bedtime now, but I'll try it tomorrow. EDIT: Well, so much for my midnight enthusiasm. In the light of day, I can't see how it would work. The following would ALMOST work: 1) Replace any existing CRLF by x'01' 2) Replace all spaces by CRLF 3) Strip all CRLF 4) Restore original existing CRLF by replacing x'01' by CRLF But that would remove ALL spaces, and not leave one space where each string of spaces originally existed. No prize yet, Terry, unless you can see your way out of this. 🙄 EDIT AGAIN: Actually the above ALMOST works, if (step 2) all DOUBLE spaces are replaced by CRLF. But some strings of spaces have an even number of spaces, and some have an odd number of spaces. The above logic leaves odd-number strings with a single space, as desired. But it completely removes even-number strings. Have to find a way around that -- still thinking.... It runs pretty fast, though. Have to go work in the garden. I'll probably plant the flowers upside down if my mind is on this problem.
  13. Remember the story where Joe says, "I will work for you starting for penny a day, but you must double my pay every day." So day 2, Joe earns 2 cents. Day 3, 4 cents. Day 4, 8 cents. Then 16 cents, then 32, then 64, then $1.28, then $2.56. Keep doubling, and in a few weeks Joe is very very wealthy. The space-replacement works just the reverse: the total spaces are DIVIDED by 2 each time the macro says "replace every instance of space-space by space." I created a text string of about 120K, entirely spaces, and here's the text box display at the finish of the macro: Beginning text length = 121311 Ending text length = 1 Spaces removed = 121310 Number of loops = 17 2 to the power 17 is 132K. So if my starting text string was more than 132K, there would be 18 loops. To test, I doubled my text string, and voila: Beginning text length = 242622 Ending text length = 1 Spaces removed = 242621 Number of loops = 18 If you DON'T use the "replace all instances" option of the ME command, then I believe the number of loops needed is (length - 1) as you suggest. // // Convert all multi-space strings to a single string -- starting with text in clipboard Variable Set String %T1% from Clipboard // Initialize counter for number of loops Variable Set Integer %N20% to 0 // Save length of beginning text Variable Set Integer %N1% from Length of Variable %T1% // Repeat until there are no multi-space strings, then put the result back into the clipboard Repeat Until %N99% <> %N99% If Variable %T1% contains " " Replace " " with " " in %T1% Variable Modify Integer: Inc (%N20%) Else Repeat Exit End If Repeat End Variable Modify String: Save %T1% to Clipboard // Save length of ending text Variable Set Integer %N2% from Length of Variable %T1% // Display beginning and ending text lengths and number of spaces removed Variable Modify Integer: %N3% = %N1% - %N2% Text Box Display: Result // Macro Return //
  14. I think maximum required loops depends on the length of the longest string of blanks, not the length of the entire string. But by the time a macro did the counting, the brute-force method could be all done processing. As you say, often the time penalty for brute force computing is trivial. When I started programming, I worked with a guy who was immensely proud if he could cut a routine from, say, 44 to 42 bytes of machine-language code, to reduce run time. The downside was, the next programmer to work with his stuff could spend hours or days trying to decipher his magic, because he also felt program logic was self-documenting and comments were for sissies. 🙂
  15. Your solution was almost identical to mine, except I put no limit on the number of loops. Instead, I included an IF to see when to exit the loop. Here are the "business" lines of code, without the housekeeping and displaying of counters: Repeat Until %N99% <> %N99% If Variable %T1% contains " " Replace " " with " " in %T1% (replace-all-instances option) Else Repeat Exit End If Repeat End With your macro, you can probably get away with far fewer passes than (length minus 1). If you use the "replace all instances" option of the Replace command, then each time through the repeat loop cuts each space string roughly in half. So the number of repeats needed is a power of 2 rather than based on overall string length. For example, I made a string of about 78K bytes, whose longest contiguous string of spaces was about 41K. It required only 16 iterations of the Replace command to do the job. Which makes sense, because 2 to the 16th power is 64K. Since my "challenge" specified a maximum of 2K contiguous spaces, your macro should be successful if you always repeated 11 times (maybe 12?) (2 to 11th power is 2K). Knowing that, you could get rid of the lines that worry about overall string length, and you would beat me by a couple lines of code. You win, pending any other entries.
  16. Sounds like COBOL code (showing my age, here). You can define a "conditional" value. For example, you have a numeric data element called Programmer's-Age. Then you define the conditional under it, like "88 the-programmer-is-a-dinosaur values 65 to 100". Within the program logic, then, you can say neat stuff like "if the-programmer-is-a-dinosaur goto eligible-for-social-security else goto standard-working-age." When people say COBOL code is like reading English, it all comes from the naming. Anyhow, the ability to use better naming is one thing that distinguishes ME Pro from my old ME 3 version. I really would like to see your solution and your naming convention for this challenge, even though I'm too lazy to work on it myself.
  17. Clarity is largely a matter of EXTENSIVE commenting. Complex macros or routines often will have almost as many remarks as functioning code. As to solving this, I have to say your Canadian Postal Code problem was fun and called for some cleverness. This one appears to be mostly grunt work, not fun.🙄 I'd be delighted to do it for a hundred bucks an hour (US bucks, not Canadian -- hours can be measured on a US, Canadian, Slovakian, or 24-hour military clock). But I can understand if you're not willing to pay that high since you've already written the code.🙃 Still eager for future challenges, though. 😛 In fact, here's one: Clipboard contains a piece of text with one or potentially many embedded strings of one or more blanks. Total text can be up to 32K characters. A string of contiguous blanks can be up to 2K in length. Write a macro that changes every string of blanks to a single blank, without otherwise changing the overall text string. At the end of the macro, display a count of how many blanks have been removed. The challenge is to do this in the fewest lines of code. Sorry, not trying to hijack your thread, I just don't want to work that hard tonight.
  18. . I haven't thought this through all the way, but since the letter 'O' never occurs within a postal code, perhaps after upper-casing the address you could change every "O" to zero, then proceed as usual. The danger would be possibly generating false positives elsewhere in the address, but as I suggested above, if there are two or more patterns that seem to be postal codes, most likely you would be safe accepting the last one. I'm surprised you haven't also had the problem of people using a lower case "L" instead of the digit "1", or vice versa. "L" is a legitimate code, so it wouldn't be amenable to the above "O" technique.
  19. Did you see this line where you can set the notification options? Settings shown get me an email for each reply to a topic I follow.
  20. This solution builds the LDL DLD pattern by substituting characters: Any letter becomes @ Any number becomes # Any space becomes $ Then it searches for the pattern @#@$#@# within the substituted text, and extracts the corresponding positions from the original text. The solution is a little crude because it doesn't allow for multiple pattern matches within the address -- probably I would add code to take the last match in that case. Joe's solution using VBSCRIPT is certainly more elegant, but kind of breaks the ME-only rule.😧 // // Extract Canadian postal code Variable Set String %T1% "1234 Chaplin Dr. Twr. 1- 6th floor , Mississauga, ON L4Q 5Z3 Canada" Variable Set String %T1% "25 Clark Street, 1st Floor, Toronto, ON, M8C 1X9, Canada" Variable Set String %T1% "111 rue de Chaplain, Montreal PQ H2P 7W9" Variable Set String %T1% "J2E 6G2 (main entrance)" // Move address to working variable T2, clear destination variable T3 Variable Set String %T3% "" Variable Modify String: Copy %T1% to %T2% Variable Modify String: Trim %T2% // Get rid of any special characters @, #, and $ that may already exist Replace "@" with "" in %T2% Replace "#" with "" in %T2% Replace "$" with "" in %T2% Text Box Display: Debug special characters removed // Replace letters with @, numbers with #, blank spaces with $, building result in T3 Variable Set Integer %N1% to 0 Variable Set Integer %N2% from Length of Variable %T2% Repeat Start (Repeat %N2% times) Variable Modify Integer: Inc (%N1%) Variable Modify String: Copy Part of %T2% to %T9% If Variable %T9% >= "A" AND If Variable %T9% <= "Z" Variable Set String %T9% "@" End If If Variable %T9% >= "a" AND If Variable %T9% <= "z" Variable Set String %T9% "@" End If If Variable %T9% >= "0" AND If Variable %T9% <= "9" Variable Set String %T9% "#" End If If Variable %T9% = " " Variable Set String %T9% "$" End If Variable Modify String: Append %T9% to %T3% Repeat End Text Box Display: Debug letters/numbers replaced with special characters // Postal code LDL DLD will have been replaced by @#@$#@#, so find position of that string within the address in variable T3 Variable Set Integer %N9% from Position of Text in Variable %T3% // Extract corresponding characters from original [trimmed] address in T2 Variable Modify String: Copy Part of %T2% to %T12% Text Box Display: Debug original address and extracted postal code // // Macro Return //
  21. The emails appear to come from noreply@invisioncloudcommunity.com
  22. ... For responses, I have had good luck by clicking "Follow" at top-right, and selecting the option to get an email whenever there is activity. Strangely enough, just because you originated a topic, doesn't mean you are automatically enrolled to "follow" it.
  23. ... If the older version does what you want, and is simpler to use, then it's perfectly OK to stick with it. After all, I still use the old Macro Express Version 3, and so far it does everything I want. If you have an experienced carpenter with an old hammer, why push him to buy a new one? 😉
  24. .. You were correct to replace the Program Launch with the two commands I suggested. I think you should also get rid of the command that types <CONTROL>n. I tinkered with this a little more, and expanded my macro as follows: Text Type: <WIND><WINU> Text Type: SnippingTool Text Type: <ENTER> Delay 1000 Milliseconds Text Type: <ALTD>n<ALTU><ENTER> Macro Return The first three lines start the snipping tool application. The delay of one second is just to give the application time to start -- you may need a shorter or longer delay. The tool has focus to receive commands when it starts, so the next line typing <ALTD>n<ALTU><ENTER> tells the tool to do a "New" snip, and <ENTER> selects the default Rectangular shape. Beyond that, I can't help much, because I'm not familiar with most Snipping Tool options.
  25. Try using the keyboard sequence to start it. The following works in Windows 7: // Text Type: <WIND><WINU> Text Type: snippingtool<ENTER> // I don't know why your macro doesn't work the way you wrote it. There's something weird about the way Windows indexes to some programs. Even though Windows Explorer shows it as a normal .exe in the System32 library, you can't open it by double-clicking the name. I read the explanation once upon a time but I'm not sure I understood it even then.
×
×
  • Create New...