RATING: Intermediate
PLATFORM: Macintosh & Windows
VERSION: FileMaker 3/4/5
TECHNIQUE FILES: Flag.fp5

Giving users the ability to flag records is a useful tool for developers to give to their users. With it they can save a found set, include records in a report that aren't easily defined by a search, or simply flag records for later tasks. The most common way to flag a record in a single user system is to use a Boolean field that when a record is flagged is set to 1 and when a record isn't flagged is set to 0.

Raise the Flag

But this type of solution won't work in a multi-user environment unless you're satisfied with everyone sharing the set of flagged records. In other words, if you want each user to be able to flag their own records without interfering with the flagged records that other users have set, a Boolean field won't do the job.

But guess what! There is a way around this and this technique will show you how.

Basic Setup

The basic idea behind the technique is that you will have a field in each record that keeps a list of the users who have flagged it. Then to find the records flagged by the currently logged in users, you simply search that field for the user's unique identifier.

The first requirement of this technique is that the system must have some way to uniquely identify each user. Many multi-user systems will include a Users or Employees file that contains the users who can log in. If your system doesn't include a this kind of file, another option is to use the Status( CurrentUserName ) function, but only if you are sure that each user has a unique name on the system. This can be set in the application preferences of FileMaker.

If you do have a Users file, you need to give access to the user ID of the logged in user to any other file where you want to give the ability to flag records. One way to do this is to have a field in your main menu file called gUser_ID that is set to the user ID of the logged in user at the time of login. Then use a constant relationship between the file that needs to flag records and your main menu file to access this information at any time.

To provide this unique user name in the sample file, there is a global text field called "gUser" which is attached on the layout to a value list of four possible users. This field must have data in it for the sample technique file to work properly.

Once your file can determine the currently logged in user in some way, it needs a text field, which in the sample file is called "Flagged_Users". This file will keep a list of the users who have flagged the current record. As you'll see when we look at the scripts, when a user flags the current record, if they haven't already flagged it, then their user identifier is added to the list. When they want to unflag a record their identifier is taken out of the list.

Users need a way to see whether they have flagged a record or not. This is provided with a calculation field with a number result. Here's the calculation.

PatternCount(
Flagged_Users,
gUser
)

Since PatternCount returns the number of times the second parameter appears in the first, this calculation returns a 0 if the currently logged in user has not flagged the record and a 1 if they have. On the layout this field is linked to a value list with a single value of "1", so if the current user has marked the record they see that field with a check mark in it.

Flag that Record!

Here is the script to mark the current record. It has a single step.

Set Field [ "Flagged_Users", "Case( PatternCount( Flagged_Users, "¶" & gUser & "¶" ), Flagged_Users, Flagged_Users & "¶" & gUser & "¶" )" ]

All this does is check to see if the Flagged_Users field already contains the currently logged in user. If it does, nothing changes. If not, we add the identifier of the current user to the list of users that have flagged the record.

The extra paragraph marks just make it easier to deliminate the user's identifiers. The technique would work with only one, or, without them at all.

Unflagging a record is just as easy and also has only one step. Here it is:

Set Field [ "Flagged_Users", "Case( PatternCount( Flagged_Users, "¶" & gUser & "¶" ), Substitute( Flagged_Users, "¶" & gUser & "¶", "" ), Flagged_Users )" ]

Like the script for flagging a record, this script checks to see if the current user has already flagged the record. If so the Substitute function is used to take that user's identifier out of the list. If the record isn't flagged, nothing changes.

The last script allows the user to find the records that they have flagged.

Enter Find Mode []
Set Field [ "Flagged_Users", "gUser" ]
Perform Find []

All this does is perform a search on the Flagged_Users field for the identifier in gUser.

Enhancements

That's it. The entire technique is just a few fields and three scripts. Obviously there is more that you could do with this technique. You could, for instance, add a toggle flag script which will change a flagged record to unflagged and an unflagged record to flagged. Another enhancement might be to change the flagged indicator to an actual graphic of a flag by storing it in a global container field and setting the Flag_Display field to that container field if the current user is in the list of users who have flagged the record.

One more enhancement to suggest: giving the users the ability to flag or unflag the entire found set of records or the entire database. This could be done with a looping script that goes through either the found set or does a Show All Records and then loops through the records.

With this simple but powerful technique you can provide your users with another useful way to gather and organize their data, and one user's flagged records will never interfere with another's.

Happy FileMaking!

Charles Ross had worked with FileMaker for over seven years and is an independent contractor specializing in database and custom application development. You can contact him at chivalry@mac.com