Monday, December 3, 2007

Form Development in R11i

Before You Begin


  • Have a good understanding of how your form is to look and function

  • Determine the Tables and Views to be used for your Blocks LOVs.

  • If you need to create a block that will display information from more than one table (i.e., foreign key descriptions, etc.), create a view joining the necessary tables with all of the applicable fields. Be sure to include the ROWID and Who columns from the main table. Also create views as needed for LOVs that will display data from more than one table.

  • Start with TEMPLATE.fmb

Forms Naming Standards


All objects should be named in the plural format for consistency. For example: Customer Names NOT Customer Name. The C located after the object name and before the object type stands for Custom to identify the object as a custom object. For example: CUSTOMER_NAMES_CRG is the customer names custom record group.


Files:

  • File names should be 8 chars in length plus a three character extension (FILENAME.ext).

  • Form Source File Names : XXXDDDDD.fmb, XXXDDDDD.fmx, or XXXDDDDD.fmt or XXXDDDDD.txt

    XXX is the three character product short name that your form is associated with. Use one of your descriptive characters, if your product short name is 4-characters.
    DDDDD is a 5–character abbreviation for the explanation of the purpose.

    For example, the Inventory Custom form for ASC Receipts would be named
    INVCREPT.fmb or ASCXRECP.fmb.

    fmb is the suffix for the source binary file
    fmx is the suffix for the executable binary file
    fmt or txt is the suffix for the source text file

    The .fmb files reside in $AUG_TOP/forms/US and the .fmx files reside in the $ASCX_TOP/forms/US directory.

Modules



  • Your form module name should match your form file name. For example, if a form is called ASCXPOMP.fmb, make sure the Module Name (visible in the Designer) is ASCXPOMP. This is especially important if you reference objects from your form. ZOOM also relies on the Module Name being correct.

Form Global Variables: gc_prod_variable

prod is the product short name, and variable is the name you would normally give to the variable. For Example: GC_PO_SECURITY_LEVEL, GC_MFG_ORGANIZATION


Items: Use logical, meaningful, and concise names.



  • Database Column: Note that table columns based on LOOKUP_CODES should have a ”_CODE” or ”_FLAG” suffix, and the displayed meaning item should have the same name but without the suffix.

  • Mirror: Mirror Items use the name of the item plus a ”_cmir” suffix. So if the item in the detail portion is ”ename ”, name the mirror–item ”ename_cmir”.
    object_CMIR

  • Buttons: object_CBT

  • Checkbox: object_CCB

  • Option Groups AKA Radio Groups: object_COG

  • Non-Database Items: Any non-database text items should have a meaningful name followed by _CND (for custom non-database). It is only necessary to do this if you are modifying a Standard Oracle form. - object_CND

Blocks: object_CB

Object is the name of the objects in the block. The block name should be 14 characters or less.
For Example: ORDERS_CB


Special Blocks
TOOLBAR: A block containing the toolbar will be named TOOLBAR_CB.
CONTROL: A block containing control items will be named CONTROL_CB
CONTEXT: A block containing display-only context items will be named CONTEXT_CB
PROGRAM: Blocks submitting concurrent request will be named program_CB
NON-DATABASE BLOCKS: Examples: Search blocks will be named action_CB or action_object_CB

If the block is shared with other forms, make the block name unique by preceding it with the name of your form.


Canvases:
1. Non-Tab Canvas: object_CCV

2. Tab Canvas: object_TAB_CCV

Object is the name of the object shown on the canvas.

For example: ORDERS_CCV or ORDERS_TAB_CCV


Alternative Region Stacked Canvasses: block_region_CAR

Block is the name of the block that the region fields are associated with. Region describes the fields shown on the tab page. For example, a block LINES has two tab pages, one showing price information and the other showing account information.

For example: The alternative region stacked canvases are named LINES_PRICES_CAR and LINES_ACCOUNTS_CAR

Note: Alternative region stacked canvases are only needed when you can't place tab region items directly on the tab pages. You can't place tab region items directly on the tab pages when you have scrolling or fixed fields within the tabbed region.


Query–Find Canvasses, Windows, and Blocks: QF_object_CCV

To distinguish windows, blocks and canvasses used for Find Windows, prefix the object name with ”QF_”. For example: QF_ORDERS_CCV


Windows: object_CW

Object is the name of the object shown in the window. For example: ORDERS_CW


LOVs: Object_CLOV

Object is the name of the first object shown in the LOV. For example: CUSTOMER_IDS_CLOV


Record Groups: object_CRG or object_criteria_CRG

Object is the name of the objects in the record group, usually the same as the basic item or LOV name. Criteria is a brief description of why specific objects are included in the record group. Use the criteria description only if using object name alone is not unique. Abbreviate the object name or criteria description if object_criteria exceeds 30 characters.


Query LOVs and Related Record Groups: QF_object_CLOV or QF_object_CRG

To distinguish between LOVs and record groups used for entry from those used for querying purposes (such as Find Windows), prefix the object name with ”QF_”.

For example: QF_FREIGHT_CODES_CLOV,
QF_DEMAND_CLASSES_CRG


Relations: master_detail_CREL

Master is the name of the master block in the relation, and detail is the name of the detail block in the relation. For example: ORDER_LINES_CREL


Item and Event Handler Packages and Procedures: Packages are used to maintain PL/SQL executed from a trigger or another package. All packages should start with the block or form name. Code within a trigger at any level (Form, Block, Item) should not call any routine defined in the others package. The code should call the appropriate event or item handler and that handler will call the routine stored in the others package. Code within the trigger should only call procedures or functions stored in the events or items handlers (including the APPS_CUSTOM package) and should not call any oracle provided routines directly.

Each user-defined procedure that accepts an event parameter must display a debug message if the routine was passed an event that is not handled by the procedure.

Block: _Events
A separate package should be created to maintain “event” trigger logic for the block and should be suffixed with _events. This package should be used to handle all block and record level event processing. For example: The event handler package for the Orders block should be orders_events.
Listed below are some common events that would be located in a block level event handler:
Insert_Row
Update_Row
Delete_Row
Lock_Row
PRE-RECORD
PRE-INSERT
PRE-UPDATE
WHEN-VALIDATE-RECORD
POST-QUERY

If more than one package is necessary to handle the events the additional packages should be named orders_events2, orders_events3 … As needed.

Items: _Items
A separate package should be created to maintain item trigger logic and should be suffixed by items. The procedures within the item handler should be named after the item and have a single parameter, EVENT which is VARCHAR2. The logic within the procedure must branch based on the event passed to the procedure. The procedure must display a debug message if an event that is not handled by the procedure is passed in as a parameter.


For example: The item handler package for the orders block should be orders_items.
The item handler package for the lines block should be lines_items
An example of an example of an item handler procedure would be order_number.

If more than one package is necessary to handle the item trigger logic the additional packages should be named orders_items2, orders_items3 … As needed.

Others: _Others or _Others
If package procedure needs to execute another procedure or function, a separate package should be created with a suffix of _others. For procedures and functions that are used in more than one block or control form level activity, the package should be named after the form with the _others suffix. Procedures and functions that only operate on items within one block should be located in the _others package named after the block.

For example: If the orders_items procedure needs to call a function to calculate the total order selling price, a package named orders_others should be created.
If a form named oecorders needs to get profile values, a package named oecorders_others would be created with a procedure named GET_PROFILE_VALUES.

If more than one package is necessary to handle these procedures, the additional packages should be named orders_others2, orders_others3 … or oecorders_others2, oecorders_otheres3 … As needed

Form: _Events
A separate package should be created to maintain “form” level trigger logic for the form and should be suffixed with _events. This package should be used to handle all form level event processing.

For example: The event handler package for the Orders forms should be oecorders_events, where oecorders is the name of the form.


Listed below are some common events that would be located in a form level event handler:
WHEN-NEW-FORM-INSTANCE
PRE-FORM
POST_FORM
WHEN-NEW-BLOCK-INSTANCE
KEY-CLRFRM

If more than one package is necessary to handle the events the additional packages should be named oecorders_events2, oecorders_events3 … As needed.

These additional packages may be needed for two reasons:


1) size of the package should be limited to less than 64K and


2) fewer than 25 procedures.

Procedure and functions names within a package should be meaningful.


Triggers: All triggers not part of the template form or copied from a block in the template form will call either an item handler or event handler package. Standards related to specific triggers are listed below.



  • PRE-FORM :
    · Author: . . i.e. A. Singh
    · Revision: i.e. ERP 010

Form Documentation and Comments
Module Comments: For every modification to a form a comment MUST be added to the MODULE level comments.


ALL FORMS:
All forms should have the following Module Comment:

Copyright ASC Corp. 2007

Form Name:
Original Oracle Form Name: (if applicable)
Initial Release:
Developer:
Purpose:
MODIFICATION BLOCK:

For example:
Form Name: ASCXDSCP
Original Oracle Form Name: N/A
Initial Release: ERP 1.0
Developer: Ajeet Singh
Purpose: Provide the ability to copy delivery sets
MODIFICATION BLOCK:


Modifications to a Form:
For each modification of a form, add the following comment at the beginning of the Modification Block section:
Release - Date of Modification - Developer Name - TAR#


For example:
ERP 1.0 - 8/12/07 - Ajeet Singh - STAR TAR #59632
Add WHEN-VALIDATE-ITEM trigger to sales channel code.



Other Comments
Other comments added to a form object should include the following header:

Release - Date of Modification - Developer Name -STAR TAR#


For example:
ERP 1.0 - 8/12/97 - Ajeet Singh- STAR TAR #59632
Add WHEN-VALIDATE-ITEM trigger to sales channel code.

Containers : Use File/Save As to create your new form (be sure to change the directory as needed. Set the module name to be the same as the file name.
* Create the windows needed for your form. There should be one Window per “page” or screen full of data.
* Set the Property Class to WINDOW
* Change the Window title.
* Set the Window height property to 5 (inches)
* Set the Window width property to 7.8 (inches)
- These are the MAXIMUM sizes for a window, these values may need to be reduced once you have the forms objects on the canvas and then the canvas and the window can be resized to fit the actual size needed.
* Create a canvas for each Window created in the previous step.
* Set the Property Class to ‘CANVAS’
* Set the Window property to the corresponding window created in the previous step.

For each Canvas created in the previous step, go into the Layout Editor and change the following settings:

* Format/Layout Options/Ruler – change the units to Character Cells, Character Cell Size to 7.2 (horizontal) and 18 (vertical), Grid Spacing to 1 and Number of Snap Points to 2 (p.3-3).

Note: Ruler settings determine the spacing and alignment of all elements in the form. It is crucial that these settings are established correctly before any layout is performed and that the "Grid Snap" setting is enabled. These settings allow objects to be drawn snapped to a character cell grid, with well defined ”rows” and ”columns.” Use of this character cell grid facilitates rapid building of, and often more aesthetically pleasing, screens than could otherwise be achieved if no grid were imposed.
* View/Snap to Grid – to turn on grid snap (checked) (p.3-3).
* View/Show Canvas – to turn off canvas viewing (unchecked)
* View/Show View – to turn on view display (checked).

Create the necessary Blocks following the Forms Naming Standards.
* Be sure to change the Canvas to the appropriate canvas created as above

* If the block will display more than one row, Check the Scroll Bar option.
* As the LAST step before pressing the OK button, Change the Block Name under the General tab in the New Block Options

For each Block created in the previous step,
* Set the block property class to ‘BLOCK’.
* If block is based on a table or a single-table view ,Set the Key-Mode property to ‘Unique’;
* For blocks based on more than one table, set the Key-Mode property to ‘Non-Updatable’.
* For blocks based on an Index-Organized Table (IOT)…
* Set the Enforce Primary Key property to 'Yes'. This property indicates that any record inserted or updated in the block must have a unique key in order to avoid committing duplicate rows to the block's base table.
* Set the Key-Mode property to 'Non-Updatable'. Non-Updatable specifies that Oracle forms should not include primary key columns in any UPDATE statements.
* Once the block level properties are set, you must set the property of at least one item on the block to indicate it is the primary key. For example, for the field in your block that is to contain only unique values, set the Primary Key property to 'Yes'.

NOTE: For blocks that are based wholly or in part, on an Index-Organize Table, certain block properties must be set as noted above. This is necessary because Forms was not designed to work on Index-Organized tables (IOT). This limitation is primarily due to Form's dependence on RowIDs. RowIDs are used by Forms to identify the row(s) accessed by the form. IOTs do not have RowIDs. You can run the following SQL query, to determine if a table is an IOT… SELECT table_name, iot_type FROM all_tables where table_name = ; The table is an IOT, if 'IOT' is returned for the iot_type field.

MetaLink Note# 74887.1 "Forms with Blocks Based on Index-Organized Tables".

* Change other block properties such as Insert Allowed, Update Allowed, Delete Allowed, etc., as needed.

. For each block, set the Navigation Style block property to
* ‘Change Record’ for multi-record blocks.
* ‘Same Record’ for single-record blocks with no detail blocks within the same window
* ‘Change Block’ for all other single-record blocks

. In addition, set the Next Block and Previous Block properties. The First Block in a form must have Previous Block set to itself and the Last Block must have Next Block set to itself. Under the Form Module Properties,
* Set the First Navigation Block to the name of the first block to be displayed on the form.

.Create Master-Detail relationships as needed. Before creating the relationships, ensure that your blocks are named exactly the way that you want them. If you have to change a Block name after relationships have been created, you will have to modify
* The join property
* ON‑CHECK-DELETE-MASTER and ON-POPULATE-DETAILS triggers
* And possibly others.

.Modify the form level PRE-FORM trigger.
* Change the parameters in the call to FND_STANDARD.FORM_INFO:
* Version = ERP 1.0.0.0.0 (there should be no $Version in the string)
* Title = The name of the form that appears in the title bar
* Application Short Name = The application short name under which your form is to be registered. For example, ASCX (ASC Custom – General).
* Date Last Modified = The date that you modified/created the form
* Last Modified By = ‘Copyright ASC Corp. 2007’ or the appropriate year(s) that the form was created/modified (there should be no $Author in the string)

Example:
FND_STANDARD.FORM_INFO('ERP 1.0.0.0.0', 'Cancel Delivery Sets', 'ASCRX',
'$Date: 01/11/24 13:29:28 $', 'Copyright ASC Corp. 2007');

* Change the 'BLOCKNAME' string in the call to APP_WINDOW.SET_WINDOW_POSITION. Change it to call your main (first) WINDOW name. For example, app_window.set_window_position('ARC_LOOKUP_VALUES_CW', 'FIRST_WINDOW');

.Modify the FORM First Navigation Block property to be your first block.
.Save your form and do a Program/Compile/All. If there are no errors, follow the steps for Form Registration and Testing. At this point you will only be able to query information on your form.

Items
1. Set the properties for all other items including:
* Property class
* Canvas,
* Width
* Query length (for text items).
* Listed below are property classes for the various widget types and behaviors:

Type of Widget -- Property Class

Check Box - CHECKBOX
Pop List (static list of <15>

Text Item -- TEXT_ITEM, TEXT_ITEM_DISPLAY_ONLY, TEXT_ITEM_MULTILINE, TEXT_ITEM_DATE

Display Item (never accepts focus) -- DISPLAY_ITEM, DYNAMIC_TITLE, DYNAMIC_PROMPT

Option Groups (Radio Buttons) -- RADIO_BUTTON , Button BUTTON, BUTTON_ICONIC

Who Date Fields (CREATION_DATE, LAST_UPDATE_DATE) CREATION_OR_LAST_UPDATE

Other Who Fields (CREATED_BY, LAST_UPDATED_BY, etc.)

WHO_NONDATE_ITEM: This is a custom property class that makes the field a DISPLAY_ITEM and sets the canvas set to ‘’.

1. Set the Primary Key property to True for the primary key field(s) in each block.
2. As needed for each block, copy the descriptive flexfield item from the BLOCKNAME or DETAILBLOCK block depending on whether your block is a single record block or a multi-record block, respectively.

3. For multi-record blocks copy the CURRENT_RECORD_INDICATOR from the DETAILBLOCK.
* Change the canvas name item property.
* Modify the WHEN-NEW-ITEM-INSTANCE trigger to prompt to the first field in the block.

Note: For combination blocks, create a drill-down indicator in place of the current record indicator.

4. For all multi-record blocks, set the scroll bar properties for the block:
* The left edge of scrollbar should be 0.3" inward from the right edge of the canvas
* Scroll Bar Orientation=Vertical
* Scroll Bar Width = 0.2"

5. Arrange the fields in the navigator to correspond to the tabbing sequence (left to right , top to bottom within a region). Displayed fields should be listed first and those on the null canvas listed last.
6. Go into the Layout Editor to position and size fields and scroll bar(s).
* Use Arrange/Align Objects to snap the fields and scroll bars to the grid.
* Align to=Grid,
* Horizontally=Align Left,
* Vertically=Align Center

7. Create field prompts, region boxes/lines and region titles as needed.
* Set the font to MS Sans Serif 10pt (Regular font style for prompts and Bold for region titles).
* Set the settings for the prompts in the "Prompt" section of the field's Property Palette.
* Arrange/Align Object to Snap to Grid.

See chart below for the appropriate settings:

-Prompt Display Style -Justification -Attachment Edge -Alignment -Attachment Offset -Alignment Offset -Snap to Grid___________________________________________


Single Record Block Prompt -First Record -End -Start -Center -0.1" -0.0" -Right, Center
Multi-Record Block Prompt Left Aligned Data * - First Record -Start -Top -Start -0.0" 0.05" -Left, Bottom
Multi-Record Block Prompt Right Aligned Data * -First Record -End -Top -End -0.0" -0.05" -Right, Bottom
Multi-Record Block Prompt – Center Aligned Data -First Record -Center -Top -Center -0.0" -0.0" -Center, Bottom
All Region Titles -N/A -N/A -N/A -N/A -N/A -N/A -Left, Center
All Flexfield Brackets -N/A -N/A -N/A -N/A -N/A -N/A -Center, Center
* Prompts for Multi-Record Blocks are to be placed one-half character cell (0.05”) in from the edge of the associated field.
8. Re-size each canvas to fit around all displayed items. Re-size the canvas’s window to be the same size as the canvas.
9.Save, Compile All and Test the form to ensure that items are displayed properly and have the correct properties. You still will only be able to view and query information on your form.

Logic and Functionality
1. If your form uses profile values, do the following:

* Create an Item in the CONTROL block (you may need to create this block if one does not already exist) to hold the value of the profile that you need.
* Create a procedure named GET_PROFILE_VALUES in the formname_OTHERS package under Program Units. This procedure should use FND_PROFILE.VALUE or FND_PROFILE.GET to assign the profile value to the item that you created in the CONTROL block.

* In the WHEN-NEW-FORM-INSTANCE trigger call GET_PROFILE_VALUES before the standard code in that trigger.
* In the KEY-CLRFRM trigger call GET_PROFILE_VALUES after the standard code in the trigger.

2. Create LOVs and corresponding record groups as needed for field QuickPicks and validation. The record group should order the data by the first column displayed. Assign the LOVs to the appropriate fields and set the LOV position.

3. For every user enterable Date field
* Set the LOV property to ENABLE_LIST_LAMP and
* Set the Use LOV for Validation property to FALSE
* Create a KEY-LISTVAL trigger for each date with an execution style of Override. The trigger should call calendar.show.

4. Create a package(s) as needed For each block you may need separate packages to contain table and event handlers or item handlers or other business rules. * Event Package: The package should be named blockname_EVENTS where blockname is the name of your block without the _CB. For example, you would name this package ORDERS_EVENTS if your block name is ORDERS_CB.
* Item Package: You may also need to create packages for item handlers (blockname_ITEMS).
* Form level packages: (formname_EVENTS) for form level events.
* Business Rules Package: A package to hold procedures for calculations, common functions and other miscellaneous procedures (blockname_OTHERS or formname_OTHERS).

5. For blocks based on a view joining more than one table, you will need to create Insert_Row, Update_Row, Delete_Row, and Lock_Row procedures within the blockname_EVENTS Package created in the previous step.
* Copy view_table_handlers.txt to another file name.
* Modify the procedures to use your form, block and table names using a text editor. Be sure to save the file as plain text because Word and Wordpad quotation will not be recognized correctly.
* In the blockname_EVENTS package body, use Edit, Import, Text to import your saved file containing the handlers.

6. For all blocks allowing insert and/or update, create Pre-Insert and Pre-Update procedures in the blockname_EVENTS package created in Step 3. Both of these procedures should call FND_STANDARD.SET_WHO.

7. Create additional table and event handlers (procedures) as needed. These procedures will reside in the blockname_EVENTS Package created in Step 3.

8. Add logic to the appropriate triggers to call the procedures created in Steps 3-5. Be sure to set the trigger’s execution style correctly. In general it should be set to Before and not Override, the default.

9. Modify the APP_CUSTOM.OPEN_WINDOW package body to reference the form’s window names. Set coordination and window position as needed.

10.Save, Compile All, and Test your form. You should now be able to Insert Update and Delete rows from your form and use your LOVs.

11.Modify the APP_CUSTOM.CLOSE_WINDOW package body. Enter the name of the first window (uppercase) and modify other logic as needed.

12.If your form contains master-detail blocks located in different windows, create a button to open the detail window and a coordination check box along with the corresponding item handler.

13.Create item handlers as needed to handle field validation, initialization and messaging. These procedures should be created in the blockname_ITEMS Package. Call the procedures from the appropriate triggers being careful to set the execution style correctly.

14.Create the appropriate handlers to define and invoke Flexfields in the blockname_ITEMS Package. Call those procedures from the appropriate triggers being careful to set the execution style correctly.

15.Add Query Find functionality:
* Row-LOV - used for a single-row block to show all possible records that a user can query. * Create query find parameters for all primary key fields.
* Create a row LOV for each block.
* Create block level PRE-QUERY and QUERY_FIND triggers.
* Find Window -used for combination blocks and other blocks to allow the user to enter query criteria to locate one or more rows.

16.Delete the unused objects from the Template, BLOCKNAME and DETAILBLOCK blocks, BLOCKNAME canvas and window.

17.Add comments on the module properties sheet that includes the module Name, Original Oracle Form Name, Initial Release, Developer, Purpose and Modification Block. Below is an example:
Copyright ASC Corp. 2007

Form Name: ERP Generic
Original Oracle Form Name: n/a
Initial Release: ERP 1.0
Developer: Ajeet Singh

Purpose: Generic form
MODIFICATION BLOCK:
6/14/01 A. Singh STAR 999999 – Modified Generic_ID field to be VARCHAR2(34) from NUMBER(15).

18.Save, Compile All, and Test your form to ensure all functionality is working as expected.
Form Registration and Testing

1. FTP the form (.fmb) to the AUG_TOP/forms/US directory on the Forms Server. You will need to connect as devmgr to ensure that the files are owned by the correct user.
2. Log on to the Forms server as devmgr and change directories to AUG_TOP/forms/US. Generate the form into the appropriate application forms directory using f60gen or the gen_form shell script.

f60gen OECMASCH apps/xyz output_file=$ASCX_TOP/forms/US/OECMASCH.fmx
OR
gen_form OECMASCH $ASCX_TOP/forms/US/OECMASCH.fmx

where OECMASCH is the name of the form, APPS is the username for the APPS schema, XYZ is the APPS schema password, and ASCX_TOP is the application top directory.
3. If you have not already done so, log into the applications and register the form:
* Using the Application Developer responsibility, navigate to Application à Form. Be sure to remember the user form name because you will need it when you create a form function
* Using the Application Developer responsibility, navigate to Application à Function. From this form create a function that accesses the user form name you created in the previous step. You will need to enter the form name under the FORM tab. Remember the function name because it will be used when you add the function to a menu.
* Navigate to Application à Menu to add the function you created in the previous step to the ERP_DEVELOPMENT_TEST_MENU menu OR to whatever menu you desire.

4. To test the form, switch responsibilities to ERP Development Test Resp. (or to the responsibility associated with the menu that you added your function to, in step 3 above) and select the appropriate option on the menu.

5. When you have completed your form, you will need to add your form function to the appropriate menu. This should be specified in the functional spec/design document.

6. Document your AOL registration.

7. Once you are ready to check your form into the repository, be sure to edit the repository's generate_all_forms script, to add the appropriate statement for your form. This file is located in the $AUGX_REPOS/forms/US directory of the repository.

*** When you generate your form on the box (using either f60gen… or gen_form…) and you get an error that says something like ‘Cannot open file. Segmentation error (coredump)’. Look at the reference information on the items that you are referencing in from the dummy form and make sure the dummy form is displayed in all CAPS. Otherwise, it does not recognize it.

Tabbed Regions
If you have too much information about an object to fit within one standard-sized canvas, you may need to create a tabbed region. A tabbed region is the area of a window that contains a group of related tabs. The group of related tabs and their corresponding tab pages are considered to make up the tabbed region. This is called a tab canvas. Each tab canvas consists of one or more tab pages. The tab control is provided by a widget that positions the tab UI mechanism at the top of a set of regions and allows the user to navigate directly to a specific region by selecting one of those tabs.
From a coding perspective, there are three degrees of coding difficulty for tabbed regions.
*The three degrees of difficulty require different types of layout methods and coding methods. *The layout method differences include using stacked canvases or not, and how many of them. *The coding method differences include extra code that is required for handling the behavior of tabs with stacked canvases.

An overview of the three degrees of difficulty is as follows:

· Simple: No scrolling or fixed fields – This case includes single-row tab pages where no fields are repeated on different pages. These are typically separate blocks of the form. If you have a form with multiple separate multi-row blocks represented as one tabbed region (one block per tab page and separate block scrollbars for each, but no horizontal scrolling of fields), that can also be coded as the simple case. For example, the Users window on the System Administration responsibility fits the simple case. In the simple case, you place items directly onto the tab pages. The simple case does not require any stacked canvases.

· Medium: Scrolling but no fixed fields – This case includes single-row tab pages where no fields are repeated on different pages, but scrollbars are required to allow access to all fields within a tab page. These tab pages are typically each separate blocks of the form. In the medium case, you place items onto stacked canvases, in front of the tab pages, to facilitate scrolling of fields.

· Difficult case: Fixed fields with or without scrolling – This case covers the presence of fixed fields shared across different tab pages. This case includes any multi-row blocks spread across multiple tab pages. Fixed fields usually include context fields, current or drilldown record indicator, descriptive flexfields, and the block scrollbar. In the fixed field case, you place items onto stacked canvases, in front of the tab pages, to facilitate scrolling of fields. An extra stacked canvas is required for the fixed fields, and additional code is required in the tab handler.

Oracle provides two template files for coding your tab handler. The two template files are as follows:
FNDTABS.txt for the simple and medium cases
FNDTABFF.txt for the fixed field case

A high-level overview for creating tabbed regions, is as follows:
1. Make a list of the tabs (field groupings) needed and give each one a name. These names will be used to name the canvases used to display the information. It is important to determine these names before you start coding because changing them later in the process can be difficult.
2. Follow the steps for the Implementing Tabbed Regions coding
3. If any of the tabs other than the first displayed tab is a detail block, you will need to add additional code to control the master-detail coordination.
* Create the appropriate relations with the following properties:
* Masterless Deletes: NonIsolated
* Prevent Masterless Operations: True
* Deferred: True
* Auto Query: True
* Create a procedure to toggle the Deferred property for the relation.

Example:

PROCEDURE toggle_ds_coordination(disp_canvas in VARCHAR2) IS
-- This procedure is used to provide block query coordination
-- for detail blocks located in a tabbed region.
BEGIN
IF (disp_canvas = '') THEN set_relation_property('',DEFERRED_COORDINATION,PROPERTY_FALSE);
ELSE set_relation_property('',DEFERRED_COORDINATION,PROPERTY_TRUE);
END IF;
-- Create the IF-THEN-ELSE statements like those above for each dependent region.
END toggle_ds_coordination;

* Code your Tab Handler, you'd call the toggle coordination procedure created above. For the simple and medium cases (FNDTABS.txt) WHEN-TAB-PAGE-CHANGED Branch, call the toggle coordination procedure

* After the 'end if' (in the event = 'WHEN-TAB-PAGE-CHANGED' section) and before the 'Move to first item on each tab' comment.
For the difficult case (FNDTABFF.txt) WHEN-TAB-PAGE-CHANGED Branch, call
the toggle coordination procedure

* After the "end if" (in the event = 'WHEN-TAB-PAGE-CHANGED' section) and before the "ELSIF (event = 'WHEN-NEW-ITEM-INSTANCE')…" statement.

* After the "end if" (in the event = 'WHEN-NEW-ITEM-INSTANCE' section) and before the "ELSE app_exception.invalid_argument…" statement.
* If the cursor is not within the tabbed region when the tab is changed, you must force the query to occur using the following statements:
rel_id := Find_Relation('');
Query_Master_Details(rel_id, '');

Creating messages in Message Dictionary
1. Log on as Application Developer, and go to the Application/Messages form.

* Type in the name of the error

* Language (US)
* Application (name of the application this error will be used for)
* Select Error in the Type field for and error message
* Fill in Description
* Fill in the Current Message Text with the statement you want to appear when the error occurs. (use & before a name of a field to create variables to pass in )

2. Save
3. Stay as Application Developer responsibility and go to the Other/Requests/Run form and submit a single request. **
* The request name is Generate Messages
* Fill in the parameters language (US)
* Application
* Leave the mode as DB_TO_RUNTIME
* Leave the other fields blank.

4. Submit the request and it should complete successfully.

5. You need to restart the Apps before your messages will appear.

** To generate messages from Unix command line, supply the appropriate application_short_name to the following command:
FNDMDGEN apps/apps 0 Y US application_short_name
So, for example, to generate the messages for the ASC Custom – General (ASCX) Application: FNDMDGEN apps/apps 0 Y US ASCX


* When we upgrade environments, the message file may get copied so your message will work even if you had not put it in the message dictionary in the new environment yet. It will work until the Generate Messages runs for that application. Just remember that you have to put your message in the message dictionary for each environment.


* For a two-tiered environment, the generated message file has to exist on BOTH the Application Tier and Database Tier servers.

What this means…
* After you've submitted the Generate Messages job as noted above, a message file (i.e. US.msb) is created in the appropriate mesg directory (for example, the directory for the "ASC Custom – General" application = $ASCX_TOP/mesg) on the Database Tier box.
* You will have to copy (i.e. using ftp) this file to the appropriate mesg directory on the Application Tier box.
* You will then have to generate the message file from the Unix command line. For example, to generate the messages for the ASC Custom – General (ASCX) Application: FNDMDGEN apps/apps 0 Y US ASCX

Customizing A Standard Oracle Form
Before modifying a standard Oracle form, review the following options for a solution

1. Descriptive Flexfields (DFF)
* Standard attributes (1-5 for local) or 6-?? For global
* If a field is available on the form, but not visible; make a DFF. This field must be available in all blocks/forms where the flexfield is used.
2. Standard Oracle Functionality (profile options, system options, standard value rules)
3. Custom Library and/or Form Personalization
4. Form Function, when form will be accessible through a specific responsibility for the country
5. Database Trigger
6. Call custom library package that performs logic, versus putting code directly into form.

* Create an Oracle application Upgrade/Patch instruction document that identifies the steps necessary to re-implement the changes.
* Library should be maintained in AUG_TOP/resource with a filename of custom_ .
7. If none of the previous options work, customize the Oracle form follow the steps in the Oracle Applications Developer’s Guide, with the following additions/exceptions
* Make a backup copy of the Oracle form. Save a copy the original standard oracle form in the repository in the $ORIG_REPOS directory, named as formname>.orig.fmb
* Do not rename the form or Module if you are just making minor modifications to the form’s functionality. The decision was made to retain the original Oracle form’s .fmb filename and module name to limit analysis and further customizations. For example: Oracle’s standard code in some forms, hard codes form names as part of functionality logic. Also, one Oracle form may reference another and this referencing expects the standard Oracle form name, not a custom name. A custom name will be given to the .fmx file only.

You should only rename the form and module if you are simply using the Oracle form as a starting point for a custom form. (For example, the Cancel Delivery Sets form is based on the standard Oracle Cancel Orders form. It can reuse several pieces of the Oracle code, but has major functionality enhancements or differences. Also, we would never expect or want another Oracle form to unexpectedly access this custom form.)

* Modify the FND_STANDARD.FORM_INFO statement in the PRE-FORM trigger:
* Version = Oracle form version - ERP 1.0.0.0.0 (there should be no $Version in the string). For example, 11.5.3 – ERP 1.0.0.0.0
* Application Short Name = The application short name under which your form is to be registered. For example, ASCX, INFX, MIGX, TRNX, etc.
* Date Last Modified = The date the you modified the form
* Last Modified By = ‘Copyright ASC Corp. 2007’ or the appropriate year(s) that the form was created/modified (there should be no $Author in the string)
The following is an example of what your FORM_INFO call should look like:
FND_STANDARD.FORM_INFO('11.5.3 – ERP 1.0.0.0.0', 'Cancel Orders', 'ASCX', '$Date: 01/11/24 13:29:28 $', 'Copyright ASC Corp. 2007');
* Add the ASC Standard form documentation block to the form level Comments Property.


MODIFICATION BLOCK:
* When you generate the form give the executable a custom name. For example, gen_form OEXOEMOE.fmb $ASCX_TOP/forms/US/OECOEMOE.fmx
* When you register the form the User Form Name, User Function Name, and Navigator Prompt should all be named: Oracle's User Form Name (where is ERP. For example, ERP Enter Orders.
* Create another form with fields/logic and copy/reference the form into the standard Oracle form. This form should be maintained in AUG_TOP/forms/US with a filename of custom__ and does not need to be generated. The purpose of this form is to make reapplying customizations easier after a patch or upgrade.

* Create an Oracle application upgrade/patch instruction document that identifies the steps necessary to re-implement the changes.
8. As a last resort, modify standard oracle database object(s). If you need to modify a standard Oracle view, the vw-info.sql script can be used to compare views from one instance to another. This is useful when checking to see if a patch changes the definition of a view. The script is located in the repository in $ORIG_REPOS/asc_utils.

Custom Library
Oracle provides a library that gives you the ability to alter the functionality of a standard Oracle form without changing the form. The library is named CUSTOM.pll and is attached to all forms. All Oracle forms (are supposed to) call the EVENT procedure in this library from the following triggers:
* WHEN-FORM-NAVIGATE
* WHEN-NEW-FORM-INSTANCE
* WHEN-NEW-BLOCK-INSTANCE
* WHEN-NEW-RECORD-INSTANCE
* WHEN-NEW-ITEM-INSTANCE
* WHEN-VALIDATE-RECORD
Some forms call this procedure from additional triggers (check for calls to CUSTOM.EVENT within the form code). The Custom Library is also called for Special Menu options, Zoom and Export.


CUSTOM Library has custom forms libraries attached to it. There is one custom forms library per form which is called at run time based on the name of the current form. These custom forms libraries are named CUSTOM_XXXXXXXX where XXXXXXXX is the Oracle form name whose functionality is altered by the code in the library. Only one developer can update the CUSTOM library at one time. To ensure that developers do not run into contention with one another, the CUSTOM library (the one that we customize, not the default one supplied by Oracle) cannot be placed on a shared drive where other developers are modifying forms.

The libraries are located in the $AUG_TOP/resource directory to mimic how Oracle maintains its libraries which are in $AU_TOP/resource. The forms server has its FORMS60_PATH set to look in our library directory and then Oracle’s. This allows us to have a CUSTOM library while leaving the Oracle provided version intact and insulates us from patches that may overwrite the CUSTOM library. Any time that we get an Oracle patch that alters the CUSTOM library, we should verify that we do not need to change our CUSTOM library.

CUSTOM Library Setup
As mentioned previously, it is very important that modifications to the custom library be performed with care to prevent disruption to other developers. The following are requirements for maintaining the Custom Library:

1. Create a separate directory for custom library development

2. Prevent other developers from locking the custom forms libraries.

3. In order to modify the CUSTOM library, you must FTP the CUSTOM library along with all of the CUSTOM_XXXXXXXX.pll files to the directory that you set up in Step 1. An alternative to this is to use an X-windows emulator (like exceed) and modify the library directly on the SUN box. Be sure to make a back-up copy of the library before making modifications and DO NOT generate the library from the forms tool. Use f60desm to get into the forms tool from an X-windows session.

4. When you generate libraries, all CUSTOM_XXXXXXXX.pll files must be generated before CUSTOM.pll is generated. Therefore, when you add a new CUSTOM_XXXXXXXX.pll file, you must generate that file before regenerating the updated CUSTOM.pll.

**Note: You may get write protection/sharing violation errors when you try to save a library when it is attached to an open form. That is why it is important your FORMS60_PATH is set correctly.

Creating a Custom Forms Library
If your form requires modification that can be accomplished through the Custom Library, you will need to begin by completing the following steps:

1. Create a CUSTOM_XXXXXXXX.pll file containing a Package by the same name. The package must include a procedure called EVENT. This is the procedure that you will use to handle any of the events passed to the Custom library. Place your library in the $AUG_TOP/resource directory. If one custom form library has errors, it will cause everyone to get errors from the Custom library or possibly APPCORE.
2. Add the copyright and version information for the library.
3. Add additional logic to the library and attach additional libraries, as needed. Remember that you cannot call any APPCORE routines or use SQL statements in the Custom Library.

4. FTP your library to the $AUG_TOP/resource directory and use the gen_lib shell script to generate the library. (For example, to generate the CUSTOM_OEXOEMOE library you would type gen_lib CUSTOM_OEXOEMOE.) This will create your executable .plx file. If you are logged into the apps when you generate your library, you must log out and log back in again to see your changes.
5. If you need to turn off your custom code while testing your form, use the Help/Diagnostics/Custom Code/Off menu option to prevent the Custom Library from being called. The Custom library can be turned of at any point and turned back on again.
6. Once you are ready to check your form into the repository, be sure to edit the repository's generate_all_libraries script, to add the appropriate generate statement for your library. This file is located in the $AUGX_REPOS/resource directory of the repository.

Special Menu
To modify or add options to the special menu through the custom library, you need to use standard Oracle Forms 6i functions. Below are some of the functions
1. set_menu_item_property('SPECIAL.SPECIAL14', ENABLED, PROPERTY_FALSE);
2. set_menu_item_property('SPECIAL.SPECIAL14', DISPLAYED, PROPERTY_FALSE);
3. set_menu_item_property('SPECIAL.SPECIAL14', LABEL, 'Revenue Splits');
4. set_menu_item_property('SPECIAL.SPECIAL14', DISPLAYED, PROPERTY_TRUE);

For examples, review the library for the Enter orders form custom_oexoemoe.pll.

Form Personalization
With 11.5.10 Oracle introduced new functionality for altering the behavior of forms without having to use the forms designer. Form Personalization is similar to the Custom library, using the same events and responds identically to the Custom Code ‘Normal’, ‘Off’ and ‘Core Code’ settings. In general, Oracle recommends using the Form Personalization feature rather than the Custom library whenever possible. .

To use the Form Personalization feature, open the form (or function) that you want to alter. Then select Help -> Diagnostics -> Custom Code -> Personalize from the menu. A form will appear for entering/updating the personalizations related to the form/function. Each personalization has its own sequence number and description. The Seq indicates the order in which the personalizations are to be evaluated and is not required to be unique. The Description should include an overview of what the personalization is for as well as the requirement number. The Level can be Form or Function. It is recommended that the level is set to Form unless the conditions are only being applied to one Function (for example, the Query Only function for the form). This way the form will react the same way regardless of the function used to open it.

On the Condition tab is used to indicate the condition under which the Actions are to take place. For the Context Level it is not recommended that Responsibility be used unless the personalization is for one specific operating unit/responsibility. Otherwise, the personalization would have to be altered each time a new Operating Unit is added. (For example, Customer Implementation Specialist would be a bad Responsibility Level Context because this responsibility exists for each Operating Unit.)

On the Actions tab (shown below), are the actions that are to take place when the Condition (defined on the Condition tab) is met. The Seq is a number that indicates the order in which the actions are to be applied and does not have to be unique. The Type can be Property, Builtin, Message or Menu. The Description should describe the action that is to be performed as well as indicate the requirement number. The right hand side of the screen will change depending on the Type and the selections that are chosen.


When the Apply Now button is presses, the Condition will be evaluated immediately and the Actions will take place accordingly. In the example shown above, pressing the Apply Now button will set the Displayed property on COPY.VERSION_NUMBER to False. Once changes are save on the Form Personalizations screen, the personalizations can be activated by closing and re-opening the form being personalized.

Using a View as the Base Table
It is highly recommended that blocks which contain information from more than one table be based on a view. Whenever possible, you should use a view instead of selects in POST-QUERY triggers. The main reason you should use a view is to reduce network traffic - POST-QUERY logic will not be needed to go back out to the database to lookup field values. Views are also nice because they allow the user to query on fields that may otherwise be display only. The form developer does however have to do a little more work in the form to handle locking, updating, inserting and deleting the appropriate table(s). In general, the extra time spent by the developer will be worth the reduced network traffic and subsequent performance gains. Any time that you create a view to be used as the base table for a block, you must include the ROWID and who columns from main table in the view. These fields will be needed to display who information. In addition, the ROWID is needed for locking, updating and deleting the row.

Creating Functions for Columns in a View
When you are creating a view with a single value from another table, it may be more efficient to create a function to bring back the value and use that function as part of the SELECT for the view definition. For example, if you just need to display the Meaning of a Lookup Code from SOC_LOOKUPS based on a specific Lookup Type and a Code value in your base table, you could create a function similar to the following:

function SOC_LOOKUP_VALUE ( LOOKUP_TYPE_STR in varchar2,
LOOKUP_CODE_STR in varchar2 )
RETURN VARCHAR2
IS
lookup_value VARCHAR2(80) := NULL;
cursor LOOKUP_CURSOR is select MEANING
from SOC_LOOKUPS
where LOOKUP_TYPE = LOOKUP_TYPE_STR
and LOOKUP_CODE = LOOKUP_CODE_STR;
BEGIN
if ( LOOKUP_CODE_STR is not NULL ) then
OPEN LOOKUP_CURSOR;
FETCH LOOKUP_CURSOR INTO LOOKUP_VALUE;
if (LOOKUP_CURSOR%FOUND) then
CLOSE LOOKUP_CURSOR;
return (LOOKUP_VALUE);
else
CLOSE LOOKUP_CURSOR;
return (NULL);
end if;
else
return (NULL);
end if;
END;

Please note that the above function already exists in the package OEC_QUERY. You should not re-create this function – please use the one in OEC_QUERY. Any time that you need a function, you should first check to see if one already exists. In addition, you should always write functions so that they can be reused. For example, in the function above, the LOOKUP_TYPE is passed in as a value rather than being hard-coded. This promotes reusability of the function.

When you are creating functions to be used in views, you must add the following line in the package specification after defining the function:
pragma RESTRICT_REFERENCES (SOC_LOOKUP_VALUE, WNDS, WNPS);
This statement tells the Oracle parser that the function does not change any database values. This statement is important because you cannot use a function in a select statement that alters data within the database (i.e., it cannot update, insert or delete records or alter database objects). If you are calling other procedures or functions in your function, you must remove the WNPS portion of the statement above or you will get an error when you compile your package.

The OEC_QUERY procedure has many other functions that may be useful when defining views. This package is located in the ERP oec_pl.sql script. If you need to create additional functions, these should be created in the appropriate XXX_QUERY package where XXX is the application short name. These packages should be included in the appropriate application SQL script.

Creating a view using functions
Once you have created functions, you can then use those functions to use in the select portion of your view. Below is an example using the function SOC_LOOKUP_VALUE as part of the view for the Apollo Import form. This view was needed because the form must allow the user to enter the Meaning for an Order Action as opposed to a Code and a Pop List could not be used in this case. Also, the Meaning for a Status Code is displayed rather than the code.

create view INF_APOLLO_20_REQUESTS_V
(ROW_ID,
REQUEST_ID,
LAST_UPDATE_DATE,
LAST_UPDATED_BY,
CREATION_DATE,
CREATED_BY,
ORDER_ACTION_CODE,
ORDER_ACTION_MEANING,
RQST_ORDER_NUMBER,
RQST_STATUS_CODE,
RQST_STATUS_MEANING,
ORIGINAL_SYSTEM_REF,
SYSTEM_ERROR_DESC)
as select
ROWID,
REQUEST_ID,
LAST_UPDATE_DATE,
LAST_UPDATED_BY,
CREATION_DATE,
CREATED_BY,
ORDER_ACTION_CODE,
OEC_QUERY.SOC_LOOKUP_VALUE ('INF_APLO_ORDER_ACTIONS',ORDER_ACTION_CODE),
RQST_ORDER_NUMBER,
RQST_STATUS_CODE,
OEC_QUERY.SOC_LOOKUP_VALUE ('INF_APLO_STATUS',RQST_STATUS_CODE),
ORIGINAL_SYSTEM_REF,
SYSTEM_ERROR_DESC
FROM INF_APOLLO_20_REQUESTS

Please note that the script to create the functions must run before the script that creates views using those functions. For this example, the view is located in inf_vw2.sql. The vw2 indicates that the view script should be run AFTER the function scripts.

When you create a view, you should always ensure that the SELECT portion of the view has been fully optimized. SQLab and other SQL tuning techniques should be used for this purpose.

When Should Functions be used in a View
* When you need one value from another table
* To eliminate outer joins
* When the data cannot be easily selected as part of a join condition
* To simplify the view definition and improve readability

When NOT to use Functions in a View
* When you need more than one column from a particular table. A join should be used in the case. (If you need to do an outer join, you may want to test the performance differences between using multiple functions and using an outer join.)

Using Parameters from the Menu
Scenario: We need to pass into a form a parameter from the menu which will indicate to the 'Revenue Lines Split' form(OECRVSPL.fmb) whether it should display the canvas-views related to header level splitting, or line level splitting. Also we will use the parameter to dynamically set the default where clause for the generic first block.

1. Define PARAMETER in Form. In this example, parameter is called 'TYPE_OF_SPLIT' and is char 30.
* Highlight Parameter
* Press the Create button
* Pull up the Properties sheet to change the name and attributes
2. Add parameter to the Function used by the menu. In Menu function define the value that you want to set it to.
* Query up your form function on the Functions screen
* Select the Form region and place your cursor in the Parameters field.
* Enter the parameter name (make sure that you use the same name that you created in your form) followed by an equal sign and a value. For example, TYPE_OF_SPLIT=LINES
3. Utilize parameter in form logic.
Example in package OECRVSPL_OTHERS (Procedure called from WHEN-NEW-FORM-INSTANCE.), we have the following code:

PROCEDURE DISPLAY_CANVAS IS
BEGIN
if :PARAMETER.TYPE_OF_SPLIT='HEADER' then <----- note, use of ':' hide_view('ord_lines_ccv'); set_block_property('ORDER_INFO_CB',DEFAULT_WHERE,'where line_id is null'); set_block_property('REV_LINES_CB',DEFAULT_WHERE,'where line_id is null'); set_item_property('order_type',next_navigation_item,'order_number'); set_item_property('order_number',previous_navigation_item,'order_type'); elsif :PARAMETER.TYPE_OF_SPLIT='LINES' then set_block_property('ORDER_INFO_CB',DEFAULT_WHERE,'where line_id is not null'); show_view('ord_lines_ccv'); end if; END DISPLAY_CANVAS;

Hints and Tips

* Save frequently. Occasional GPF errors can result in lost work.
* Compile errors may cause the designer to shut down, so you should save changes before you Compile packages and procedures.
* If you do not have ROW_ID as one of the columns in a view, the Who information will not be displayed correctly.
* If a package begins to get too large, split it logically into more than one package. Packages should be limited to less than 64K and fewer than 25 procedures. If your package is too large, create another one by the same name with the number 2 (or 3, 4, 5, etc., as needed) added to the end.
* If you get an error in the PL/SQL Editor that does not make sense (i.e., Error at Line 0, Column 0…), try using File Compile All.
* CTRL-B is the Key Menu key and can be used to get the LOV for Alt Regions.
* CTRL-Shift-<> can be used to add an item.
* To rename a program unit, open the PL/SQL editor and change the definition of the Package or Procedure. When you save the Package or Procedure, the Program Unit name will reflect the Package or Procedure’s new name.
* When a referenced form is changed, you must FTP both the referenced form and the one that is using the reference.
* To find where an object is referenced from, look at the Reference Information property. If a More button does not show up at the top of the window, look at the next higher level or Object Group.
* Alternative Regions are not easy to code.
* Some forms have referenced LOVs and other objects from “standard” application forms (for example, OEXSTAND). These LOVs are returning values into blocks that do not exist in the “standard” form, so you cannot alter them.

* Dependent and/or conditionally mandatory fields may cause problems when querying records because the code does not fire at the right time and you may get a “Field must be entered” error message an some rows will not be returned. See Tara for a work-around.
* You cannot call APPCORE routines from the Custom Library, so putting code in triggers when customizing Oracle forms may be easier than trying to use the Custom library.
* Views are a pain to code, but they are better for performance reasons than POST-QUERY selects.
* You should not use a combination block for header and detail information because the header will be cleared when you query. Use a dummy block to hold the header information.
* When calling messages from the Message Dictionary, be sure that the name is typed exactly as it is defined in the Message Dictionary. Be especially careful of imbedded spaces, which may be hard to see.
* You must FTP forms, libraries and reports as binary. If you use ASCII, you will get a cannot open file message.
* The file extensions must be in lower case (i.e., forms does not recognize .FMB files).
* To ensure that file ownership is correct, FTP and generate files as devmgr.
* You must have write permissions on form (.fmb) and library (.pll) files to be able to generate them. You will get “Cannot create form file” error messages if the permissions are not correct.
* If a library attached to the CUSTOM library is missing, you will get an error message about APPCORE when you try to generate forms.
* If you get the message ‘Record was updated by another user’ when you try to change a value in a block based on a view, check your LOCK_ROW procedure and make sure that you are comparing the fields correctly (fields that can be null must have the null conditions tested; ROWID in the view must be from the same table that your cursor is using; forms removes trailing spaces, so you may need to use rtrim.)
* The APP_ITEM_PROPERTY.SET_PROPERTY routine does not always work correctly for buttons, pop lists, check boxes and display items. Make sure that the properties being set can be set for the item.
* All select statements in triggers should be encapsulated in an exception handling routine especially for NO DATA FOUND or possibly, TOO MANY ROWS.
* Forms 2.3 only returns one value in a select statement even if more than one row exists. To reproduce this in Forms 4.5, you should use a cursor or add where rownum = 1 to the select.
* Field attributes must be set and unset on a record by record basis. Setting an attribute changes it for all records.
* You cannot have an attached library and a referenced form by the same name.
* Excluding a function from an Oracle form does not necessarily prevent navigation to the region or totally disable the functionality. Be sure that you test to ensure the function is disabled using both mouse functions and keyboard shortcuts and keys.
* If you want to disable a trigger, you can delete it (since your code is in a procedure rather than in the trigger) or comment out the procedure call and add a null; statement to the trigger.
* Debug only shows what the changes are in the form and not necessarily each trigger that is being fired.
* When you add new fields to an existing block, it appears that the new fields are automatically placed at the beginning of the block. You will need to move them to the correct location within the navigator.
* A stacked canvas will automatically display when the cursor is in a field on the canvas. To prevent a canvas from displaying automatically out of sequence, make sure that your field prompting sequence is correct.
* If you want a scroll bar to automatically appear on a stacked canvas view, make the Width/Height size smaller than the Display Width/Height and set the View Vertical/Horizontal Scroll Bar to True.
* Any time you get the message ‘Attached library … contains a non-portable directory specification. Remove Path?’, answer YES to remove the path. If you answer No, you will get FRM-99999 errors. You will need to remove and reattach all libraries. (FNDSQF, APPCORE and APPDAYPK are the only libraries attached to the template form – all others are attached to these libraries.)

New Hints/Tips –Forms 6i:

* To convert a form to a text format, use the File-->Administration-->Object List Report option in the Forms Builder (Forms 6i tool). This file (.txt) will show the properties of all form objects, code in triggers, procedures (and so forth), in text format. Note: When using the File-->Administration-->Convert, Form, Binary to Text option, the file (.fmt) that is produced will show the code in the triggers and procedures in hexadecimal format.
* Property Class Names are specified by clicking in the "Subclass Information" property. A "Subclass Information" window opens up. Within this window, you can click on the "Property Class" radio button, to specify the Property Class Name value.
* The "Canvas Type" Property for a TAB Canvas should be set to TAB. If you place a value other than TAB_CANVAS (or leave it null) in the "Subclass Information" Property, the "Canvas Type" Property is auto. flipped to CONTENT. Need to be aware of this because once this is done, your Layout Editor will look WACKY! Also, by that "Canvas Type" Property being flipped to CONTENT, you will no longer see your Tab Pages under the Canvas node. You have to flip the "Canvas Type" Property back to TAB. Then you'll see your Tab Pages under the Canvas node, again.


No comments: