Marcus' Macro Blog

Tips and News on Macro Recording and Automating Windows with Macro Scheduler
December 22nd, 2014 by Marcus Tettmar

Someone asked me how they could buy a Macro Scheduler subscription for a friend, for Christmas and I thought what a great idea!

A monthly subscription costs only $15. Or you can buy a three month subscription for $40.

More info and subscription signups here.

That would make a great Christmas present for someone. You can buy a three month subscription and then cancel before the end of the term and they get three months of uninterrupted, unlimited use. A great way to introduce someone to the power and flexibility of Macro Scheduler.

If you want to buy someone a subscription, use your details when you signup and then forward them the activation email. Keep the subscription going for as long as you want.

December 15th, 2014 by Marcus Tettmar

Just a quick note to wish all our customers and readers of this blog good tidings for this festive season. Whether you celebrate this time of the year or not, we’ll be raising a glass to all of you.

Forum regular JRL has put together this snazzy little Macro Scheduler script. Paste it into a new macro and hit run for some festive cheer:

OnEvent>key_down,VK27,0,Quit
SRT>Quit
  SetControlText>Sparkler,TEdit,1,Complete
  WaitWindowClosed>Sparkler
  Wait>1
  DeleteFile>%temp_dir%Sparkler.scp
  Exit>0
END>Quit

DeleteFile>%temp_dir%Sparkler.scp
LabelToVar>SparkleScript,vScrData

Dialog>Dialog1
object Dialog1: TForm
  BorderStyle = bsNone
  Caption = 'Happy Holidays'
  ClientHeight = 330
  ClientWidth = 780
  Color = 111111
  Position = poScreenCenter
  object Panel3: TPanel
    Left = 0
    Top = 0
    Width = 780
    Height = 330
    BevelEdges = []
    BevelOuter = bvNone
    Caption = 'And a Happy New Year'
    Color = 111111
    Font.Charset = ANSI_CHARSET
    Font.Color = clRed
    Font.Height = -80
    Font.Name = 'Vladimir Script'
    Font.Style = []
    ParentFont = False
    Visible = False
  end
  object Panel2: TPanel
    Left = 0
    Top = 0
    Width = 780
    Height = 330
    BevelEdges = []
    BevelOuter = bvNone
    Caption = 'Merry Christmas'
    Color = 111111
    Font.Charset = ANSI_CHARSET
    Font.Color = clRed
    Font.Height = -96
    Font.Name = 'Old English Text MT'
    Font.Style = []
    ParentFont = False
  end
  object Panel1: TPanel
    Left = 0
    Top = 0
    Width = 780
    Height = 330
    BevelEdges = []
    BevelOuter = bvNone
    Caption = ''
    Color = 111111
  end
end
EndDialog>Dialog1

Show>Dialog1

ExecuteFile>%temp_dir%Sparkler.scp

Let>WIN_USEHANDLE=1
  GetWindowPos>Dialog1.handle,Dia1X,Dia1Y
Let>WIN_USEHANDLE=0
Add>Dia1Y,165
Let>StartY=Dia1Y
Let>YFlag=1
Wait>0.3

Let>kk=0
Repeat>kk
  Add>kk,4
  If>Dia1Y>{%StartY%+20}
    Let>YFlag=0
  EndIf
  If>Dia1Y<{%StartY%-20}
    Let>YFlag=1
  EndIf
  Add>Dia1X,4
  If>YFlag=1
    Add>Dia1Y,8
  Else
    Sub>Dia1Y,8
  EndIf
  Wait>0.025
  If>Dia1X>40
    SetControlText>Sparkler,TEdit,1,%Dia1X%;%Dia1Y%
  EndIf
  SetDialogProperty>Dialog1,Panel1,Left,kk
Until>kk>750

Timer>Begin

GetWindowPos>Sparkler,SparkX,SparkY

Label>Loop
If>{%Dia1X%<%SparkX%+150}
  Add>Dia1X,1
EndIf
If>Dia1Y>StartY
  Sub>Dia1Y,1
EndIf
If>Dia1YDia1Y,1
EndIf
SetControlText>Sparkler,TEdit,1,%Dia1X%;%Dia1Y%
Wait>0.01
Timer>Stop
If>{%Stop%-%Begin%>5000}
  GoSub>Fade
EndIf
Goto>Loop

SRT>Fade
  SetDialogProperty>Dialog1,,AlphaBlend,True
  Let>Fader=255
  Repeat>Fader
    Sub>Fader,5
    SetDialogProperty>Dialog1,,AlphaBlendValue,Fader
    Wait>0.1
  Until>Fader<0
  Let>Fader=255
  SetDialogProperty>Dialog1,Panel3,Visible,True
  SetDialogProperty>Dialog1,Panel2,Visible,False
  SetDialogProperty>Dialog1,,AlphaBlendValue,Fader
  Wait>3
  Timer>Begin
  GetScreenRes>ScreenX,ScreenY
  While>{%Stop%-%Begin%<10000}
    Timer>Stop
    Random>100,Pct
    Add>pct,1
    Let>Dia1X={round(%ScreenX%*(%pct%/100))}
    Random>100,Pct
    Add>pct,1
    Let>Dia1Y={round(%ScreenY%*(%pct%/100))}
    SetControlText>Sparkler,TEdit,1,%Dia1X%;%Dia1Y%
    Sub>Fader,5
    SetDialogProperty>Dialog1,,AlphaBlendValue,Fader
    Wait>0.2
  EndWhile
  SetControlText>Sparkler,TEdit,1,Complete
  WaitWindowClosed>Sparkler
  Wait>1
  DeleteFile>%temp_dir%Sparkler.scp

  Exit>0
END>Fade

/*
SparkleScript:
Let>size=200

OnEvent>key_down,vk27,0,Quit

SRT>Quit
  Exit>0
END>Quit

Dialog>Dialog2
object Dialog2: TForm
  BorderStyle = bsNone
  Caption = 'Sparkler'
  Color = 1
  TransparentColor = True
  TransparentColorValue = 1
  object Panel1: TPanel
    Left = 0
    Top = 0
    BevelOuter = bvNone
    Caption = 'Panel1'
    Color = 1
    TabOrder = 0
  end
  object Edit1: TEdit
    Text = '-1000;-1000'
    Visible = False
  end
end
EndDialog>Dialog2

Let>WIN_USEHANDLE=1
  MoveWindow>Dialog2.handle,-1000,-1000
Let>WIN_USEHANDLE=0
AddDialogHandler>Dialog2,,OnClose,Quit
SetDialogProperty>Dialog2,,ClientHeight,size
SetDialogProperty>Dialog2,,ClientWidth,size
SetDialogProperty>Dialog2,Panel1,Height,size
SetDialogProperty>Dialog2,Panel1,Width,size
SetDialogProperty>Dialog2,,AlphaBlend,True
SetDialogProperty>Dialog2,,AlphaBlendValue,0
Show>Dialog2

Let>halfSize={round(%size%/2)}
Let>85Per={round(%halfSize%*0.85)}
Let>15Per={round(%halfSize%*0.15)}
Let>ang2=0
Let>kk=0
SetDialogProperty>Dialog2,,AlphaBlendValue,255
Repeat>kk
  GetDialogProperty>Dialog2,Edit1,Text,vPos
  If>vPos=Complete
    Let>kk=-100
    Goto>Done
  EndIf
  Separate>vPos,;,Cur
  Sub>Cur_1,%halfSize%
  Sub>Cur_2,%halfSize%
  MoveWindow>Sparkler,Cur_1,Cur_2
  Add>kk,1
  Random>85Per,res
  Add>res,%15Per%
  Random>50,color
  Add>Color,45500
  Random>90,ang2
  Let>ang2=%ang2%*4
  GoSub>Angle,Dialog2,Panel1,ang2,%halfSize%,%halfSize%,%halfSize%,4,1
  Random>90,ang3
  Let>ang3=%ang3%*4
  GoSub>Angle,Dialog2,Panel1,ang3,%halfSize%,%halfSize%,%halfSize%,4,1
  Random>90,ang
  Let>ang=%ang%*4
  SetDialogProperty>Dialog2,Panel1,caption,space
  GoSub>Angle,Dialog2,Panel1,ang,%halfSize%,%halfSize%,res,2,color
  Label>Done
Until>kk<0

//Angle Usage:
//GoSub>Angle,Dialog,Object,Angle(in degrees),XStart,YStart,Length,PenSize,PenColor
//Requires Drawline subroutine
SRT>Angle
  Let>DegreeAngle=Angle_var_3
  Let>XStart=Angle_var_4
  Let>Ystart=Angle_var_5
  Let>LineLength=Angle_var_6
  Let>RadAngle={%DegreeAngle%*(pi/180)}
  Let>XEnd={trunc((cos(%RadAngle%))*%LineLength%)}
  Let>YEnd={trunc((sin(%RadAngle%))*%LineLength%)}
  Let>XEnd=%XEnd%+%XStart%
  Let>YEnd=%YEnd%+%YStart%
  GoSub>DrawLine,%Angle_var_1%.%Angle_var_2%.Handle,Angle_var_7,Angle_var_8,XStart,YStart,XEnd,YEnd
END>Angle

SRT>DrawLine
  LibFunc>user32,GetDC,HDC,%DrawLine_var_1%
  LibFunc>gdi32,CreatePen,Penres,0,%DrawLine_var_2%,%DrawLine_var_3%
  LibFunc>gdi32,SelectObject,SOPres,hdc,Penres
  Libfunc>gdi32,MoveToEx,mtres,HDC,%DrawLine_var_4%,%DrawLine_var_5%,0
  LibFunc>gdi32,LineTo,ltres,hdc,%DrawLine_var_6%,%DrawLine_var_7%
  LibFunc>gdi32,DeleteObject,DOres,Penres
  LibFunc>user32,ReleaseDC,RDCres,HDC_1,HDC
END>DrawLine
*/

Enjoy! :-)

December 2nd, 2014 by Marcus Tettmar

“Here in the North Pole our elves work hard every year to ensure presents are created and delivered on time to good little boys and girls all over the world,” says Santa Claus, “but with a booming world population and the ever increasing demands of modern employment and elf-and-safety regulations, our task is getting harder and harder and we need to modernize without breaking the bank or requiring specialist skills”.

On Christmas Day Santa Claus delivers toys to well behaved boys and girls all over the world. Budgets are tight, especially with the collapse of the Icelandic banking system where most of Santa’s investments were held. As an ethical organization Santa’s operation must also be seen to be economic and efficient and now has to adhere to strict new guidelines on the amount of hours per day elves can work.

Up until now Santa’s operation was largely manual. “We are in an awkward position,” says Claus “people expect us to carry on our traditions of elf-labour and creating products by hand, but at the same time the world has moved on and we need to compete with the likes of Walmart and ToysRUs and cut our costs. So we needed to find ways of improving efficiency without losing our traditional appeal. 100% mechanization is a no-no. But something that would help with the repetitive manual number crunching and data entry tasks would be ideal. We also had to find something that didn’t require specialist IT knowledge. I mean, our elves, bless them, they’re wonderful at toy-making, but technology? Not so much. So we turned to Google and found Macro Scheduler.”

Many of the tasks carried out by the elves are repetitive and time-consuming, taking elves away from the more productive work of producing toys and wrapping presents. “Once a day we have to download the new lists from our incoming server. There’s the naughty list and the good list.” says Jingle, Santa’s Chief Elf, “We need to check for duplicates, then copy and paste each list into our own master list. Of course boys and girls can switch from list to list too, so we need to cross reference. If someone was on the good list but has been naughty we need to find their record, remove it from the good master list and place it on the naughty list. This used to be a manual process, taking around 6 hours a day. With Macro Scheduler we were able to automate the entire process. A macro trigger responds to the lists appearing in the inbox and then reads through the data and cleans our master list automatically. It’s entirely automated. We used to take turns doing this job and you wouldn’t believe how much happier everyone is now that they can make toys instead.”

That task alone is saving over 2000 elf-hours a year. But it’s not just the elf-savings that Santa’s team is benefiting from. Elves are happier too. It also saves a number of embarrassing mistakes. “In the past it was easy to mess up a change in the lists. Some poor kid ends up being put on the naughty list by mistake and he doesn’t get a present. That was a real PR nightmare! Santa would lose his rag too. I mean you didn’t want to be there! Yeh, the elves are much happier now and we’re now more likely to hit our toy-creation performance targets too. Everyone wins”.

Santa and his team are now using Macro Scheduler wherever they can and can see many opportunities to expand its use across their North Pole operations center over the following year.

“We’re really impressed with the product and the support that comes with it. None of our elves were programmers, with only basic IT skills, but they’ve picked up Macro Scheduler quickly. The possibilities are endless and we’re really glad we found it.” says Claus.

For more information on Macro Scheduler click here. For more case studies and success stories go here.

November 25th, 2014 by Marcus Tettmar

Today I was asked if Macro Scheduler can trigger an action if the number of connected monitors changes. Yes, all we need is a way to determine how many monitors are connected to the system. VBScript is one way to do that. So then all we need is a loop that constantly checks this value. So we end up with something like this:

November 21st, 2014 by Marcus Tettmar

When robots get it wrong:

November 18th, 2014 by Marcus Tettmar

When you run code in the Script Editor you are in fact running it inside a debugger.

This allows you to run code line by line or in chunks, and evaluate the values of your script variables in the watch list as you go.

By default – after a first install – the debugger always runs scripts from the top – the very first line. Just as would happen if you run the script some other way. From top to bottom.

But when you are debugging a script you often want to run a select number of lines or start debugging from a different line. So, to do this, you can disable “Run From Top”. This option is under the Tools menu.

When “Run From Top” is disabled the macro will start from whichever is the current line – i.e. whichever line currently has the cursor on it.

Recently in the forums two different people have had seemingly strange issues with scripts which turned out simply to be because they had this option turned off and weren’t running from the top. In both cases they were getting errors because some variables they were referencing hadn’t yet been created! The script had been started from a point after the variables were set.

So, when running in the editor, if you’ve previously disabled “Run From Top”, and you want to run the script as normal, either reset this option or put the cursor on the first line before running.

And if you see some seemingly strange behaviour which goes away when you run the script outside of the editor – it’s probably just because you haven’t run the script from the top!

For more info on how to use the debugger please see:

http://help.mjtnet.com/article/7-using-the-debugger
http://help.mjtnet.com/article/42-using-macro-schedulers-debugger-to-aid-script-creation

November 17th, 2014 by Marcus Tettmar
November 12th, 2014 by Marcus Tettmar

With our MacroScript SDK you can add the ability to run Macro Scheduler code right inside your own applications.

The SDK lets you run Macro Scheduler scripts and code, as well as query Macro Scheduler script variables during code execution. The SDK gives you a more seamless way to run Macro Scheduler code and use Macro Scheduler capabilities within your own applications.

Back in 2012 Steen Jakobsen of DM Software integrated the SDK into their Dialog Manager software. He kindly agreed to a case study.

Macro Scheduler made it very easy to integrate the SDK. The input parameters for the scripts are completely integrated and direct, and secure and reliable data transfer is being accomplished – all thanks to the brilliant architecture of the MacroScript SDK. …. We’ve saved the doctors and nurses enormous amounts of time, and at the same time, added very valuable and sophisticated calculation and decision support across five systems that otherwise have no link to one another. This can only be done with the unique Windows automation capabilities of Macro Scheduler combined with the tight integration with Dialog Manager.

Steen Jakobsen, DM Software

Read the Case Study here.

November 7th, 2014 by Marcus Tettmar

I am pleased to announce that we have today released Macro Scheduler 14.2

Amongst other things this new version includes the following great new features:

  • Self Documenting Macro Recorder with snapshots of Windows/Objects being Activated/Clicked on
  • The ability to run Python code within your macros!
  • A native JSON Parser
  • A native XML Parser using XPath

Here’s an overview of these main new features, but for a more complete list of improvements view the history list here.

Self Documenting Macro Recorder

Ever recorded a macro and then tried to edit it but couldn’t figure out which bit did what? Well, now when you record a macro the macro recorder will take snapshots of windows that are activated and objects that you click on. These will be inserted into the script as image comments, right above the line of code they refer to. So, now, it’s easier to see exactly what your macro is doing and which bits you want to edit/copy.

Run Python Code Inside your Macros

In 14.2 there’s a new function called PyExec. It allows you to run real Python code and get back the values of any Python variables you specify. You’ll need to install the Python 2.7 DLL to your Macro Scheduler folder (or compiled .EXE folder) – there’s a link in the help file to a zip file with all the files you need.

You can run any Python code and even use third party Python imports. This is pretty wild IMO – the possibilities are endless. Here’s a simple example:

/*
First ensure Python27.dll and imports are in your Macro Scheduler program folder.
Download and unzip this file:

https://www.mjtnet.com/software/python27.zip

*/

Let>url=http://ip.jsontest.com/

/*
python_code:

import urllib2
import json

# grab data from http://ip.jsontest.com/ - see www.jsontest.com
response = urllib2.urlopen('%url%')

# load the json
dict = json.loads(response.read())

# get the ip member
myip = dict["ip"]

# make a nice string representation of the dict
sdict = json.dumps(dict)

# Anything we print to IO is returned in the PYExec output var
print "All Done"
*/

//Load the Python code to a variable
LabelToVar>python_code,pcode

//Run the code and request the values of the sdict and myip variables ...
PYExec>pcode,output,sdict,myip

//Display the IP address
MessageModal>Your pubic IP is: %myip%

Parsing JSON

In the last few years JSON has become a very popular way to transmit data objects. Most web services now use it so it cannot be ignored. While you can parse JSON using string handling/regex having an easy to use native parser is essential. Enter: JSONParse

In the above Python example we used Python’s own JSON handling to extract an IP address from some JSON retrieved from a web service. Here’s how we can do the exact same thing using native MacroScript code:

HTTPRequest>http://ip.jsontest.com/,,GET,,JSON
JSONParse>JSON,ip,myIP
MessageModal>Your pubic IP is: %myIP%

And here’s an example which gets data out of a more complicated structure:

//Requires Macro Scheduler 14.2

/*
MyJSON:
{ "uid" : "1234",
  "clients" : ["client1","client2","client3"],
  "people" : [{"Name":"Marcus","Age":"21"},{"Name":"Dorian","Age":"18"}],
  "color" : "red",
  "size" : 14 }
*/

LabelToVar>MyJSON,sJSON

JSONParse>sJSON,uid,result
JSONParse>sJSON,clients,result
JSONParse>sJSON,clients[1],result
JSONParse>sJSON,people[1].Name,result

Parsing XML

Of course XML is also still very popular. Up til now we’ve had to parse XML using substring handling/regex or use Microsoft’s XML object via VBScript – which is a little over-complicated IMO. We now have a simple to use native XML parser function – XMLParse. Here’s an example:

//Requires Macro Scheduler 14.2

LabelToVar>XML,sXML
XMLParse>sXML,/bookstore/book,val,numBooks
Let>k=0
Repeat>k
  Let>k=k+1
  XMLParse>sXML,/bookstore/book[%k%]/title/text(),val,len
  MessageModal>val
Until>k=numBooks

/*
XML:
<?xml version="1.0" encoding="UTF-8"?>




  Everyday Italian
  Giada De Laurentiis
  2005
30.00



  Harry Potter
  J K. Rowling
  2005
29.99



  XQuery Kick Start
  James McGovern
  Per Bothner
  Kurt Cagle
  James Linn
  Vaidyanathan Nagarajan
  2003
49.99



  Learning XML
  Erik T. Ray
  2003
39.95



*/

How to Download/Upgrade

If you have a valid maintenance plan you can download the update from your account here. If your maintenance has lapsed you can also purchase upgrades and renew maintenance from within your account.

Trial versions can be downloaded here.

October 30th, 2014 by Marcus Tettmar

Following on from my last post with some examples of using the MacroScript SDK within Python I thought I’d post a simple C# and C++ example. These are the same examples that ship with the MacroScript SDK:

C#

C++

More info on the MacroScript SDK is here.

    • Archives

  • Categories