Download Subject As PDF

 

Learning Ffenics: Forms

Introducing The Form

The form is the basic building block in Ffenics.

When you plan your application, you will spot a number of ‘things’ that are of importance. For example, in the FFulcrum demonstration application, we are interested in:

  • Organisations
  • Contacts at an Organisation
  • Ways to communicate with those Contacts
  • Instances when contact took place.

Each ‘thing’ in this list will be represented by a form in our application.

A form is made up of a set of fields, and each field describes one detail of the thing that the form represents. So in the case of a Contact, we might record their:

  • First Name
  • Last Name
  • Title (Mr, Mrs, etc)
  • Job Title
  • Date Of Birth
  • The Organisation for which they are a Contact.

How much detail we use to describe a thing depends on our business need, and on how much we can actually find out about it. I think of forms as sketching the thing in question, like a cartoonist, providing enough information to create a passable likeness. Other times, though, you’ll need the detail of a microscope camera.

Define Your Form

To start a new form:

  • Select ‘File » New » Form’ from the top line menu, OR
  • Double-click the word ‘Forms’ in the catalog, OR
  • Right-click the word ‘Forms’ in the catalog, and select ‘New’, Or
  • Type Alt + Shift + F.

Whichever option you choose, the ‘New Documents’ dialog appears, with ‘Form’ selected as the type of document:

New Form Dialog

What To Call Your Form

Getting the name right for your forms (and fields, and whatever else needs a name) is an important step.

  • It shows that you understand what it is you are trying to describe.
  • It makes it easier to think about and discuss the components of the application as you develop it, whether talking to yourself, a co-developer, staff, or even your bank manager!
  • It makes it easier to maintain the app on an ongoing basis, especially useful as you attempt to understand it after a break when it is no longer fresh in your mind.

You need a unique name for each document in your application. For forms, the name should reflect the actual thing you are going to describe. The maximum length is 50 characters, so there is no need to be cryptic!

Some people use a prefix to indicate the type of document. I suggest doing this for all documents other than forms.

You can use any alphanumeric character, or punctuation mark. I suggest you use punctuation (other than perhaps an underscore) rarely, and for special effect.

Don’t start with the ‘$’ sign, as Ffenics uses this to indicate some of its own internal forms (yes, bits of Ffenics are written in Ffenics!).

To name your form, double-click ‘<New Form>’ in the ‘View Existing Forms/Select a Parent Form’ list. The ‘New Form Document’ dialog appears:

New Form Document

Type the form name in the field as shown, and click ‘OK’. A blank new form appears in Design Time mode.

Single or Multiple Word Names

Many development tools require that all names be single words, and that they avoid so-called reserved words.

Ffenics does not require single word names, and it is so rare to hit reserved word issues that it’s hardly worth mentioning.

However, ‘single word’ names looks more professional and reduces ambiguity to a minimum. More importantly, if you are using Ffenics to prototype an application, or if you decide to move to another platform in the future, ‘single-word’ names will speed migration and reduce costs.

It is what I recommend, and what I do in my own applications.

I prefer names like ‘TelephonyType’; others may prefer ‘Telephony_Type’. Either way, the name should make sense in normal English (or whatever language you think in), simply because this makes it easier to understand and discuss.

Forms vs Aspects

When you create a form, you will be both defining your data, and building at least a basic user interface.

I recommend that you create forms that provide just enough user interface to test out your data, and create more sophisticated user interfaces using Aspect documents.

However, if you are up against the tightest of deadlines, you can get a ‘good enough’ app up and running with using just forms in the place of aspects. Convert them to aspects later when the heat is off.

In the rest of this section, I concentrate on the data definition part of the form, which mainly involves how – and why – you create fields.

How to add a new field

The easiest way to add a new field is to press the new field shortcut F10. The cursor will change to a plus sign with the word ‘Field’ in a vertical rectangle. Click anywhere on the form to bring up the form definition dialog:

New Form Document

This dialog will appear in numerous points in your Ffenics development.

(Some of its options are not immediately relevant to data definition, so for now ignore ‘Object Name’, ‘Summarize’, ‘Visual Control’, ‘Layout Only’, and the ‘Display...' and ‘Fonts...’ buttons.)

Maximum number Of Fields

Each form can contain a total of 255 fields, be they non-virtual or virtual.

With a well-designed system, you generally have a few fields per form, and many forms.

Field Name

The same suggestions for form names applies to field names. You have up to 50 characters; use a name you’ll understand. Equally, don’t make every name an essay. See the Ffulcrum application for ideas.

Data Types: Text

Each field must be of one data type. Someone’s name is stored in text fields, money in number fields, ‘when’ information in date and time fields, and so on.

Text, Memo and Long Text

Text fields, probably the most commonly used type, allow you to enter any character – letters, numbers, punctuation.

You may use text for things like telephone numbers – despite that word ‘number’, you’ll find you’ll need to add other characters such as spaces, dashes, brackets to make it easier to read.

The text field can be up to 255 characters in length – twice the length of a Twitter tweet! Make sure that you select a length that should be long enough to accommodate the longest possible name, city, country, etc.

(Longest useful country name is around 30 characters, unless you prefer things like ‘The United Kingdom of Great Britain and Northern Ireland’ to simply ‘UK’. ‘Llanfairpwllgwyngyllgogerychwyrndrobwllllantysiliogogogoch’ is 58 letters long, but can be abbreviated to ‘Llanfair PG’.)

If you need longer blocks of text, use either the Long Text option, or the Memo field.

Long text allows a maximum of 1,999 characters; memo is basically unlimited. The difference is that memo data is stored outside of the normal Ffenics structure, and can’t be manipulated or searched.

Most of the time, you’ll find the regular text field sufficient. Keep note-type information short and to the point.

There is a minor glitch if you try to specify a long text length greater than 999, as that is the maximum value it will let you type. To workaround this, enter 999, then press the ‘up’ arrow until the value has incremented to your target length.

Data Types: Number and Currency

The Number type lets you store integer, fixed and floating point numbers.

To create an integer, select number as the type, with the number options of digits set to a value from 1-15, and the decimals set to ‘none’.

Fixed point numbers such as monetary values are defined by choosing the number of digits and how many decimal points.

The Currency type is a shorthand for a default of 7-digit, fixed-point number, with two decimal places (for values up to 99,999.99). Note that it if you redisplay the field definition, its type will have reverted back to a fixed point number.

For floating point numbers such as you might use for measurements, select ‘float’ in the decimal list.

A floating point number can be up to 14 digits long, with one digit given to the decimal point.

Data Types: Date and Time

Date field types store dates, with either two-digit (standard) or four-digit (extended) years.

Date fields ensure that valid dates are entered, with a date range from 01/01/1776 to 31/12/9999 for four-digit years.

Two-digit years assume that the full year is within a 100-year span, depending on the value found on the ‘Application » Preferences » Database Administration » Date: Base Year ‘field. By default this is set to ’75’, which gives a span of 01/01/1975 to 31/12/2074.

The date style (day/month/year, month/day/year, year/month/day, etc) is entered according to the settings in the PC’s ‘Control Panel » Regional And Language Options’ dialog. All PCs using the same Ffenics application need to have the same setting.

Dates must be entered with two-digit days and months, starting with a leading ‘0’ if the value is less than 10, for example ‘06/09/2011’. If you enter two-digit year value in an extended date, Ffenics will insert the current century.

Time fields allow entry of time values in HH:MM:SS . You can omit typing the seconds, in which case Ffenics will insert ‘00’.

Data Types: Numeric String and Sequenced ID

Numeric Strings consist of a row of numbers, sometimes with formatting between the numbers to make them easier to read.

The format is fixed. To specify a number to appear like this:

123-456:789

You enter a format of:

999-999:999

Where the ‘9’ shows where the numbers appear. The other characters, the formatting between the numbers.

The user only needs to enter the numbers.

Formatted numeric strings prescribe a format that really should never change during the useful life of your application. It is rare to find such real-life number strings that stay the same, or are used consistently in all situations. ISBN and UK telephone numbers, for example, are both guilty or having morphed over time. You will probably find, therefore, that you use formatted numeric strings rarely, possibly only for values internal to your organisation over which you may have control.

If you want to omit any formatting, just enter a sequence of 9s for each required digit.

Sequenced ID a variation on an unformatted numeric string. The value in a new record increments by one from the last saved value, and can be useful for values like invoice and delivery numbers.

You can also use them as unique identifiers for records. Note that the topic of how to identify a record sparks a debate that can only be survived with strong coffee or alcohol, which unfortunately I can’t avoid. Click here for a beverage-free attempt to introduce this topic.

There are also potential (but avoidable) issues with sequenced IDs for invoice-type numbers; click here for more on that discussion.

The starting value lets you increment from a specified figure. You might not want your delivery numbers to start at 0001 to avoid the impression that your business is brand new and possibly inexperienced.

Data Types: Choice List and Yes/No

Choice List is a pre-set list of choices, a list that you don’t expect to change over time.

To create a choice list:

  1. Choose the Choice List data type
  2. Enter your first choice in the field labelled ‘choice List’, and press enter, or click the ‘Add’ button
  3. Repeat for the remaining choices.
  4. Click OK when ready.

The list can then be presented as either a drop-down list, or a set of radio buttons.

The user can only enter an item from the list (or, if displayed as a drop-down, can clear the field so it contains no value). You can add or remove options later, but it is better to use the multi-box option for lists whose value may change. Click here for more on multi-boxes. But for rough and ready (and relatively short) lists, you may find the Choice List option good enough to get going.

Yes/No fields are a kind of pre-set choice list, limited to three options: yes, no and blank. You can display them as a list, as a set of radio buttons, or (the better option) as a check box.

Note: even though the field type allows it, ‘blank’ is not a meaningful option, as yes/no answers are by their nature black and white. Instead, you should decide whether the field tends to be ‘yes’ or ‘no’, and give it a default derivation instead. If you really want three options – such as yes, no, and unknown – then create a choice field with these options.

It is good practice to always choose a default value for a choice list, as this removes ambiguity in your data when you look at it later. A blank value could mean: “did the interviewee decline to answer; did the interviewer forget to ask; or did the person entering the data forget to put it in?” In such a case, you might have choices “Didn’t Answer/Didn’t Asked/No Value Input”, and probably set the latter as a default just in case.

Alternatively, you could make the field required with no default, which will force the data-entry person to choose something.

If you want to reuse the same list in another field on this form, enter a value in ‘List Name’. To copy the items to another choice field, just enter this name in ‘List Name’ for the second field, and the items in the list will be copied for you (save the field first to see them).

Field Data

The field data section of the field definition dialog sets a number of important properties:

New Form Document

Field Data: Required and Prevent-Entry

Required

If checked, prevents the user from saving blank information.

Also prevents a procedure or import from adding records that lack information in this field.

Prevent-Entry

Stops the user gaining direct access to the field.

This means that the value in the field is set either via a derivation, via a procedure posting to it on another occasion, or (sometimes) by being a match field in a relationship.

Since prevent entry stops the user gaining direct access to the field, it also stops the developer or whoever is looking after the system from doing the same. If you create aspects over your forms for the user interface as I recommend, you can omit fields that might be prevent-entry candidates. If you need a value shown, use a virtual instead (see virtuals). You can then use the form to get into the field and make manual data corrections later should the need arise.

Field Data: Indexed

An index speeds searches and can improve performance.

Without an index, a search has to look through the physical records to see if a value exists. Like an index in a book, a Ffenics index is arranged to provide quick access to the location of that value in the data. You can imagine Ffenics turning quickly to the back of a book, memorising all the page references, and then jumping to each page in turn.

Generally, you should index:

  • A unique field (see Unique). Ffenics will use the index to check that the value does not already exist, allowing you to quickly save information.
  • A field that you will probably search on through the various search options. For example, a Contact’s LastName field.
  • A field used as the match in a relationship.

You cannot index:

  • Virtual fields
  • Fields with the Memo data type
  • Fast Text Indexing

For longer text values where you know you will always that you will do an exact match search (i.e. no wild cards), you can apply a ‘FastText’ Index’. This uses compression to create a significantly smaller index file, one that is much faster to search, especially on a network.

If you attempt to index a text field longer than 115 characters, the Fast Text option is selected automatically (along with a confirming message).

You can use Fast Text on the following data types:

  • Text (but not Memo or Long Text)
  • Numeric String and Sequenced ID

This is an advanced option I have rarely used, and mention it merely for completeness.

Field Data: Unique

When one field has the unique flag set, it means that no two records in this form can have the same value in that field.

When more than one field has the unique flag set, it means that no two records can have the same combination of values in all the unique fields.

Generally, it is more efficient to have a single field flagged as unique, and for this reason when more than one field is justified as being set to unique, it is better to create an extra field that combines the values in a single field, and to flag this as unique and indexed.

Click here for more on uniqueness.

Field Data: Virtual Fields

Virtuals are one of the jewels in the Ffenics crown, and fields are effectively divided into virtual and ‘not virtual’ groups.

The data in a ‘not virtual’ field is stored in the data file for a form.

A virtual field does not store data. Instead, it is derived on the fly each time you asked a question of it.

It is important to know when developing your application whether or not a field is virtual. If it is, there is no point writing a procedure to post data into it. You should also take care when using virtuals in relationships.

For these and other reasons, I make it a rule to precede the name of a virtual with a lower case ‘v’, which gives me an important visual clue.

Prevent-Entry and Derivations

By default, a virtual field is prevent-entry. You can override this, but most of the time, you don’t want to gain access to the field directly. Instead, you want to use the value it contains via its field derivation formula.

You will find many uses for virtuals as you become more familiar with Ffenics. Some general uses include:

To act as a summary of some or all of the data on a form.

For example, if you have Title, FirstName, MiddleName, LastName and Suffix fields, you can save yourself a lot of work later by creating a single virtual vFullname with the derivation:

concat ( if ( Title = blank , blank , concat ( Title , " " ) ) ,
if ( FirstName = blank , blank , concat ( FirstName , " " ) ) ,
if ( MiddleName = blank , blank , concat ( MiddleName , " " ) ) ,
if ( Suffix = blank , LastName , concat ( LastName , ", " , Suffix ) ) )

Yes, it’s a bit of a wordy derivation, but I’ve just given it to you for free (click here for an explanation of what is going on), and you can now use this field instead of the five separate data-entry fields to consistently address your contacts across your application.

To summarise or repeat details from related forms

Generally, a relationship is either ‘looking up’ the one and only value from a parent form records, or is ‘seeing’ all the values in child form records.

So a virtual with a derivation of:

any "GetOrg" "Name"

means that, for that contact, you can see its organisation. If the name of the organisation changes later, you only need to change it in one place. The virtual will always show the current saved value.

We can also look in the other direction, to child records. This:

Count of SeeContacts

when included in a virtual on the Organisation form, will tell us how many contacts there are.

Highest of SeeInteractions InteractionDate

gives the last time we interacted with a given contact, and the more complicated:

( current date – lowest of SeeInteractions InteractionDate )
/ count of SeeInteractions

gives the average gap between interactions to date since we first had contact with the contact.

As in intermediate Result for use in another field or relationship

Sometimes we need to do quite complicated calculations on our data. Rather than squeeze the entire derivation into a single ‘results’ field, it is easier to break the derivation up into bite-size chunks, with one virtual per chunk, and then join them all together in a final calculation.

As a ‘copy’ field for a prevent-entry version of an allow-entry field

Sometimes you want to let a user add a value when a record is first entered, but let them only see it and not modify it later.

The outline of this scenario is:

One Form with FieldA, not prevent entry, and vFieldA, virtual and derived:

concat ( "" , FieldA )

Two aspects. The first used for adding records only, the other for updating. AspectA has FieldA, and thus the user can add information. AspectB has vFieldA but not FieldA, which only lets the user see the data but not touch it.

Sometimes you will use a similar technique to pass a value to an object script – see Object Scripting for more details.

Allow-Entry Virtuals

By default, a virtual is prevent-entry, but you can uncheck the prevent-entry option. This lets the user type some value into the field which will not otherwise be stored on disk.

This is an advanced topic, and care needs to be taken if used with a field derivation.

Field Data: Field Security

Each user can be assigned a security level. Typically, developers like yourself have high security, and everyone else has a level from medium1 to low3.

In order to view or write data in a field, the user must have at least the minimum security specified (normally low3, which everyone has). Otherwise they will not see or be able to change or add information.

You should change the security settings only when you really need to; the default settings will work 99.99% of the time.

Derivation and Range Check Panels

New Form Document

We touched on field derivations earlier.

Derivations

At its simplest, you can think of a derivation as simply being a default, a value the application will enter for you if you leave it blank.

A simple default value could be, for a yes/no field, just:

Yes

Or for the Title text field:

"Mr"

Or, if there is a Gender field:

If ( Title = blank , if ( Gender = Male, "Mr", "Mrs” ) )

Or you could use one of the ‘current’ options:

Current date

For a DateEntered field.

There is a lot to field derivations, and it is possible to write some very complicated bits of automatic derivations and checking.

The various windows – Functions, Relationships, Fields and Operators – act as reminders, and ways to save a bit of typing by double-clicking values. The field derivation is entered in the main window, and must be able to parse (if you are familiar with entering formulae in spreadsheets like Excel, you will know what happens if you have a syntactical error). You’ll find many examples on this site and on the forum exploring derivations in all their glory.

To enter a new line in the derivation edit box, hold down the shift key and hit ‘enter’. Otherwise you will ‘OK’ the field derivation dialog, and probably get an syntax error.

You can add comments to derivations by starting the line with two hyphens.

Range Check

This provides a mechanism to ensure that data entered obeys certain rules.

The window is identical to that for a derivation. The syntax is a bit different, though.

The range check formula should describe the conditions when the data is valid. For example, in an InteractionDate field:

InteractionDate between current date – 14 to current date

To only allow the earliest value to be a fortnight ago, and the latest (at the moment the edit is taken place) to be today.

If the value entered does not match the range check, a message similar to this is displayed:

New Form Document

And the user will have to correct the value before they can save.

Field Help

The field help panel lets you add a help message. For example, in the case of our InteractionDate, we could add this to the field help:

New Form Document

When the user enters the field, this message will be displayed on the status bar:

New Form Document

Other Form Considerations: Properties

Most of your form creation work will involve the field derivation dialog. There are a few other elements that belong to the form, all accessed from the Document menu.

Document » Properties

New Form Document

The one item that ‘belongs’ to the form on this dialog is ‘Preserve old CURRENT DATE, etc. on modify’.

It can only be set at the form level, and affects the behaviour of all aspects that use this form, as well as the form itself.

If this option is checked (which it is by default), derivations that use the ‘current’ keyword will not change on update. So a date field whose derivation is ‘current date’ will retain the date from when it was first entered.

But if this option is not checked, the field will update to today’s date.

So if you want two sets of fields to record when the record was first entered and when it was last modified:

  1. Uncheck the ‘Preserve old CURRENT DATE, etc. on modify’ on the Document Properties dialog.
  2. Add two date fields, one called DateFirstEntered, the other DateLastModified.
  3. DateFirstEntered is derived:

If ( DateFirstEntered = blank , current date , DateFirstEntered )

  1. DateLastModified is derived:

Current date

When the record is first saved, both fields derive to today’s date.

When it is updated, DateFirstEntered’s derivation looks to see if it already has a value. If it does, the second part of the ‘if’ function is executed – it basically keeps its current value.

DateLastModified, on the other hand, will update to today’s date.

The set of ‘current’ variables includes:

  • Date
  • Time
  • User name
  • Computername (the workstation they are using)
  • Computeruser (the Windows account they have logged in)

Other Form Considerations: Security and Performance

Document » Security

New Form Document

Use this dialog sparingly, if at all. It gives you quite a fine level what a user can do based on their security level. The following items, if set at the form level, will be the minimum security requirement for all other documents:

  • View records
  • Enter records
  • Modify Records
  • Delete Records
  • Use Data Encryption

Document » Performance

New Form Document

This is an advanced option that can be occasionally useful. It lets you save records in a particular physical order in the form. In this screenshot I want these records ordered first by InteractionDate, then by InteractionTime, which basically means the oldest first. The actual reordering only takes place whenever the form is reorganised.

However, you can sort records on the fly, and specify sort orders in aspects and other documents. Generally, records rarely need to be physically sorted. You also cannot use clustering if you have specified a field as sequenced ID.

FREE Trial Buy Fforum

FREE! Newsletter

Sign up to receive product news, tips, tricks and more

We respect your privacy
Migration From DataEase
The Ffenics Promise:

If you’re not satisfied, for any reason, within 90 days you get a full refund, full stop, no questions asked. We don’t want your money if you’re not amazingly happy.