Is there a way to "lock" (make it not modifiable) a record once it has been entered by (any) user?
It is not a script step or function. You lock the field as part of the field definition using a field Validation setting:
1. Go to field definitions: File —> Manage —> Database —> Fields
2. Select the field you wish to set the lock option for (i.e. the field you want to prevent editing of)
3. Click Options —> Validation. This will bring you to the Options dialog shown below. Select the Validate by calculation option, which opens a standard calculation dialog window. This is where you will post the calculation I included in my previous post. Notice that at the bottom of the window the message "Calculation result must be Boolean" This means True/False; the validation will not work as expected otherwise. When the calc is entered select OK to exit this window.
4. Notice that I have also checked the Custom message option and written my own message; while this is optional, I recommend it as if you don't do this you will get the default message which is often confusing.
5. Repeat this process for any field you want to lock.
6. The field the validation calculation refers to is set by script to 1 (although it can be manually set if you prefer). Once it is set, any attempt to alter a field with that validation setting in place will be disallowed and the custom message will be displayed.
Yes, "edit" privileges can be set via calculation for any table in the privilege set settings under File > Manage > Security.
For instance, you could have an auto-enter field of "Creation Account" and then lock editing of that record to the original creator via:
Table::Creation Account = Get(AccountName)
I've seen this type of request before. It's always concerned me that your user could very easily lock themselves out of a record prematurely since all they need do is create a record and then click a blank area to commit it and now they can do no further data entry on the record.
You might want to set this up such that setting a field to a particular value locks the record so that the user can click a check box formatted field to both mark the record as complete and and lock it against further data entry. You might also use an auto-entered timestamp or date field to keep a newly created record editable for a specified period of time. So are are some variations of Mike's basic technique:
LockFIeld <> "Locked" //format field as check box field with "locked" as sole value. Clicking check box locks the record
Get ( CurrentTimestamp ) - CreationTimeStampField <= 3600 // Field remains editable for 3600 seconds (1 hour) after creation
The user is not identified with an account when he uses the application (ios or desktop). So the "privilege" solution will not work in this case. But thanks
The user should be identified by an account and given a privilege set. Not doing so is generally not a good idea.
Actually the user could go back and forth to the record and edit it. But once he hit a button that triggers a script (in this case send an email) I need to "lock" that record.
The question is ... how do you lock a record? What command or script step makes it unmodifiable?
I would combine what Mike and Phil suggested. For every privilege set, you can lock down a record from being edited using the calculation that Phil gave in the record-level security. (maybe that's what Phil was suggesting).
If a record has to be locked down, we don't want to fake the lock by doing some 'obscurity' only. You'd maybe consider having a read only layout that is navigated to when the record is locked, but also use FileMaker's built in security to prevent someone from subverting your navigation scheme.
If you don't have privilege sets, I guess I'd suggest adding them since the default priv sets can't be altered. As users log in even with some generic, custom-made priv set. I certainly hope they're not logging in with full access.
Generally though, FileMaker's security is the best way to go.
Yes Jeremy, that's the idea that I was referring two. You simply set up a "lock" expression that locks down the record when it is set to a particular value. In one of my solutions, a user clicks "Print" to print a Purchase Order (We'd call it an invoice, but the customer is selling scrap metal or redeeming the deposit on used beverage containers). That script prints the PO, and also sets a status field to "Printed". That field is part of a lock expression in Manage | Security that locks the record against modification.
I think that you should require users to log in with an account name and password to access your solution, but if you don't want to do that, you can use file options to have the solution automatically log the user in under a specified account. You can then use that account's privilege set to limit access to a given record using such a "lock expression".
"From discussion will come light"..
What do you suggest is only applicable with a user log in process and then change him to a different account privilege... Not the case here.
If we have a button launching a script and that script set a specific field "SELECT123" to "yes or no" or from "0 to 1", we can select that button use "hide object when" in behavior and use the calculation with condition "SELECT123 = "1".
The button disappears...
and although the record can still be edited, it cannot be resend or printed again or other process behind the button that is hidden.
This sounds a bit like 'security by obscurity', something wimdecorte and jormond and others really do not like.
If you want the record to be locked and not be edited, the best way is to use FileMaker's security.
That said, security by obscurity can be implemented if the risks are understood.
“What do you suggest is only applicable with a user log in process and then change him to a different account privilege... Not the case here.”
No, that is not the case.
A different way to do this would be to use a popover or a different layout and populate it with global fields. Then only create the record when the user clicks on a button which will create a new record and fill in the fields. Then it's easy to lock the record in the layout just not allowing any entry in browse mode.
Then users with different access levels can correct or change the record but others cannot.
This is usually my preferred method! The globals can be used to fill data that can be edited as well (by level). Submit and don't allow changes anywhere else.
Yes that is also a good approach.. Thanks for the idea.
I use a combination of the methods suggested here in a cashbook. It may have relevance for you. Briefly:
1. Data is initially entered into a utility record (similar to globals as described by Kurt), then the actual cashbook record is created by script and the utility record is deleted.
2. Most data remains editable initially, allowing correction of inadvertent errors.
3. Once a bank reconciliation is done it is essential that some data cannot thereafter be altered (e.g. amount). To achieve this I have a flag field that is checked when a record is included in a bank rec. I have field validation set to prevent editing of the relevant fields once this field is checked. (along the lines suggested by Phil.)
4. A further level of 3 above occurs when a tax report is completed; it then becomes essential that certain other fields must not thereafter be altered (e.g. expense category). When a tax report is done a second flag field is checked, and the additional relevant data fields are locked by field validation as above.
5. Some fields are locked by both the above processes.
Obviously this is a different scenario from yours, but the methodology would be applicable I imagine.
and how do you script the part where you « have the field validation set to prevent editing »...?
The actual field validation is preset in the fields that need to be covered. The validation is simply If ( LOCK_reconciliationField = 1 or LOCK_TaxReportField = 1 ; 0 ; 1 ) for fields covered by both, or just one condition otherwise.
Bank reconciliation is straightforward; records are checked off one by one. I use a portal to display all unpresented records and have a button on the portal row that marks the record as presented—essentially, sets the lock field.
Tax report is a bit different, since it depends on finding a set of records and running assorted reports. In this case, once the reports are completed the script loops through the found records and marks them all.
Sorry to insist, but what precise step/function do you utilise to lock the field or fields... I can’t find anywhere how to do that..
That is the whole question...
You don't have any such function. You change the Value of a field. The lock expression references that field to determine whether the user may edit the record. Since field's value has changed the expression evalutes differently and thus the change to the field's value controls the record's accessibility.
That is it !!!
That is exactly what I was looking for!!!!
Retrieving data ...