This action might not be possible to undo. Are you sure you want to continue?
Oracle Forms 10g release 2 : Demos, Tips and Techniques
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.
2. Description of the sample dialogs
2.1 Main screen
This dialog is the entry point of the samples. Click on a button to start the corresponding dialog.
file:///D|/Cours/tuto_forms/paper/PDFtutoforms10g.htm (1 sur 24)29/05/2006 23:09:57
Oracle Forms 10g : Demos, Tips and Techniques
This sample shows three types of canvas : § § § The content canvas (light green) The stacked canvas (white) The tab canvas (dark green)
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 A stacked canvas allows to scroll a big canvas in a delimited window. In this sample, the stacked canvas (CV_EMP_1) is twice bigger than its viewport. The <Down> button allows to move the stacked canvas programatically:
Set_View_Property('CV_EMP_1', VIEWPORT_Y_POS_ON_CANVAS, 140) ;
file:///D|/Cours/tuto_forms/paper/PDFtutoforms10g.htm (2 sur 24)29/05/2006 23:09:57
Oracle Forms 10g : Demos.3.3 Blocks 2.1 Block based on a complex view file:///D|/Cours/tuto_forms/paper/PDFtutoforms10g. Tips and Techniques Here are the properties of this stacked canvas: Viewport Viewport X position Viewport Y position Viewport Width Viewport Height 77 11 212 138 Physical Viewport X position on canvas 0 Viewport Y position on canvas 0 Width 212 Height 324 The second Stacked canvas (CV_EMP_3) demonstrates how to integrate in a Tab canvas: 2.htm (3 sur 24)29/05/2006 23:09:57 .
Found -> update -Message('Update DEPT table').DEPTNO ) .Not found -> insert -Message('Insert into DEPT table'). DEPT and EMP) and when you can insert. Tips and Techniques TEST_BLOC_VUE.DEPTNO.DNAME ) . 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 . INSERT INTO DEPT ( DEPTNO. :EMP_DEPT.DEPTNO . DNAME ) VALUES ( :EMP_DEPT. The code that handles the target table is located in a program unit. Exception When no_data_found Then -.Table DEPT -Begin Select 1 Into LN$Dummy From DUAL Where exists( select deptno from dept where deptno = :EMP_DEPT. UPDATE DEPT SET DNAME = :EMP_DEPT. -.htm (4 sur 24)29/05/2006 23:09:57 . update and delete from the target tables from this view.DNAME WHERE DEPTNO = :EMP_DEPT.Oracle Forms 10g : Demos.FMB This sample show how you can base a block on a view that aggregate the columns of several tables (in this case. BEGIN -. file:///D|/Cours/tuto_forms/paper/PDFtutoforms10g.
ENAME WHERE EMPNO = :EMP_DEPT. END.Oracle Forms 10g : Demos.FMB This sample demonstrates how a block can be based on stored procedures. Tips and Techniques End . Exception When no_data_found Then -. End .Found -> update -Message('Update EMP table').EMPNO.3.Not found -> insert -Message('Insert into EMP table').htm (5 sur 24)29/05/2006 23:09:57 . 2. -.EMPNO ) .Table EMP -Begin Select 1 Into LN$Dummy From DUAL Where exists( select empno from emp where empno = :EMP_DEPT. ENAME ) VALUES ( :EMP_DEPT.2 Block based on stored procedures TEST_BLOC_PROC. INSERT INTO EMP ( EMPNO. -. This feature can be implemented in two ways: file:///D|/Cours/tuto_forms/paper/PDFtutoforms10g.ENAME ) . :EMP_DEPT. UPDATE EMP SET ENAME = :EMP_DEPT.EMPNO .
htm (6 sur 24)29/05/2006 23:09:57 .comm%TYPE).empno. there are also two different locations where to implement this functionality: § § The ON-xxx triggers The transactionnal triggers In this sample.job LR$Emp.job.empno. :emp. Collection and transactionnal triggers file:///D|/Cours/tuto_forms/paper/PDFtutoforms10g. r.ename. END. the top block uses a REF CURSOR with the ON-xxx triggers The bottom block uses a collection with the standard transactionnal triggers. comm) VALUES(r. job emp. r.empno LR$Emp.empno%TYPE. r.ename.ename LR$Emp.comm).sal. ename. Block2 (EMP_TRG).ename%TYPE.comm := := := := := :emp. r.job%TYPE. Tips and Techniques § § A REF CURSOR A PL/SQL table In addition to that. Block1 (EMP).job.sal LR$Emp.emp_rec. emp_pkg.Oracle Forms 10g : Demos. The variable used as parameter is of type of emp_pkg. REF CURSOR and ON-xxx triggers The Query Data Source Type is set to Procedure and the Query Data Source Name indicates the name of the query procedure.sal. sal. sal emp. BEGIN LR$Emp. :emp.sal%TYPE. :emp.comm. job. :emp. END emp_insert. The stored procedures are located in the PKG_EMP package shipped with the scripts. delete and lock orders are managed in the corresponding On-xxx triggers: Example of ON-INSERT trigger: DECLARE LR$Emp emp_pkg. ename emp. update.emp_rec TYPE emp_rec IS RECORD( empno emp.emp_insert( LR$Emp ).Insert ------------PROCEDURE emp_insert(r IN emp_rec) IS BEGIN INSERT INTO emp (empno.emp_insert() stored procedure: ------------. Then the emp_pkg. The insert. comm emp.
END emp_query. TYPE emptab IS TABLE OF emp_rec INDEX BY BINARY_INTEGER. ii := ii + 1. LOOP FETCH empselect INTO emp_data( ii ). update. CURSOR empselect IS SELECT empno. (see them in detail in the EMP_PKG package) Have also a look at the Query Data Source Column property that manages the relation between the columns of the collection and the items of the block. file:///D|/Cours/tuto_forms/paper/PDFtutoforms10g. The collection of records is an IN OUT parameter.Oracle Forms 10g : Demos. END LOOP. sal.htm (7 sur 24)29/05/2006 23:09:57 . job.pkg. emp_data( ii ). emp_data( ii ). BEGIN OPEN empselect. PROCEDURE emp_query(emp_data IN OUT emptab) IS ii NUMBER.empno. The insert. Tips and Techniques This block uses a collection of records with the emp.delete and lock orders are also managed by stored procedures.comm. emp_data( ii ). read from the database and returned to Forms. ii := 1.job.emp_query procedure. emp_data( ii ). comm FROM emp ORDER BY ename . EXIT WHEN empselect%NOTFOUND. ename.sal.ename.
Oracle Forms 10g : Demos. TAB_TYP_CASE is a table of objects of type : TYP_CASE create or replace TYPE TYP_CASE AS OBJECT file:///D|/Cours/tuto_forms/paper/PDFtutoforms10g. we can see how to handle a table that contains a nested table (collection).2).FMB In this dialog.3 Block based on a relational table that contains a collection TEST_COLLECTION. but we will see how easy it is to work with this sort of object via the ON-xxx triggers.3. Tips and Techniques 2. PRIX NUMBER(8. CASES TAB_TYP_CASE ) NESTED TABLE CASES STORE AS CASES_NT RETURN AS VALUE.0). QTETOT NUMBER(8. LIBELLE VARCHAR2(100 BYTE). There is no standard buit-in to base a block on a collection. Here is the description of the table (ARTICLES) CREATE TABLE ARTICLES ( CODE VARCHAR2(20 BYTE).htm (8 sur 24)29/05/2006 23:09:57 .
LC$Req ) .Insert the row in the collection -INSERT INTO TABLE ( SELECT cases FROM articles file:///D|/Cours/tuto_forms/paper/PDFtutoforms10g. QUERY_DATA_SOURCE_NAME. End . Go_Block('ARTICLES') .QTE FROM TABLE ( SELECT cases FROM articles WHERE code = ''' || :ARTICLES. Then after.Oracle Forms 10g : Demos.CODE || ''') cases)' .cannot contain a NULL collection --------------------------------------------------------------INSERT INTO ARTICLES ( CODE.we are doing an explicit insert because the new record --. -. if we insert a NULL collection. PRIX. End if . Populate the detail block (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 If :ARTICLES. QTETOT.PRIX. Set_Block_Property( 'CASES'. Else Go_Block('CASES' ). NUMBER In this sample. Clear_Block . LIBELLE.QTETOT. it will be no longer possible to insert anything in the nested table.CODE.EMP. CASES ) VALUES ( :ARTICLES. Go_Block('ARTICLES') .htm (9 sur 24)29/05/2006 23:09:57 .populate the block -Execute_Query . the first block (ARTICLES) displays the standard columns of the ARTICLE table and the second block (detail) displays the columns of its nested table.LIBELLE. TAB_TYP_CASE() -. it is easy to manage the detail records with the ON-xxx triggers of the CASES block: ON-INSERT: -. cases. :ARTICLES. Tips and Techniques ( EMP QTE ) VARCHAR2(10). Go_Block('CASES' ).insert an empty collection ) . we have to handle the insertion into the ARTICLE table in a ON-INSERT trigger: --------------------------------------------------------------. Because it is not possible to create a new article with a NULL collection. :ARTICLES. Clear_Block . Indeed. :ARTICLES.CODE Is not null Then -.Dynamic query of secondary block -LC$Req := '(SELECT cases.
4 Block based on multiple data sources TEST_DATA_SOURCES.EMP.EMP . etc.Delete row in the collection -DELETE FROM TABLE ( SELECT cases FROM articles WHERE code = :ARTICLES.3. (see the JANVIER. Tips and Techniques WHERE code = :ARTICLES.QTE ) ).Oracle Forms 10g : Demos.sql script) The list item is populated with the name of three tables that share the same structure: file:///D|/Cours/tuto_forms/paper/PDFtutoforms10g.emp = :CASES.FMB I this sample dialog. 2.CODE ) Values ( TYP_CASE( :CASES. ON-DELETE: -.htm (10 sur 24)29/05/2006 23:09:57 .CODE ) cases WHERE cases. :CASES. FEVRIER and MARS tables created by the install. we can see how to base a block on several tables that share an identical structure.
htm (11 sur 24)29/05/2006 23:09:57 . :global. -. go_block('TEST2').3.CHOIX ). clear_form .choix := :ctrl. execute_query.5 Block based on an object table that contains a collection of references file:///D|/Cours/tuto_forms/paper/PDFtutoforms10g. 2. the source table of the block is changed dynamically in the When-List-Changed trigger: If :CTRL. End if . QUERY_DATA_SOURCE_NAME.choix .Oracle Forms 10g : Demos.change the Query Data Source -Set_Block_Property('TEST2'. :ctrl.CHOIX is not null Then :global.choix . Tips and Techniques Then.choix := :global.
FMB Let’s see how to manage an object table that contains a collection of references. QTETOT NUMBER (8). Tips and Techniques TEST_OBJETS.QTETOT.ref_emp. -.record cannot contain a NULL collection -------------------------------------------------------INSERT INTO ARTICLES_OBJ VALUES ( TYP_ARTICLES ( :ARTICLES.CODE Is not null Then -.collection ) CREATE TABLE ARTICLES_OBJ OF TYP_ARTICLES NESTED TABLE REMP STORE AS REMP_NT RETURN AS VALUE. End . Clear_Block .change the Query Data Source Name -Set_Block_Property( 'CASES'. REMP TAB_REF_TYP_EMP -.htm (12 sur 24)29/05/2006 23:09:57 . emp. Begin If :ARTICLES. :ARTICLES. LC$Req ) .PRIX. TAB_REF_TYP_EMP() ) file:///D|/Cours/tuto_forms/paper/PDFtutoforms10g.CODE.An ON-INSERT trigger to insert a new record with an empty collection: -------------------------------------------------------.Oracle Forms 10g : Demos. This sample is based on the object table (ARTICLE_OBJ) that contains a collection of references: create or replace TYPE REF_TYP_EMP AS OBJECT ( ref_emp REF TYP_EMP ) create or replace TYPE TAB_REF_TYP_EMP AS TABLE OF REF_TYP_EMP create or replace TYPE TYP_ARTICLES AS OBJECT ( CODE VARCHAR2 (20). LIBELLE VARCHAR2 (100). Go_Block('ARTICLES') . :ARTICLES.A when-New-Record-Instance trigger on the master block to populate the detail block (the collection of references): Declare LC$Req Varchar2(256) .qte QTE FROM TABLE( SELECT REMP FROM articles_obj WHERE CODE = ''' || :ARTICLES. Go_Block('ARTICLES') . End if . -. Else Go_Block('CASES' ).CODE || ''') emp WHERE emp. QUERY_DATA_SOURCE_NAME.CODE || ''')' .emp EMP.2). PRIX NUMBER (8.Dynamic query of secondary block -LC$Req := '(SELECT emp.populate the block -Execute_Query .ref_emp. :ARTICLES. Clear_Block .ref_emp.LIBELLE.art = ''' || :ARTICLES. The tip is the same that the one used to manage the relational table with nested table: .We are doing an implicit insert because the new --. . Go_Block('CASES' ).
4 Items 2. 2.EMP = ''' || :CASES.ref_emp.CODE || ''') VALUES ( REF_TYP_EMP ( (SELECT REF(a) FROM EMP_OBJ a WHERE a.emp = :CASES.CODE || ''' AND a.Delete the row (REF) of the collection -DELETE FROM TABLE ( SELECT remp FROM ARTICLES_OBJ WHERE code = :ARTICLES.ART = ''' || :ARTICLES. The collection of references is managed with the corresponding ON-xxx trigger of the detail block: ON-INSERT: -.EMP .EMP || ''') ) )' .CODE And emp.4. Forms_Ddl( LC$Req ) . End .Insert a row (REF) in the collection -Declare LC$Req Varchar2(256) .art = :ARTICLES. ON-DELETE: -.ref_emp.htm (13 sur 24)29/05/2006 23:09:57 . Tips and Techniques ) . Begin LC$Req := 'INSERT INTO TABLE ( SELECT remp FROM ARTICLES_OBJ WHERE code = ''' || :ARTICLES.Oracle Forms 10g : Demos.1 Principal items file:///D|/Cours/tuto_forms/paper/PDFtutoforms10g.CODE ) emp WHERE emp.
2. Change the value of the first list and it will adapt the content of the second then the content of the third.LISTE1').LISTE2'. -. LC$Day Varchar2(20) . 1 ) . -.FMB Here is a description of the main items. Tips and Techniques TEST_ITEMS. Click everywhere on each item to see some information messages and some particular behaviours. CLEAR_LIST('BLOC2. POPULATE_LIST('BLOC2. b) Then init the second list item -. the corresponding value and label are displayed.Update the weeks list -errcode := Populate_Group( 'RG_SEMAINES' ). a) The first list item is populated with the RG_MOIS record group: -. BEGIN file:///D|/Cours/tuto_forms/paper/PDFtutoforms10g. 'RG_MOIS' ).LISTE1'. 1 ) . For each new list value. 'RG_SEMAINES' ).LISTE2'). POPULATE_LIST('BLOC2.LISTE2 := Get_List_Element_Value('BLOC2.List 1 -errcode := Populate_Group( 'RG_MOIS' ). c) That finally init the third list item: PROCEDURE Init_Liste3 IS LC$D Varchar2(12) .LISTE1'.Select the first value -:BLOC2.LISTE1 := Get_List_Element_Value('BLOC2.2 List items TEST_LISTES. In this sample.FMB Let’s study and handle the three sorts of list item and also the different ways to populate them. the three list items are synchronized.Select the first value -:BLOC2.LISTE2'. CLEAR_LIST('BLOC2.htm (14 sur 24)29/05/2006 23:09:57 .4.Oracle Forms 10g : Demos.
htm (15 sur 24)29/05/2006 23:09:57 .. Exception When Others then Null .3 Image items ALBUM_PHOTO. Clear_List( 'BLOC2.Select the first value -:BLOC2.LISTE3'. Tips and Techniques -. CREDIT VARCHAR2(50 BYTE) NOT NULL ENABLE. Add_List_Element('BLOC2. LIEN VARCHAR2(100 BYTE).Update the days list -LC$D := '01/01/2005' . You can build a photo album based on a one image’s column table.LISTE3' ). FORMAT VARCHAR2(50 BYTE) NOT NULL ENABLE. -.FMB This dialog is the main part of the ensemble that allows to search.LISTE3'. attach and display images. i + 1. 'DD/MM/YYYY' ) + (i + ((To_number(:BLOC2. PHOTO BLOB NOT NULL ENABLE.4.0) NOT NULL ENABLE. LC$Day. 2. For i IN 0.Oracle Forms 10g : Demos. 'FMDay DD Month' ) Into LC$Day FROM dual .6 Loop SELECT to_char( To_date(LC$D. IDENTIFIANT NUMBER(5. CREATE TABLE PHOTOS ( LEGENDE VARCHAR2(100 BYTE). END.LISTE2)-1) * 7)).LISTE3 := Get_List_Element_Value('BLOC2. 1 ) . LC$Day ) . End loop . file:///D|/Cours/tuto_forms/paper/PDFtutoforms10g.
It shows two ways to search a filename on the local machine with and without Webutil. Tips and Techniques NOM VARCHAR2(50 BYTE). CONSTRAINT PHOTO_PK PRIMARY KEY (IDENTIFIANT) ENABLE ) .Oracle Forms 10g : Demos. By clicking on a picture.htm (16 sur 24)29/05/2006 23:09:57 . you can navigate on another canvas to display the detail of the picture: file:///D|/Cours/tuto_forms/paper/PDFtutoforms10g.
htm (17 sur 24)29/05/2006 23:09:57 . file:///D|/Cours/tuto_forms/paper/PDFtutoforms10g. Tips and Techniques CHARGE_PHOTO. because it is so easy to pick-up a file with the File_Open_Dialog() Webutil function.Oracle Forms 10g : Demos.FMB The get_file_name sample dialog is only a “pure exercice of style” . 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.
2.FMB Another dialog to store the picture and its properties.htm (18 sur 24)29/05/2006 23:09:57 .4.Oracle Forms 10g : Demos.4 Java Bean component file:///D|/Cours/tuto_forms/paper/PDFtutoforms10g. Tips and Techniques CHARGE_PHOTO_WEBUTIL.
5 Calculated items file:///D|/Cours/tuto_forms/paper/PDFtutoforms10g.FMB Here is a sample to demonstrate how to handle a bean area.Oracle Forms 10g : Demos.jar file on the OTN page http://www.htm (19 sur 24)29/05/2006 23:09:57 . This dialog use the Oracle FormsGraph Java Bean that is part of the Oracle Forms demos. Tips and Techniques TEST_GRAPH.zip 2. You can download the FormsGraph.oracle.4.com/technology/sample_code/products/forms/files/formsgraph_patch2005.
FMB Let’s see how to use the calculated items.Oracle Forms 10g : Demos.htm (20 sur 24)29/05/2006 23:09:57 . The first calculated item use the Summary calculation mode: The third one use a Formula calculation mode 2.5 Alerts file:///D|/Cours/tuto_forms/paper/PDFtutoforms10g. Tips and Techniques TESTS_CALCUL.
TITRE VARCHAR2(100).0) NOT NULL ENABLE. CONSTRAINT MSG_PK PRIMARY KEY (CODE) ENABLE ) ----- unique identifiant text of the message title of the alert Shall we stop the process ? (raise -.name of the alert box This sample use the Affiche_Message() procedure of the TUTO_FORMS pl/sql library to display the messages. Tips and Techniques TEST_ALERTES_MESSAGES. TEXTE VARCHAR2(256) NOT NULL ENABLE.6 Property classes and visual attributes file:///D|/Cours/tuto_forms/paper/PDFtutoforms10g. %2 and %3). CREATE TABLE MESSAGES ( CODE NUMBER(5.htm (21 sur 24)29/05/2006 23:09:57 . The main block is based on the MESSAGES table.Oracle Forms 10g : Demos. The message texts are read from the database then displayed via Alert boxes. § § § AL_ERREUR wich is the simple “OK” alert box. STOP VARCHAR2(1) DEFAULT 'N' NOT NULL ENABLE. AL_MSG_OUI_NON wich is a yes/no alert box (default yes) AL_MSG_NON_OUI wich is a yes/no alert box (default no) 2. These messages can be displayed through the 3 alert boxes available in every dialog of this demo. some of them can take from 1 up to 3 parmeters (%1. To reduce the number of messages needed in the application. form_trigger_failure) ALERTE VARCHAR2(15). A pipe (|) character allows to split the message on several lines.FMB This dialog shows how to use the Alert boxes to build the messaging engine of your Forms application.
Oracle Forms 10g : Demos. etc. Tips and Techniques TEST_CLASSES_PROP.olb object library.7 Forms internal triggering events file:///D|/Cours/tuto_forms/paper/PDFtutoforms10g.htm (22 sur 24)29/05/2006 23:09:57 . 2.). item.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. Property classes and visual attributes are located in the OBJ_TUTO_FORMS. current record.
Under the /tutoforms/ directory compile all the source modules § You can use the compile_all. 3. /scripts that contains the Sql script files to create the database objects. you can clear the list of triggers window. the Oracle user where you have created these objects must have the WEBUTIL_DB package compiled or a grant EXECUTE to this package if it is present in another schema.zip file Unzip the tutoforms10g.sql script note : because this demo use the Webutil functions.FMB This dialog allows you to understand what trigger fire and in what order when you use the application.env file to indicate your own settings (in blue in this example) file:///D|/Cours/tuto_forms/paper/PDFtutoforms10g. Before each particular action. This window show you what trigger is firing in what order and from what block and what item. This zip file contains 2 sub directories: /config that contains the configuration files. compile_all user/password@instance § Edit the /tutoforms/config/tutforms10g.bat file located in the same directory to compile all objects at once.htm (23 sur 24)29/05/2006 23:09:57 .zip file shipped with the article. Create a new user in your database § With Sql*plus or SqlDeveloper.g. § § § Download the tutoforms10g.Oracle Forms 10g : Demos. run the /scripts/install. Tips and Techniques TEST_CYCLES. Installation steps This sample dialog need database objects to run.zip file under your <DEVSUITE_HOME>/forms/ directory. All the necessary objects are provided in the tutoforms10g. e.
Tips and Techniques #oracle home adapt this value to your own setting 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.%ORACLE_HOME%\jlib\debugger.cfg § Edit the /tutoforms/config/ add_to_formsweb.%ORACLE_HOME%\forms\tutoforms\myIcons. # webutil config file path WEBUTIL_CONFIG=D:\Dev10gR2\forms\server\webutil.cfg section..jar.env to the /forms/server directory add the /tutoforms/config/ add_to_formsweb.cfg at the end of your /forms/server/formsweb.Oracle Forms 10g : Demos. http://machine:8890/forms/frmservlet?config=tutoforms10g file:///D|/Cours/tuto_forms/paper/PDFtutoforms10g. lookAndFeel=Oracle colorScheme=blaf logo=no #don't forget to put your own database connexion userid=tutoforms10g/tutoforms10g@XE § § Copy the /tutoforms/config/tutforms10g.%ORACLE_HOME% \forms\tutoforms\FormsGraph.jar.cfg file to set your own database connect string (in blue in this example) .cfg file § Then.jar. you can start the demo by indicating the new [tutoforms10g] formsweb.jar..htm (24 sur 24)29/05/2006 23:09:57 .
This action might not be possible to undo. Are you sure you want to continue?
We've moved you to where you read on your other device.
Get the full title to continue listening from where you left off, or restart the preview.