FileMaker 7 End of Life

May 2nd, 2008

Important news for FileMaker 7 users. As of September 26, 2008, technical support and replacement media will no longer be available for any FileMaker 7 products. After that date, if you want to get the latest version of FileMaker products, you will be required to purchase the full product not just an upgrade.

If you act now, you get three versions' worth of new features for a special low price.

Upgrade to FileMaker Pro 9 for AUD$199.00 inc GST. That's a $100 saving.

An upgrade to FileMaker Pro 9 Advanced is just AUD$295.00 inc GST. That's a saving of $155.

Note that these upgrade prices also apply if you are currently using versions 8 and 8.5. So you can still save with this special offer.

These offers are available until 26 September 2008 unless withdrawn earlier.

Exclusive Checkboxes

April 30th, 2008

Problem: Provide the user with a choice of options, limited to only one selection and allow them to deselect a selection.

When selecting the control style for a field, you have the choice of radio buttons and check boxes. Both are based on a value list. A radio button set gives the user an exclusive choice – if they select an second choice, the first is turned off. A checkbox set gives the user the ability to select multiple items.

One problem users sometimes have with radio buttons is accidental selection. Perhaps you make a selection and you want to 'unmake' the selection. A radio button can be turned off if you hold down the Shift key - but most users don't know that. And it is not something you should have to teach. You can't use checkboxes because you want an exclusive choice – only one item selected.

So how can you combine the usefulness of an exclusive choice provided by radio buttons with the ability to turn them off provided by checkboxes? I'm glad you asked.

Firstly, use a checkbox for the control style. Then set the auto-enter options for the field. Choose to auto-enter a calculated value using the expression:

GetValue ( yourfield ; ValueCount ( yourfield ) )

If you are using FileMaker Pro 9 and want to apply this to a number of fields, you can take advantage of the new Self function. The following expression can be copied and pasted for any field:

GetValue ( Self ; ValueCount ( Self ) )

When exiting the field options dialog, make sure "Do not replace existing value of field (if any)" is unchecked.

Auto-entered calculation

Now when you use the checkbox, you will have an exclusive choice enforced like a radio button set. And you have the added advantage of being able to turn off a checked field.

If you don't want or need to know how it works, you can stop reading. If you are curious or just need to know, read on!

One of the keys to this technique is knowing how checkbox fields work behind the scenes. When you select multiple items, they are stored as a return-separated list in the order in which they were selected. So the last item selected is the last item in the field list. You can see this if you have two copies of a field on a layout – one using checkboxes, the other a plain edit box.

In our scenario, we don't want to allow multiple selections – when a user selects a second item from the checkbox list, you want only that item to be retained. The auto-entry calculation above returns only the last (most recently selected) value in the field. It does this with two functions.

The first is the GetValue function. The syntax is GetValue ( listOfValues ; valueNumber ). In the calculation, you are using the current field (or Self) to supply the listOfValues. You want the valueNumber to be the number of the last value in the field. The number of the last value is calculated with the ValueCount function – the number of values is the number of the last value!

In summary, the expression says "give me back only the last value in the field". And that works for you because the last value is the most recently selected value. If the last remaining value is deselected, the field is empty and remains so.

Challenge: This technique can be extended to allow a maximum number of values to be selected from a checkbox list. For example, select your three favourite colours from a list. When you select a fourth, the first selected will be removed.

Control the scroll (wheel)

April 21st, 2008

These days, many users use a mouse scroll wheel to get around screens quickly. It is much faster to use a scroll wheel than scroll bars to move up and down in a window. The support of the scroll wheel in FileMaker Pro 8 and above is described in the FileMaker KnowledgeBase Article 5439.

There are three commonly asked questions about using the mouse scroll wheel:

1. How can I use the scroll wheel to scroll through portal rows?
Click in the portal row (but not in a field). Hold the mouse cursor over the portal, then rotate the scroll wheel.

2. How can I use the scroll wheel to scroll through records in Form view on a Macintosh?
Move the mouse cursor over the book or slider in the status area, then rotate the scroll wheel.

3. How can I STOP the scroll wheel scrolling through records in Form view on Windows?
Hide and lock the status area. The record scrolling behaviour is not disabled unless that status area is locked.

Note that you can only lock the status area with a script step – Show/Hide Status Area. This script step provides three actions – Show, Hide and Toggle. There is a further option to specify Lock for any action.

The Show/Hide Status Area script step can either be assigned to a button or it can be part of a script. If you choose to lock the status area, be sure to duplicate any required status area functions and information on your layout. You can create buttons to scroll through records and switch between layouts. You can create calculations to display the current record number, found count, total record count and sort state.

Also be aware that if you close the status area, you will probably need to open it when in Preview mode during report printing. This gives the user access to the book icon to scroll between pages and also to the Continue button when paused in Preview mode. So open it when you need it, and close (and lock) it when you are finished.

Quick Delete

April 8th, 2008

Here is a shortcut that I used today when I was visiting a client. They were so amazed that I thought I would share it with you.

Usually, when you delete a record, FileMaker Pro displays a dialog asking if you are sure. The most important word here is PERMANENTLY. Once you click the Delete button, there is no way to get that record back. And I should know – I have wanted it back on more than one occasion!

FileMaker delete dialog

When you are deleting a lot of records, say from a list, the warning dialog can get very tedious. Delete. Yes, delete. Delete. Yes, delete. Delete. Yes, delete. Get the picture?

So here is the tip. If you hold down the Shift key on Windows or the Option key on Macintosh, there will be no warning. The record will be deleted instantly. It's a great timesaver but be very careful with it. Be sure you have a current back-up before you start deleting lots of records.

uLearnIT gains FileMaker Authorised Trainer status

April 4th, 2008

uLearnIT is proud to announce that David Head has been recognised as a FileMaker Authorised Trainer. As a FileMaker Authorised Trainer, David has undergone training directly from FileMaker, Inc. to deliver the FileMaker Training Series programs and has extensive knowledge of FileMaker best practices and solutions.

FileMaker Authorised Trainer

uLearnIT offers a three day course based on the official FileMaker Inc., training curriculum - the FileMaker Training Series. This course is scheduled for Sydney, Melbourne, Auckland and Christchurch. Check the course schedule for dates and costs. Book online early to avoid missing out on your place and to qualify for FREE FileMaker Training Series training materials valued at $129.

2008 FileMaker Developers Conference

February 21st, 2008

FileMaker Developer Conference 2008

The 2008 FileMaker Developers Conference has been announced by FileMaker Inc. It will run 13-17 July at the JW Marriott Desert Ridge Resort & Spa in Phoenix, Arizona. This venue has great facilities including the obligatory lazy river where all the business get done!

This year, David Head will be presenting a workshop - Developing for Understanding: Self-Documenting Custom Functions. This sessions starts by looking at examples of good and bad expressions written in the FileMaker Pro calculation engine. It then moves on to look at the use of custom functions to produce better functions that more clearly express the intent in an expression. Participants will receive a list of useful custom functions they can incorporate into each and every solution they create.

The conference schedule reveals a wealth of incredibly useful stuff about FileMaker. If you can make it to Devcon 2008, you won't be sorry.

Tracking changes to a single field

February 7th, 2008
When creating a new table, it is often thought good practice to include fields to store the record creation and record modification timestamps (date and time). These fields are timestamp fields with the field option to automatically enter the Creation Timestamp or the Modification Timestamp. You would also check the option to "Prohibit modification of value during data entry" to protect the data from change.

Timestamp auto-enter modification

Developer Quiz Question
Where is the Creation or Modification Timestamp drawn from? What is the potential problem with this? (Check the answer at the end of this article)

The problem with the modification timestamp is that it records when the record was last modified. That is, when any field was edited, even if that field was edited and changed straight back without committing the change.

So the question is how do we track when any single field has been changed? An example may be that we want to track when a status field was last modified. If the status was changed from 'interested' to 'enrolled', we would like to know when it was changed (and possibly by whom).

There is a simple technique that uses the Evaluate function. The Evaluate function evaluates an expression as a calculation with optional fields to trigger the calculation to update. For example,

Evaluate ( "Get ( CurrentHostTimeStamp )" ; Status )

Notice that the expression is represented as a text string (in quotes). Note also that we have supplied one field name as a trigger. This means that every time the Status field is changed, the expression will be evaluated and the current value returned to the field.

So where do we put this? In this case, we could set up a timestamp field named Status_LastModified and then set an auto-enter calculated value that would be the expression above.

Timestamp auto-enter calculation

It is important that we uncheck the 'Do not replace existing field value (if any)' checkbox so that the calculation will update. Having set this, any change to the Status field will prompt an update of the timestamp in the Status_LastModified field.

Notice also that we are extracting the timestamp from the host (perhaps a FileMaker Server) and not the client. This ensures better consistency of timestamps where the client time may be incorrect or where clients are in different time zones.

So how do we record the person who changed the status? Here we are assuming that all users log in to the database with their own account and password (considered best practice in security). Therefore, we can set up another text field called Status_LastModifiedBy and using an auto-entered calculation:

Evaluate ( "Get ( AccountName )" ; Status )

Finally, if you don't need the modification data in separate fields, you could set up a single text field that uses an auto-entered calculation:

Evaluate ( "GetAsText ( Get ( CurrentHostTimeStamp ) ) & \" \" & Get ( AccountName )" ; Status )

If you extend this technique further, you can also record the data entered in the field and you are well on your way to setting up an audit trail on a field.

Developer Quiz Answer
The date and time for the record creation or modification is drawn from the time set on the client computer. This means that the either timestamp can be 'wrong' if the client computer date and time is incorrect (whether by accident or design).

The creation timestamp can be drawn from the database host (say the FileMaker Server) by using an auto-entered calculation:

Get ( CurrentHostTimeStamp )

This is also important if you want to standardise time entry between clients existing in different time zones.

There is not a similar simple solution for the modification timestamp apart from setting up a modification field as described above with all fields as triggers. However, the modification timestamp is of more use to show how long a record has remained unmodified rather than when it was last modified.

FileMaker Server 9.0v3 Updater

February 6th, 2008
Available now for download:

FileMaker Server and Server Advanced 9.0v3 for Leopard (OS X 10.5.x)
FileMaker Server and Server Advanced 9.0v3 for Tiger (OS X 10.4.x)
FileMaker Server and Server Advanced 9.0v3 for Windows

This welcome update includes a lot of bug fixes including compatibility between FileMaker Server and Leopard.

To download, go to the downloads page on the FileMaker web site. Please read the installation instructions on the web site carefully as they apply to your current server and FileMaker Server installation.

Telephone Number Formatting

January 24th, 2008
You probably have a preference for how you would like a telephone number to appear. And the appearance will probably be different if the number is a mobile (cell) or a free call number. In Australia, there are a range of different number types. My preference is for formatting like this:

Standard phone numbers - (08) 8981 1144 or 8981 1144
Mobile numbers - 0402 839 829
Freecall numbers - 1300 797 201 or 13 13 13 or 1800 123 456

Phone numbers in the United States might be formatted (408) 987-7000. And in the UK, they are formatted like this (01923) 242926.

The problem here is having users remember how to format different numbers for different countries and uses, and then having them do it consistently. What we need is a database that can take a number and automatically format it as it should appear. This takes the onus off the user to do it properly and results in more consistently entered data.

So how is it done? Over the years, many developers have proposed many quite complex calculations to use as either a separate calculated field or, more recently, as an auto-entered calculation that replaces the text. The business logic of the required format is built into the calculation.

What I will show you here is a different approach that uses a custom function to format the phone number. That custom function can then be used directly in an expression, or indirectly through another custom function.

So let's get straight to the custom function. Custom functions can be created and edited using FileMaker Pro Advanced. Once created in a file, they can be used by anyone who has access to the FileMaker Pro calculation engine.

This custom function is called phoneMask and requires two arguments - number and format. The number is the phone number that needs to be formatted. The format is the phone mask to be used, supplied as a text string and using the # character for a digit placeholder. Some examples of phone masks you might use are:

(08) 8981 1144 would use (##) #### ####
13 13 13 would use ## ## ##
1300-797-201 would use ####-###-###
(408) 987-7000 would use (###) ###-####
23. 456.1212 would use ##. ###.####

The idea is that you can add any other required characters to the mask. The custom function will use the mask and replace any # characters with digits.

So you want to see the custom function?
It is called phoneMask (number; format). Here it is:

Let ([
digits = Filter ( number ; "1234567890" );
left_digit = Left(digits; 1);
left_format = Left(format; 1)
];

If ( left_format = "#" and not IsEmpty(left_digit); left_digit; left_format )
&
If ( Length (format) > 1;
phoneMask (
 If ( left_format = "#"; Right ( digits; Length (digits) - 1) ; digits ) ;
 Right ( format; Length (format) - 1 )
)
)

) // end Let

The first thing the function does it to filter the number supplied down to just digits (0-9) stripping out all other characters.

Then, using this statement:

If ( left_format = "#" and not IsEmpty(left_digit); left_digit; left_format )

It looks at the first character of the supplied format (mask). If it is a digit placeholder (#) and there is a digit available, it returns the first digit of the number supplied. Otherwise, it returns the first character of the supplied format.

Then, if there are more format characters to process, it calls the phoneMask function again using a reduced form of the number and the format mask. The act of a function calling itself is called recursion and is a powerful feature of custom functions in FileMaker Pro. In this case, it calls itself until it runs out of format mask characters.

An intended side-effect of this recursive process of replacing the # placeholders with digits is that if the function runs out of digits, the placeholders are used. For example, if 088981114 was entered using a format mask of (##) #### ####, it would return (08) 8981 114#. This is feedback to the user that not enough digits were entered.

So now we have a custom function, how do we use it? We could use it in an auto-entered calculated replace. That is a field option that we could set for the telephone field. We make sure that we uncheck the Do not replace existing value (if any) checkbox so that any telephone number entered is updated with the correctly formatted version. The calculation we would use could be:

phoneMask ( telephone ; "(##) #### ####" )

Auto-entered calculation

This will enforce the same formatting on every telephone number entered. To be more flexible, we could build in conditional selection of a format mask based on data in the record (such as country) or within the telephone number entered (such as number of digits or starting digits). An example of this is:

Let ([
number = Filter ( telephone ; "1234567890" );
digit_count = Length ( number );
format = Case (
  country = "USA"; "(###) ###-####";
  country = "Netherlands"; "##. ###. ####";
  country = "Aust" and digit_count=6; "## ## ##" ;
  country = "Aust" and digit_count=8; "#### ####" ;
  country = "Aust" and Left(number;2)="04"; "#### ### ###" ;
  country = "Aust" and Left(number;4)="1800"; "#### ### ###" ;
  country = "Aust" and Left(number;4)="1300"; "#### ### ###" ;
  country = "Aust" ; "(##) #### ####" ;
  "(##) #### ####" // this is the default format mask
  );
format_digit_count = PatternCount ( format ; "#" );
red = RGB ( 200 ; 0 ; 0 )
];
phoneMask ( number ; format )
&
If ( format_digit_count < digit_count; TextColor ( Right ( number; digit_count - format_digit_count ) ; red ) )
)

In the above calculation, the last If statement will take any remaining digits after the placeholders have been exhausted and add them to the end of the formatted number in red. This is visual feedback for the user that too many digits have been entered.

Finally, it is also possible to create a second custom function that contains the logic above. This function can then be used more simply to format the phone number while hiding the choice of format masks.

There is a sample file to go with this article. It can be downloaded from this link: Telephone Formatting. It contains the custom functions and examples of their use.

Managing ‘User Abort’ in Scripts

January 22nd, 2008

The Allow User Abort script step is used to prevent users from stopping a script. One reason this may be necessary is when a script takes the user to an unfamiliar location. If the user aborts the script, they may not be able to get back to where they started. 

By default, user abort is on. If a user clicks Cancel on a print dialog during a script, FileMaker Pro will inform the user that print has been cancelled and give them the option of continuing or canceling the script. 

Print Cancelled, Cancel Script? 

The problem is that many users don’t know what a script is (or that they were running one!), don’t know if they should continue, and therefore click Cancel. This stops the script dead and often leaves them in a foreign location in the database. 

One solution to this problem is to insert a script step Allow User Abort and set the option to Off. With this step before the Print step that displays a Print dialog, FileMaker Pro does not ask the question when the user clicks Cancel - the script always continues. There are many other places where the user’s ability to cancel the script is stopped.

But as a developer you should also be aware that it prevents every user (even you) from stopping a script (unless you are running the Script Debugger in FileMaker Pro Advanced). This can be disastrous if an untested script enters an infinite loop or if you want to stop a process that you know is going to take a while.

So what this usually means is that you will put an Allow User Abort step in a script where you need it but set the option to ‘On’ while you are testing. When you are satisfied that there are no infinite loops or other serious bugs, you reset the option to ‘Off’.

Do you see the problem here? At some stage, you need to change all the Allow User Abort script steps in all your scripts to ‘On’. How many scripts is that? And how do you know you got them all? And what do you do when you need to turn them all off again for further testing?

Here is a simple solution - use a subscript instead of a script step. Confused? I will explain.

  1. Create a one step script called Allow User Abort On. The one step is Allow User Abort with the option set to ‘On’.
    Allow User Abort On
  2. In any script where you need to control User Abort, ‘call’ the script with the Perform Script step.
    Perform with User Abort On
  3. Test what you need to test.
  4. To turn User Abort Off in your solution, open the script, change the name to Allow User Abort Off and reset the script step option to ‘Off’.
    Allow User Abort Off
  5. To turn User Abort On again in your solution, open the script, change the name to Allow User Abort On and reset the script step option to ‘On’.
  6. Rinse and repeat as needed.

The point about always updating the script name to reflect the state of the User Abort step is that it makes sense when you read scripts that call it:

Perform with User Abort On

Now, more advanced users may be thinking - “Can we make that subscript more dynamic? I keep forgetting to change the name or the option”.

Well I’m glad you’re thinking! Of course we can. Try this script instead - it uses the last word in the script name to determine if User Abort is on or off. All you need to do is to rename the script to alternate between states.

Flexible User Abort Script

So what we have now is a method to turn user abort on or off in our database in just one location. Master control!