October 29, 2012

Macro Scheduler 13.2.2 Available

Filed under: Announcements — Marcus Tettmar @ 11:44 am

Macro Scheduler 13.2.2 Update is now available with the following changes:

  • Fixed: ReadFile errors not being trapped correctly
  • Fixed: If a macro is being edited and its schedule fires, a file lock error occurs, macro should not be run by scheduler if being edited
  • Fixed: IEGetTagsByAttrib not setting correct array index
  • Added: IEWait function

Registered Updates | Trial Downloads | Upgrades

My Most Used RegEx

Filed under: Automation, Scripting — Marcus Tettmar @ 10:33 am

It occurred to me the other day while working on a script for a customer that I use this regular expression frequently:

(?<=TOKEN1).*?(?=TOKEN2)

It is very useful when parsing information out of web pages, or when finding elements in web pages.

What it does is pull out all the text between TOKEN1 and TOKEN2. Those could be other pieces of text, or html characters, or whatever.

As an example, recently I wrote a script which loops through all rows in an HTML table, and pulls out an order number, then looks this order number up in an Excel sheet. The order number appeared in a table cell along with other information. It was the first item inside an <i> (italics) tag and was followed by a space and then a hyphen. So I used this to pull it out of the row:

RegEx>(?<=<i>).*?(?= -),this_row,0,matches,nm,0

See how it looks for everything between the ‘<i>’ and ‘ -‘ (space then hyphen).

The next thing my code needed to do was find the ID of the single input field in the same row. This input was used to enter the order quantity, obtained from the Excel sheet. The ID is not something we know up front but it’s the only input field in the row. So I did this:

RegEx>(?<=id=").*?(?="),theInput,0,matches,nm,0

In other words, pull the text between id=” and “, which gives us the input’s ID value. We can then use that later to identify and fill the input field.

Regular Expressions are daunting at first. But eventually you find a small number of patterns help in many situations. This is one that I often find useful.

What’s your oft-used regular expression?

October 18, 2012

Amazon Timetravel 1.0

Filed under: General — Marcus Tettmar @ 1:42 pm

Gotta love Amazon. Received the following in an email today 18th October. I have removed identifying info. Emphasis mine:

date: 18 October 2012 11:53
subject: Your Amazon.co.uk Enquiry

I’m sorry to hear that you haven’t received your order ############# yet.

I’ve checked and can see that it was sent via DPD_24_PRIME to the following address:

redacted
redacted
redacted

The estimated delivery date given for this order last 17 Oct 2012

Your order is still in transit and I’m confident that it’ll arrive by the estimated delivery date. You can confirm the estimated delivery date by visiting the “Your Orders” section of Your Account or by clicking on the following link:

https://www.amazon.co.uk/gp/css/history/orders/view.html

Awesome!

October 3, 2012

Sending/Retrieving Emails via Gmail

Filed under: Automation, Scripting — Marcus Tettmar @ 9:36 pm

Since version 13.2 Macro Scheduler‘s email functions now support SSL. Google’s Gmail and many other email services now insist on SSL secured connections.

To use SSL you first need to install the OpenSSL library files.

Here’s an example of sending an email via Gmail:

Let>SMTP_AUTH=1
Let>[email protected]
Let>SMTP_PASSWORD=your_password
Let>SMTP_PORT=465
Let>SMTP_SSL=1
SMTPSendMail>[email protected],smtp.gmail.com,[email protected],your name,test,hello world,

And to retrieve emails from Gmail via POP3 (make sure you have enabled this in your gmail settings):

Let>POP3_PORT=995
Let>POP3_SSL=1
RetrievePOP3>pop.gmail.com,[email protected],your_password,c:\emails\in\

September 27, 2012

Video Tutorials on YouTube

Filed under: Announcements — Marcus Tettmar @ 12:39 pm

We recently had some problems with the service we were using to host our video tutorials (divshare.com). Since most of them were also on YouTube we have therefore updated our YouTube channel to include all the videos and have modified our site so that the videos are now served from YouTube.

My only worry is that some companies may block YouTube, although I was also aware that some organizations also blocked divshare. So I guess you can’t win. If you are accessing our site from behind a company firewall and can’t view our videos drop us a line and we’ll see what we can do.

September 18, 2012

September 17, 2012

Macro Scheduler 13.2 Available

Filed under: Announcements — Marcus Tettmar @ 1:04 pm

Macro Scheduler 13.2 Update is now available with the following changes:

  • Added: IEGetTagsByAttrib function
  • Added: IETagEventByAttrib function
  • Added: SSL Support to RetrievePOP3
  • Added: SSL Support to SMTPSendMail
  • Added: HTTP_CHARSET variable to override charset decoding (e.g. for XML)
  • Added: HTTP_USERAGENT variable to set user agent to string of choice
  • Fixed: Suppress unnecessary ftp errors on ftp disconnect …
  • Fixed: GetWindowChildList code builder not working
  • Fixed: TELNETSESSION_LOG, WIN_SLEEP not syntax highlighting

Registered Updates | Trial Downloads | Upgrades

September 4, 2012

Custom Dialogs: How to make a keypress alter a button click outcome

Filed under: Scripting — Marcus Tettmar @ 2:35 pm

Today I was asked how the outcome of a button click on a custom dialog could be altered if the ALT or CTRL key was pressed down at the time of the click.

This is possible by trapping the dialog’s OnKeyDown and OnKeyUp handlers. Using these we can detect if ALT or CTRL is pressed/released and set a flag accordingly. Then in the button’s OnClick handler we can check the value of this flag and decide what we should do.

Here’s some example code. Run it and click the button without holding down any keys. You’ll see a message saying that ALT was not pressed. Now click the button while holding down the ALT key and you’ll see the “you clicked the button while ALT was pressed” message.

Dialog>Dialog1
object Dialog1: TForm
  Left = 467
  Top = 241
  HelpContext = 5000
  BorderIcons = [biSystemMenu]
  Caption = 'CustomDialog'
  ClientHeight = 212
  ClientWidth = 431
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'MS Sans Serif'
  Font.Style = []
  KeyPreview = True
  OldCreateOrder = True
  ShowHint = True
  OnTaskBar = False
  PixelsPerInch = 96
  TextHeight = 13
  object MSButton1: tMSButton
    Left = 147
    Top = 47
    Width = 75
    Height = 25
    Caption = 'MSButton1'
    TabOrder = 0
    DoBrowse = False
    BrowseStyle = fbOpen
  end
end
EndDialog>Dialog1

AddDialogHandler>Dialog1,MSButton1,OnClick,doClick
AddDialogHandler>Dialog1,,OnKeyDown,doKeyDown
AddDialogHandler>Dialog1,,OnKeyUp,doKeyUp

Let>CTRL_DOWN=FALSE
Let>ALT_DOWN=FALSE

Show>Dialog1,r

SRT>doClick
    //button was clicked, which key is down
    If>ALT_DOWN=TRUE
      MessageModal>You clicked the button while ALT was pressed
    Else
      MessageModal>You clicked the button without pressing ALT
    Endif
END>doClick

SRT>doKeyDown
    //is CTRL key pressed
    If>DoKeyDown_Key=17
      Let>CTRL_DOWN=TRUE
    Endif
    //is ALT key pressed
    If>DoKeyDown_Key=18
      Let>ALT_DOWN=TRUE
    Endif
END>doKeyDown

SRT>doKeyUp
    //was ctrl released
    If>doKeyUp_Key=17
      Let>CTRL_DOWN=FALSE
    Endif
    //was ALT released
    If>doKeyUp_Key=18
      Let>ALT_DOWN=FALSE
    Endif
END>doKeyUp

You might be wondering how I know that the CTRL key is number 17 and the ALT key is 18. To find out the value of a key press the simplest way is just to pop a breakpoint at the start of the doKeyDown subroutine, then run the script in the debugger, press a key and look in the watch list to see what value is produced. Alternatively there’s a table here. Note that ALT is known as VK_MENU and CTRL is VK_CONTROL.

July 26, 2012

Retrieving all Items and Indexes from a Listbox

Filed under: Announcements, Scripting — Marcus Tettmar @ 11:26 am

Some people have reported issue with the GetListItem command failing to work with some applications. While we investigate the issues we’ve created a small workaround. This is a .Net tool called ListInspector. It’s a command line tool which you can pass a listbox handle to and it will dump out a list of all the items and their indexes.

Here’s an example of use:

//get handle of putty and find handle of listbox
GetWindowHandle>PuTTY Configuration,pHwnd
FindObject>pHWnd,ListBox,,1,hWnd,L,T,R,B,res

//run ListInspector to get a list of items
Let>RP_WINDOWMODE=0
Let>RP_WAIT=1
Run>cmd.exe /C "%SCRIPT_DIR%\ListInspector.exe" %hWnd% > %TEMP_DIR%\items.txt
ReadFile>%TEMP_DIR%\items.txt,items

//find the index of the item we want
Let>item_required=Pluto Server
RegEx>\d*(?=:%item_required%),items,0,matches,nm,0
If>nm>0
  Let>index=matches_1
  MessageModal>Index of %item_required% is %index%
Endif

The script here gets the items of the session selection box in the Putty SSH client. The first thing it does is get Putty’s window handle, then find the handle of the list box we want to inspect. It then runs ListInspector.exe and passes the listbox handle to it, piping the results to a temporary file. It then reads in the file and uses a RegEx to extract the index for the item we are looking for.

This is useful for those listboxes which don’t allow us to “drill down” properly and where the items and order of items may be dynamic, leaving us with no easy way to automate the selection of an item. Using ListInspector we can get the item’s index and then we know how many times we need to “Press Down” (first using Home to make sure we’re at the top).

You can download ListInspector here. The zip file contains the example script and a small readme file. .Net 2.5 or higher is required.

June 25, 2012

Sorting a String

Filed under: Scripting — Marcus Tettmar @ 1:22 pm

In the forums this morning PepsiHog asked for some code to sort a string of numbers.

We have a built-in method for sorting arrays. But here we want to sort a string of characters. E.g. we want the string “4731” to end up as “1347”.

I ended up writing a reusable subroutine which will sort any length string alphanumerically. I thought I’d post it here as it demonstrates a few useful ideas:

//CharSort, parm1: the string to sort, parm2: name of variable to return
SRT>CharSort
  Let>LOCALVARS=1
  Let>tmp=
  RegEx>.,CharSort_Var_1,0,matches,nm,0
  ArraySort>matches
  Let>x=0
  Repeat>x
    Let>x=x+1
    Let>this_char=matches_%x%
    Let>tmp=%tmp%%this_char%
  Until>x=nm
  Let>LOCALVARS=0
  Let>%CharSort_Var_2%=tmp
END>CharSort

To use the subroutine do something like:

Let>MyString=317536492750930
GoSub>CharSort,MyString,{"MyString"}
MessageModal>MyString

This demonstrates a number of things:

– How we can call a subroutine with parameters, and how we can use one of those parameters to set a “result” variable (note the second parameter is set to a string value, and the subroutine sets a variable with this name to the result).

– How we use LOCALVARS to ensure the subroutine has local scope (except when we need to set the return variable). This is important for functions we might re-use elsewhere and drop into other scripts, as we would want to avoid the subroutine modifying any existing script variables. By using local scope we make sure the variables used in the subroutine are local only to that subroutine.

The subroutine works first by splitting the string into an array of characters. It does this by using a Regular Expression which identifies all characters (“.”). RegEx returns an array of matches, which will therefore be all the characters in the string (because “.” means match any character). We can then sort this array using ArraySort and then finally loop through the array and concatenate each item back into a string.