Automatic Field Code
Use the Code property in the Field Properties Panel to set up a short program that will run when data is entered into the field. (Starting with Panorama X 10.1, you can also set up code to run immediately when a field is clicked in the Data Sheet, see Running Code when a Field is Clicked at the bottom of this page.)

In this example, the code checks the value entered into the field and displays a warning if it is too small or too large.

With this code in place, Panorama checks values entered into the A field.

Each field can have its own code.

#### Calling a Named Procedure

If multiple fields share a significant amount of code, you can set up a named procedure (see Procedures) with the shared code and use the call statement to call it. For example, I could set up a procedure called checkFieldLimits to validate entered data against defined limits.

Notice that instead of using specific field names (A, B, C, etc.) this procedure uses `«»`. The `«»` symbol can be used in any formula to access the value of the current field. Use of the `«»` symbol allows this procedure to work with any field without modification.

Now that this procedure is set up, we can call it from the code for each field.

This same subroutine can also be called from fields B, C and D, only changing the limits passed as parameters as necessary. Then if you ever need to modify the limit checking code, you only have to make that change in one place, not over and over again for each field. For example, the message statement could be changed to nsnotify. With this change, any entry of an out-of-range value will cause a notification instead of an alert that has to be dismissed.

In this example the code in the field has been completely replaced by a single call statement, but that’s not necessary. You can mix in whatever code you want into the field’s code, including multiple call statements if necessary.

#### Automatic Code vs. Automatic Field Calculations

Only the code associated with the field being edited will run. If Automatic Field Calculations cause other fields to be modified, the code associated with those other fields will not run. For example, suppose code has been associated with the Total field, as shown here. You might think that this code would run automatically when you modify data in A, B, C or D, since this causes a formula to run that modifies the Total. However, this doesn’t happen – only the code in the edited field (in this case A) will run.

If you want the code for another field to also run, you must add the runfieldcode statement, like this. This statement has one parameter, the name of the field with the code you want to run.

Note: When a field’s code is run with the runfieldcode statement, the current field is still the original field. So if the code for the target field uses `«»` to get the current field’s value, it won’t work.

If you want to run the code for multiple fields, you must use runfieldcode multiple times, like this:

    localparameters minValue,maxValue
    if «» < minValue or «» > maxValue
        nsnotify "Invalid Value",
            "TEXT","Value must be from "+minValue+" to "+maxValue
    endif
    runfieldcode "Total"
    runfieldcode "Avg"

#### Running code when ANY field changes

As an alternative to setting up code for specific fields, you can also set up a special procedure named `.ModifyRecord` that will be run whenever any field is modified. See Implicitly Triggered Procedures for more information.

#### Running Code when a Field is Clicked

Starting with Panorama X 10.1, you can add a special `click:` label to the code and specify actions that will run immediately when a field is clicked in the Data Sheet. Here is an example that overrides what happens when you click on the Use field in this database.

With this code, clicking on the Use field will toggle between Public and Private.

Note: You can still press the Tab key after clicking and manually edit the cell (unless you have un-checked the Editable option).

A common application is to toggle between blank and a value, like this.

This code takes advantage of the the fact that `«»` means “the current field name”, and also uses the ?( true-false function. You can copy and paste this code into any field you want.

    click:
        «»=?(«»="","Y","")
        return

You don’t have to use the letter `"Y"`, you can use any text you want. A handy trick is to use an emoji, like this:

You can set up a toggle for three or more choices, but if the list gets long you might want to use a pop-up menu. Here is code that will do that for the Type field in the example airport database:

    return

    click:

    local choice
    let choices=commatocr("Airport,Balloonport,Gliderport,Heliport,SeaplaneBase,Ultralight")
    popupclick choices,"",choice
    if choice<>""
      Type=choice
    endif

And here is the code in action.

You may have noticed that the code in all of these examples begins with a return statement, and then the `click:` label. This return statement will be run if the user uses the Tab key to open the standard editor window, then presses Return or Enter. If you want any other actions to run in this situation, put them above the return statement. The return statement ensures that the click code doesn’t run when the editing window closes.

    if «»="Y" or «»=""
        return
    endif
    message "Must be blank or Y, no other values allowed"
    «»=""
    return

    click:
        «»=?(«»="","Y","")
        return

Alternatively, you can add a `modify:` label to the code. If Panorama sees this label, it will run the code afterwards when the editing window closes. Here is an example that includes both the `click:` and `modify:` labels. This works exactly the same as the previous example.

    click:
        «»=?(«»="","Y","")
        return

    modify:
        if «»="Y" or «»=""
            return
        endif
        message "Must be blank or Y, no other values allowed"
        «»=""
        return

Earlier on this page it was described how the call statement can be used to move the automatic code into a separate, named procedure (see Calling a Named Procedure above). This works even if the code contains the special `click:` and `modify:` labels. If the call statement is used by itself (no other statements in the code), Panorama will look in the named procedure for the special labels and run the code as needed.

### Automatic Code and the Run Loop

The operation of automatic field code is tightly intertwined with the system’s run loop for dispatching events. See Understanding the Run Loop for more on this topic.

See Also

- addfield -- adds a new field to the current database (on the end).
- Adding New Fields -- adding one or more fields to a database.
- autoallfieldwidths -- automatically sets the width of all fields based on the data in each field.
- autofieldwidth -- automatically sets the width of the current field based on the data in it.
- Automatic Field Calculations -- performing formulas automatically when data is entered into a field.
- automaticfieldchoices -- updates the current field's Choice list with actual data in the database.
- automaticfieldname( -- returns an available field name.
- cell -- enters a value into the currently active field (i.e. cell).
- changetimer -- modifies a repeating task that will be performed periodically when Panorama is not otherwise busy.
- checkdesignlock -- checks if field structure can be changed, if not, returns an error.
- commonfieldspopup -- pops up a list of common fields, and changes the current field specifications when a field is chosen from this menu.
- Construct Multiple Fields -- using a template to quickly add multiple fields to a database.
- constructfields -- creates one or more new fields based on a template.
- databaseconsoledump -- dumps the raw contents of the specified database to the console in comma delimited format.
- Date Patterns -- control how dates are displayed or converted to text.
- Dates -- working with dates.
- dbinfo( -- gets information about a database: what forms it contains, what fields, what flash art pictures, etc.
- deletefield -- deletes the current field from the database.
- Deleting Fields -- deleting fields from the database.
- editfield -- begins editing of the specified field.
- editfieldname -- opens the data sheet window's field properties inspector and selects the field name.
- endnoshow -- resumes the output of text and graphics after it has been disabled with the noshow statement.
- executeasap -- executes the specified code at the first possible opportunity, non-atomically.
- Field Blueprint Dialog -- examining and modifying the raw specification of a field.
- Field Properties -- available field attributes.
- Field Properties Panel -- examining and modifying field attributes.
- Field Width -- adjusting the width of a field in the data sheet.
- fieldalignment( -- returns the alignment of a database field.
- fieldformula( -- returns the formula associated with a database field.
- fieldname -- changes the name of the current field.
- fieldnumber( -- returns the number of a database field (starting with 1).
- fieldpattern( -- returns the output pattern associated with a database field.
- Fields -- introduction to database fields.
- fieldtype -- changes the data type of the current field.
- fieldtypes -- returns a carriage return delimited array with list of fields and field data types.
- fieldtypes( -- returns a carriage return delimited array with a list of the fields and field data types.
- fieldwidth( -- returns the width (in the data sheet) of a database field.
- findreplacedialog -- opens the Find & Replace dialog.
- firstcolumn -- moves to the first column in the data sheet (leftmost column).
- getfieldproperties( -- returns a dictionary containing all of the properties of the specified field. (See the setfieldproperties statement if you want to change one or more field properties.)
- hiddenfields( -- returns a list of hidden fields in the curent data sheet window
- hidecurrentfield -- hides the current field in the data sheet.
- hidefieldsbetween -- shows all fields except those in between specified numbers.
- hidelineitemfields -- hides all line item fields.
- hidethesefields -- hides specific fields in the data sheet, making all others visible.
- Hiding and Showing Fields -- temporarily hiding fields in the data sheet.
- Implicitly Triggered Procedures -- Procedures that are triggered automatically when the user performs some normal Panorama action are said to be "implicitly triggered."
- info("computername") -- returns the name of the computer (as set up in the System Preferences Sharing panel).
- info("datatype") -- returns the data type of the current field.
- info("noshow") -- returns true if noshow is currently turned on, false if it is not.
- info("runningatomic") -- returns true if the current procedure is running as a "atomic" procedure.
- insertfield -- inserts a new field into the database in front of the current field.
- lastcolumn -- move to the last column in the data sheet (rightmost column).
- Limiting the Maximum Number of Data Sheet Columns -- adjusting the maximum number of columns displayed in data sheet windows.
- Line Item Fields -- are used for repeating items within a record
- mergefieldsdialog -- opens the standard *Merge Fields* dialog.
- Merging Adjacent Fields -- merging two fields into one.
- movefieldbefore -- moves the current field to a new position.
- newdatabasewithfields -- creates a new database with one or more fields.
- newdatabasewithtemplate -- creates a new database with a template.
- noshow -- temporarily disables the output of text and graphics.
- Numeric Data -- numeric data (fixed and floating point).
- Numeric Patterns -- control how a number is displayed or converted to text.
- Rearranging Field Order -- rearranging the order of fields in the data sheet.
- reorderfieldsdialog -- opens the Reorder Fields dialog.
- resumeaftertask -- resumes after a waitfortask statement.
- serverdatabaseconsoledump -- dumps the raw contents of the specified database on the server to the console in comma delimited format.
- setfieldnames -- changes the names of all database fields at once.
- setfieldproperties -- modifies one or more properties (name, data type, formula, etc.) of the current field.
- setwaitinglocal -- assigns a value to a local variable in the parent procedure of an asynchronous task, allowing the asynchronouse code to pass a value back to the code that spawned it.
- showallfields -- makes every field in the data sheet visible.
- showcolumns -- forces Panorama to display specified fields.
- showfields -- forces Panorama to display specified fields.
- showfieldsbetween -- hides all fields except those in between specified numbers.
- showhidefieldsdialog -- opens the standard Show/Hide Fields dialog (in the Fields menu).
- showthesefields -- makes specific fields in the data sheet visible, hiding all others.
- Smart Dates -- keyboard entry of dates.
- splitfielddialog -- opens the standard *Split Field* dialog.
- Splitting a Field -- splitting a field into two fields.
- starttimer -- sets up and starts a repeating task that will be performed periodically when Panorama is not otherwise busy.
- Timer Workshop -- provides a tool for monitoring timers and testing timer configurations.
- timerexists( -- checks to see whether a timer exists.
- Timers -- executing recurring periodic background code at fixed intervals.
- tokenname( -- returns the name of a field or variable (instead of the value contained in the field or variables).
- Understanding the Run Loop -- explanation of how Panorama code interacts with the run loop to respond to mouse clicks, keyboard presses, display updates and other events that require attention.
- visiblefieldnumbers( -- returns a data array of visible fields (by number) in the data sheet.
- visiblefields( -- returns a list of visible fields in the data sheet.
- wait -- pauses the program for a specified period of time.
- waitfortask -- temporarily pauses a procedure until the specified task is complete.

History

Version | Status | Notes
10.1 | Updated | Panorama can now run code immediately when a field is clicked in the Data Sheet.
10.0 | Updated | Carried over from Panorama 6.0, but now formulas and code are separate.