Multi-User Scripting Considerations
By John Mark Osborne, (jmo@databasepros.com)
BONUS: None
PLATFORM: Macintosh & Windows
RATING: Intermediate
FileMaker scripting works well when scripts are performed in a single-user environment. As long as the final script does what you want, you can utilize any script command your heart desires. However, the reality of the real world is that most solutions need to function in a multi-user setting. Unfortunately, scripting is a whole new beast to tame when programming for multi-user scenarios. If you are interested in learning the pitfalls of multi-user scripting, workarounds and general rules to follow, then this article is for you!
The Real World
The reality of the FileMaker world today is that more and more people are utilizing the networking capbilities of FileMaker Pro. Back in the FileMaker Pro 2.x days, most people were using FileMaker for home and small business use. Nobody took FileMaker seriously enough to use it in a larger business. All that has changed! (As consultants with too much work to handle know.) FileMaker is now a multi-user maniac. When I survey the students in my training courses, I find that 90 to 100 percent of them are using FileMaker in a multi-user scenario.
Not many things change in FileMaker when considering a multi-user scenario. Calculations, finds, sorts and relationships don't change a bit. The biggest exception is scripting, which is the focus of this article.
A General Rule
You will find a function called "record locking" in most databases, and FileMaker is no exception. When a user is editing a record in a multi-user scenario, that record is locked. This means no other user can edit the record until the first user exits the record. Any number of users can sort, find, export, print, export and generally view the contents of any records including locked records. But, only one user at a time can edit a particular record.
So, a general rule you can follow when scripting for a multi-user environment is to never script beyond the current record. This means no record loops, scripts with the Replace command or any script that moves beyond the current record.
In fact, it is a good idea to make sure the current record is locked before running a script in a multi-user scenario. It is possible for a user to run a script on a record they are viewing when another user is actually editing it.
Checking if a Record is in Use
If a user attempts to modify a locked record, FileMaker will display a message telling them who is currently editing the record. However, if a script attempts to modify a value on a locked record, only the script steps that modify the record will be skipped. What you want to do is test whether the record is locked. The best way to do this is to enter a field on the current record. Not only does this produce error number 301 if the record is locked, but it will lock the record for the person running the script if possible. Here is a sample script that demonstrates the technique:
Set Error Capture [On]
Go to Next Field
If ["Status(CurrentError) = 301"]
Show Message ["This record is locked!"]
Else
Comment ["Put your script steps that modify the current record here"]
End If
You may be wondering why the Go to Next Field script was used rather than Go to Field. The choice is really yours. I like the Go to Next Field approach because it makes your script dynamic. You can run your script from any layout without worrying if the field you specified is on the layout.
However, there are a couple of problems with this approach. If there are no fields in the tab order on the current layout, no field will be selected. This is unlikely since most data entry layouts that users have access to will have at least one field in the tab order.
Another problem can occur if the field selected is a global field. Global fields can be selected even if the record is locked. You can get around the global problem by using the Set Field command to modify a field on the record. You can either modify a dummy field or set a field to itself, which will also generate the 301 error. Here is an example of setting a field to itself so the contents are modified but not changed:
Set Field ["My Field", "My Field"]
Well... Maybe
It is possible to run a script that modifies a span of records as long as you check to make sure there are no users currently connected. This might work by scheduling these types of scripts to run at night when nobody is using the database. For example, a user could schedule a report that modifies many records to be run at night.
If this is not possible, you are better off thinking outside the box and coming up with an alternative solution that does not modify a set of records. The best example that comes to mind is a solution published in Scriptology <www.scriptology.com>. It demonstrates how to mark a found set of records so they can be retrieved at a later date. Previously, developers would use a looping script or a Replace command to mark the records in the found set. With this new technique, a unique value is grabbed off every record in the found set and stored in a separated database. The found set can then be rebuilt anytime a user desires.
Unfortunately, many solutions cannot be solved using a different approach. So, the general rule still applies: Only modify data on the current record when programming for a multi-user environment.
Happy Multi-User FileMaking!
## END ##