Sei sulla pagina 1di 36

WacGen III

Authority 4GL Screen Generator

AUTHORITY
Version 1.0 ~ August 28, 2010

WacGen III

Contents
SYNTAX CONVENTION .............................................................................................................................................. 1 FORM SYNTAX IN BRIEF................................................................................................................................................ 1 OVERVIEW OF W ACGEN FORMATTING CONVENTIONS .................................................................................................... 1 Ugly attribute names replaced... ........................................................................................................................... 2 STANDARD INFORMIX FORM SECTIONS ................................................................................................................ 3
COPYRIGHT-BLOCK ...................................................................................................................................................... 3 DATABASE-SECTION..................................................................................................................................................... 3 SCREEN-SECTION ........................................................................................................................................................ 3 LAYOUT-SECTION ........................................................................................................................................................ 3

General container facts ......................................................................................................................................... 3 The container types .............................................................................................................................................. 4 Implicit containers added by the generator ........................................................................................................... 5 Embedded containers ........................................................................................................................................... 5 Bonus attributes .................................................................................................................................................... 6 TABLES-SECTION ......................................................................................................................................................... 6 ATTRIBUTES-SECTION .................................................................................................................................................. 7 Use a form field or static item? ............................................................................................................................. 7 Static field widgets accepted by WacGen, and their attributes ............................................................................ 8 Notes about form field items ................................................................................................................................. 8 Notes about attributes ........................................................................................................................................... 8 INSTRUCTIONS-SECTION ............................................................................................................................................10 COMMAND SECTION A.K.A. WACGEN OR FOURGEN SECTION........................................................................10
MENU-SECTION .........................................................................................................................................................11 VIEW-SECTION (OBSOLETE FOR GENERO >= 2.10) ......................................................................................................13 QUERY-SECTION ........................................................................................................................................................13 MAINTENANCE-SECTION (ZOOMS ONLY) ......................................................................................................................14 BROWSE-SECTION (MAIN FORM ONLY).........................................................................................................................15 FUNCTION-SECTION ...................................................................................................................................................16 DEFAULTS-SECTION ...................................................................................................................................................16 DEFINE-SECTION N ....................................................................................................................................................19 INPUT-SECTION N ......................................................................................................................................................19 COMPLEX COMMANDS ................................................................................................................................................23

check command ..................................................................................................................................................23 lookup command.................................................................................................................................................24 zoom command ..................................................................................................................................................26 autozoom ............................................................................................................................................................27 zoom maintenance..............................................................................................................................................27 Variables in globals.org ......................................................................................................................................27 SHARED COMMANDS ..................................................................................................................................................28 TIPS AND TECHNIQUES ..........................................................................................................................................28 PROGRAMMATICALLY DISPLAY OR HIDE SCREEN FIELDS ...............................................................................................28 WHAT ELSE??? ........................................................................................................................................................29
POSSIBLE TUTORIAL SUBJECTS ...................................................................................................................................29

WacGen III

Syntax convention
... is conventional. No surprises in the notation chosen (the only surprise will be if it's used consistently): either an obvious generic object like integer or a term defined elsewhere a literal token written as-is '' a literal symbol (the chars in the quotes) [ thing ] contents are optional at this place { thing }+ optional list; if the + is used then one or more must be given { thing x... }+ optional list; if more than one item given, separator is x; same rule about + thing | thing ... choice of one thing from all the alternatives ( things ) grouping of things to avoid ambiguity italics bold

Form syntax in brief


[ copyright-block ] database-section screen-section | layout-section [ tables-section ] attributes-section instructions-section [ menu-section ] [ view-section ] [ query-section ] [ browse-section ] [ function-section ] defaults-section [ define-section n ] input-section n

Overview of WacGen formatting conventions


All of WacGen source is written in lower case. Do not use the seemingly universal practice from the rest of the 4GL world of using uppercase keywords "to make them stand out". If your brain can't see the keywords, then maybe you should think about turning up to work sober. For the purposes of illustration, the WacGen documentation will always show 4GL keywords in uppercase, but that is only to make them stand out in essays. The only exceptions to uppercase keywords are the tags of the fields on the screen, the words GOTO, LABEL and NOTFOUND in 4GL source, or the names of widget classes in the form files. Your identifiers cannot start with underscore because the code generator reserves all such identifiers for items it adds into the generated .per or .org files. Indentation should generally be the normal WacGen standard of 4 characters. In the LAYOUT section, each nested container must be indented only one space; the generator enforces this.

Version 1.0

1 of 36

WacGen III

Use only uppercase alphanumeric tags for screen fields; use only two characters for these tags so that they line up neatly in the attributes section. The tags have little meaning so longer names don't add much information. Typical tags are A1, A2, ... A9, B1, B2, .... but feel free to label related fields in groups - for example D1 .. DF for the detail fields. Keep the entries in the attributes section in the same order as they are listed in the screen record(s). The screen record ordering determines the flow of focus from field to field, and it's a good idea to keep the same order in the attributes section. You don't have to relabel the tags if you re-order the fields (although that would be a nice thing to do). The simplest style guide rule of all applies: If your code looks like it comes out of the generator, then it's in style. That includes indentation, placement, case, quoting, comments, etc etc etc etc etc Stylistic flair or formatting rules from other languages is inappropriate. Overview of form syntax - variations from Informix and FourJs WacGen takes a few liberties with the syntax of forms, such that it does not quite match the original Informix 4GL syntax or the newer syntax from FourJs. So if you read the FourJs manual for ideas (which is a good thing to do) just be aware that the syntax you must use may be slightly different. WacGen also adds several new keywords for the benefit of smarter code generation. A noticeable difference from original Informix 4GL and FourJs syntax is the removal of section keywords such as ATTRIBUTES, INSTRUCTIONS and END. Actually, the keywords are not illegal, but they are totally optional and strongly discouraged because they just add noise. The giant screaming FOURGEN word wrapped in braces and two lines of # characters enveloping the command section are also completely discouraged. Please remove any of these things whenever you see them. Finally, the TABLES section has been integrated with the DATABASE section as described below, and you are strongly encouraged to shift the table definitions. NOTE: some new features that FourJs may provide from time to time may not be accepted by the generator. If you see something that looks useful, just let me know and I'll see what I can do. I try to keep up but sometimes things slip under the radar.

Ugly attribute names replaced...


Some of the keywords that FourJs added for attributes are ugly monsters that have been replaced by shorter, sweeter keywords. However the FourJs keywords are still recognized so the generator can give you an error message and tell you the correct keyword to use. Feel free to read the FourJs manual and give it a try. TODO: include a table of the wacgen replacement attributes

Version 1.0

2 of 36

WacGen III

Standard Informix Form Sections


copyright-block
Typically looks like:
###################################################################### # Copyright (C) 1992-2009 Civica Pty. Limited # All rights reserved. # Use, modification, duplication, and/or distribution of this # software is limited by the software license agreement. # @(#) $Id: sal001a.dsp,v 1.21 2009-04-02 12:27:29+11 aclarke Exp $ Civica # non_source_form embellished_per ######################################################################

Hot tip: with the standard WacGen .vimrc, you can position the cursor on the first line (or under a pre-existing copyright block) and press Q. This will replace/rewrite the header to use the current standard. You can find the current WacGen-recommended .vimrc in $wacgen/Samples The non_source_form is optional; it tells the generator NOT to generate 4GL code into .org files. The .dsp file is still processed to create a .per file. The embellished_per is even more optional, and can only be given when non_source_form is given. This is used only occasionally for advanced screen control. TODO: reference to and description of "advanced screen control"!

database-section
database formonly or

database dbname [ '@' server ] { list-of-tables } The dbname can be the keyword formonly which means the form does not reference any tables from the database. The list of tables is optional in this position but is preferred with WacGen since it brings the database and table declarations together. See the rules described below for the tablesection.

screen-section
The traditional screen layout used before Genero is still acceptable in WacGen because there's a lot of old code out there. Even here, there are a few special features that WacGen offers. TODO: check the generator for any special syntax allowed in screen in WacGen

layout-section
General container facts
FourJs enhanced the screen design capabilities in Genero by giving the ability to design the form based on nested containers. The container syntax in WacGen is slightly different from the Standard FourJs syntax because it includes a simpler, more uniform syntax and a number of short-cuts.

Version 1.0

3 of 36

WacGen III

The general syntax is


containerType [ name ] [ '(' { attribute ['=' value] ','... } ')' ] '{' contents '}' [ '--' containerType [ name ] ]

The trailing comment must nominate the correct container, optionally with the container's name if it helps to clarify the bounds of the container. Random commentary is not allowed. The contents of grid, scrollgrid, and table containers must be text and fields similar to the old screen sections, all other containers must have nested containers only. Listed below are the available containers, their standard attributes and notes. Many containers can also support extra attributes depending on the context; this will be described after all the container definitions. The generator enforces a strict indentation policy of 1 extra column indent per nested container. At most one space is allowed between the tokens in the attribute list, and the opening brace must be separated by exactly one space. The closing brace must be aligned with the opening keyword of the container. NOTE (mid 2009): due to a mistake in the generator, the contents of grid, scrollgrid and table containers are not checked properly for indentation. However they WILL BE so please indent them appropriately.

The container types


In this section, the name of the container is given, followed by a list of the optional attributes. layout wizard text, spacing, style (style not implemented) text, spacing, style (style not implemented)

The root container must be a layout or wizard. Wizard containers can only be used for wizard type forms. When using a wizard as the root container, the direct child containers must be one of the gift, quest or grail containers. gift text, hbox, vbox quest text, hbox, vbox, paths grail text, hbox, vbox Wizards must have these containers under the root wizard container.. By default the contents of these containers must be a single other container (which can have further nested containers of course) but the hbox or vbox attributes automatically add such a container for you. The text attribute is the label for each step of the wizard. The first container of a wizard must be a gift which is an introductory page for the wizard. Flow from page to page of a wizard proceeds sequentially by default, but you can create branches using the paths attribute. The paths attribute must be given a list of other container names (more quests or grails). The names listed in the paths attribute must be blank-separated only. You may not branch backwards in the flow, but your flow can rejoin by directing more than one page to another page. If you use the paths attribute, code is generated allowing you to insert conditions using a trigger. The conditions can be used to choose the path to follow. The last page of any path must be a grail, which is a final page for the wizard path, and will not flow to another page. There may be more than one grail if you have branched paths that do not return to the main flow. As a consequence of this rule, the last container of a wizard MUST be a grail; a quest that goes nowhere is illegal.

Version 1.0

4 of 36

WacGen III

vbox splitter Child containers are aligned vertically. This container requires more than one child container otherwise it is an error of stupidity. hbox splitter Child containers are aligned horizontally. This container requires more than one child container otherwise it is an error of stupidity. group text, fontpitch, splitter, align (align is probably implemented wrongly) The contents are wrapped in a standard Windows "group box" - i.e. a thin-lined frame that has a string displayed over the top-left portion of the frame. folder fontpitch

the parent container for a number of tabbed pages. page text, fontpitch, boring, splitter the child containers inside a folder. grid fontpitch the closest thing to a traditional screen image. Contents must be text and field definitions, along with a few other possible extensions added by FourJs or WacGen. TODO: describe the contents of grid scrollgrid fontpitch, align is like a grid but it has a scrollbar down the side. This container is a compromise made available to suit screen arrays with several lines per row of data. table stacked, lines, fontpitch, unsortable, allvisible, anchored, fixedpage is a spreadsheet-like container which represents a screen array. The columns are aligned neatly without intervening spaces, and the fields for each row MUST be on one line. NOTE: as at mid-2009 on Genero 2.10 or 2.11, some screen widgets such as textedit placed into tables are not drawn very nicely. Beware this effect if you try to use special field types in a table.

Implicit containers added by the generator


If a layout has more than one child container, they are automatically wrapped in a vbox for your convenience. If any child container of a folder is not a page, then a generated page is wrapped around it. This child container must have a page="string" attribute to provide the label for the page. If a page contains more than one child container, then they are automatically wrapped in an hbox. Using hbox is different from the implicit vbox on the layout because it's more likely to be useful.

Embedded containers
Inside grid and scrollgrid containers, you can paint up "inline" containers using something like:
<g name <s name <t name > > >

Version 1.0

5 of 36

WacGen III

Although this is a FourJs extension, as at mid-2009 the code generator is not too smart about this; in particular it cannot find an inline table that you might use for the detail, so there will be some defects in the generated code. The generator also fails to interpret the requisite blank spacing around the fields (see the Genero BDL manual) because FourJs changed the syntax and effect several months after it was first introduced; after the facility was first written into WacGen. The generator has never been corrected to interpret this 2nd-generation syntax properly or to generate the code correctly for tables. WARNING: In general, stick with real containers; the savings from the inline containers are questionable at best even if they worked in WacGen.

Bonus attributes
Depending on the context, WacGen allows some of the containers to contain extra attributes for various purposes. Some of the attributes are hoisted out to the surrounding container or an automatically generated container as appropriate. All containers except layout, wizard, gift, quest or grail may have a group="string" attribute. This causes the container to be wrapped in a group box labelled with the specified text. The ="string" is optional for the group attribute; an empty string is assumed if none is given. The group and page containers may have a hbox or vbox attribute; this wraps the contents (which must be more than one sub-container) in a hbox or vbox respectively. Any direct child container of a folder must be either a page container or must have a page="string" attribute. If a direct child container of a folder has both the page and group attributes, then the container is wrapped in a group which is then wrapped in a page. Any direct child container of a folder may have a boring attribute. This tells the generator to prevent access to the fields unless the user clicks on the tab of the page. In other words, the contained fields are declared "boring". Any direct child container of a folder may have an action=identifier which binds the named action to the tab of the page. The action is fired when the user clicks the tab of the page.

tables-section
If the database is specified as formonly, then there cannot be any tables listed.
tables [ alias '=' ] [ database [ '@' server ] ':' ] [ "owner" '.' ] table ...

More than one table may be listed; please list one table per line. The optional alias allows the same table to be referred to with different names, but now that I think of it, I'm not sure what the generator would think of this - something may go wrong! The alias is useful for referring to a remote table, but you need to understand that this is unusual. The database server and owner can only be given if an alias is used. Remember that with WacGen, the list of tables can be written under the DATABASE instruction which is a lot more appropriate than the ancient Informix syntax. Please shift all the tables to the DATABASE instruction whenever you edit a form.

Version 1.0

6 of 36

WacGen III

attributes-section
Before I describe the attributes syntax further, I need to point out that the syntax for writing the optional widget class of a field has gone through a number of variations. Following are the older syntaxes:
[widget] TAG = tabname.colname, TAG [widget] = tabname.colname, TAG = [WIDGET] tabname.colname, TAG = tabname.colname [WIDGET], .... .... .... .... # # # # FourJs original syntax original WacGen "improved" syntax briefly used - I thought this was nicer FINAL new improved syntax

The first style is FourJs impression of a nice syntax. The original WacGen syntax (2nd style) was designed to keep all the tags nicely lined up and visible; it read a little better than FourJs syntax. The 3rd style was added because the alignment of the words and equals sign in (2) was still wobbly and a bit hard on the eyes. Unfortunately this syntax still makes the tabname.column words wobble around. The 4th style was added because let's face it, once you're mucking around, you may as well do it properly. Note also that I've shown the WIDGET on (3) and (4) written in upper-case. This helps the widget to stand out nicely and it's the preferred style. Note also that there is no comma between the tabname.colname and1` the widget type because it's unnecessary. Finally, with syntax (4), if it's a formonly field with a type attribute, it would look like this
A1 = formonly.thingy COMBOBOX type char(10), ........

Use a form field or static item?


Each field drawn into the screen or layout needs to be defined in the attributes section. FourJs provides two way of specifying attributes for fields
A1 = table.form ...... B1 : widget-type .....

The first type is the original Informix syntax (using the = symbol) which describes a field that can be used for data entry and display. The second variant is a new addition from FourJs, for "static" form items with a widget type of button, label, image, canvas, group, scrollgrid or table. NOTE: widget types label and image can be static or variable; the other widgets listed can only be static. A static item is not associated with a field record and cannot be accessed in an INPUT, DISPLAY or CONSTRUCT command. Their attributes are pre-defined in the form file, and can be over-ridden using library functions. A static button widget cannot have a name, but must have an action=identifier in first place. The other static widget types can have an optional name=identifier which must be the first attribute specified. The only widget that requires a name is the canvas.

Version 1.0

7 of 36

WacGen III

Static field widgets accepted by WacGen, and their attributes


B1 : BUTTON action, color, comments, fontpitch, hidden, image, tag, text L1 : LABEL name, color, color where, hidden, fontpitch, justify, tag, text I1 : IMAGE name, autoscale, hidden, width, height, stretch, tag, image C1 : CANVAS name, comments, hidden, tag G1 : GROUP name, fontpitch, hidden, tag, text, align S1 : SCROLLGRID name, fontpitch, hidden, tag, align T1 : TABLE name, fontpitch, hidden, tag, unsortable, unsizable, unmovable, unhidable, visible, anchored, fixedpage

Notes about form field items


The original Informix syntax for formonly fields did not allow you to specify the full type of the field, only an unqualified type such as CHAR, DECIMAL, DATETIME. For hand-written 4GL this is not a problem, but WacGen needs to generate a field in the p_ record and it's often impossible to guess what type of variable to generate without help. If the formonly field is of type CHAR (the default) and it does not have a scroll attribute, then the size of the field is easy to determine. For other field types (e.g. decimal, datetime etc) or for CHAR fields with the scroll attribute, the generator cannot guess. Therefore WacGen will accept a full type spec on formonly fields:
A1 = formonly.thingy type decimal(10,3), .....

and will map it to


A1 = formonly.thingy type decimal, ....

when it is written into the .per file. This will keep the 4GL form compiler happy and still supply the necessary type information to the generator.

Notes about attributes


In general you should look in the FourJs manuals (or other programs) to know all the legal attributes that can be applied to fields. The following paragraphs only offer interesting facts, rules or ideas about attributes. Do not use the required, default, display like or validate like attribute in the attributes section: required will interfere with the action of the code generator - you should use a nonull instruction in the appropriate input section at the end of the form. Specifying a default value in the attributes section is pointless with generated code - use a default instruction in the generator section. display like and validate like have no place in a WacGen program. We don't want the hassle of maintaining the stupid little background tables! Do not use the reverse or colour attributes on a field. Specifying fixed styling attributes is crude compared to the use of Genero styles. NOTE: For FreightPac projects, this attribute causes style="reverse" to get attached to the field; this is an interim measure to assist porting to Genero. The include=(list) attribute can contain value mappings and the name of a p_ or q_ field which will get the mapped values:
A1 = tabname.colname1, include into colname2 = (x1=y1, x2=y2, ...)

Version 1.0

8 of 36

WacGen III

The field called colname2 in the p_ or q_ will be assigned the y values whenever one of the x values is entered into colname1. The fields behave like a combobox but the user is unaware that they're not directly entering the values that will be stored in the database. The FourJs manual seems to suggest that fields allowing an ITEMS attribute can also accept an INCLUDE attribute. This seems meaningless to me, so don't try it. If you come up with a valid reason that makes sense of this, please let me know! The items attribute in WacGen is formatted differently to the FourJs syntax. It looks like
items = (NULL, "A", "B", "C")

or
items = (NULL, "A"="Angola", "B"="Botswana", "C"="Cameroon")

You should specify the NULL value first because the empty value should be the default for all fields. STOP PRESS: the generator now puts NULL as the first entry no matter where it's found. NOTE: even a required field must allow NULL in the list of items! The generated code takes care of enforcing the required fields when you use the nonull command. It is bad for the user if you try to stop them temporarily clearing the value of any field; doing so can sometimes grid-lock the user, and their only recourse is to cancel the entire data entry and start again. NOT NICE!!! The tag=identifier attribute can be specified more than once. It attaches a string value to the field, which can be used for searching out groups of fields. See the dom_find_thing() set of functions in the WacGen library. NOTE: the generator can also add entries to the tag, but they will always be distinct because your tags are converted to upper case whereas the generator-added tags are lowercase. The domain=identifier attribute can be used to attach an abstract type to a field. Current domain types are postcode, state and adr1 through adr6 which are handled by the lib1/aulocale.4gl file (Authority only). The idea here is, when the form is opened, fields marked with a domain have their attributes and width fiddled to suit the locale e.g. AU, NZ or UK as set in the environment. The locale=locale-spec attribute is used to control the visibility of fields depending on the users locale. Currently we support AU, NZ and UK in Authority. The allowable locales need to be specified in the Application.ctl file of the project; the generator cross-checks the named locales to prevent spolling mistaiks. The locale-spec can look like
locale = [ not ] { locale-code }+

for example
locale = uk locale = au nz locale = not nz au

Smart choice here would mean thinking about what might happen if MORE locales are added to Authority - do we want something to appear ONLY in the listed locales, or do we NOT want something to appear only in the listed locales? Think carefully and the choice becomes easy. hot tip: don't use 'not uk' to mean 'au nz' - the two are not the same - think about what will happen if we ever add Hong Kong or Malaysia. Pick intelligently. CHECKBOX widgets need a pair of attributes unchecked="value", checked="value". You may leave off the pair of attributes, in which case the default values are 0, 1 (false, true)

Version 1.0

9 of 36

WacGen III

CHECKBOX widgets can have a special not null attribute which stops the checkbox acting like a "tristate" value. That is, a tri-state checkbox can be clicked to have values NULL, unchecked or checked in a cycle, but a bi-state checkbox can only have the values unchecked or checked. The tri-state will cycle around the three values when the user clicks, the bi-state checkbox will cycle around the two values. NOTE: a bi-state checkbox can still be attached to a null value in a variable! The not null attribute only affects the behaviour when the user clicks. Tri-state: the user can set it to NULL; bi-state the user cannot set it to NULL. Finally, even a bi-state checkbox can be set to NULL during CONSTRUCT which is desirable if you think about it...
A1 = tabley.thingy CHECKBOX, not null, checked="Y", unchecked="N"

instructions-section
Apart from the screen record definitions, there is very little of interest in the instructions section. In particular, the delimiters clause is totally useless and should be removed. Be aware that the first screen record is attached to the header, the second is attached to the detail in a header/detail, the third is attached to the other detail in a header/detail-detail or header/detail/detail form, and any other screen records are ignored by the generator. Exception: header/detail forms can have an "overflow" section which is a record under the detail. Therefore the 3rd screen record can be significant in this case. COMING SOON: extra input sections may be applicable for a generalised header/detail which can have as many details as you can fit on the screen; each of those details MAY have an overflow section too. This will probably happen to improve the power of the new Wizard type forms, and it will then be available for ordinary forms. When the screen type is specified as add-on, it will be an add-on-detail if the first screen record is an array, otherwise it will be an add-on-header. NOTE: this rule is an old weirdo from FourGen; you can also specifically set a form's type to add-on-header or add-on-detail, and this would be preferred. Field tab order follows the field order in the screen record. Forgetting to put a field into a screen record can often lead to mysterious behaviour.

Command section a.k.a. WacGen or FOURGEN section


Originally wrapped up as a { comment } in the .per file and marked with a whopping big pair of hash lines and the FOURGEN keyword, the Commands section used to support sections defaults, input 1, and input 2. WacGen has, over the years, added to the sections which are laid out in this order: menu, view, query, maintenance, browse, function, defaults, define N, input N Do not use the big { FOURGEN and hash-line } wrapper on the command section. If you see it, remove it pronto. Comments are introduced using the # symbol, there is no trailing ; and lines are continued onto the next line only if it ends in a comma (there might be other cases where the lines continue, but comma is the easiest and most reliable place to line-break a command). The keyword introducing the section must not have leading spaces, and the commands within the section must be indented 4 spaces.

Version 1.0

10 of 36

WacGen III

Many commands are unique to a specific section (even if it appears to be the same command keyword) and others are shared by many sections - perhaps with variations in effect depending on the section. Therefore, the description of the sections below will list the shared commands and then describe the unique commands of that section. After all the sections are described, the shared commands will be described.

menu-section
hotkey '=' ....... group '=' { identifier ','... }+ title '=' string

USELESS for Genero DOES NOTHING right now USELESS for Genero

Why useless? In character-mode 4GL, the MENU command


MENU "Adventure" COMMAND "Camel" "Cross the Simpson Desert by camel" COMMAND "Donkey" "Cross Melbourne by donkey" COMMAND "Quit" "Quit the program" END MENU

presents the list of associated commands on a line across the top of the form, and the string "Adventure" is used to label the line:
Adventure: Camel Donkey Quit

In any GUI version of 4JS, the title is clearly useless. So if you see it still hanging around in the forms, remove it.
style '=' [ obsolete ','] menu-style

where
menu-style = action | empty | process | print | enquiry | find | admin | add

menu-style

Resultant commands in the main menu Add, Update, Delete, Find, Browse, Next, Prev, Quit Quit Process, Quit Print, Quit Enquiry, Find, Browse, Next, Prev, Quit Find, Browse, Next, Prev, Quit Add, Update, Quit Add, Quit

action (default) empty process print enquiry find admin add

The obsolete keyword was used to make slight variations for historical compatibility, and should not exist in Authority code any more. The process, print and enquiry menu styles are obsolete for Genero builds; this is due to historical incompatibilities. There's a good chance it's now worth bringing them back since the old stuff has been purged from our source. Until then, the generator will give an error if you attempt to use them in Genero. Stay tooned for future change.

Version 1.0

11 of 36

WacGen III

for process: for print: for enquiry:

Use menu/style=empty and menu/command=process Use menu/style=empty and menu/command=print Use menu/style=find and menu/command=enquiry

Once the coarse menu style has been picked, the list can be augmented with the command command, include command, or reduced using the exclude command.
include '=' { standard-command ','... }+

The commands listed will be added back into the menu.


exclude '=' { standard-command ','... }+

The commands listed will removed from the menu TODO: list the "standard commands"
command '=' {name['='(add|update|delete|process|found|clear) [stay] ] ','... }+

Allows arbitrary commands to be added to the main menu. By default, the commands are always available unless one of the "command type" modifiers are attached to the command. The modifiers affect the availability of the command depending on conditions, and also what work is performed by the menu code before and after your code is called.
add update delete process found clear TC DTL DTLP TC D C P L C D T requires a document to be found (or freshly added) before it's enabled wraps the command in a BEGIN WORK / (COMMIT or ROLLBACK) WORK attempts to lock the current document clears the form and the variables (p_ and q_ etc by calling mlh_clear and mld_clear) prompts the user to confirm deletion before proceeding

NOTE: type process appears to be useless because it does not do anything differently from the add type. The problem here is lack of clarity on just exactly what process is in Authority. There appears to be at least three generic coding patterns that are all called "process". Future work should try to make sense of this and maybe add more smarts to the system. Whatever the command type, it doesn't actually have to add, update or delete the document. The "big three" variables (ringMenuIdent, ringMenuCurrent, ringMenuTotal) are available to the command, and if the command affects their value according to the rules (to be documented) then the libraries will listen to those variables no matter what the end result. The stay option is only accepted for =found or un-typed commands. DO NOT avoid use of a proper =type just to get around this rule! I don't see a reason for allowing stay on other command types but I'm perfectly willing to be convinced otherwise.

Version 1.0

12 of 36

WacGen III

What does stay mean? Well, when you find a document in a header/detail, the user is allowed to scroll up and down the detail lines in view-mode. If the user picks a command, once the command is finished, the libraries will redisplay the document, causing the user to be returned to the 1st line of the detail even if they've scrolled down several lines. This can be disconcerting. The stay option means that the code generated for that command will not return to the main library code, so the user will remain on the detail line they were previously viewing. It is your responsibility as a programmer to ensure that the document is not changed when using the stay option (which is why I think other command types cannot work with this option). Trigger points for each of the commands are generated into main.org. You use a
command mycommand code end

trigger to inject the code you want to execute. Learn about the "big three" so you can inform the libraries about what storage actions you've taken with your document. TODO: describe the Big Three For transaction-wrapped commands, your code may force a rollback by setting int_flag to true. Otherwise commit is attempted. BEWARE: the value of sqlcode can "bleed" through and cause a rollback for some commands, but the value of sqlcode is splatted by the unlock operation of update or delete, so this reliance on sqlcode is very dodgy as a way to force a rollback. In fact I'm thinking about bringing this under some sort of control. If I can't think of a way to make it reliable and useful, I'll completely block the action. Either way it will change. The safest option right now is to check sqlcode yourself and set int_flag, otherwise if you know that the value of sqlcode is irrelevant, you should assign 0 to it for your own safety.

view-section (obsolete for Genero >= 2.10)


event action

NOTE: from here, the placement of commands into sections is a bit rough. Some are used in more than one section, so some sort of uniform placement and crossreferencing needs to be applied.

query-section
see shared commands: nonull, zoom, lookup, depend, action, using Normally the CONSTRUCT generated for the Find command only allows the user to enter search values into the fields of the header and detail tables. Commands have been added to allow the programmer to remove some of those fields from the construct, include fields from ancillary tables, and perform some standard actions on the fields such as zooms and lookups. From Genero 2.10, the generator is capable of creating a combination of INPUT and CONSTRUCT commands inside a DIALOG block, therefore allowing choice of QBE or controlled data entry on any choice of field during the Find command.
exclude '=' { field ','... }+

Version 1.0

13 of 36

WacGen III

Blocks the named header or detail fields from participating in the Find command.
include '=' { field ','... }+

Includes the named fields from ancillary tables into the Find command. NOTE: requires use of the extra command in the defaults section so that the ancillary tables can be joined into the main select.
edits '=' { field ','... }+

From Genero 2.10, the named fields are put into an INPUT statement tied together with the CONSTRUCT command. Whatever the user enters into an edit field is stored into the p_ record; patterns and wildcards are obviously not allowed. This allows you to ensure the end user enters a single value rather than a pattern, and also allows you to choose if and how the value is mixed into the CONSTRUCT string. NOTE: the value entered into an edit field WILL NOT be in the CONSTRUCT string. You can append it after the CONSTRUCT or DIALOG is finished, ie use an extension on the #_ret block in mlh_construct().
event '=' something

TODO: can't remember what this beasty does. Probably obsolete for Genero.
screen '=' formname

TODO: this doesn't actually work any more (not since RDS days). The idea is you can paint a distinct query form which pops up to override the main form as the user does the Find operation. Therefore the query screen can present a searchable form that is more attractive for Find. Since there is great interest in this concept, it may well be updated to suit Genero in the near future.

maintenance-section (zooms only)


title = string Augments the bubble-help on the Add, Update and Enquire buttons (TODO - not implemented in code) program '=' identifer [ '('identifier')' ] mprogram '=' identifer [ '('identifier')' ] eprogram '=' identifer [ '('identifier')' ] Nominates the program used to perform the maintenance or enquiry. mprogram is used for maintenance (Add, Update) and eprogram is used for Enquire. The program keyword can be used to apply the same program to both tasks. The identifier in parentheses nominates the "security" program - some nonsense about permission to maintain is sometimes controlled by allowing or disallowing a user to run the named program from the VB menu. Check with Stu, he understands... TODO: bring on proper description of the security filter '=' expression mfilter '=' expression efilter '=' expression Supplies a command line filter "string" to the maintenance program. This is the standard FourGen way of nominating a record to fetch. You must make sure the filter is explicit enough to nominate exactly one record. The filter is only used for Update or Enquire actions.

Version 1.0

14 of 36

WacGen III

The filter can (must!) refer to fields of the current zoom line by using the syntax &fieldname anywhere in the expression. It can get access to the p_ and q_ fields of the zoom. This syntax is interpreted at runtime just before the maintenance program is called. options '=' expression moptions '=' expression eoptions '=' expression Supplies more random options to the command line of the maintenance program. The string is first parsed to replace &fieldname (same as the filter expression) and then plugged onto the command line. Use this to add arbitrary control options or flags to Authority programs. TODO: describe &field symbolism

browse-section (main form only)


see shared commands: action exclude '=' { field ','... }+ Blocks the named header fields from showing in the browse tab. Fields listed in exclude cannot be listed in include, visible, interesting, boring or locked commands. include '=' { field ','... }+ Sorry to say this, but the include list is not used. I think the idea way back was to be able to pick and choose the fields you want in the browse, but it was never implemented. One day it might if there is any demand; normally the exclude command would probably do the trick. Please remove any browse/include commands you find in .dsp files. Fields listed in include cannot be listed in the exclude command. locked '=' { field ','... }+ Prevents the named fields from being hidden by the user. By default, the primary key fields are locked unless this command is used. Fields listed in locked cannot be listed in exclude or visible commands. visible '=' { field ','... }+ Lists the fields that are visible by default. If this command is not used, then all the fields in the header's p_ record are visible by default. Fields listed in visible cannot be listed in locked or exclude commands. interesting '=' { field ','... }+ Fields listed in this command are put up the front of the browse fields. By default, the key fields are assumed to be interesting and will be at the top of the list; you can override this by listing them in the boring command. Fields listed in interesting cannot be listed in boring or exclude commands. boring '=' { field ','... }+ Fields listed in this command are put to the end of the browse fields. By default, the cre_dte_tme, mod_dte_tme, and mod_opr fields are assumed to be boring; you can override this by listing them in the interesting command. Fields listed in boring cannot be listed in interesting or exclude commands. label '=' { field '=' string ','... }+ Most table.column in the Authority database have a nice label stored in a table. For the columns without a pre-defined label, and for formonly fields, you can assign a nice label using this command.

Version 1.0

15 of 36

WacGen III

lines '=' integer By default, the browse page will have 12 lines, however if the main form is larger it will be stretched out automatically. This command lets you nominate the number of lines, but is almost useless in real life. width '=' integer Obsolete for Genero, this command was once available to expand a browse page when there are sod-all fields in it.

function-section
include '=' { identifier ','... }+ A few value-added functions can be generated but are not normally included. Use this command to request their generation. Currently, the available functions are startup and ringMenu_enable. The startup function can be used in ancillary forms. It provides a hook for a form to initialise anything necessary for the successful use of the form. The generated startup function will be called from main.4gl (see the startup command below to list the screens needing startup) The ringMenu_enable function is only used in main forms. It provides a framework for putting conditions on the disabled state of any commands added to the ring menu. You will see trigger points inside the function which can be used to cleanly code the conditions applied to the menu commands. exclude '=' { identifier ','... }+ A very old and dubious technique for modifying a generated function was to copy its code into a .src file, then block the generation of the function using this command. Unfortunately, this technique is very high maintenance because it makes it impossible for generator improvements to get into the cloned functions. In general, do not use this technique, and try to remove its use whenever you are editing existing programs.

defaults-section
title '=' string Assigns the window title bar for the program. The string is generated into main.org, and you have an opportunity to modify the string using triggers. type '=' screen-type Nominates the type of the form to the generator. Although it is possible for the generator to guess a form type, it is really bad to rely on this; one day I may make it an error NOT to give a form type. Possible form types are header, header/detail, header/detail/detail, header/detaildetail, zoom, add-on, add-on-header, add-on-detail, view-header, view-detail, extension, query and maybe one or two other secrets. attributes '=' junk An ancient FourGen command that is useless for GUI mode. It let you choose things like the border colour of the form, and a few other attributes I can't even remember. Remove this command in every form you visit. location '=' y ',' x

Version 1.0

16 of 36

WacGen III

An ancient FourGen command that nominated the popup location of a form. Useless in GUI mode. Remove this command in every form you edit. module '=' identifier An ancient FourGen command that nominates the application module the program is in. Just make this thing match the .4gm parent directory of the program e.g. use gl for all programs under gl.4gm. fixes '=' { [no] keyword ','... }+ In the beginning was the FourGen code. Occasionally it had some bugs, and there was also a wishlist of desirable features. These needs were addressed when WacGen was written, but it was important not to break compatibility of existing code. Thus, a whole culture of 'fixes' was born to enable the differences. The fixes cover anything from new fashions to cover-ups for almost criminal defects in the generated code. NOTE: for Authority 6.0 and above, or all projects using Genero 2.10 and above, the fixes array, check, clear, construct, default, hfilter, and skip are automatically enabled, so if you see these settings in .dsp files for such projects, please remove them. The optional no keyword can be used to negate the effects of the automatically applied fixes. Please don't use this however... TODO: document the fixes array - smarter code which enables better control of detail arrays check clear construct decimals default dodgyconstruct explain filter formonly formpath gotoline hfilter join lookups mlh_cursor p_cur q_empty readonly select skip startup varchar zoomevent switchbox '=' { identifier [ identifier ] ','... }+

Version 1.0

17 of 36

WacGen III

Extra forms added to a program need to be hooked into the switchbox function generated into main.org. Traditionally, a trigger called switchbox_items was used to tell the generator about them. The problem with the trigger is, it makes the generator dependent on trigger files only for the switchbox_items trigger. To get around this weakness, the switchbox command should be used in the main form to plug in extra forms. The first identifier is the name of the screen, and the second optional identifier is the name of the local switch function inside the form; this defaults to the same as the form name. Zoom forms use the form name as the name of the function, but other form types add an S_ prefix to the function names. Please replace all switchbox_items triggers in .trg files with this command in the main .dsp file. sockets '=' pointless in Authority... Way back, FourGen had a way to reduce the size of a linked Informix RDS program by avoiding large slabs of library functions related to addon form types. With FourJs dynamic linking, this is a pointless exercise. So I'm not going to describe this command. scr_id '=' junk No idea what I had in mind for this! extra '=' tablename [ alias ] '=' expression For all fields that can be used in the Find command, the generator and library needs to know how to include the field and its table in the SELECT statement it builds to fetch documents. The fields of the header and detail tables are easy because the join and filter commands describe the details used in the WHERE clause. However, when fields from ancillary tables are included in the Find mode using the query/include command, you need to supply an extra command to describe the join condition back to the header or detail, or back to other extra tables. The library scans the string returned by the CONSTRUCT (in mlh_construct or similar functions) and for every table found that is mentioned in an extra command, the join clause is added to the SELECT. NOTE: each time an extra table is added, the join-expression is scanned for more tables. Therefore it is quite possible and reasonable to bring on fields from extra tables via a chain of intermediate tables: extra extra
= tab1 = tab1.k1 = tab2.k2 = tab2 = tab2.k2 = header.k3

with this sequence, a Find on tab1.fld1 will bring in a join to tab2, then the join from tab2 to the header will be added, and then the SELECT statement will be complete and valid. init '=' expression This filter can be used to make the program start up with a pre-loaded document set. The standard "nothing" filter is "1=0" which is recognised by the library - no pre-fetch is performed. Any other filterexpression causes the fetch of the nominated records. For example init
= state="NSW"

will cause all records with state="NSW" to preload. This setting can be overridden on the command line using the arguments .... filter string .... returning '=' { field ','... }+

Version 1.0

18 of 36

WacGen III

Used in zoom forms. Nominates the field(s) to be returned from current row of the p_ or q_ arrays when the user presses the Select action. Yes, you can make it return more than one string, but the returning convention is novel so pay close attention if you choose to use it. Also note that a multi-return zoom used in a form cannot perform lookups or after_field blocks of any field except the key field of the zoom call, so there are definite issues. One day I'll figure out how to make multi-return zooms more useful. In the meantime have fun but expect problems. startup '=' { formname ','... }+ Can only be used in the main form. All the forms named by this command will have their startup function invoked from main.4gl soon after the database is opened. This allows you to initialise temporary tables, fetch and store arrays of facts, etc etc etc parent '=' undocumented Not currently used. Intended to relate embedded forms to a parent form. label '=' { ident '=' ( string | expression ) { ',' label-attr } ','... } label-attr = right | blink | reverse | underline | COLOR An old-fashioned way to put programmed labels on the form, yet still worth using. The label must be painted on the form using {L1} syntax (looks like a field but uses curly braces). The string or expression is painted to the label every time the form is cleared - this is to restore the default value. The programmer can change the value using the mlh_label( ) or LB_form( ) functions that are generated. The optional list of attributes may not be usable for GUI mode in Genero. Suck it and see. Not that we approve of programmers writing literal colours in general.

define-section n
Declares a list of fields that will be generated into the q_ record of the nominated input section. Each line is a stand-alone declaration for a list of variables and their type. Do not put a trailing comma, and do not use the "define" keyword on each line. As a bonus, the generator can recognise record and end record lines; it will properly handle the record and its nested fields in the generated code. What's that, Skip? You want an array in the q_ record? Push your luck! MIGHT work!

input-section n
see shared commands: nonull, required, zoom, lookup, action (what else?) table '=' [ unique ] table-name [ alias ] { ',' [ outer ] table-name [ alias ] } The unique and outer keywords, the alias, or more than one table can only be used in zoom forms. This command names the main table for the screen section, and in zoom, the extra bleaching power of the extended command will help you make the SELECT using many tables. Be sure to specify appropriate join and/or filter commands too! key '=' { field ','... }+ dupchk '=' { field ','... }+

Version 1.0

19 of 36

WacGen III

The key command is used to supply both the primary key (needed to fetch records) and the list of fields used in the duplicate checking function (llh_dupcheck or equivalent). However occasionally the primary key field list is NOT the same as the duplicate-checking field list. The dupchk command can be used to override the duplicate-checking field list of an input section. This applies more often to a detail section where the true key is most likely not fully visible to the user ie for a start, it will include the PK of the header, which should not be visible or editable on each line of the detail. Also in details, if the key is based on an autonum or autokey field, you are more likely to want to maintain line uniqueness on other fields such as a userID, product number, etc etc etc. order '=' { column-spec [ desc ] ','... }+ Specifies the sort order applied to the list of rows fetched from the database. Directly copied into the ORDER BY clause of the SELECT. In the great SQL tradition, it is legal to use a number for the column-spec, but good luck picking the right number! You'd have to be insane to try this. TODO: stop digits being acceptable for the order command. filter '=' expression Gives a WHERE-clause fragment that affects the rows selected for the header or detail rows of a form. Limits the possible set of rows that may be found. Examples are
= state = "NSW" filter = mdu_ref = "GL" filter join '=' expression

In the main form, this command specifies the join condition between the header and detail tables. In add-on header forms, the expression from this command is ripped apart to discover the key fields that will be passed in. In zooms where you are selecting from more than one table, this command can be used to neatly express the join condition between those tables. More than one join can be given; they will be concatenated with "and" between them. Be careful to wrap the bits in parentheses if the concatenation would ruin the precedence. arr_max '=' ( dynamic | N ) [ limited ] For array sections only. Sets the maximum size of the array. If you use the dynamic keyword, the array is unbounded, otherwise it is limited to the integer size (default value is 100). if the limited keyword is given, the size of the array is limited to the value rec1_cnt (arr_cnt for secondary forms) which is the current actual count of lines. This is most useful for a dynamic array, but still useful for a fixed-size array. autonum '=' field [ from N ] [ step M ] For array sections only. The nominated field is automatically numbered during data entry and while saving the array to the database. The field should be noentry, because the user will not win. By default the autonum starts at 1 and increments by 1, but you can influence this using the from and step clauses. It is even possible to use negative numbers for N and M. autokey '=' field For array sections only. The autonum command has been in FourGen/WacGen for a long time, but it is unsuitable for use as part of the primary key on a detail array; if a user deletes a row of a detail, all the rows get renumbered, and links to related tables are therefore broken.

Version 1.0

20 of 36

WacGen III

The autokey command was added to address this problem. The autokey field is like a little private serial number for each header record. When the document is loaded, the highest value in the autokey field is recorded. When the user adds a new row to a detail, the stored autokey value is incremented and assigned to the field. Note that from top to bottom, the autokey field may not be in sorted order if a user inserts a row in the middle of pre-numbered rows. Do not expect this column to be sorted or contiguous. It's probably a bad idea to display the autokey field on screen. For each detail row per header row, the allocated number will never be changed or re-used. The only situation where a number might be re-used is if the user deletes the highest numbered rows; the next time the document is loaded, the highest number will therefore be lower than the previous max. This should not be a problem, however, because you're a good little programmer who cascade-deletes related rows, aren't you? You can use both autonum and autokey if you like, but they must of course be on different fields in the detail table - a perfectly acceptable design choice, since ordering a set of rows is a different problem from identifying the row by a key. title - (array only) this is suss for an array - what does it do?

Not sure what the idea was with titles on arrays! overflow '=' identifier parallel '=' archaic and defective version of the overflow command. Replace parallel with the overflow command. For array sections only. Many detail tables have a large number of fields, and it can become impractical to try to paint them all up on the form. Even using an old-fashioned scrollgrid can get ugly really quickly. The overflow command can be used to nominate an extra screen record that will be used to display and edit any matching fields from the p_ and q_ record (ideally the q_ record) that happen to be painted into the screen record named by overflow. As the user rolls up and down the detail array, the contents of the overflow record are repainted with fields from the new current row. Note: I believe there is a weakness in the field traversal when using the new multi-DIALOG feature of Genero 2.10. If you find the field traversal dodgy or annoying, please talk to me and we'll try to improve it. Note: currently there is a defect with the overflow command; the fields of the overflow should probably participate in the CONSTRUCT used by the Find command, but they don't. I'm aware of this problem and will get to it one day; probably sooner if I'm nagged. depend '=' { field1 '=' { fieldN }+ ','... } This nominates fields that "depend" on field1. If field1 is changed, the dependent fields are cleared, and any possible lookups down a chain of depend sets will be fired. Note there is no comma inside the list of FieldNs Whether you know it or not, the concept of a field dependency list is an important part of the generator. Every into and from_into field of a lookup is dependent on the key field of that lookup. If a dependent field is a key field of another lookup/dependency set, then its dependents are recursively dependent on the top key field. [Try not to setup circular chains of dependents; I have no idea what might happen...]

Version 1.0

21 of 36

WacGen III

Normally the automagic dependency lists generated from lookup and math commands is sufficient, but occasionally you want a subservient field to be cleared if a master field is changed, despite the lack of any lookup command relating the two. This is exactly where the depend command can help. For example, you might make a manufacturer code 'depend' on a stock number. If the user changes or clears the stock number, the manufacturer code is cleared so they must select a manufacturer code again. Any dependents due to lookups on the manufacturer code would also be cleared, and so on. nonull '=' { field['*'] ','... }+ when expression Lists fields that the user must enter during data entry or Find. When used in the query section, this applies to normal CONSTRUCT fields and to fields listed in the edits command. hotkey '=' seriously obsolete Before the days of Genero, this command was used to add hotkey actions in forms. It is unusable now. skip '=' { field ','... }+ Lists the fields that should have skip logic generating. Originally, the FourGen code generator would not generate skip logic unless this command was used. The fixes=skip command was added to WacGen several years ago to mean "all fields please". From Authority version 6.0, fixes=skip is enforced, so this command is basically obsolete. TODO: write a skip tutorial, and reference this section to it. event '=' rubbish This command is illegal for Genero 2.10 and above; for non-Genero or Genero less than 2.10 it is blocked :-D math '=' { field '=' expression ','... }+ This command allows you to perform elementary maths between fields. For math between fields in the same record, you can reference other fields. math for a header can also reference an aggregate function of fields in the detail - for example, sum(field), count(field), max(field), min(field) The generated code must detect and handle null values, especially when aggregates are involved, therefore the complexity of the expression is strictly limited. You can try something, but if the generator barfs or generates nonsense, you'll just have to try something different or convince me it's worth fixing. default '=' { field '=' value ','... }+ For many forms, it can be useful to stuff a default value into a field just prior to data entry. Try to pick nice convenient values that are likely to make the user happy. NOTE: lookups, after_field and after_change_in triggers are NOT performed on the fields you supply a default value to. This includes any fields you might programmatically stuff a default value in. Doing this has some serious consequences, and you must perform the lookups and/or change code appropriately. This is a deserving subject for a tutorial since it has often been coded badly in the past. use_q '=' { field ','... }+ This was a special command for Informix RDS generates of programs that used separate browse forms. The idea was to tell the generator that some fields in the browse should be obtained from the main form's q_ record. This command is obsolete for Authority or any project using auto-generated browses. blobdef '=' field ',' "program" ',' ('y' | 'n')

Version 1.0

22 of 36

WacGen III

BYTE and TEXT columns (also known collectively as BLOBs) cannot in general be represented literally on a form. This command causes code to be generated which exploits 4GL's ability to invoke an external program to show and/or edit the data. Back in character mode 4GL, some sort of indicator was painted into the field, and user could press ! to trigger the program. The 'y' or 'n' says whether the user is allowed to change the data and save it back. Codd only knows what happens in Genero: if you are inspired to use this then talk to me; we'll have to hit the manuals and see exactly what's going on. Also, Genero is getting better at rendering novel data within a form, so blobdef may not be necessary for some data. record '=' identifier global '=' identifier The global command is replaced by the record command. In the unlikely event you see it, replace it. The record command can be used to override the name of the p_ q_ and m_ records. In general this is a waste of time, but it is useful to overlay a form's records with the records of the main form.

complex commands
This section lists the commands that are too huge to document above without breaking the flow.

check command
The check command is like a turbo-charged version of the nonull command, excepting it allows you to apply more complex rules for the legal values in a field. Due to it's similarity with the nonull command, its code is normally executed when the user tries to leave a record (i.e. after row, or after input for a record) but this can be overridden whenever necessary. The code generated for check is carefully arranged so that NULL values in any of referenced variables causes the check to silently not fail. If any fields in the expression are required, then you need to use a nonull command; it is not the job of the check command to enforce required fields. Notwithstanding this, if the nullness of any particular field or variable is involved in the success or failure of a check test, it's easy enough to include a test for null. check '=' { check-option ','... }+ Options described below.
immediate

Causes the check condition to fire as soon as the user leaves a field, rather than waiting for the row/record input to be terminated. This is ideal for fields where, for example, you are enforcing a positive number because there is no reason to wait. Don't use this option for any checks that involve some sort of relation between fields, otherwise the user may end up gridlocked by the complaints from the generated code. when=expression This expression supplies a condition that must be true before the check is invoked. If the condition is not true, the check is bypassed. NOTE: this is subtly different from simply including this condition in the rule of the check. Use the when option if there are rules about WHEN to check the quality of a field. This distinction is important because in the future, fields with checks may be coloured or otherwise marked. name=identifier

Version 1.0

23 of 36

WacGen III

Supplies a unique identifier the code generator can use to label code and trigger points. Pick a name that has some meaning for the purpose of the check message=string If the check condition is false, this message is presented to the user. Therefore write the string as if it's complaining about an error. rule=expression The Boolean expression used to decide if the value in a field is invalid. In general, a NULL result from the expression is NOT considered a failure. key=field field=field The name of the field that triggers the check. I originally added the field option, but that's inconsistent with the poorly-named key option from lookup, zoom etc which perform the same duty... So the key option was added for consistency. At this time I don't care which one is used.

lookup command
The lookup command documented here will introduce some unexpected surprises. Be aware that the lookup extensions are a work in progress, so use of multiple keys, multiple filters or joins is at your own risk. Originally I intended the multiples would allow complex multi-table lookups to be performed, but recently an idea has been suggested that the same lookup could search for a value from one or more places until something is found. Therefore there may well be changes in the near future that alter the meaning of multi-field, multi-table, multi-join options. If you feel the need to do a complex lookup, talk to me first. lookup '=' { lookup-option ','... }+ Options described below. optional optional If the lookup fails to find a row, this option makes it ok. No complaint will be issued, and dependent fields will be cleared. rowid optional If no fields are fetched at all, this option makes it fetch the rowid (for a project setup to avoid the use of rowids, this makes it fetch the literal value 1 instead). This is mostly to satisfy the SQL syntax when the only purpose of the lookup is code validation name '=' identifier
required*

*required when more than one table listed, otherwise highly desirable. This provides the default identifier used by the code generator to write unique code. If the lookup only has one table, then the table name is the default identifier. However by long-standing tradition, it's desirable to name the lookup according to the purpose of the lookup rather than the table it accesses. key '=' identifier
1 or more

Nominates the screen field that needs to be edited to trigger the lookup. BEWARE: multiple key lookups are not working properly! I need to think about the technique to solve a few issues. Talk to me if you want to use this. when '=' expression
0 or more

Version 1.0

24 of 36

WacGen III

This expression supplies a condition that must be true before the lookup is invoked. If the condition is not true, the lookup is bypassed. NOTE: failure of the when does NOT cause dependent fields to be cleared. A good way to exploit this is to use two or more similar lookups to fetch from the same key field into the same target fields, selecting the lookup to use based on another field. For example, when=$mdu_ref="GL" will fire this lookup only when it's referring to a row from GL message '=' string
optional

Traditionally, if a lookup fails, a very generic and vague error dialog is popped up. This option will (eventually) be used as a more specific and meaningful error message for lookup failure. event '=' read | edit optional Normally lookups are called when the document is fetched from the database, AND during data entry whenever the user changes the value in the key field. You can make the lookup fire only during document read OR editing by using this option. table '=' table-spec
1 or more

Lookups ultimately translate to a SELECT statement. Sometimes a single-table lookup is not sufficient. WacGen was changed to allow more than one table in the SELECT; you must also supply a join condition to complete the complex SELECT. filter '=' expression 1 or more This option provides the WHERE clause in the generated SELECT. It must introduce a screen field using the $field notation as part of the expression, thereby relating the SELECT back to the value on screen. NOTE: currently, if you give more than one filter, they are merely joined together with the AND keyword. However if the idea of lookups into many places takes off, the meaning of multiple filters may change. join '=' expression
0 or more

If you nominate more than one table in the lookup, you must provide a join between the tables.
0 or more into '=' field from_into '=' column field 0 or more

By default, the lookup will fetch a value from every column of the lookup table that also appears on the main form - the match is based on table.colname. If you do not like the default choice of fetched fields, you can nominate the target fields with the into option (matching is my field name only) or the from_into option if you wish to fetch from a column into a field with a different name. Once you start naming the columns being fetched, the default field list is NOT generated. order '=' order-spec
0 or more

The final SELECT built for a lookup does not have to yield a single unique row. If more than one row would be satisfied by the lookup, only the first row fetched is used. You can use the order option to influence which "first" row pops out. NOTE: since the order list needs to use a comma-separated list of fields, it will consume all remaining commas on the line. Therefore the order option must be the last option of the lookup.

Version 1.0

25 of 36

WacGen III

zoom command
The zoom command documented here will introduce some unexpected surprises. Be aware that the zoom extensions are a work in progress, so use multiple keys, multiple filters or joins at your own risk. There are also some serious issues with the use of multiple keys, so do not rush in without talking to me first. zoom '=' { zoom-option ','... }+ Options described below. key '=' field
1 or more

Nominates the screen field that the zoom is attached to. BEWARE: multiple keys are very experimental, may go horribly wrong, and may change in the near future as I tinker with this. named '=' identifier
optional

Normally the generator uses the key field name to help it generate unique identifiers in the .org code. However for zooms with multiple keys, or if you are putting more than one zoom on the same key field, you must help the generator distinguish the zoom code by providing a unique name. screen '=' identifier required Names the zoom screen to call. Normally the generator can inject this form into the switchbox() function of main.org, but if you are adding a unique zoom to a secondary form, you may have to use the switchbox command in the main .dsp file to assist the generator. noautozoom optional table '=' table-spec from '=' identifier
optional optional

WARNING: There is universal misunderstanding of these three options. A proper explanation of autozoom and the use of these options is provided after all the zoom options are described. The noautonum command blocks the generation of autozoom code. Otherwise the autozoom code usually needs assistance by telling it the name of the target table and column through the use of the table and from options. If you do not supply the table or from options, the generator guesses these values from the name of the key field; and the guess is usually wrong. filter '=' expression 0 or more When a zoom starts up, it can either go into query mode, present its own list of default select, or be provided with a select condition to pre-fill the list. If this option is provided, the zoom will use it to preselect rows. If a filter expression 1=1 is used, that's effectively like telling the zoom to fetch every possible row. Note: this depends on the zoom also having an init=expr command - i.e. a request to pre-fill rather than go into query mode. The filter is ignored/overridden if the autozoom capability is triggered. Also, be aware that the filter passed in is NOT persistent. It may trigger a prefetch of a limited set of rows, but if the user chooses to query again in the zoom, this filter is lost and won't be applied. If you want to pass in a persistent filter, see the hfilter option. hfilter '=' expression optional Although the called zoom can contain a filter on the rows it will find (eg filter=mdu_ref = "GL") you may want to pass in a fixed, persistent limiting filter to restrict the set of rows that can be found. The hfilter option is a "hard filter" that always applies inside the called zoom. The user cannot override the hfilter or the zoom's built-in filter by any means. Do not confuse the filter and hfilter options; the filter option is a suggested pre-fetch, the hfilter is a limit on the legal set of found rows.

Version 1.0

26 of 36

WacGen III

join '=' expression - NOT YET! 0 or more Something about relating tables if multiple tables ever get a leg-up when '=' expression
0 or more

This expression supplies a condition that must be true before the zoom is invoked. If the condition is not true, the zoom is bypassed. A good way to exploit this is to use two or more similar zooms on the same key field, selecting the zoom to use based on another field. For example, when=$mdu_ref="GL" will fire this zoom only when it's referring to a row from GL message '=' string
optional

Geez, a message on a zoom? What was I thinking? mtitle mprogram eprogram mfilter efilter moptions eoptions
'=' '=' '=' '=' '=' '=' '=' optional string identifier [ '('identifier')' ] optional identifier [ '('identifier')' ] optional 0 or more expression 0 or more expression 0 or more expression 0 or more expression

These options can be used to override the zoom maintenance settings written into zooms. Please read the section on zoom maintenance for details.

autozoom
blah blah blah

zoom maintenance
blah blah blah

Variables in globals.org
progid char(17), # scr_id char(7), # ringMenu record # ident integer, # current integer, # total integer # end record, zoom_maint record title char(60), mod, enq record program char(20), secure char(20), filter char(2047), options char(2047) end record end record, menu_item char(32), # scr_funct char(20), # sql_filter char(2047), # hard_filter char(2047), # sql_order char(200), # this_dia ui.dialog, # exit_level smallint, # Program identification Current screen id ringMenu list and position current document PK current position total documents

Current menu item running Current screen function being run Filter portion of SQL statement Hard filter passed to zoom screens Order portion of SQL statement references current dialog object 0=input, 1=row, 2=field

Version 1.0

27 of 36

WacGen III

input_num smallint, # progid char(17), # scr_id char(7), # ringMenu record # ident integer, # current integer, # total integer # end record, zoom_maint record title char(60), mod, enq record program char(20), secure char(20), filter char(2047), options char(2047) end record end record, menu_item char(32), # scr_funct char(20), # sql_filter char(2047), # hard_filter char(2047), # sql_order char(200), # this_dia ui.dialog, # exit_level smallint, # input_num smallint, #

Current input section within screen Program identification Current screen id ringMenu list and position current document PK current position total documents

Current menu item running Current screen function being run Filter portion of SQL statement Hard filter passed to zoom screens Order portion of SQL statement references current dialog object 0=input, 1=row, 2=field Current input section within screen

shared commands
action = { identifier ,... }+ adds an ON ACTION command to the CONSTRUCT or INPUT which is available during Find. Use an on_event trigger to inject the code. nonull = { identifier ,... }+

Tips and techniques


Programmatically display or hide screen fields
call dom_set_hidden(dom_find_fields("fieldname"), true | false) call dom_set_hidden(dom_find_fields("labelname"), true | false) fieldname = name of the field, e.g. gis_zne labelname = text of the corresponding label for this field, in the specified case, e.g. Zone true = hide the field/label false = show the field/label

If the properties of a field are dependent on the value in another field, execute call_dom_set_hidden() at the following trigger points:

Version 1.0

28 of 36

WacGen III

1. after_change_in dependent fieldname 2. before block llh_display For example: custom.src function to show or hide the field and its corresponding label
###################################################################### function set_field_properties() ###################################################################### case $gis_pro when "NZGD2000" call dom_set_hidden(dom_find_fields("gis_zne"), true) call dom_set_hidden(dom_find_labels("Zone"), true) otherwise call dom_set_hidden(dom_find_fields("gis_zne"), false) call dom_set_hidden(dom_find_labels("Zone"), false) end case end function #set_field_properties()

.trg call the function in the after_change_in trigger for the dependent field; this ensures whenever the operator changes the field value, the show/hide effect occurs immediately.
after_change_in gis_pro call set_field_properties() end

standard.ext1 inject a call to the function before the ll*_display block to ensure the show/hide effect is immediately apparent on existing records that are retrieved into the form: ######################################## start file "header.4gl" ######################################## before block llh_display display call set_field_properties() end

what else???
possible tutorial subjects
use of $ & and @ in various commands using and abusing zoom calls using and abusing lookups and math

If you are creating a new standard.ext file for this purpose, ensure a reference to this file is added to the base.set file.

Version 1.0

29 of 36

WacGen III

to q_ or not to q_? What for the globals? duplicate checking constraint checking required field management noentry management array management more power, less code in zoom forms zoom maintenance concepts and use multi-details wizards improving layouts overflow records calling addons, getting status and values back YOUR IDEAS FOR SUBJECTS!

Version 1.0

30 of 36

WacGen III

__END__

author's reference junk follows shared commands using = { "filename" ,... }+ list of files to include into midlevel. NOTE: 4GL include files have .4gh if they are hand-written, or from the generator the extension is .inc. The generator can be asked to create a .inc file for a form with the options = typedef command (in the defaults section). This makes the generator emit typedefs of the p_ and q_ records into a .inc file, and it also uses those typedefs in the generated .org file. zoom lookup depend xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

Screen screen [size <lines> [by <columns>]] { image layout }

The image layout can contain plain text, fields delimited by [ ] and | labels {L1 }

or lines drawn with + - and | characters. The lines will be replaced with graphicalised characters using the old \g and \b \d \p \q NOTE: not sure this graphical line conversion happens for Genero builds; must check

Labels wrapped in { } were used to define things that could be used to put different text up on the screen. Before Genero, the DISPLAY AT command in 4GL was used to overwrite the labels in that position via some generated functions.

Version 1.0

31 of 36

WacGen III

They are now implemented differently in Genero TODO: explain the Genero version of labels. action = name=Ident, hotkey=String, title=String, message=String query event === view event === event = Ident=String [, filter=Expr ] # view event DISABLED # OBSOLETE - but the filter might be interesting

---------------------------------------------------------------------menu include = Ident_list menu exclude = Ident_list query include = Ident_list query exclude = Ident_list query required = Ident_list function include = Ident_list function exclude = Ident_list

query screen = Ident # patches in a different screen to be used for the query use_q = Ident_list # forces browse to reference listed variables from q_ record # obsolete

arr_max = N attributes = Ident_list autokey = Ident autonum = Ident [=Expr] blobdef = Ident, String, /[YN]/i label = {+ Ident= (String | Expr) {+ /right|reverse|blink|underline|black|blue|cyan|green|magenta|red|white|yellow/i }, }, default = { /before|after|null/i Ident=Expr }, menu title = String

Version 1.0

32 of 36

WacGen III

menu type === menu style = [obsolete,] Ident # menu type is obsolete title = String # if in defaults section title = { Ident=String }, # if in array section query depend === depend = { Ident Ident }, init = Expr primary = Ident_list key = order_clause location = y, x module = Ident scr_id = Ident parent = Ident global === record = Ident # global is obsolete parallel = Ident nonull === required = Ident_list order = order_list # literal rubbish also stored returning = { Ident }, skip = {+ Ident }, table = Ident [ Ident ] type = ScreenType sockets = {+ ScreenType },

Version 1.0

33 of 36

WacGen III

startup = {+ Ident }, switchbox = {+ Ident Ident }, filter = Expr extra = Ident=Expr join = Expr # literal rubbish also stored check = name=Ident, message=String, rule=Expr, key|field=Ident query lookup === lookup = rowid, name=Ident, key=Ident, table=lookup_table, filter=Expr, join=Expr, into=ColSpec, from_into=ColSpec ColSpec, order=order_sequence math = {+ Ident=Expr }, query zoom === zoom = key=Ident, screen=Ident, table=lookup_table, filter=Expr, join=Expr, hfilter=Expr, from=Ident, message=String, noautozoom

Version 1.0

34 of 36

Potrebbero piacerti anche