Attachable Scripts

As of MoneyWorks Gold 7, attached platform-specific helper scripts are deprecated in favour of document-based MWScript scripts.

You can write a script which MoneyWorks will send messages to every time something happens with the user interface (open window, validate window, validate field, exit field etc). This script should be named "Helper.scpt" and goes into the Scripts folder of MoneyWorks Custom or Standard plug-ins.

On Mac, the Helper.scpt script must be written in Applescript (and the .scpt extension implies that it is compiled);

On Windows, the Helper.scpt file should actually be a one-line text file containing nothing but the name of a COM object that is registered in the registry. The COM object can be implemented in VBScript or similar using a .WSC file or you can go the whole hog and implement it as a DLL with an IDispatch interface. If this is gobbledegook, don't worry—wait for the code samples, which you can just modify to do what you want.

The following messages will be sent to the Helper script:

Script messages

Load - when script is loaded

Unload - when script is unloaded

Document messages

OpenedDocument - when the document opens

AllowCloseDocument - when the document is about to close. You can prevent it from closing by returning false.

ClosedDocument - after the document has closed

AllowSaveDocument - just before saving the document. You must return true to allow the document to be closed. You must return true to allow saving to go ahead. You can prevent it from saving by returning false.

SavedDocument - after the document has been saved

UserLoggedIn - after a user has logged in (you won't get this if the document is not password protected)

UserLoggingOut - just before a user logs out.

Window messages

WantMessages - when window opens

Before - when window opens or loads a new record

Validate - when window is about to be accepted

Cancel - when window is cancelled

After - when window is accepted

ValidateField - when field is about to be exited

ValidateCell - when detail line field is about to be exited

ExitedField - when field has been exited

ExitedCell - when detail field has been exited

And by "messages", I mean that your script implements functions with these exact names and MoneyWorks calls them.

For more details and examples of use, see the sample scripts.

New user interface scripting

Of course, having your script be notified of events like exiting a field is only useful if you can get and set field values. To this end MoneyWorks 4.1.1 and later has enhanced scripting access to the user interface. You can get and set field values in dialog boxes, and add and delete detail lines.

Applescript Object Model (Mac)

MoneyWorks 4.1.1 added the following classes and verbs to the Applescript dictionary. In keeping with standard Applescript terminology, the detail line entry list in a transaction window is referred to as a "table", containing "rows". Each row in turn contains "cells". You can make new rows and delete rows. You can get and set contents of cells and fields. The front window (the one you will usually be concerned with is always window 1 although you can also refer to windows by name. Likewise the detail line entry table is always table 1, but you can refer to it by it's name which is the same as the selected tab (i.e. "Service" or "Product" etc).

See the Applescript Dictionary in Script Editor for details.

Component Object Model (Windows)

On Windows, the following functions are available in the COM IDispatch interface. The dialogHandle and listHandle parameters get passed to your attached script by MoneyWorks. Since this is the only way to get a dialogHandle, you can only use these functions from within an attached script, not from a standalone script.

BSTR GetField([in] LONG dialogHandle, [in] LONG fieldNumber)

Get a field value from a dialog box. The dialog box handle is passed to you as a parameter to your script function.

void SetField([in] LONG dialogHandle, [in] LONG fieldNumber, [in] BSTR value)

Set a field value in a dialog box

BSTR GetListField([in] LONG listHandle, [in] LONG lineNumber, [in] LONG columnNumber)

Get a detail field value in a dialog box. lineNumber and columnNumber start at 1

void SetListField([in] LONG listHandle, [in] LONG lineNumber, [in] LONG columnNumber, [in] BSTR value)

Set a detail field value in a dialog box.

void AddListLine([in] LONG listHandle);

Add a line to a list

void DeleteListLine([in] LONG listHandle, [in] LONG line);

Delete a line from a list

LONG GetListHandle([in] LONG dialogHandle, BSTR listName);

Get a reference to a list in a dialog box. The list name should match the selected tab in the dialog box. e.g. "Service", "Product" etc.

LONG GetDialogHandle([in] LONG listhandle);

Get a reference to dialog box that a list belongs to

LONG GetListLineCount([in] LONG listHandle);

Get number of lines in list. listHandle is either passed to your attached script by MoneyWorks or you can convert a dialog handle to a list handle using GetListHandle

LONG GetFieldNumber([in] LONG dialogHandle, BSTR fieldName);

Get the index of a field whose symbolic name you know. Thus to get the contents of the transaction description field you would use:
mw.GetField(dialog, mw.GetFieldNumber(dialog, "e_desc"))

ImportantField numbers may change between MoneyWorks versions. You must get the field number at runtime using the symbolic name.

BSTR GetFieldName([in] LONG dialogHandle, LONG fieldNumber);

Get the symbolic name of a field

LONG GetFieldCount([in] LONG dialogHandle);

Get number of fields in a window. Use this if you need to iterate over fields (maybe to get all their names)

Code Samples

Mac

/download/scripting/Mac.zip

The Mac code sample is named Helper.scpt. Chuck it in the Scripts folder. This contains declarations for all messages you will get. The sample just has a "say" statement that will tell you each message as it is called. You can comment out or delete the messages you don't care about.

Windows

/download/scripting/Win.zip

The Windows code sample consists of Helper.scpt (which contains nothing but the text "MoneyWorks.Helper"), plus the actual script which is named Helper.wsc. You need to place these in the Scripts folder, and, having done so, you need to register the Helper.wsc script. Do this by right-clicking on it and choosing Register from the contextual menu. It will not work until you do this. The reason that there is an indirection file (Helper.scpt) is so that you can have different Helper.scpt files in different Custom Plug-Ins folders that point to different registered .wsc files. Without this indirection you could not have different scripts for different documents.

You can double-click Helper.wsc to edit it in Notepad. The file is XML containing declarations of the script functions that it implements. Don't touch this stuff. The only thing that you might change here is the progid, which you will note matches the contents of Helper.scpt. To have different scripts on the same machine you need different progids. If you do this, each unique progid also needs a unique classid. You can use the Windows Script Component Wizard to create a new .wsc from scratch but probably easier to edit the sample one. You'll need the guidgen.exe tool to make a new classid, although it is probably safe to just change the last digit of the one that is in there.

Other than that, the only bit you care about is inside the <![CDATA[ ... ]]> section. This is text containing Vbscript code that actually implements the script. In most of these I have just put some script code that uses the built-in Wshell object to log to the system log. As usual, to call back into MoneyWorks you need to CreateObject("MoneyWorks.Application").

You can look at the results of the logging in Start -> Control Panels-> Administrative tools -> Event Viewer -> Application Log (in which you have to hit F5 to see new log entries)

Q&A

Q. How do I know what kind of transaction it is?

A.  Look at the window name.

Q. I know that in AppleScript I can get the window name using get the name of the front window. How do I do it on Windows?

A.  Use the pseudo field number: -1.
GetField(dialogHandle, -1).

Posted in AppleScript, COM/VBS | Comments Off on Attachable Scripts