Ask Reuben

Fieldnames in Dialogs

Why does auto-complete not offer me the name of a field for a BEFORE FIELD, NEXT FIELD, or AFTER FIELD ?

Why does the real time syntax check not pick up a misspelt field name in my INPUT, CONSTRUCT, or INPUT ARRAY statement ? 

Why does the compiler not pick up a misspelt screen field name in my INPUT, CONSTRUCT, or INPUT ARRAY statement ? 

Why is a misspelt screen field name picked up at runtime and not beforehand?

As a  Genero and Informix 4gl developer you have probably encountered at run time  a -1119 “NEXT FIELD name not found in form” or a –1129  “Field (fieldname) in BEFORE/AFTER clause not found in form” at least once in your lifetime.  Typically this has occurred because you have misspelt  a field-name, either in the NEXT FIELD or BEFORE FIELD or AFTER FIELD block, or perhaps in the first line of the INPUT statement, or in the form itself.

A question you could ask is, “Why is this typo being detected at runtime, and not before hand? either at compile time or as you are typing.  The good news is that there has been an improvement in this area in the 4.01 release with enhancement FGL-5702 that was included in the 4.01 release.  However it won’t pick up all cases and I’ll explain why.

To understand why it is not always possible to detect at compile time, you need to look at the syntax for INPUT, INPUT ARRAY, and CONSTRUCT statements.  I’ll use the syntax documentation for the INPUT statement, the other dialogs are similar.

INPUT { BY NAME { variable | record.* } [,...]
              [ WITHOUT DEFAULTS ]
      | variable | record.* } [,...]
              [ WITHOUT DEFAULTS ]
              FROM field-list
| BEFORE FIELD field-spec [,...] 
| AFTER FIELD field-spec [,...]
   | NEXT
   | field-spec

where field-list defines a list of fields with one or more of:

{ field-name
| table-name.*
| table-name.field-name
| screen-array[line].*
| screen-array[line].field-name
| screen-record.*
| screen-record.field-name
} [,...]

where field-spec identifies a unique field with one of:

{ field-name
| table-name.field-name
| screen-array.field-name
| screen-record.field-name

The key thing to observe is that in field-list, the values include screen-array[line].*, screen-record.*.  The members of the screen-array and screen-record are NOT defined in the .4gl file, they are defined in a .per / .4fd form file.  Hence when they are referenced by the field-spec entry in BEFORE FIELD field-spec, AFTER FIELD field-spec, NEXT FIELD field-spec, the compiler cannot check what you have typed as the .4gl does not have the information as to what a valid value for field-spec is, that information is held in the form file.

Now it has been pointed out that this unnecessarily pessimistic.  Yes its true that if the statement uses the screen-array[line].*, screen-record.* syntax then the valid values for field-spec are not known, but what about the other values for field-list where the values used in field-spec are explicitly listed, that is table-name.field-name, screen-array[line].field-name, screen-record.field-name.  Similarly what about when BY NAME clause is used, in that instance the 4gl does know the values for field-spec as they are listed in the 4gl record definition.

This is the area where there has been some improvement.   The compiler now has the ability to raise a warning for the case where BY NAME is used.  See the form-field-name warning in Table 2 here.

In the two screenshots below, the first INPUT … BY NAME statement, the 3.20 screenshot on the left does not have a warning that field4 is not in the record list field1, field2, field3.  The 4.01 screenshot on the right does have a warning …

… The second INPUT which does not use the BY NAME clause does not have the warning.

With an INPUT ARRAY statement, the only syntax option uses FROM screen-record.*.  When the compiler sees an INPUT ARRAY it can not check that what values are used in BEFORE FIELD field-spec, AFTER FIELD field-spec, NEXT FIELD field-spec as these are always defined in the form file.

The human developer knows as in their head they know what form is open at that time, the compiler cannot make that judgement.  Reasons why include the fact the OPEN WINDOW, OPEN FORM maybe in a seperate 4gl!, there maybe some logic to open two different forms, the form file used in the OPEN WINDOW, OPEN FORM might be a variable.

There is room for improvement.

Should we raise an error and not a warning? One of the dangers in adding an enhancement in a maintenance release is that we don’t think of something and suddenly your code does not compile or run.  Adding the new check as a warning means that existing code would still compile, and still allows the option of making that an error in a major release along with a note in the Upgrade Guide.

Should we also provide a warning for the syntax where the screen record members are explicitly listed in the .4gl?

Should we provide a hint to the compiler what the form is so it can look up the screen record members there?  That is give the compiler the same information the human developer has.  This would help in the INPUT ARRAY case.

In my opinion the original Informix-4gl designers were very pessimistic by not having a compiler error and only detecting a bad field name at runtime.  There are valid reasons why the compiler does not know what the valid values are, but there are some instance where the compiler can determine what the valid values, and maybe in the future we will provide more information to the compiler so it can make the same reasoning a human developer does.