Downwards compatibility of documents

Now that all products use the same document type, it is perhaps less obvious when a document is not openable in Express after you have been making changes in Gold (because you no longer need to do a down-save which would warn you).

It's worth knowing what the factors are that will prevent a file from being opened in Express or Cashbook. As an exercise, you might want to do a custom report that checks these things for you.

Features not supported by Express (there must be no instances of these in the file):

  • Departments
  • Jobsheet entries
  • Purchase orders
  • Sales Orders
  • Quotes
  • Stock Journals
  • Inventoried Products
  • More than one P&L account
  • More than one AP account
  • More than one AR account

For cashbook, you must not have any:

  • Jobs
  • Debtors
  • Creditors
  • Debtor Invoices
  • Creditor Invoices
  • Balances of AR and AP accounts must be zero
Posted in Database, Esoterica | Comments Off on Downwards compatibility of documents

Silent installation

Our Windows installers (based on NSIS) have a "silent" mode that allows them to run from the command line without user interaction. This is enabled with the command switch /S.

You can type, for example:


"Install MoneyWorks Gold.exe" /S

This works for the Datacentre server installer as well, however it does result in launching the Console, so not completely silent.

Posted in Esoterica | Comments Off on Silent installation

Optimised searching

Sometimes you need to do a search that involves a fast component and a very slow component.

Maybe something like this

detail.parentseq = transaction.sequencenumber and testflags(detail.flags, #0008)

The problem with this search expression is that it defeats the search optimiser because of the function call. The search optimiser only works for sequences of field = constant. The result is that the entire expression is evaluated for every record in the Detail file. This is very slow (on the order of 30 seconds when done on a network). However, the first part of this search involves an indexed field and should be very fast. How can we force MoneyWorks to do that fast search first and then do the slow search for just the small number of records found by the first part? Well idealy the search optimiser would be smarter. But it isn't.

Relational search syntax to the rescue. The relational search syntax is explicit about separating a search into separate stages (normally for the purpose of searching in separate, related files). But how about we use it to separate two searches in the same file and make use of the implied and between the terms?

[detail:detail.parentseq = transaction.sequencenumber][detail:testflags(detail.flags, #0008)]

In the first stage, the search is simple and also is searching an indexed field, so this part of the search will be very fast. The second stage will only need to examine the relatively small number of records yielded by the first stage.

If you are implementing any kind of automation that may run frequently (especially REST requests!), avoid using non-indexed fields for a search when an indexed field is available. Search a non-indexed field can result in loading every record in the table, resulting in high CPU load.

How do I know what fields are indexed?

Here's a script to dump the entire database schema, which indicates which fields have indexes

on Load
    let x = Export("xmlschema")
    syslog(x) 
    // indexed fields have attribute indexed="true"
end
Posted in Esoterica | 1 Comment

Adding and removing Transaction images via script

Although it is obvious that you can create transaction images yourself in the Pictures/Transactions folder (see also The Pictures Folder), MoneyWorks won't "see" the picture unless the fHasScan flag (= 0x00100000) is set in the flags field of the transaction. This is an optimisation to save MoneyWorks the considerable expense of testing for a transaction image every time you open a transaction.

MoneyWorks 6.0.6 adds a method of synchronising this flag if you have added or removed a transaction image behind its back.

evaluate "SyncTransactionImage(trans_seq_num)"

The SyncTransactionImage function (available only to the evaluate command) will check to see if there is an image for the transaction with the given sequence number and set or reset the hasImage flag as appropriate (provided the transaction is not locked). The function returns 1 if there is an image; 0 if there is not.

Posted in Database, Esoterica | Comments Off on Adding and removing Transaction images via script

Reports as Scripts

By popular request (actually just multiple requests from Grant), from v6.0.6, you can run reports from the Command menu by placing them in the Scripts folder.

The "No Dialog" report settings option—which used to completely suppress the report settings dialog and always output the report to Preview—has been renamed to "No output options"

If you have no custom controls, then the behaviour is as before; the report goes direct to preview with no settings dialog. If there are custom controls, then you get a simplified settings dialog with just your custom controls. The Preview button is labelled Run. If the report generates no output (actually this bit is now true for any report), then no preview will be displayed. If there is any output then it is displayed in Preview as before.

The differences are really purely cosmetic, but it will now make more sense to run a report that simply does something for side effects (such as updating a record in the User file) without displaying any results.

As of v7, this is deprecated, since MWScript is a better option than running a report for side effects.

Posted in Esoterica, Reporting | Comments Off on Reports as Scripts

The Pictures folder

MoneyWorks currently stores 2 types of images. Transaction images and product images.

These go in a subfolder of Custom Plugins called "Pictures for NAME", where NAME is the company name from the company details dialog box. If you change the company name, MoneyWorks will rename the folder to match. If you duplicate a document, it will be able to "see" the same pictures because the company name will still be the same. (Beware, however, of changing the company name in the duplicate because that would effectively disconnect the pictures folder from the original file). This Pictures folder contains a "Products" folder and a "Transactions" folder.

Product images in the products folder are named PRODCODE.ext. The extension will indicate the type of image. It will generally be .png or .jpg or .pdf. As of v7, special characters such as * / < > | are hexencoded as @xx since these characers are illegal in filenames on Windows. On a Mac, if there are existing product images with, e.g. a / in the name, these will need to be manually renamed (replace the / with @2f).

Transaction Images are named SEQNUM.ext where SEQNUM is the (decimal) sequence number of the transaction.

On a network, the Pictures folder resides only on the server; it is not downloaded to clients (they get individual images on demand).

There is some concern that large numbers of files in one folder can cause problems for the OS (possibly on the order of 20,000-30,000) or more. In my (admittedly cursory) testing, I did not find any such problem (IIRC I looked at folders on Mac OS X with 50,000-odd files). I got some feedback from the filesystem team at Apple which suggested that there are no hard limits in HFS+ or NTFS but FAT32 on Windows may have some problems.

Posted in Esoterica | Comments Off on The Pictures folder

Orphaned Branch Names

The Headoffice-branch relationship is defined by the head-office code being e.g. "HEAD.", and branches being "HEAD.BRANCH". Any Name code with an internal dot is taken to be a branch of some head office. MoneyWorks now warns you about using internal dots inappropriately, but some users manage to have spurious ones.

Having such broken not-really-branches can break the Aged Debtors report.

How to find these non-branches?

Here's a search:

PositionInText(code, ".") > 0 and Lookup(Left(Code, PositionInText(code, ".")), "Name.Code") = ""

This will find all Names with a code that appears to be a branch (has internal ".") but does not have a head office. Such codes should be changed to remove the "."

As of v7, the Aged Debtors/Creditors reports are smart enough to detect orphan "branches" and treat them as normal non-branches.

Posted in Esoterica | Comments Off on Orphaned Branch Names