Professional Documents
Culture Documents
Racle Forms 10g
Racle Forms 10g
1. Introduction
Here is a collection of Oracle Forms 10g sample dialogs extracted from a complete Oracle Forms tutorial.
This tutorial has been written in French and it would be too time consuming to translate it all in English.
This is the reason why I have only extracted and translated these sample dialogs.
The purpose of this article is not to teach how to build a new form from scratch. It intends to show some of
the main advanced features of the product.
To clearly understand in details how these dialogs work, you will have to open them in the Forms Builder
and examine them thoroughly.
However, in this article, I am going to explain the best I can the most important mechanisms of each
sample.
These sample have been tested with an Oracle Forms 10g release 10.1.2.0.2 on an Oracle
Database 10g Express Edition Release 10.2.0.1.0.
This dialog is the entry point of the samples. Click on a button to start the corresponding dialog.
2.2 Canvases
TEST_CANVAS.FMB
Stacked canvas
A stacked canvas is displayed atop—or stacked on—the content canvas assigned to the
current window. Stacked canvases obscure some part of the underlying content canvas,
and often are shown and hidden programmatically. You can display more than one
stacked canvas in a window at the same time
Viewport
Viewport X position 77
Viewport Y position 11
Physical
Viewport X position on canvas 0
Width 212
Height 324
The second Stacked canvas (CV_EMP_3) demonstrates how to integrate in a Tab canvas:
2.3 Blocks
TEST_BLOC_VUE.FMB
This sample show how you can base a block on a view that aggregate the columns of several tables (in this
case, DEPT and EMP) and when you can insert, update and delete from the target tables from this view.
The code that handles the target table is located in a program unit, called from the three block-level
triggers:
ON-INSERT
ON-UPDATE
ON-LOCK
This is the code of the ins_upd_emp_dept procedure:
PROCEDURE ins_upd_emp_dept IS
LN$Dummy PLS_INTEGER := 0 ;
BEGIN
-- Table DEPT --
Begin
Select 1
Into LN$Dummy
From DUAL
Exception
End ;
-- Table EMP --
Begin
Select 1
Into LN$Dummy
From DUAL
Exception
End ;
END;
2.3.2 Block based on stored procedures
TEST_BLOC_PROC.FMB
In addition to that, there are also two different locations where to implement this functionality:
The ON-xxx triggers
In this sample, the top block uses a REF CURSOR with the ON-xxx triggers
The bottom block uses a collection with the standard transactionnal triggers.
The stored procedures are located in the PKG_EMP package shipped with the scripts.
The Query Data Source Type is set to Procedure and the Query Data Source Name indicates the name
of the query procedure.
The insert, update, delete and lock orders are managed in the corresponding On-xxx triggers:
DECLARE
BEGIN
empno emp.empno%TYPE,
------------
-- Insert --
------------
BEGIN
END emp_insert;
ii NUMBER;
CURSOR empselect IS
BEGIN
ii := 1;
LOOP
ii := ii + 1;
END emp_query;
The collection of records is an IN OUT parameter, read from the database and returned to Forms.
The insert, update,delete and lock orders are also managed by stored procedures.
TEST_COLLECTION.FMB
In this dialog, we can see how to handle a table that contains a nested table (collection).
There is no standard buit-in to base a block on a collection, but we will see how easy it is to work with this
sort of object via the ON-xxx triggers.
)
NESTED TABLE CASES STORE AS CASES_NT
RETURN AS VALUE;
(
EMP VARCHAR2(10),
QTE NUMBER
)
In this sample, the first block (ARTICLES) displays the standard columns of the
ARTICLE table and the second block (detail) displays the columns of its nested table.
The detail block (CASES) is dynamically populated each time a master record change in a When-New-
Record-Instance of the master block:
Declare
LC$Req Varchar2(256) ;
Begin
LC$Req := '(SELECT cases.EMP, cases.QTE FROM TABLE ( SELECT cases FROM
articles WHERE code = ''' || :ARTICLES.CODE || ''') cases)' ;
Go_Block('CASES' );
Clear_Block ;
Execute_Query ;
Go_Block('ARTICLES') ;
Else
Go_Block('CASES' );
Clear_Block ;
Go_Block('ARTICLES') ;
End if ;
End ;
Because it is not possible to create a new article with a NULL collection, we have to handle the insertion
into the ARTICLE table in a ON-INSERT trigger:
--------------------------------------------------------------
--------------------------------------------------------------
(
CODE,
LIBELLE,
PRIX,
QTETOT,
CASES
)
VALUES
(
:ARTICLES.CODE,
:ARTICLES.LIBELLE,
:ARTICLES.PRIX,
:ARTICLES.QTETOT,
)
;
Indeed, if we insert a NULL collection, it will be no longer possible to insert anything in
the nested table.
Then after, it is easy to manage the detail records with the ON-xxx triggers of the CASES
block:
ON-INSERT:
(
SELECT
cases
FROM
articles
WHERE
)
Values
(
);
ON-DELETE:
(
SELECT
cases
FROM
articles
WHERE
) cases
WHERE
cases.emp = :CASES.EMP
;
etc.
2.3.4 Block based on multiple data sources
TEST_DATA_SOURCES.FMB
I this sample dialog, we can see how to base a block on several tables that share an identical structure.
(see the JANVIER, FEVRIER and MARS tables created by the install.sql script)
The list item is populated with the name of three tables that share the same structure:
Then, the source table of the block is changed dynamically in the When-List-Changed trigger:
:global.choix := :ctrl.choix ;
clear_form ;
:ctrl.choix := :global.choix ;
go_block('TEST2');
execute_query;
End if ;
2.3.5 Block based on an object table that contains a collection of references
TEST_OBJETS.FMB
Let’s see how to manage an object table that contains a collection of references.
This sample is based on the object table (ARTICLE_OBJ) that contains a collection of references:
RETURN AS VALUE;
The tip is the same that the one used to manage the relational table with nested table:
- A when-New-Record-Instance trigger on the master block to populate the detail block (the collection of
references):
Declare
LC$Req Varchar2(256) ;
Begin
FROM TABLE( SELECT REMP FROM articles_obj WHERE CODE = ''' ||
:ARTICLES.CODE || ''') emp
Go_Block('CASES' );
Clear_Block ;
Execute_Query ;
Go_Block('ARTICLES') ;
Else
Go_Block('CASES' );
Clear_Block ;
Go_Block('ARTICLES') ;
End if ;
End ;
-------------------------------------------------------
-------------------------------------------------------
VALUES
TYP_ARTICLES
(
:ARTICLES.CODE,
:ARTICLES.LIBELLE,
:ARTICLES.PRIX,
:ARTICLES.QTETOT,
TAB_REF_TYP_EMP()
)
) ;
The collection of references is managed with the corresponding ON-xxx trigger of the detail block:
ON-INSERT:
Declare
Begin
VALUES
End ;
ON-DELETE:
WHERE
emp.ref_emp.art = :ARTICLES.CODE
And
emp.ref_emp.emp = :CASES.EMP
;
2.4 Items
TEST_ITEMS.FMB
Click everywhere on each item to see some information messages and some particular behaviours.
2.4.2 List items
TEST_LISTES.FMB
Let’s study and handle the three sorts of list item and also the different ways to populate them.
In this sample, the three list items are synchronized. Change the value of the first list and it will adapt the
content of the second then the content of the third.
For each new list value, the corresponding value and label are displayed.
a) The first list item is populated with the RG_MOIS record group:
-- List 1 --
CLEAR_LIST('BLOC2.LISTE1');
POPULATE_LIST('BLOC2.LISTE1', 'RG_MOIS' );
:BLOC2.LISTE1 := Get_List_Element_Value('BLOC2.LISTE1', 1 ) ;
CLEAR_LIST('BLOC2.LISTE2');
POPULATE_LIST('BLOC2.LISTE2', 'RG_SEMAINES' );
:BLOC2.LISTE2 := Get_List_Element_Value('BLOC2.LISTE2', 1 ) ;
PROCEDURE Init_Liste3 IS
LC$D Varchar2(12) ;
LC$Day Varchar2(20) ;
BEGIN
LC$D := '01/01/2005' ;
Clear_List( 'BLOC2.LISTE3' );
SELECT
Into
LC$Day
End loop ;
:BLOC2.LISTE3 := Get_List_Element_Value('BLOC2.LISTE3', 1 ) ;
Exception
END;
2.4.3 Image items
ALBUM_PHOTO.FMB
This dialog is the main part of the ensemble that allows to search, attach and display images.
You can build a photo album based on a one image’s column table.
) ;
It shows two ways to search a filename on the local machine with and without Webutil.
By clicking on a picture, you can navigate on another canvas to display the detail of the picture:
CHARGE_PHOTO.FMB
The get_file_name sample dialog is only a “pure exercice of style” , because it is so easy to pick-up a file
with the File_Open_Dialog() Webutil function.
This sample is interesting to see how to use the HOST() and TEXT_IO() functions to get the list of the local
machine drives and their content.
CHARGE_PHOTO_WEBUTIL.FMB
TEST_GRAPH.FMB
This dialog use the Oracle FormsGraph Java Bean that is part of the Oracle Forms demos.
http://www.oracle.com/technology/sample_code/products/forms/files/formsgraph_patch2005.zip
2.4.5 Calculated items
TESTS_CALCUL.FMB
TEST_ALERTES_MESSAGES.FMB
This dialog shows how to use the Alert boxes to build the messaging engine of your Forms application.
The message texts are read from the database then displayed via Alert boxes.
To reduce the number of messages needed in the application, some of them can take from 1 up to 3
parmeters (%1, %2 and %3). A pipe (|) character allows to split the message on several lines.
STOP VARCHAR2(1) DEFAULT 'N' NOT NULL ENABLE, -- Shall we stop the
process ? (raise form_trigger_failure)
ALERTE VARCHAR2(15), -- name of the alert box
)
This sample use the Affiche_Message() procedure of the TUTO_FORMS pl/sql library to display the
messages.
These messages can be displayed through the 3 alert boxes available in every dialog of this demo.
TEST_CLASSES_PROP.FMB
Let’s see some ways to use the property classes and the visual attributes to colorize and highlight
dynamically different objects of the form (alert, item, current record, etc.).
Property classes and visual attributes are located in the OBJ_TUTO_FORMS.olb object library.
2.7 Forms internal triggering events
TEST_CYCLES.FMB
This dialog allows you to understand what trigger fire and in what order when you use the application.
Before each particular action, you can clear the list of triggers window.
This window show you what trigger is firing in what order and from what block and what item.
3. Installation steps
All the necessary objects are provided in the tutoforms10g.zip file shipped with the article.
/scripts that contains the Sql script files to create the database objects.
Download the tutoforms10g.zip file
Under the /tutoforms/ directory compile all the source modules
You can use the compile_all.bat file located in the same directory to compile all objects at once.
e.g. compile_all user/password@instance
Edit the /tutoforms/config/tutforms10g.env file to indicate your own settings (in blue in this
example)
ORACLE_HOME=D:\Dev10gR2
FORMS_PATH=%ORACLE_HOME%\forms\tutoforms
ORACLE_PATH=%ORACLE_HOME%\forms\tutoforms
FORMS_TRACE_PATH=%ORACLE_HOME%\forms\tutoforms
CLASSPATH=D:\Dev10gR2\forms\java\frmwebutil.jar;%ORACLE_HOME%\jlib\debugger.jar;
%ORACLE_HOME%\forms\tutoforms\FormsGraph.jar;%ORACLE_HOME
%\forms\tutoforms\myIcons.jar;
WEBUTIL_CONFIG=D:\Dev10gR2\forms\server\webutil.cfg
Edit the /tutoforms/config/ add_to_formsweb.cfg file to set your own database connect string
(in blue in this example)
...
lookAndFeel=Oracle
colorScheme=blaf
logo=no
userid=tutoforms10g/tutoforms10g@XE
Copy the /tutoforms/config/tutforms10g.env to the /forms/server directory
Then, you can start the demo by indicating the new [tutoforms10g] formsweb.cfg section.
1. Purpose
This is an article to show how to handle a hierachical tree in an Oracle Forms application.
The goal is to build a tree menu with the possibility of enabling the database roles.
Because we want to handle a database stored menu, this sample use the first option
with a record group populated by a database table.
ICON contains the icon name (without extension) attached to the node.
1 expanded
-1 collapsed
If you want to enable the database roles in the tree menu, you have to execute the
following steps :
...
...
Here is the content of the tables after the provided script is executed:
Table : MENU
5 Menu1 Opt 3 Sub Opt 3 suboptionmenu 4 1 Dialog131
Table MENU_ROLES :
ID ROLE
1 ROLE_MENU1
2 ROLE_MENU1
3 ROLE_MENU1
4 ROLE_MENU1
5 ROLE_MENU1
6 ROLE_MENU2
7 ROLE_MENU2
FROM MENU
ICON that contains the (16x16 pixels) icon name of the node (can be NULL)
HTREE := FIND_ITEM('BL_TREE.MENU');
V_IGNORE := POPULATE_GROUP('RG_TREE');
FTREE.SET_TREE_PROPERTY(HTREE, FTREE.RECORD_GROUP,'RG_TREE');
FROM MENU
Two buttons are added to show how to expand or collapse all the nodes of the tree:
A double click populate the “Node activated” display item and call the corresponding
screen:
A radio button allows to take into account the database roles.
For this purpose, the tree use another record group (RG_TREE_ROLES) that filters the
query.
FROM MENU m
WHERE EXISTS
(
)
Assign ROLE_MENU1 to one user and both roles to another user.
Copy the 4 icons of the /icons directory in your icons directory
It uses two calculated items, one in the data bock and another in a control block.
The first calculated item (:DEPT.MATCH_FOUND) is added to the DEPT block. It contains the
formula as follow:
Comparaison(:ctrl.charsave, :dept.deptno||:dept.dname)
Notice in this case,that we want to avoid duplicates on both DEPTNO and DNAME values.
Return number
Is
answer number := 0;
Begin
answer := 1;
end if;
return(answer);
End;
COMPARAISON is a program unit stored in the Forms module.
The two values are compared to each other, then the function returns 1 (a value greatest than 0) if
both the values are identical.
The first value (:ctrl.charsave) contains the bakup value of the current record.
It summarize the values contained in all the rows of the DEPT block (dept.match_found).