VRAD: VERY RAPID APPLICATION DEVELOPMENT IN FORMS 5.0
Dr. Paul Dorsey
Dulcian, Inc.
Peter Koletzke
A & Z Software Co., Inc.
Introduction
When building applications in GUI or character mode, much of the work is repetitive. Major portions of each application are similar to many other applications. There has to be a way to re-use all that work. Very Rapid Application Development (VRAD) is possible with Developer/2000 Forms through the use of a template. A template form enables developers to generate simple applications in minutes and complex applications in a fraction of the time normally required.
The benefits of using a template are numerous. The most obvious are the immediate productivity gains from using a template. However, just as important are the benefits that arise from enforcement of standards throughout your applications. Not only do you automatically get similarity in the visual look and feel of your applications; but you also get similarity in the coding practices. Most of the major triggers are already written, and need only be modified by individual developers.
Another benefit is that the creation of the template forces you to seriously think through the process of GUI standards. There is no way to create the template without going through the process of making decisions about the look and feel of each kind of application and how those application types will interact. We have never had the experience where a company actually thought through their GUI standards to the level necessary to enforce standards without developing a template.
Next, there is a real benefit to the novice developer. Many developers are not comfortable with the amount of latitude that GUI development gives them. They find themselves lost in a daunting list of possible triggers and options. The skilled C++ programmer fights the tool trying to force it to act exactly like their favorite C++ program. Less skilled developers and kids fresh out of college take weeks to build simple forms. With a Template present, novice developers can build simple forms almost as quickly as experienced developers. This frees up the experienced developers to work on the key applications.
Finally, working with a template is fun. Rather than drudging through hours of tedium when building an application, the developer gets to concentrate his/her time on the interesting parts of the application because the hours of tedious work are reduced to minutes. It is much more fun to build applications when you don’t have to spend hours doing work that you are sure a trained monkey could do just as well.
Levels of Template Development
Our thinking with respect to templates has evolved over the last few years. The current templates and object reuse capabilities that we are not taking advantage of are qualitatively different from our early templates. Our templates are now in their third generation. All three levels of templates that we have developed are all still in use although each has become more sophisticated over time. Each one builds on the previous level of template. Most applications are now using templates when developing forms. However, most are still using templates that in this taxonomy would be classified as Level 1 templates. Although all three levels of templating are possible with Forms 4.5, Forms in Developer/2000 2.0 will make it even easier to achieve 2nd and 3rd level templating.
In this section we will discuss the three levels of template development and the architecture associated with each one:
Level I - Basic template:
Level 1 templating is where a single template is used for every form. The template contains referenced objects to support GUI standards, example objects and code, and attached libraries. The idea is to provide a starting point for developers that makes development more efficient and helps to encourage consistent application of GUI, coding and development standards. Such templates can be extraordinarily rich and complex but often suffer from being too generic. Because they must support many different kinds of applications, they cannot support any particularly well.
Level II - Specific templates for specific types of applications:
Not all modules are the same. Having only one underlying template frequently includes many unnecessary elements that are not customized for each module. For Level 2 template development, you must identify different kinds of applications and modify the base template so that it will particularly support only that type of application. The idea in Level 2 templating is that the base template is used for core and/or unique form modules; but for recurring modules, there is a specialized template for development of these modules Once complete, these specific template types then become base templates for specific applications. Although time consuming, doing development in this way has an incredibly fast payback in all future system development.
Level III: Creating generic building blocks:
Level 3 templating came from a desire to support the building of highly complex core applications that invariably take up much of a project’s development time. Core forms are usually complex and have little in common with other applications. However, such core applications do share common elements.
The idea behind level 3 templating is to identify these common elements and create generic objects so that developers can rapidly bring that functionality into the form being built. But all of these objects are not necessarily used in every form. They act as building blocks for the developer to assemble the components necessary to create a complex application. For example, tab controls, multi-select LOVs and special functions to support high-volume data entry applications are the kinds of objects that are good candidates for a level 3 template. The objects in a level 3 template are used in conjunction with either the general level 1 template or a specific level 2 template to facilitate complex form development.
These reusable objects can be used to assemble major components of very complex applications with incredible ease.
Discussion and examples of each Level of template follow.
SECTION 1
Level I Template Architecture
The basic template is a partially built application that developers can modify for each application they build. It is built to take full advantage of Forms’ object oriented techniques. This template contains many generically written programs that can be accessed as needed by applications. It is only by using such a template that developers can get the full benefit of Forms.
Of course, building a complex set of templates for a major application is not a week-long task. We had one client where we spent an afternoon with a group of developers deciding on screen and field colors.
To explain the concepts involved with VRAD using templates, we will use an example template system we have developed and which is available from the web site mentioned at the end of the paper. You can download and use these forms without charge as a basis for your own template work.
Underlying Architecture
The template system consists of a number of files that must be available to developers when creating a new application. The following is a quick look at the files used in the template system.
1. REFER.FMB A file called REFER.FMB, contains all of the property classes (referenced objects), visual attributes, and the default toolbar. This allows skilled developers to create objects in this file and attach the proper code and special properties. Starting-level developers can take advantage of these objects without having to worry about the internal details. These developers would not be given access rights to modify the REFER objects.
The REFER objects are referenced into the template form. Objects are referenced in Forms by opening the source and the target form at the same time in Forms Designer. Then the objects from the source are dragged into the target form with a specification that they be referenced, not copied. The copy option simply copies the object from one place to the other. Referencing means that you have to open REFER to make changes in the objects or create new ones.
2. TEMPLATE.FMB
When a base application is used, as the developer opens the template and saves with a new file name, the developer can then make modifications and add application-specific elements like data blocks and code. This will be discussed more a bit later.
3. OBJLIB.FMB for Level 3 template support
This file contains features you might want to regularly include in your forms, but do not always include in all forms. Possible features in this category are: tabbed canvas windows implemented with Forms objects, sticky notes, a calendar object for entering dates, etc. The method you use for incorporating these into the form is to copy (not reference) the object from this form into the target working form.
4. TMPLLIB.PLL
This is the Forms PL/SQL library that is attached to the TEMPLATE.FMB file and that provides all code for the default template functionality as well as generic procedures you can use in your application.
5. TMPLMENU.MMB
There is a default menu file attached to the template form that provides features included in the template. You can make changes in this file for your application or copy it and attach the new version to the forms on a one-by-one basis.
6. Other Files
There are icon files for the toolbar buttons that must be available when the form runs. These are included with the template system. In addition, a sample HELPABT.FMB file gives general information about the form that you supply when you first create it. This form is called from the Help About menu item to parallel the functionality of many Windows programs.
Figure 1 summarizes the relationship of the TEMPLATE file to the other main Forms files in the template system.
Figure 1. Template System Forms Files
Using the Template
As already mentioned, the template is really a set of Forms modules. One Form (REFER.FMB) stores your property classes and unchangeable referenced objects. A second application (TEMPLATE.FMB) has all objects from REFER.FMB referenced in it as well as additional triggers and objects that will need to be modified for each application. The third (OBJLIB) has objects you can copy if needed for a specific form.
Applications are built by opening up TEMPLATE.FMB, renaming it and modifying it to be the new application. All referenced objects are stored in REFER.FMB so any changes made there will propagate through all Forms applications the next time they are generated.
The use of the template is based upon the following model:
1. The organization decides on their GUI standards and basic look and feel of various application types.
2. Lead developers create the template.
3. Junior and senior developers alike can effectively use the template. The idea is that developers start with the development template and simply add functionality to create their own applications. Because the code for most common features is already in the template, applications can be brought to production in record time.
Building the Template System
Two major parts of the template system that you need to carefully consider when building it are property classes and PL/SQL code. We will describe some issues involved with each in context of the sample forms.
Property Classes
Property classes should be replaced with subclassed objects when Developer/2000 2.0 is released. However, the principles of their use remain the same. Since Developer/2000 2.0’s interface design was still being finalized as of the writing of this paper, the discussion will refer to property classes.
A property class is a group of pre-defined attributes. Each property class can be assigned to any object within a form. For example, a property class can be assigned to a text box, a table, a radio button, etc. Actually, each property class is an object itself.
In order to understand how to get the property class to manipulate objects properly, it is necessary to understand each attribute. Instead of boring you with a full description of each one, there is a much easier approach. But first, it is necessary to explain how to create the property class.
The easiest way to create a property class is to define an object (like a text item) and assign appropriate property values to it. Then click on the property class button from the toolbar on the top of the property sheet (the fifth button over from the left). This will create a property class with all the properties and attributes you just defined for the item. You can then open the properties for that property class and delete or modify it as needed.
Another even faster way to create a property class is just to copy another property class from within the Object Navigator. Just select the property class you want to copy by clicking on it in Object Navigator. After this, just press CTRL-D and this will provide you with a copy of the original property class. Almost any object in Forms 4.5 can be duplicated by this procedure. Its list of attributes can be obtained by double-clicking on the icon to the left of the property class name. In, order to get a description of each attribute, click on the attribute in question and press the F1 key and a description will appear in the help window.
Once the basic aspects of property classes are understood, the hierarchical structure can be explained. You can base a property class on another property class, which will give you multiple levels of inheritance. You could create, for example, a property class called TEXT_FIELD that has properties for all text items in the form. This might have a default height, font name, font size and color. You could then define a property class called TEXT_FIELD_DATE that has properties of a format mask and class name of TEXT_FIELD. This property class would inherit all TEXT_FIELD properties (font, color) and additionally have the format mask property. The next step in the hierarchy might include different property classes for various date formats: one for month-date-year and another for just month-year, etc.
Each higher level property class is dependent upon all of the ones below it. Therefore, if we change TEXT_FIELD, the rest of the property classes connected to it will all take the changes. If we change TEXT_FIELD_DATE, all property classes depending upon it will be altered; but TEXT_FIELD will remain untouched.
An item’s individual properties and property class creation both use the same screen, meaning that the screen that comes up from the right click menu labeled properties is identical to the properties screen that comes from the Object Navigator.
Property classes are extremely useful because they save time; and in the real world time is money. Instead of setting the same exact attributes twenty different times, a property class can be created once and the user can reference its pre-defined group of attributes as many times as deemed necessary.
We reference other property classes by defining them in the class property, which is the second level down from the top. As with defining any attribute, if there is more than one option to choose from, the text area beneath the toolbar will become a popbox that lists all options pertaining to that one specific attribute. So, when we want to assign a pre-existing property class, we click on the class category and then click on the down arrow button on the right side of the property indicator located beneath the toolbar and scroll down to find the property class that we need.
Suggested Template Property Classes v. 4.5 or Referenced Objects v. 5.0
Another paper in this volume discusses the differences between property classes in v.4.5 and the new object library SmartClasses in v.5.0. Please refer to that paper, "Oracle Forms 5.0 Templates and Object Libraries - Now That We Have Them, What Do We Do With Them?" form more information. Here, we suggest a variety of property classes for the template. They include the following:
These provide a list of possible choices to be entered into a table. This helps prevent errors due to misspellings, typos or differing versions of the same word (i.e. NY, NYC or New York City)
This is a scrollable field for entering comments, which is 20 characters wide by 3 lines. We suggest a maximum of 1000 characters. The user can modify the width and thickness of this field.
NUM DISP DISP: This is a field for displaying numbers. It is like a label. It is a static display object only and it cannot be manipulated.
TXT DISP DISP: This is a field for displaying text only.
These objects are queryable but no user insertions or updates may be made.
NUM DISP TXT - for numbers
TXT DISP TXT - for text
There are many available fields for entering money values.
The Checkbox property class contains the standard size, checked and unchecked values.
If there is a need to handle a label programmatically, use textlabel property class to modify the label.
Enterable date field.
Note: Be careful of property classes on stacked canvases. There is an intermittent bug in older versions of Forms which prevents the user from adding boilerplate text.
Height and width for 800x600 screen sizing.
Property class for height and width of main window.
Standard size text button for labels.
Iconic button.
PL/SQL Code in the Template
Other than property classes, the most important decisions and objects in the form are the PL/SQL program units. This section explains the use of PL/SQL code in our sample template and the strategies used to implement it. Understanding this will allow you to plan your own template system code or modify the sample.
Strategy
All objects in the template (whether created in TEMPLATE or referenced from REFER) are supported by PL/SQL code in the TMPLLIB.PLL library file. This library is a rich collection of PL/SQL packages arranged by object. The strategy for the organization and placement of this code is based on the following guidelines:
Menu Code
All items in the menu have PL/SQL code that calls code in the underlying form. All items are in one of the following types:
Toolbar Code
The toolbar buttons are referenced from REFER as the TOOLBAR block. You may add to the buttons, but don’t remove them in case they are needed in the future. If there is a button you do not need, add the code in WHEN-NEW-FORM-INSTANCE to hide it
¾fp_item.hide(‘BLOCK.ITEM’)
There is one WHEN-BUTTON-PRESSED trigger on the TOOLBAR block level that calls a procedure in the local TOOLBAR Program Unit package to handle all buttons in the block according to the following rules.
Triggers in the Template
The triggers in the template are divided into three levels: form, block, and property class.
The form-level triggers are those you may wish to customize for your form such as WHEN-NEW-FORM-INSTANCE, WHEN-NEW-BLOCK-INSTANCE, WHEN-TIMER-EXPIRED, and WHEN-VALIDATE-RECORD. They all call procedures in local PL/SQL packages so you may also change the code that they call. Since these triggers are local to the template, any changes you make to one form will not be reflected in any other form. Thus it is important to plan what additional functions these triggers will perform early in the development process.
The block-level triggers are attached to the TOOLBAR block and manage activities on the buttons. There are no item-level triggers for these buttons so the block-level triggers provide all of the functions needed. These triggers implement the bubble (micro-help) text on the buttons and the WHEN-BUTTON-PRESSED event discussed in the Toolbar Code section above. The source of these triggers is the REFER form as the toolbar block is referenced in TEMPLATE, so any changes needed should be done in REFER. All forms, when regenerated, will automatically pick up the new functionality.
The property class-level triggers are mainly KEY- and user-defined triggers for the form-level. There is a property class called FORMS_TRIGGERS that is referenced from REFER into the template form module. This property class has KEY- triggers that the menu or toolbar will call in addition to user-defined triggers for those events that are not KEY- events like SHOW_HIDE_TOOLBAR, TB_BACK, etc. There are also triggers for the ON-ERROR and ON-MESSAGE events. All triggers in this property class call procedures in the following packages:
Global Variable Use
Global variables are avoided as they lack sufficient length, and, in some cases, require creation and destruction and need cross-checking for existence. Also, there is no spelling or syntax check for global variables. For example, by mistake, you could use :global.block_name in one trigger and misspell it as :global.blockname in another. You would not get any compile errors and debugging this mistake at runtime would be difficult. Package variables solve all of these drawbacks.
Since package variables are not available outside the scope of the form that is running, you need to use other methods to pass values to another form. Use parameter lists to pass values to another form that you call with call_form, new_form or open_form. Use global variables only if the value that you pass from one form to another is modified by the second form and used again by the first form. If you do use global variables, be sure to track when they are created and destroyed and make use of the default_value Forms built-in to assist.
Code to Modify
The code in the template system is contained either in the library or the template form itself. The code in the library is generic and should not be modified unless there is some behavior you wish to change in all forms in your application. The form is designed around the idea of ease of use for developers, so there are very few packages that need or can be modified in order to customize a form.
When you use the template to create a new form, you need to carefully review the local code in the template, specifically in the STARTUP package and modify it for the blocks and canvases you will create. All codes in this package have samples and comments to explain their use. The following are the packages and procedures to modify:
1. STARTUP Package - Modification Required
The STARTUP package contains a procedure called initialize_form that provides the global package variable assignments. Read the comments for each and assign the values based on your form. The top section of this procedure is the most important; the bottom section contains settings that you can modify but do not need to modify if you are not changing the template form objects.
There is also a procedure called populate_forms_screen. This initializes the values seen on the screen when you start the form or issue a do_key(‘clear_form’) from the menu or button. This procedure should be customized to the form and also has comments on its use.
The last procedure to look at in the STARTUP package is the setup_objects procedure. This customizes the toolbar and initializes the objects in the template. You would modify or enhance this if you had list items to populate from queries or buttons to hide. There are samples of these in the procedure’s comments.
2. TOOLBAR Package - Modification Optional
This package contains all the code that is called from the toolbar buttons, key triggers and menu items. Since this is local to the form, you may change the procedures to do different things or supplement them with other procedures for additional buttons or menu items. There is one procedure for each key-press/menu item/button call.
3. UTIL Package - Modification Optional
This supports form-level triggers that are local to the form. The triggers call this code which you may modify or supplement to do application-specific functions. There is one procedure for each trigger. For example, there is an on_error procedure that is called by the ON-ERROR trigger. This captures the message that Forms gives when an error occurs and shows an alert with the message. You may wish to trap specific error numbers and give a message other than the default Forms message by adding code to this procedure.
Another example of a modification would be if you created another timer programmatically and wanted to place it in the WHEN-TIMER-EXPIRED trigger on the form level. This trigger calls a timer_expired procedure in this package that you may change or supplement.
Notes on Adding Code
Whenever forms built-ins are used, the do_key() form of that built-in should be called if available. Therefore, when issuing a call to ENTER_QUERY, the code uses a do_key(‘enter_query’) instead so that the key triggers will fire and send the control into the corresponding procedure.
In regards to PL/SQL code formatting in the template, all SQL and PL/SQL structure keywords are in upper case and all variable parameter, forms built-in, cursor, table and column names are in lower case. The comment style is /* */ for the header comments on each procedure and -- comments to explain the sections within the code. It is good to maintain one code format style to make the code easier to read.
If you add triggers on a lower level than triggers in the template form (form, toolbar block or property class-levels), be sure to set the trigger
property Execution Style to Before, After or Override based on whether you want your trigger to fire before, after or instead of the trigger in the template that is on the higher level, respectively.
Remember that there are form-level triggers attached to the property class on the form module that are not visible in the Object Navigator Form node. These may be viewed in the property class node under the property class FORMS_TRIGGERS. If you need to add to the code in these triggers, refer to the corresponding Program Unit in the REFER form.
SECTION 2
Level II Template Development
The previous discussion in Section 1 explained how templates are constructed and architected in a Level 1 "simple template" environment. Level 2 uses all the same components and strategies as Level 1 with its multiple files and code, but adds the idea of specific templates for specific purposes. Each of these templates will be a stripped-down version of the full Level 1 template.
Three common types of modules will be discussed here: Navigation, Administration and Locator. Depending upon your GUI standards, you may or may not find these appropriate but the basic idea of specific templates for specific applications remains the same. Included with each template is a set of instructions on how to develop using the template. These instructions include information such as what triggers need to be modified, what properties or which objects need to be filled in and how to safely add or remove form elements.
A) Navigation template: A navigator module is a top-level form used to navigate to other applications. If the application is very large, the navigator might involve several canvases including top-level and subordinate canvases for each interest area. In my experience, I have never needed more than two levels of screens for navigation.
The navigation template is constructed with a very light PL/SQL Library. All this navigator form is doing is calling other forms. In addition to including property classes, this template is really a fully built navigation application. All the developer has to do is change the labels on the buttons, enter the names and paths of forms that are called and perhaps duplicate or delete a few buttons to correspond to the exact application.
Having a partially built application greatly minimizes the amount of time needed to build a full application. Normally, a skilled developer would bring up an existing similar application and modify it. For the skilled developer, having a generic template will not significantly improve development speed. The novice developer may have difficulty knowing what to change in an existing application. For this novice developer, the template will increase development speed and efficiency tremendously.
B) Administration template: The administration module supports the code description tables. Usually, 20-30% of all tables in a given system are code description tables. There are many ways to build the modules to support these tables. Traditionally, a developer will build one block for each code description table. However, if code description tables are implemented as one large, single table, then a single block can support many different vertical tables merely by altering the default WHERE clause of the block at runtime. If these tables are stored separately, the only way they can be supported through a single block is through the creation of a dynamic view. Of course, if the developer chooses, there can be one block for each table. I believe that this one block for each table approach provides the nicest user interface.
The administration application can be built using tabs. Each tab holds 2-4 administration tables. To speed performance, blocks are only queried when their respective tabs are selected. To create the administration template, start with a very simple base template. Then, a generic object group is created which includes canvases and items for the standard structure for the code description table. Many systems have a few different types of code description tables, for example with/without active flag or history information. Therefore, you may need a few different object groups. The object group includes its own stacked canvas.
To then build the administration application, drag in copies of the appropriate object group from an object library (implemented as a form in Forms 4.5 or in an object library in Forms 5.0). Assuming you are using good column naming conventions, all that remains to be done is to change boilerplate text, canvas position and the name of the base table block.
C) Locator template: A locator application stemmed from the need for greater querying capability than was available through Oracle’s query mode for locating a particular record. For example, to identify a particular employee, all we know is that he works in one of two states, in one of two departments, was hired in the last three years and whose last name starts with "SM." To support those types of user requests, we built a locator application. On various tabs, the user can select different types of filters. On the final tab, the user can see what records their query retrieved. Users are able to name and save their queries for future retrieval. In addition, by adding criteria for sorts and breaks, also use this type of application to support a flexible reporting system that we include with all of the systems we develop.
The first time we built this type of module, it required several months of developer time. We decided to genericize the triggers and create appropriate object groups similar to those in the Administration template. A complete discussion of this template can be found in Joseph P. Strano’s paper on Flexible Reporting Systems in these conference proceedings.
SECTION 3
Level III Template Development
With Level I templates, we have a foundation for eliminating the repetitive work that is common to the development of all modules. With Level II templates for specific types of modules, we can build specific applications in a small fraction of the time normally required. Where is the bulk of time in application development really spent? It is spent on the key applications. These highly complex applications often don’t fall into any specific category. However, you will find that complex applications tend to use the same techniques and components. Level III templates provide the building blocks to assemble major components of complex applications.
Examples include tab controls and multi-select LOVs. Tab controls can be implemented by drawing lines in the shape of tabs, adding display objects and associated triggers to control stacked canvases. If you place all of the tab objects on a small stacked canvas, they can be grouped together in an object group and easily copied into a form. Multi-LOVs are more difficult to support.
Both traditional LOVs and pop-lists suffer from the limitations that a user can only select a single item. Many applications exist where multiple selection is necessary. Forms does not supply a multi-select LOV. However, such a structure can be built. This is actually a relatively interesting application. A detailed explanation of how the multi-LOV is created along with some of the code follows:
Currently, with Forms, the only way to support a multi LOV is through a substantial amount of coding. However, it is possible using Forms to build this object in such a way that developers can take advantage of this powerful feature while only writing a small amount of code. The trick is to think through the process of the multi-select LOV, write the code and build the appropriate objects so that this feature can be created very quickly. The multi-select LOV is comprised of an object group and a library. Therefore, to use a multi-select LOV, you have to bring in the object group and attach the library. The object group is composed of a canvas, two blocks and several iconic buttons with their associated triggers.
The library contains two packages:
From the developer’s perspective, after bringing the appropriate objects into the application, what they have done is effectively extend Forms to support multi-LOVs using only two lines of code. To create the multi-LOV, the develo
per need only write a single line of code: MLOV.CREATE.
It takes as parameters a two-column record group and the name of the LOV. Wherever the multi-
LOV is supposed to appear, call MLOV.INVOKE, passing it merely the name of the LOV, the return field and the X and Y coordinates of the LOV, and the return value is a comma delimited list of values. As of this writing, we would have liked to make the return value a PL/SQL table, but that functionality was not yet implemented in the product.
Behind the scenes, the multi-LOV populates a record group and then populates a generic multi-LOV block with the data. When users are selecting items on the block, the multi-LOV simultaneously keeps track of the selected records in the record group. Then, when the user clicks on the OK button, the record group is scanned and the selected records are extracted. There is quite a lot of planning, code and several days of development time required to build this structure but its usefulness in many applications will quickly offset the investment in development effort. To list the entire system documentation for the multi-LOV is beyond the scope of this paper. However, the following is an example of the code behind the invoke procedure.
Invoke
Display the Multi LOV dialog box.
--If the user wants to execute code when
--this is finished, store the trigger
--name they want to fire in the global
--variable.
Multi_Lov_Lib.Name_Triggerx :=
Par_Trigger_Name;
--Store system information into global
--variables
execute_trigger('Multi_LOV');
-- Set up the Record Group, Return Item,
-- and destination globals.
multi_lov_lib.lov_name := par_rg_name;
multi_lov.name_of_item := Multi_Lov_Lib.Item_Cursor;
--so we will know where to send the
--cursor back to
multi_lov.drop_out := par_out_drop;
--where to send the final list
--If the user wants to recreate the record group, then delete the old group and re-create it.
IF par_recreate_group = 'Y'
THEN
my_group_counter :=
Get_Group_Row_Count('my_group');
FOR i IN 1 .. my_group_counter
LOOP
var_rg_name :=
Get_Group_Char_Cell('
my_group.col1',i);
IF var_rg_name = par_rg_name
THEN
var_query :=
Get_Group_Char_Cell(
'my_group.col2',i);
END IF;
END LOOP;
Delete_Group( par_rg_name );
multi_lov_lib.CREATE_RG (
par_rg_name,var_query );
END IF;
--Get the datatype of the columns
Col_name := Get_Group_Char_Cell( par_rg_name||'A.col1', 1 );
data_type := Get_Group_Char_Cell(
par_rg_name||'A.col2', 1 );
Gc_id := Find_Column(
par_rg_name||'.'||col_name );
--Show the Multi LOV window
Show_Window('MULTI_LOV',
par_x_pos,par_y_pos);
go_block('multi_lov');
--Use the proper Get Group Cell function
--for the datatype. Covert the
value to
--character and place it in our Multi LOV
--block.
clear_block;
the_rowcount := Get_Group_Row_Count(
par_rg_name);
FOR i IN 1 .. the_rowcount
LOOP
multi_lov_lib.DOUBLE_CLICK
(par_rg_name);
IF data_type = 'NUMBER'
THEN
temp := Get_Group_Number_Cell(
par_rg_name||'.'||col_name,I);
copy(to_char(temp),'value_item');
ELSIF data_type IN ('VARCHAR2',
'CHAR')
THEN
copy(Get_Group_Char_Cell(
par_rg_name||'.'||
col_name,I),'value_item');
ELSE
copy(To_Char(Get_Group_Date_Cell(
par_rg_name||'.'||col_name,
I)),'value_item');
END IF;
IF i <> the_rowcount
THEN
Next_Record;
END IF;
END LOOP;
One of the problems with the "Invoke Multi-LOV" package is that the code following the invoke function would be executed immediately because all that "invoke" does is make the multi-LOV appear. There is no way in Forms to suspend the action of a PL/SQL block; but we wanted to provide developers with the ability to execute code after the user clicked on the OK button. Therefore, one of the parameters in the invoke function is to execute a named trigger after the user clicks on the OK button. This is an example of the kinds of things that can be stored in the Object Library.
The goal in Level III template development is to completely genericize objects such as tabs and multi-select LOVs so that their complexity is hidden from developers. How hard is it to use tabs and multi-select LOVs? Sitting behind the scenes in tabs are many relatively subtle decisions such as ensuring that the appropriate canvas appears in the right place and that the space under the tab looks right. None of these decisions is particularly difficult; but thinking through all of the decisions involved can be time consuming particularly for the novice developer. There is no reason to think that any two developers would arrive at the same decisions.
The multi-LOV example includes very complex code requiring very experienced senior development staff to think through. Sitting behind this apparently simple multi-select LOV object are 10-15 pages of interesting PL/SQL code. From the developer’s perspective, all that needs to be done is to bring in an object group, attach a library and write two lines of code. Thus, Level III templates provide the user with very sophisticated functionality that is easy for even novice developers to use.
Disadvantages of Template Use
Template use does have a negative side. In a heavy template environment, with senior developers building the objects, novice developers (particularly those new to Forms) never get experience with basic PL/SQL coding. With the template, there is little need to write any code. The only time PL/SQL is ever necessary is for very complex PL/SQL, which is automatically assigned to a senior developer. Thus, junior developers never learn how to code. To combat this, we use novice developers to maintain, document and write exception handling for the templates. We try to make sure that novice developers work on extensions to the templates so that when developers need to go outside the template in creating new modules, they will have the skills to do so.
Conclusion
We have described the basic considerations you need to have when thinking about developing and using template forms for Very Rapid Application Development. Without the use of a template, Forms is a very good product. It compares favorably with the leading development tools on the market. However, with a well-built template, rich with property classes, triggers and generic objects, Forms is an extraordinary product. With a good template and a handful of good developers, projects can be brought to production in a period of time that appears almost magical.
Please feel free to download the sample files mentioned from the web site: http://ourworld.compuserve.com/homepages/Peter_Koletzke