October 5, 2009

More on Reading and Writing CSV Files

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

More on Reading from CSV Files

In Reading from CSV Files I showed you how you could read an entire CSV file into an array of rows and columns. It used a SELECT * SQL statement to retrieve the entire table.

If you just want to read in a specific set of data you could use a more selective SQL statement. But before we can do that we need to make a slight change to the connection string. The connection string used in my last article includes the text HDR=NO which tells the database driver that the CSV file does not have a header record. If we want to be selective in what data we wish to retrieve we would need to know how to reference that data. So we would need a header record. The following example CSV file starts with a header record:

forename,age,fav_color
“sally”,28,blue
“fred”,32,green
“john”,28,yellow

We now have a way to identify each column of data. We can now change our connection string to use HDR=YES. So our code to connect to the database becomes:

Let>ConStr=Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\My Documents;Extended Properties='text;HDR=YES;FMT=Delimited'
DBConnect>ConStr,dbH

We could now create a selective query. For example to select all people who are 28 years old we would use the following SQL:

SELECT * FROM csvfile.csv WHERE age=28

That would retrieve all fields. We may just want to retrieve their names:

SELECT forename FROM csvfile.csv WHERE age=28

In Macro Scheduler the code to do this is:

Let>SQL=SELECT forename FROM csvfile.csv WHERE age=28
DBQuery>dbH,SQL,fields,num_recs,num_fields

We then get an array called fields containing the results. See Reading from CSV files for example code that loops through the results.

Writing to CSV Files

As I mentioned in Reading from CSV Files, CSV files are just text files, so you could just use the WriteLn function to add a record of data to the end of the file:

WriteLn>”sally”,28,”blue”

But if you only want to add specific fields to the end of the line and want to save yourself the bother of having to correctly delimit the text you might want to treat the CSV file as a database table and use Macro Scheduler’s database functions instead.

In Reading from CSV Files we looked at using an ADO connection string and DBQuery to connect to the CSV file as if it were a database table and then using SQL to pull out the data. Well, we can do the same thing and use SQL “Update” and “Insert” queries in order to modify and insert data into the CSV file.

Here’s the code we used to connect to the CSV file as a data source:

Let>ConStr=Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\My Documents;Extended Properties='text;HDR=NO;FMT=Delimited'
DBConnect>ConStr,dbH

To insert a row of data to the end of the file we can use the SQL INSERT statement as follows:

INSERT INTO csvfile.csv VALUES (“george”,19,”purple”)

In Macro Scheduler we need to use the DBExec command to execute this SQL:

Let>SQL=INSERT INTO csvfile.csv VALUES ("george",19,"purple")
DBExec>dbH,SQL,res

If you look at the connection string we used you’ll see the directive HDR=NO. This tells the database driver that the CSV file does NOT contain a header record. If we DO have a header record we should change this to HDR=YES. This also means we can specify individual column names in the INSERT statement. E.g. we may have the following CSV file:

forename,age,fav_color
“sally”,28,blue
“fred”,32,green

So now we can insert data for only two fields and because we have HDR=YES we can determine which of those fields should be set:

Let>ConStr=Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\My Documents;Extended Properties='text;HDR=NO;FMT=Delimited'
DBConnect>ConStr,dbH
Let>SQL=INSERT INTO csvfile.csv (forename, fav_color) VALUES ("george","purple")
DBExec>dbh

Unfortunately it would appear that it is not possible to perform DELETE or UPDATE queries on CSV files. I’ve spent a few hours trying to find a definitive reference for JET’s text file driver but cannot find anything. All I know is that when I tried a DELETE or UPDATE query nothing happened. This is a shame as this possibility would be extremely powerful. As it is there’s not really much of a benefit over using DBExec instead of WriteLn.

If anyone knows of a definitive reference or a way to be able to perform DELETE or UPDATE queries using the Microsoft CSV driver, please let me know.

September 18, 2009

Fun with Chinese Windows

Filed under: General — Marcus Tettmar @ 11:12 am

As you may have noticed, in the last Macro Scheduler update we fixed a problem that prevented compiled macros from running on Chinese Windows. This probably affected other non-Western language versions of Windows too. It took us a while to track down this little bug even though, as is often the case, it turned it to be a simple little thing.

In order to replicate the problem quickly I installed the Chinese Simplified version of Windows XP into a Virtual Machine. That was interesting when I have no knowledge of Chinese whatsoever. Luckily (or unluckily) I’ve installed XP so many times I knew from the location of each option what each one did. Here’s our XP Windows showing the control panel:

Do what?

Do what?

It did give me a great idea for a way to stop my friends and family from mucking up their PCs. Maybe if they don’t understand what the screen says they can’t muck it up …oh wait …

Anyway, with the 490 million Chinese Internet users soon to outnumber the rest of us, I’m glad this little bug has been squashed.

September 17, 2009

Macro Scheduler 11.1.14 Update

Filed under: Announcements — Marcus Tettmar @ 2:52 pm

Macro Scheduler 11.1.14 is now available with the following changes:

  • Added: WLN_ENCODING=UNICODE setting to make WriteLn create Unicode file if file does not already exist
  • Added: WriteLn will detect encoding and output accordingly (ANSI or Unicode)
  • Added: ReadLn and ReadFile can now detect and read data from Unicode files
  • Fixed: Syntax highlighter wrongly highlighting start of block comment tokens when inside other commands (not at start of line)
  • Fixed: FTPGetDirFile issue with format of directory list and wildcard matching with some flavours of FTP server
  • Fixed: Dialog Designer: Ability to view TDialog properties with F11/Right Click restored
  • Fixed: Problem compiling on Chinese versions of Windows (and possibly other non-Western language versions)
  • Fixed: Image Capture Tool not refocusing after capture
  • Fixed: WSI_TIMEDOUT not coloured as system variable by syntax highlighter

Registered Downloads/Upgrades | Evaluation Downloads | New License Sales

September 9, 2009

Including Often Used Library Files

Filed under: Scripting — Marcus Tettmar @ 3:49 pm

If you create lots of Macro Scheduler macros you probably have pieces of code you use frequently. You might have blocks of VBScript or subroutines you often use in your macros. Copying and pasting code like that into your scripts is time consuming and also means if you ever need to change that code you’ll end up having to edit all your macros. A better way to use such “library code” is to Include it using the, yes, Include function:

Include>%SCRIPT_DIR%\MyLib.scp

This function includes the content of MyLib.scp in your macro.

Some people seem confused about how this works. It’s simpler than you might realise. It literally sucks in the code in place of the Include line and then executes it. When the script runs that Include line is actually replaced with the code in MyLib.scp. So the code in MyLib.scp actually becomes part of the overall macro.

One way to visualise how it works is to step through an Inlude line in the debugger. You’ll see the debugger pull the code into the script. Here’s a video to show you what I mean:

In the above example I’ve kept the include file small so that the entire script still fits in the editor. You’ll see the code jump into the editor and then disappear when the script ends or is stopped.

With Include you can reference commonly used functions and code. Some projects may involve lots of scripts that all use some core functions which you would put into an Include file.

Include is different to the Macro command which just “calls” another script file. With the Macro command that other script is run in isolation, almost like another process. The code isn’t shared between the two scripts. Include doesn’t just run the code, it pulls the code into the current macro so that it becomes part of it and is executed at that point. It remains part of the script until the script terminates. So the code could be subroutines or dialog blocks or VBScript blocks or anything you need the main script to reference.

September 8, 2009

August 28, 2009

Kudos

Filed under: General — Marcus Tettmar @ 4:44 pm

Just received this email and had to share it.  It’s notes like this that make it all seem worth it, especially at the end of a long week. 🙂

To ALL

I’m sorry.  I know I must sound like a broken record.  But……

OMG!!!

You guys are AWESOME!!!

The LEVEL of Tech Support here is insane!! It is through the roof!  The Freak’n roof is on FIRE!!!

The POINTS are OUT the WINDOW!!

How DO you do it?  You have to answer so many e-mails and yet you maintain this unheard of level of
EXELLENCE!!  I KNOW you have to deal with some….well you know.  And yet…..

OMG!!!

Please tell me you can’t help me, just so I know I’m still ALIVE!!

Keep up the GREAT work!
PepsiHog

Determine IE Version and Automate IE Dialogs

Filed under: Automation, Scripting — Marcus Tettmar @ 2:25 pm

If you are automating web pages or web applications you may at some point need to automate dialog boxes produced by client side script, like the one that pops up when you click the link below:

Confirm Popup

So you might want to be aware that the title of these popups varies between different versions of Internet Explorer. In IE6 it was “Microsoft Internet Explorer”. In IE7 it is “Windows Internet Explorer” and in IE8 it is now “Message from webpage”.

I much prefer the last one from an automation point of view since it differs significantly from the title of the main IE window which usually contains the phrase “Microsoft Internet Explorer” in IE7 and “Windows Internet Explorer” in IE8.

So if we wanted to click on the Yes button if we were writing a script for IE8 we could use the following code:

SetFocus>Message from webpage
Press Enter

But what if we didn’t know what version of IE our script would be automating? If you were giving your script to someone else or putting it on some other PC you may not know what version of IE was being used. What we need to do is make the script find out what version of IE is installed on the computer.

Here’s how to make the script determine which version of IE is in use:

RegistryReadKey>HKEY_LOCAL_MACHINE,SOFTWARE\Microsoft\Internet Explorer,Version,IEver
Separate>IEVER,.,bits
Let>IEVER=bits_1

IEVER now contains the major version number of Internet Explorer.

So we could now use this to define the title we expect from the dialog box and confirm it:

RegistryReadKey>HKEY_LOCAL_MACHINE,SOFTWARE\Microsoft\Internet Explorer,Version,IEver
Separate>IEVER,.,bits
Let>IEVER=bits_1

Let>dialogTitle_IE6=Microsoft Internet Explorer
Let>dialogTitle_IE7=Windows Internet Explorer
Let>dialogTitle_IE8=Message from webpage

SetFocus>dialogTitle_IE%IEVER%
Press Enter

Of course this is all assuming you’re using the English version of Internet Explorer. I cannot vouch for other languages.

August 26, 2009

Strange Support Requests

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

I never ceased to be amazed at some of the queries we get. This one came in today via Live Chat. Perhaps it was a joke:

Strange Support Chat

Weird.  Now, I did wonder for a minute if the thesis had something to do with the use of Macro Scheduler or automation tools or similar, in which case I might have been able to help somehow, but after asking how the question related to Macro Scheduler the requestor simply said sorry and left.  So it clearly didn’t.

The only way to initiate a live chat request is via our website, which I’m pretty sure doesn’t say anything about offering translation services. Last time I looked (just now) mjtnet.com is pretty obviously all about Macro Scheduler and our other automation tools.

August 25, 2009

The Power of DOS: Looping Through Subfolders

Filed under: Automation, Scripting — Marcus Tettmar @ 7:37 pm

Twice today, for two different people, I needed to write some code to iterate through files in a tree of subfolders. The subfolder structure could not be known up front and there may be any number of subfolders and any number of folders deep.

One could use GetDirList iteratively, or use VBScript’s FileSystem Object. But then I was reminded of the power of DOS by JRL in this post.

The following returns a file containing a list of the jpg files throughout all folders, starting in c:\root_folder\ with full paths:

dir c:\root_folder\*.jpg /s /b > outputfile.txt

So, as JRL suggests, we can call that command from Macro Scheduler and then read in the output file. We should use a temporary file:

Let>RP_WINDOWMODE=2
Let>RP_WAIT=1
Run>cmd /c dir c:\root_folder\*.jpg /s /b > %TEMP_DIR%~temp_dir_list~
ReadFile>%TEMP_DIR%~temp_dir_list~,dir_list

Now we can explode that list into an array and loop through it, doing whatever it is we need to do to each file:

Separate>dir_list,CRLF,files
If>files_count>0
Let>f=0
Repeat>f
  Let>f=f+1
  Let>this_file=files_%f%
  //do something with this_file
Until>f=files_count

It’s easy to forget the power of DOS – it can save you a fair few lines of code sometimes.

Remember that any DOS command can be “piped” to an output file by appending >filename to the command line. This is very useful as we can then use ReadFile to get the output from the command, as we have done above.

August 17, 2009

Summer Sale – Prices Reduced – 20% off Upgrades

Filed under: Announcements — Marcus Tettmar @ 10:46 am

For summer only we’ve reduced the prices of our popular items. Macro Scheduler Pro (Single User) is now only $195 USD and Macro Scheduler Standard (Single User) is $95 USD. Incredible value!

See prices and purchase on-line here.

And with the following coupon code you can get 20% off all Macro Scheduler upgrades:

Coupon Code: UPGRADE11

(Enter the coupon code on the cart page and hit Checkout to view calculated discount)