June 28, 2011

June 17, 2011

End of Life for Old Versions

Filed under: Announcements — Marcus Tettmar @ 8:45 am

We do our best to support all our customers whatever version they are using. But there are only so many versions we can run. So after a few years we need to officially “end-of-life” older versions.

To that end, as of January 1st 2012 we will no longer be supporting Macro Scheduler v9 or lower. The latest version is v12. We will continue to provide support for customers using v10 or later. However, please note that right now only v12 is being maintained.

June 13, 2011

Calling Macro Scheduler Functions from PowerShell

Filed under: General, Scripting — Marcus Tettmar @ 11:34 am

Further to my post about the MacroScript SDK the other day, here’s an example of loading the MacroScript SDK COM object from PowerShell and running some Macro Scheduler code:

  $objMS = new-object -comobject "mscript.macroscript"
  $objMS.Init()
  $objMS.RunCode( "Run>notepad.exe" + [Environment]::NewLine + 
  		"WaitWindowOpen>Untitled - Notepad" + [Environment]::NewLine + 
  		"Wait>0.5" + [Environment]::NewLine + 
  		"Send>Hello World", "")
  $objMS.Cleanup()

You will need to put the mscript.dll file into the system path (e.g. System32/SysWow64) or into the PowerShell folder.

Don’t forget that with the MacroScript SDK you can retrieve information and query the data back to PowerShell using the GetVar function (see previous post). So for all you system administrators using PowerShell but needing the GUI automation capabilities of Macro Scheduler as well, the MacroScript SDK is the perfect companion.

June 10, 2011

Macro Scheduler 12.1.7 Available

Filed under: Announcements, Macro Recorder — Marcus Tettmar @ 1:07 pm

Macro Scheduler 12.1.7 is now available for download.

This is a minor update to fix a small mistake in the help file (example for XLGetCell) and also an issue with the macro recorder which would fail to work if it had previously been cancelled after being started from within the Script Editor.

Registered Downloads/Upgrades | Evaluation Downloads | New License Sales

June 9, 2011

About the MacroScript SDK – How to Run Macro Scheduler Code Within Your Own Applications

Filed under: General, Uncategorized — Marcus Tettmar @ 8:46 am

What Is The MacroScript SDK?

The MacroScript Software Development Kit is a software component that allows developers to use the Macro Scheduler scripting language within their own applications. It comes in ActiveX and DLL form so that almost any programming language, including VB, C#, C++, Delphi, PowerBuilder, etc, can make use of it. It makes it possible for other applications to run Macro Scheduler code internally. As well as run Macro Scheduler code it allows the programmer to query or modify MacroScript variables at any point during execution.

Who Would Use It and Why?

The SDK is aimed at application developers. It is commonly used in projects where some integration is needed with other third party or legacy applications where no API exists, or where the developer needs to provide a means of creating macros within their applications.

For example, DM Software in Denmark used it in their Dialog Manager product to simplify integration with other systems and share data with them, as well as allow their users to create scripts for custom integrations. You can read the case study here.

Why Not Just Compile a Macro with Macro Scheduler Pro and “shell” it?

If all you want to do is have your application run a Macro Scheduler macro to perform some automation, then, sure, all you really need to do is compile your macro to a .exe and then call or “shell” this .exe from your application. E.g. using the VB/VBA Shell function.

This might be fine if that is really all you need to do. But what if you want to get data back from the macro? Let’s say the macro scrapes data from a web page and you need to get this data back into your calling application. This would be difficult to do with an external .exe. While you could use temporary file storage or a database and have your .exe macro write the data out and then read it back in with your application, this requires extra work and validation. You also have to consider the implications of the external macro process being terminated prematurely, perhaps by the user.

With the SDK you can execute script code directly from within your application in whole, or in sections or even one line at a time. And between lines or code sections you can directly query the value of a variable or variables. So using the SDK you have much greater control, there is no need to handle shelling out to an external process, waiting for it to complete and reading/writing to file. Instead you can control the logic flow as you wish and access macro data directly, storing it in local variables as and when needed.

– Control of logic flow
– Direct access to script variables
– No need to start an external process

How Do I Use It?

The MacroScript SDK ships with both an ActiveX and native DLL interface so is compatible with the majority of development environments and languages. A basic set of methods provides access to the functionality and examples are included for VB, VBScript, C++, C# and Delphi.

Here’s a simple example in VB:

    Set MacroScript = CreateObject("MScript.MacroScript")
    MacroScript.Init

    'Run notepad and send some text to it
    MacroScript.RunCode "Run>notepad.exe"
    MacroScript.RunCode "WaitWindowOpen>Untitled - Notepad"
    MacroScript.RunCode "Send>Hello World"

    'set variable x to the value entered in Text1 multiplied by 5
    MacroScript.RunCode "Let>x=" & Text1.Text & "*5"

    'get the value of x and put it in Text2
    Text2.Text = "x=" & MacroScript.GetVar("x")
    MacroScript.Cleanup

In the above example first we demonstrate running some code to start Notepad and send text to it. Next we create a MacroScript variable set to the value supplied in a text box on the form multiplied by 5 and then demonstrate how we can retrieve values back from the script.

As well as run script code you can also run script files and pass parameters into code blocks and scripts as you would command line parameters for regular scripts. In addition the ActiveX has script and parms properties and a Run method for an easy way to apply a script and run it.

For more information click here; download the evaluation which includes full documentation and examples; or read a case study on how DM Software makes use of the SDK in their Healthcare Application.

June 7, 2011

Letting off Steam?

Filed under: General — Marcus Tettmar @ 9:04 am

For the licensing mechanism for our ClipMagic product (ClipMagic is an easy to use Windows Clipboard Extender if you didn’t already know) we adopted a server based activation system. I know that some people have a passionate dislike for software that needs to be activated, but you can’t please everyone. And until now we’ve had no complaints.

Then yesterday we get a ticket with no name and an invalid made-up email address saying simply:

“Unfortunately I purchased your product without realizing it required web authorization. I’ll just use a competing product”.

Now, before I’d seen the email address my immediate reaction was to reply and offer a refund. Perhaps I’m too nice but I don’t see the point in having customers that don’t want to be customers. But then I noticed that if I did reply the email would simply bounce. The “customer” has provided no identifying information at all!

I don’t get it. He says he purchased but doesn’t want it – and won’t activate it. Yet doesn’t want me to know who he/she is and isn’t asking for a refund. So why bother emailing me? Letting off steam perhaps. But it seems odd that there was no request for a refund.

I’ll file it away in our “Strange Emails” category.

May 23, 2011

Why Can’t I Colour My Dialog Buttons?

Filed under: General — Marcus Tettmar @ 8:45 am

Some people have asked why they can’t change the colour of a button that they place onto a custom dialog.

The short answer is that these buttons are standard Windows buttons and are drawn by Windows. And Windows has some “rules”.

Microsoft lays down some design guidelines. Take a look at this document here which says:

If you use standard windows and Windows controls, these border styles are supplied for your application automatically. If you create your own controls, your application should map the colors of those controls to the appropriate system colors so that the controls fit in the overall design of the interface when the user changes the basic system colors.

So, a standard control, like a dialog button will adopt the colour and design as decided by Windows and the user’s system wide preferences and we as the programmer have little or no control over it. Idealistically this is a good thing.

I believe that convention helps usability. If all buttons look alike a user knows it’s a button and so it’s purpose and functionality is obvious.

Of course, there are exceptions and sometimes there may be a reason (justified or not) for ignoring the guidelines and making a button look like something very different, e.g. in a game. So how do you do it? Well, obviously you don’t use standard Button objects.

On the whole Macro Scheduler dialogs are meant to be just that – standard looking Windows dialogs, designed for requesting data from users or giving them choices and controlling macros.

If you want complete freedom to design something snazzy then arguably you are using the wrong technology and should be considering something like Flash or HTML instead. And there’s no reason why such an interface can’t trigger Macro Scheduler macros anyway.

Having said that there are some things you can do to make more glorified looking dialog “buttons”. One option is to use Image objects. Don’t forget that you can respond to a mouse click on any object, so you can easily have a clickable image. You can trap other events too – such as mouse over events. So if you want to be really clever you can have your image’s mouse over event change the image, e.g. to one with a slightly different border style so that the user knows it is the active “button”.

May 20, 2011

Scraping Data From Web Pages

Filed under: Automation, Scripting, Web/Tech — Marcus Tettmar @ 1:02 pm

I’ve seen quite a lot of requests lately from people wanting to know how to extract text from web pages.

Macro Scheduler’s optional WebRecorder add-on simplifies the automation of web pages and includes functions for extracting tables, text or HTML from web page elements. WebRecorder’s Tag Extraction wizard makes it easy to create the code.

Sometimes you can choose a specific HTML element and identify it uniquely via it’s ID or NAME attribute. But other times you might want all the text from the whole page, or you may need to extract the entire page and then parse out the bits you’re interested in using RegEx or some other string manipulation functions.

To extract an entire page I specify the BODY element. If you want to extract data from web pages it does help if you know a little about HTML. And if you do you’ll know that each page has just one BODY element which contains the code making up the visible portion of the page.

Here’s code produced using WebRecorder when navigating to mjtnet.com and using the Tag Extraction wizard to extract the BODY text:

IE_Create>0,IE[0]

IE_Navigate>%IE[0]%,http://www.mjtnet.com/,r
IE_Wait>%IE[0]%,r
Wait>delay

//Modify buffer size if required (you may get a crash if buffer size too small for data) ...
Let>BODY0_SIZE=9999
IE_ExtractTag>%IE[0]%,,BODY,0,0,BODY0,r
MidStr>r_6,1,r,BODY0

MessageModal>BODY0

The macro simply displays just the text in a message box but could be set to pull out the full HTML. You could then parse it with RegEx to get the information you are interested in.

You will need WebRecorder installed for the above to work.

If you don’t have WebRecorder you can do the same with a bit more work using VBScript. Some library functions for doing this can be found here and here.

So here’s the equivalent in VBScript:

VBSTART
Dim IE

'Creates IE instance
Sub CreateIE
  Set IE = CreateObject("InternetExplorer.Application")
  IE.Visible=1
End Sub

'Navigate to an IE instance
Sub Navigate(URL)
  IE.Navigate URL
  do while IE.Busy
  loop
End Sub

'This function extracts text from a specific tag by name and index
'e.g. TABLE,0 (1st Table element) or P,1 (2nd Paragraph element)
'set all to 1 to extract all HTML, 0 for only inside text without HTML
Function ExtractTag(TagName,Num,all)
  dim t
  set t = IE.document.getElementsbyTagname(Tagname)
  if all=1 then
    ExtractTag = t.Item(Num).outerHTML
  else
    ExtractTag = t.Item(Num).innerText
  end if
End Function
VBEND

VBRun>CreateIE
VBRun>Navigate,www.mjtnet.com

VBEval>ExtractTag("BODY",0,0),BodyText
MessageModal>BodyText

But what if you already have a macro which already opens IE, or works against an already open instance of IE? The above macros need to create the IE instance before they can access them and extract data from them. You may have a macro that already starts IE some other way – maybe just by using a RunProgram or ExecuteFile call, or indirectly via some other application. Many times people tackle the extraction of data from such an IE window by sending keystrokes to do a Select-All, Edit/Copy and then use GetClipboard; or even File/Save As to save the HTML to a file. This of course adds time and can be unreliable. So how else can we do it?

Well, this tip shows us a function we can use to attach to an existing IE instance. So let’s use that and then use our ExtractTag function to pull out the BODY HTML:

VBSTART
Dim IE

' Attaches to an already running IE instance with given URL
Sub GetIE(URL)
  Dim objInstances, objIE
  Set objInstances = CreateObject("Shell.Application").windows
  If objInstances.Count > 0 Then '/// make sure we have instances open.
    For Each objIE In objInstances
      If InStr(objIE.LocationURL,URL) > 0 then
        Set IE = objIE
      End if
    Next
  End if
End Sub

'This function extracts text from a specific tag by name and index
'e.g. TABLE,0 (1st Table element) or P,1 (2nd Paragraph element)
'set all to 1 to extract all HTML, 0 for only inside text without HTML
Function ExtractTag(TagName,Num,all)
  dim t
  set t = IE.document.getElementsbyTagname(Tagname)
  if all=1 then
    ExtractTag = t.Item(Num).outerHTML
  else
    ExtractTag = t.Item(Num).innerText
  end if
End Function
VBEND

VBRun>GetIE,www.mjtnet.com

VBEval>ExtractTag("BODY",0,1),BodyHTML
MessageModal>BodyHTML

This snippet assumes a copy of IE is already open and pointing to www.mjtnet.com. The GetIE call creates a link to that IE window and then we use the ExtractTag function to pull out the HTML of the BODY element.

These examples use the BODY element, which will contain everything displayed on the page. As I mentioned before you can be more specific and specify some other element, and with WebRecorder, or a modified version of the ExtractTag VBScript function use other attributes to identify the element (the existing VBScript ExtractTag function shown above just uses the numeric index). WebRecorder tries to make it simple by giving you a point and click wizard, making some assumptions for you, so that you need not fully understand the HTML of the page. But it still helps you understand HTML. Looking at the source of the page you should be able to identify the element you need to extract from. And whether you extract directly from that or extract the BODY and then use RegEx being prepared to delve into the HTML source is going to get you further.

UPDATE: 19th January 2012

As of version 13.0.06 Macro Scheduler now includes a function called IEGetTags. For a given tag type and IE tab this will retrieve an array of tag contents. It can extract just the text, or html of the tags. This example extracts the inner HTML of all DIV elements in the open IE document currently at www.mjtnet.com:

IEGetTags>mjtnet.com,DIV,H,divArr

You can then cycle through each one with a Repeat Until

If>divArr_count>0
  Let>k=0
  Repeat>k
    Let>k=k+1
    Let>this_div_html=divArr_%k%
    .. 
    .. do something with it
    .. e.g. use RegEx or substring searching to determine 
    .. if this is the DIV you want and extract from it
    .. 
  Until>k=divArr_count
Endif

To further identify the tag you are interested in, or find the data you want, you can use RegEx, EasyPatterns, or string functions.

Macro Scheduler 13.0.06 and above also has a function called IETagEvent which will let you simulate a Click on a given tag, focus it, or modify its value. So once you have identified a tag using IEGetTags and your Repeat/Until loop you can click on it, focus it or modify its value (e.g. for form fields).

Macro Scheduler 12.1.6 – Now With Macro Recording in Script Editor

Filed under: Announcements, Macro Recorder — Marcus Tettmar @ 10:59 am

Macro Scheduler 12.1.6 is now available. This release includes a bonus new feature: Access to the Macro Recorder from within the editor.

This means you can now record steps within the editor, with the recorded code being inserted at the current cursor position. This also means the macro recorder can be invoked multiple times to insert recorded steps at whatever point in the script you like.

So you could build up recorded scripts step by step or add recorded code to a script you have already written. You might have a macro which gets to a specific point in a script and then you want to record some keystrokes against that application, then manually add some more code afterwards. By being able to access the Macro Recorder from the Editor and insert recorded steps on the fly building up scripts like this becomes much easier.

Check it out. Look for the Macro Recorder icon on the Editor toolbar and under the Tools menu. Download from the usual locations (links below).

Registered Downloads/Upgrades | Evaluation Downloads | New License Sales