October 17, 2019

Version 14.5.5 update. Improved text capture, improved OCR, and more.

Filed under: General — Dorian @ 1:52 pm

It’s been a while in the making, but we just released Macro Scheduler Version 14.5.5.
Registered users can download it here, and the trial version is here.

Version 14.5.5 15/10/2019

– Upgraded Python engine to Python 3.7.4 with ability to run Python 2.7 (PYTHON_DLL variable)
– Updated OCR engine to latest version of tesseract
– Updated native text capture engine
– Fixed: ArrayFind crashes if null array suffix provided
– Fixed: non existent subroutine cause script to end after error even if ignoring error
– Fixed: OCRArea incorrectly giving error on negative coordinates
– Fixed: Access Violation in OCRScreen for large screens (scaling has been removed for OCRScreen).

You should notice an improvement in OCR engine speed. Just this morning we tested OCRImage on a 1700 x 900 BMP image packed with text, and it extracted every character flawlessly in under three seconds.

The native text capture engine has been updated, improving the previous text capture capabilities.

One or two of you were asking about running Python 3.7, so we upgraded the engine to Python 3.7.4.

January 9, 2019

PrettifyScp – Code Clean Up

Filed under: General,Scripting — Marcus Tettmar @ 2:10 pm

I often end up working on Macro Scheduler code that is hard to read because of a lack of indentation. Sometimes this is simply because the code has been chopped and changed so many times it’s become a bit messy and needs a bit of a clean up. And I’m not pointing fingers here either – some of this code is my own!

Indenting code inside code blocks makes it much easier to read. But cleaning up code and sorting out the indentation manually is tedious. So I wrote a little script to do it!

So here is my first PrettifyScp script. Just run it and browse to the .scp file you want to fix up. Wait a few seconds and it will pop up a message when it’s done.

//tokens to identify start and end of indented code
Let>incTokens=^IF.*|^SRT\>.*|^REPEAT\>.*|^WHILE\>.*|^ELSE|^ELSE>
Let>decTokens=^ENDIF|^END\>.*|^UNTIL\>.*|^ENDWHILE.*|^ELSE|^ELSE>

//tokens to identify blocks to ignore
Let>inIgnores=^DIALOG\>.*|^VBSTART|^/\*.*
Let>outIgnores=^ENDDIALOG\>.*|^VBEND|\*/.*

//set tab chars
Let>tabs={"  "}

Let>numTabs=0
Let>inIgnoreSection=0
Let>outText={""}

//ask user for input script file
Input>scp_file,Select script file

If>scp_file<>{""}

  //create backup file name
  ExtractFilePath>scp_file,path
  ExtractFileName>scp_file,scp_name
  ExtractFileName>scp_file,scp_name_no_ext,1
  Let>backupfile=%path%\%scp_name_no_ext%.BAK

  //read in script lines to loop through
  ReadFile>scp_file,scp_data
  //temporarily remove percent symbols to avoid unwanted variable resolution
  StringReplace>scp_data,%,~^PERCENT^~,scp_data
  //split to array of lines
  Separate>scp_data,CRLF,scp_lines

  //if there are lines, loop through them
  If>scp_lines_count>0

    Let>k=0
    Repeat>k

      Let>k=k+1
      Let>this_line=scp_lines_%k%

      //Message>To do: %this_line%

      //left trim the line
      LTrim>this_line,trimmed_line

      //are we going into a section to ignore?
      RegEx>inIgnores,trimmed_line,0,matches,pIgnore,0
      If>pIgnore>0
        Let>inIgnoreSection=1
      Endif

      If>inIgnoreSection=1
        //if we are in a section to ignore, are we coming out of it?
        RegEx>outIgnores,trimmed_line,0,matches,pIgnore,0
        If>pIgnore>0
          Let>inIgnoreSection=0
        Endif
      Else
        //otherwise we are not in an ignore section so see if we need to do anything

        //should we unindent?
        RegEx>decTokens,trimmed_line,0,matches,dec_nm,0
        If>dec_nm=1
          Let>numTabs=numTabs-1
          //capitalise first letter while we're here
          MidStr>trimmed_line,1,1,fChar
          Uppercase>fChar,fChar
          RegEx>(^.{1}),trimmed_line,0,matches,nm,1,fChar,trimmed_line
        Endif

        //create the indent chars
        Let>indent={""}
        If>numTabs>0
          Let>t=0
          Repeat>t
            Let>t=t+1
            Let>indent=%indent%%tabs%
          Until>t=numTabs
        Endif

        //insert indent chars to line to output
        Let>this_line=%indent%%trimmed_line%

        //should we indent further lines?
        RegEx>incTokens,trimmed_line,0,matches,inc_nm,0
        If>inc_nm=1
          Let>numTabs=numTabs+1
          //capitalise first letter
          MidStr>trimmed_line,1,1,fChar
          Uppercase>fChar,fChar
          RegEx>(^.{1}),trimmed_line,0,matches,nm,1,fChar,trimed_line
        Endif

      Endif

      //output the new line
      Let>outText=%outText%%this_line%
      If>k<scp_lines_count
        Let>outText=%outText%%CRLF%
      Endif

    Until>k=scp_lines_count

    //swap percent symbols back in ...
    StringReplace>outText,~^PERCENT^~,%,outText

    //backup the file
    DeleteFile>backupfile
    CopyFile>scp_file,backupfile

    //write output to original file name
    DeleteFile>scp_file
    Let>WLN_NOCRLF=1
    WriteLn>scp_file,res,outText

    MessageModal>Done! Backup saved to %backupfile%

Endif


The old script is renamed to a .BAK file so that your original script is backed up. So if there’s something I haven’t thought of in this first stab and something gets messed up, you can’t lose anything, but hopefully you are backing up your code already!

I’m ignoring code inside Dialogs and VBScript blocks as well as comment blocks. Dialogs shouldn’t be messed with and the indentation is handled by the dialog designer. VBScript could be cleaned up but would need a different parser and there are already VBScript code beautifiers out there so you could copy and paste those. So in this version I haven’t touched VBS blocks.

Hope this is useful. Any feedback or suggestions, or if you notice a bug, please post in the comments below.

December 20, 2018

Season’s Greetings!

Filed under: Announcements,General — Marcus Tettmar @ 1:01 pm

From all of us at MJT we wish you season’s greetings and a wonderful start to 2019.

Here’s a fun little script with a message from Macro Scheduler. Open Macro Scheduler (download the trial if you don’t already have it), click New to create a new macro and paste this code in and hit run.

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
WriteLn>%temp_dir%\Sparkler.scp,wres,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
*/

Thanks to Dick Lockey for writing this little script (back in 2014).

Remember this?
Case Study: Macro Scheduler Saves 3600 Elf-Hours and Gets Presents Delivered On Time

May 15, 2018

Nice Customer Testimonial

Filed under: General — Marcus Tettmar @ 12:20 pm

Just had this testimonial from a recent customer and had to share it with you:

“Just wanted to take some time to say thank you for helping us out on this project at such short notice. We’d sunk quite some time into getting up to speed with a competing product, and had bought personal licenses as well as evaluation and then to find that it could not script all the parts we needed, and frankly how terrible their support was left us in a very bad spot – thank God we’d not stumped up the £3k for their .NET module which we were on the verge of doing. We quickly ran through 4 other web automation packages – none of which were up to the job for our task, or the learning curve was too steep to find out – then stumbled on your Macro Scheduler. If only we’d got to you first. Thanks again, I have no doubt we’ll find use for Macro Scheduler on other projects – it’s a very useful tool to have in the tool-box now.”

You can read more testimonials here.

April 19, 2018

Macro Scheduler Subscriptions from only 12.50/month

Filed under: Announcements,General — Marcus Tettmar @ 8:40 am

Did you know we offer monthly, quarterly or yearly subscriptions for Macro Scheduler Standard?

These subscriptions have no minimum term, so can work out very cost effective if you only need the product for a short while. You may also prefer the budgeting aspect of fixed priced subscriptions over the up front cost of a perpetual license and then potential future upgrade or maintenance costs.  I know I do.

A subscription gives you access to the latest version of Macro Scheduler for as long as your subscription is active. So maintenance and upgrades are included and you never go out of date.

Check our the subscription options here.

 

March 28, 2018

Will robotic process automation take your job away?

Filed under: Automation,General,Macro Recorder — Marcus Tettmar @ 2:25 pm

TLDR: No! That’s not what we’re here for. Robotic process automation is here to help you.

We often get called in to help a company automate a process. Many times this involves automating something that an end-user does. To make macros that make their job easier, less painful, and make them more productive.

Initial Resistance to Change

Sometimes, at the outset, we (or the IT department proposing Macro Scheduler as a solution) detect a little resistance from the end user. If not properly briefed they may be concerned that what we want to do is take work away from them, and they may be concerned that the macros, or software robots, are about to take their jobs away.

Epiphany!

Nothing could be further from the truth and by the time we’re done, the end users love us to bits and usually give us a long list of other things they’d like us to automate! Often they discover how easy it is to do it themselves with tools like the Macro Recorder and other code wizards.

I’ve written thousands of macros for hundreds of companies. I’ve never worked on anything that was designed to take a job away from an employee, other than one the employee didn’t like doing and didn’t have time to do without it impacting on their core purpose. In every case the macros we wrote were there to make the employees’ jobs easier, or to allow them to be more productive in more important areas. For example: removing a tedious admin task from an already overstretched clinician, allowing them to see more patients.

I suppose you could argue that the many over-night data-entry style macros we’ve written could have been done instead by a team of data entry personnel. But such a team didn’t exist to start with, or would have been cost prohibitive, or too error-prone to be considered in the first place.

Improving Productivity

So to answer the question, no, I don’t believe robotic process automation is about taking jobs away. It’s not about replacing staff. In my 21 years of automating user interfaces this isn’t what I’ve seen. Instead, I’ve been rewarded with making people’s lives easier, removing cumbersome, painful, processes, or using macros to simplify and improve an existing process.

March 15, 2018

Saving You Time and Money With Robotic Process Automation

Filed under: Automation,General,Macro Recorder — Marcus Tettmar @ 3:24 pm

Before Macro Scheduler existed I was a junior member of an IT department. As part of my job I built small tools to automate specific tasks. At the time I was using VB. Each time I had to automate a task I had to reinvent the wheel a little.

The whole point of Macro Scheduler was to simplify the task of building automation routines, or software robots. To avoid having to reinvent the wheel.

There’s no reason why you can’t automate your Excel-to-SAP/WEB/ERP/ACME-Desktop-App by writing code using C# or C++. But it’s going to take you longer than using Macro Scheduler. Macro Scheduler functions like “SendText” and “UISetValue” encapsulate some pretty low level and quite convoluted code. The code wizards and macro recorders which help you use them are even more complicated.

One of the main purposes of Macro Scheduler is therefore to enable people to automate things more quickly and more easily than could be done with traditional programming tools. It makes it possible for non-programmers but also simplifies and speeds up automation for developers.

Over the last 21 years – yes 21, Macro Scheduler was first launched in 1997! – we’ve helped people with a lot of automation tasks. We offer consultancy and have been into people’s offices and also helped over the phone and remote desktop. Most routines take us a few hours to create a macro for. Some take a day or two. Rarely do we need to spend more than three days on one process, though there are some projects which involve a series of automation routines that may therefore take longer or be done over a few sessions.

To do the job from scratch with C#, C++ or VB might take weeks. Many people who approach us seem to be imagining that to automate their task may take days or weeks. They are often very surprised when we tell them it’s a few hours not a few days.

We are all about saving time and money. That’s what our tools do and it’s why we built them. Our tools mean you don’t have to pay developers lots of money to spend weeks or months building custom solutions.

The only down side to this from our point of view is that we routinely disappoint large consultancy businesses and potential partners who are used to selling IT contracts worth hundreds of thousands. They approach us thinking that there’s a huge opportunity and that we’ll pay them a large cut of a big consultancy project.

But rarely does a job require so much time, and that’s the reason we’re here. Sometimes I sense these people want us to “flesh” projects out. They think we’re “too good” at what we do. We should slow down, make things more complicated and thus charge for more time.

But that isn’t us. That’s not why we’re here or why we created Macro Scheduler. The whole ethos of Macro Scheduler and MJT Net Ltd is to save time, to find more efficient, less expensive ways of doing things that were once thought impossible or too expensive to do, and to enable people to automate without specialised knowledge.

That said we’re happy to work with companies on an on-going basis. I have found that most businesses approach us with one specific routine in mind and then when they see what can be done they realise how it can be applied across the organisation in other departments, for other teams. Saving a team one hour a week may not seem like much, but do that for 500 other teams and it adds up to a huge efficiency saving for the entire business.

If you would like to talk to us to find out how we could help your business, whether on an ongoing basis or just for a one-off job, please drop me a line here.

January 2, 2018

Happy New Year – Welcome to 2018!

Filed under: Announcements,General — Marcus Tettmar @ 10:16 am

Just a quick note to say Happy New Year to all our customers. This year will be our 21st year of selling Macro Scheduler. I think that’s pretty amazing. Thanks for all your support over the years and for continuing to use Macro Scheduler. It’s always great to hear how Macro Scheduler helps in your work and business processes, so please continue to keep in touch and let us know how it’s helping you. Here’s to a happy and healthy 2018!

October 11, 2017

What is Robotic Process Automation (RPA)?

Filed under: General — Marcus Tettmar @ 2:32 pm

Our longstanding customers will know we’ve never really been into jargon here at MJT. Jargon in the IT industry tends to come and go. And there’s something quite amusing about a term that pops up and is touted as being some amazing new thing when it simply describes something we’ve been doing here at MJT Net Ltd for 20 years! On the other hand any term that helps to describe what we do is useful and I suppose it’s nice to know that finally, after all this time, what we do in our little niche of the IT world now has a name: Robotic Process Automation or RPA.

So those of you who have been using Macro Scheduler for a while know what RPA is, even if you’ve never called it that.

Robotic Process Automation tools allow you to create “bots” (we’ve always called them macros) to automate business processes (often by simulating a user). With RPA we automate repetitive tasks – taking the robot out of the human – freeing people up for more value-adding activities.

Our customers have been automating their processes robotically for years, ever since Macro Scheduler was first released way back in 1997.

August 11, 2017

Morning Rant

Filed under: General — Marcus Tettmar @ 10:13 am

A customer filing PayPal disputes rather than emailing us and then, despite confirming that they have the software, failing to cancel the dispute and PayPal finding in their favour, leaving us out of pocket!

PayPal is costly and causes so many accounting headaches it isn’t true. I’ve a good mind to remove it from our site. How many people only buy because we accept PayPal? Anyone?

Another “customer” asking us to write a script, watching us write code, seeing it working, speaking favourably throughout the project at every step, never voicing any concern and then refusing to pay at the end. What’s the answer, lawyers and contracts, which would mean we’d have to put the prices up, or just stop offering script development services? Answers below.

Maybe give up completely. It isn’t what it used to be. This was fun in the early Internet days. Now it just feels like everyone wants something for nothing. Convince me otherwise below.

Older Posts »