Oracle Forms Customization:


CUSTOMIZATION OF FORMS
Form Customization:

  • Open template.fmb from c:\Apps10\fnd75\forms\us in the Object navigator and save this file with u r custom name before doing any changes to template.fmb.
  • Delete the blocks BLOCKNAME and DETAILBLOCK.
  • Delete the canvas BLOCKNAME.
  • Delete the window BLOCKNAME.
  • Create the base table block with name EMP in the canvas with name MYCAN in the window MYWIN.
  • Set the window and canvas properties for the respective window and canvas.
  • Also set the First navigable block property of the form to EMP.
  • Modify the PRE_FORM trigger as app_window.set_window_position(‘MYWIN’, ‘FIRST_WINDOW’);.
  • Modify the APP_CUSTOM(Package Body) as
if (wnd = ‘MYWIN’) then
app_window.close_first_window;
RETURN;
elsif (wnd = ‘’) then.
  • Set property classes of all custom defined objects to their respective property classes defined apps.
  • To read the Apps Packaged procedures, Ex: — open the c:\Apps10\au10\res\plsql\fndsqf.pll (the library module and then read the respective package in PL/SQL editor).
 Tracking Data Changes with WHO
 The WHO feature reports information about who created or updated rows in Oracle Applications tables. Oracle Applications upgrade technology relies on WHO information to detect and preserve customizations. If you add special WHO columns to your tables and WHO logic to your forms and stored procedures, your users can track changes made to their data. By looking at WHO columns, users can differentiate between changes made by forms and changes made by concurrent programs.
You represent each of the WHO columns as hidden fields in each block of your form (corresponding to the Who columns in each underlying table).
CREATE TABLE EMP WITH EXTRA WHO COLUMNS
1 CREATED_BY NUMBER(15) NOT NULL
2 CREATION_DATE DATE NOT NULL
3 LAST_UPDATED_BY NUMBER (15) NOT NULL
4 LAST_UPDATE_DATE DATE NOT NULL
5 LAST_UPDATE_LOGIN NUMBER (15)
6 REQUEST_ID NUMBER(15)
7 PROGRAM_APPLICATION_ID NUMBER(15)
8 PROGRAM_ID NUMBER(15)
9 PROGRAM_UPDATE_DATE DATE
10 Write the two block level triggers PRE-UPDATE and PRE-INSERT with the following code
  • set_who
11 For the blocks which don’t have who columns disable the about menu using the following WHEN-NEW-BLOCK-INSTANCE block level trigger with style property of the trigger
override
  • event(’WHEN-NEW-BLOCK-INSTANCE’);
  • enable(’ABOUT’, PROPERTY_OFF);
12 Set the who columns class properties of date columns to
CREATION_OR_LAST_UPDATE_DATE and rest of the columns to TEXT_ITEM class property.
Form properties
  1. Property Class: Warning: Do not change any values set by the MODULE property class.
  1. Module Names: Make sure that in each of your forms, the Module Name matches
the file name. For example, if a form is called POXPOMPO.fmb, make sure the
Module Name (visible in Oracle Forms Designer) is POXPOMPO.
 First Navigation Block: Set this property to the name of the first block that users
visit when a form is run. Do not set to a WORLD or CONTROL block. This property also controls where the cursor goes after a CLEAR_FORM, as well as the default ’Action à Save and Proceed’ behavior.
 4 From the APPSTAND form, windows automatically inherit the proper look and feel of the GUI platform on which they are running, such as characteristics of the frame, title bar fonts, and window manager buttons. This section describes features common to all Oracle Applications windows, as well as behaviors for modal and non-modal windows.
 ROOT_WINDOW
The ROOT_WINDOW is a special Oracle Forms window that behaves differently from other windows. Do not use the ROOT_WINDOW, because it interferes with the proper functioning of the Toolbar and other standard Oracle Applications objects.

Blocks

Most standard Oracle Forms functions, such as Save, Next Block, and Clear all do not apply in a dialog block. Although the Oracle Applications menu and toolbar may not be accessible, Oracle Forms Functions can still be invoked from the keyboard unless you disable them. You should disable all KEY- triggers for the block by coding a KEY-OTHERS trigger that calls APP_EXCEPTION.DISABLED, which will cause a beep when the user attempts a disabled function. You then specifically enable some functions for the block by coding the following additional KEY- triggers:
 An Example of a Dialog Block with a single record is “Help about this record” menu (of WHO columns details)
 You may need to implement blocks that have no base table or view. Use transactional triggers (ON-INSERT, ON-LOCK, etc.) if such a block must process commits.
Do not base the block on a dummy table such as FND_DUAL.
 Drill Down Indicator
If the multi-record block supports drilldown to one or more detail blocks, create a drilldown indicator as follows:
  • Create a text item in the multi-record block. Name it ’DRILLDOWN_RECORD_INDICATOR’, and apply the property class ’DRILLDOWN_RECORD_INDICATOR.’
  • Add an item-level WHEN-NEW-ITEM-INSTANCE trigger (Execution Style: Override) to the drilldown indicator item. Call the same logic as the button that corresponds to the drilldown block. For Combination blocks, this should move to the Detail window. In other blocks, if there are one or more child blocks, drilldown moves you to one of them.
Ex:- In BOM while defining the bills.
 Summary-Detail
 Combination blocks are hybrid formats, where fields are presented in both multi-record (Summary) and single-record (Detail) formats. The Summary and Detail formats are each presented in their own window, but all of the fields of both formats are part of a single block.
Attention: Do not confuse the Detail of Summary-Detail
                   with the Detail of Master-Detail.
 Master-Detail
 Prevent Masterless Operations A user cannot enter or query detail records except in the context of a master record. Always set this property to
  • Prevent Deletion of Detail Records Because your form should be built using underlying views instead of actual tables, you should not allow the normal Oracle Forms deletion of detail records. Instead, set the Master Deletes property of the relation to Isolated. Then, delete your detail records as part of your Delete_Row procedure in the table handler for the master table.
Other Behaviors
 @ When a detail block is in a different window than its master, but the detail window is modal, the detail block should only query upon navigation to the  block. Set Deferred to True and AutoQuery to True for the relation. Do not
code any logic for this relation in the OPEN_WINDOW or CLOSE_WINDOW procedure.
 @ The first master block of a form does not autoquery unless
     – Only a very small number of records will be returned
     — The query will be fast
     — Most likely the user will operate on one or more of the queried records
To autoquery the first block of a form, code the following:
Trigger: WHEN-NEW-FORM-INSTANCE
               do_key(’execute_query’);
 @ Do not code anything specific to windows being iconified, even though      iconifying a window that contains a master block may make it difficult to operate with a detail block.
 @ Do not use Master-Detail cascade delete because it is an inefficient operation on the client side. It also generates triggers with hardcoded messages.
Properties of Widget Objects
The following topics are covered:
  • ? Text Items
  • ? Display Items
  • ? Poplists
  • ? Option Groups
  • ? Check boxes
  • ? Buttons
  • ? Lists of Values (LOV)
  • ? Alerts
  • ? Editors
  • ? Flexfields
  • ? Setting Item Properties Dynamically
Data Type
For date fields, use the DATE data type unless the user needs to enter time. Use the DATETIME data type to require the user to enter time. To default a form field to the current date without the time, use $$DBDATE$$. To default a form field to the current date and time, use $$DBDATETIME$$.

Date Field Maximum Length

Create date fields as 11 characters without time, or 20 characters with time. You do not need to specify a format mask in the item. Oracle Forms defaults the format correctly for each language from the environment variable NLS_DATE_FORMAT. Oracle Applications currently requires an NLS_DATE_FORMAT setting of DD-MON-RR. Forms date fields that are 11 or 20 characters long will display a four-character year (DD-MON-RRRR) automatically.

Date Field Validation

In general, validate your date fields at the record level rather than at the item level.
Record level validation allows the user to correct errors more easily, Especially in a From Date/To Date situation. After entering an Incorrect date (last year instead of next year), the user should not need to change first the To Date before correcting the From Date.
 Poplists

Poplists are used for two distinct purposes in Oracle Applications:
To hold data in a small list of possible values, and to set the displayed region for a set of alternative regions.
 Limits
The maximum width of a list element is 30 characters. Your longest value in English for a 30-character-wide poplist should be no longer than 23 characters to account for expansion of values for some languages.
Dynamic List Elements
You may need to populate a list at runtime. If so, be aware of the following issues:
  • ? Never use a list item if you expect more than fifteen elements
  • ? Do not change a list on a per-record basis
  • ? Make sure each populated list has a value that matches the default value. You can
dynamically change the default by specifying it as a reference to another field, as opposed to a hard coded value.
Option Class(Radio buttons)
Property Class

Apply the RADIO_BUTTON property class to each button of an option group.

There is no property class to assign to the group itself.

 Check Box
Property Class
Apply the CHECKBOX property class to each normal check box (used for data entry). Apply the CHECKBOX_COORDINATION property class to each coordination check box.
 Buttons

Property Class

Textual buttons use the BUTTON property class. Iconic buttons use the BUTTON_ICONIC property class and typically appear only in the toolbar or in folder forms.
Warning: Never override the height specified by the BUTTON property class.
 Navigable and Mouse Navigate Properties
Single record block buttons are Navigable TRUE. Multi-record block buttons are Navigable FALSE. The exception is Clear buttons, which should always use Navigable FALSE. This is to prevent users from accidentally clearing records when they expect to fire the default button.
All buttons are Mouse Navigate False.
 Enter-Query Mode
Most buttons do not apply in Enter-Query mode. Users cannot leave the current record while in this mode. You do not need to explicitly disable a button while in Enter-Query mode; instead set the trigger property ”Fire in Enter-Query mode” for the WHEN-BUTTON-PRESSED trigger to FALSE. Call APP_STANDARD.APP_VALIDATE Buttons should call APP_STANDARD.APP_VALIDATE and pass a scope before performing their action. This ensures that your records are valid before performing an action, and that the button acts on the expected block.
 lists of Values (LOVs)
Use Lists of Values to provide validation on a text item when you expect to have more than fifteen values.
 Auto Refresh
If the values displayed by the LOV are static during a session and the number of rows is not excessive, turn Auto Refresh off (False) to cache the LOV values for the session. Caching the values avoids database hits and network round trips for subsequent invocations of the LOV, and eliminating unnecessary round trips is a key factor in producing a product that can run on a wide area network. However, the caching consumes memory that is not recovered until the form is closed.
 Long List
If an LOV may show more than one hundred rows, then the user must be prompted to reduce the list of valid values first (Long List: True). Never have Long List set to True, and Auto Refresh set to False, on an LOV. This combination would cause only the reduced set of rows to be cached if the user enters something in the reduction criteria window.With Auto Refresh off, there is no way of returning to the full set of rows. Typically it is not wise to cache an LOV that returns more than 100 rows.
 Dependent Fields
An LOV on a dependent field should use the value in the master field to reduce the list.
For example, if NAME is dependent on TYPE, the entry LOV for NAME’s WHERE clause would include the condition:
WHERE TYPE = :MY_BLOCK.TYPE
LOVs in ENTER-QUERY Mode
LOVs in ENTER-QUERY mode should be used sparingly, as QueryFind is the preferred method for a user to locate records. You should only code them where they dramatically improve the usability of ENTER-QUERY mode, and you expect this mode to be used regularly despite Query Find.
 Attention: WHEN-VALIDATE-ITEM does not fire in ENTER-QUERY mode. Therefore, you cannot depend on the WHEN-VALIDATE-ITEM trigger to clear hidden fields when selecting from an ENTER-QUERY LOV.
 Implementation
To enable LOVs in ENTER-QUERY mode on an item, create an
item-level KEY-LISTVAL trigger as follows:
Trigger: KEY-LISTVAL
IF (:SYSTEM.MODE != ’ENTER-QUERY’) THEN LIST_VALUES;
ELSE SHOW_LOV(’query lov’);
END IF;
 Alerts
Oracle Applications does not use the native Oracle Forms alert object. The Oracle Application Object Library Message Dictionary feature is used instead, as it provides full translation capabilities and handles text larger than 80 characters.
Editors
Do not write special code for the editor. Rely on native Oracle Forms behavior.
CODING MASTER -DETAIL RELATIONSHIPS
When a detail block is in a different window than its master, and each window is non-modal, then the detail block must provide a mechanism for the user to toggle between immediate and deferred coordination. This allows a user to keep a block visible, but control the performance cost of coordinating detail records when the master record is changed. When a detail block is not visible, its coordination should always be deferred. Use the procedure APP_WINDOW.SET_COORDINATION to coordinate master-detail blocks in different windows.
the sample code below uses the following objects:
  •  Master block ’DEPT’, in window DEPTWIN
  •  Detail Block ’EMP’, in window ’EMPWIN’
  •  Relation DEPT_EMP
  •  Coordination check box ’CONTROL.CO_ORD
  •  Button to navigate to the EMP block ’CONTROL.EMPLOYEES’
 Step 1
Create a button to navigate to the detail block.
 Step 2
Create a coordination check box in a control block in the detail window to specify the user’s preference of immediate or deferred coordination when the window is open. The check box should have the CHECKBOX_COORDINATION property class, which provides a value of ”IMMEDIATE” when checked and ”DEFERRED” when unchecked.
The check box value should default to checked (IMMEDIATE).
 Step 3
Create your item handler procedures as follows:
PACKAGE BODY CONTR IS
PROCEDURE EMP_PACK(EVENT VARCHAR2) IS
BEGIN
IF (EVENT = ‘WHEN-BUTTON-PRESSED’) THEN
app_custom.open_window(‘EMPWIN’);
END IF;
END EMP_PACK;
PROCEDURE CO_ORD_PACK(EVENT VARCHAR2) IS
BEGIN
IF (EVENT = ‘WHEN-CHECKBOX-CHANGED’) THEN
APP_WINDOW.SET_COORDINATION(EVENT,:control.CO_ORD,’DEPT_EMP’);
END IF;
END CO_ORD_PACK;
END;

Step 4

CLOSE WINDOW
if (wnd = ‘DEPTWIN’) then
app_window.close_first_window;
RETURN;
elsif (wnd = ‘EMPWIN’) then
–defer relations
–close related windows
APP_WINDOW.SET_COORDINATION(‘WHEN-WINDOW-CLOSED’,:CONTROL.CO_ORD,’DEPT_EMP’);
elsif (wnd = ‘’) then
–defer relations
–close related windows
null;
end if;
OPEN WINDOW
if (wnd = ‘EMPWIN’) then
–position the window
–reset master-detail relations
–navigate to a block in the window
APP_WINDOW.SET_COORDINATION(‘OPEN-WINDOW’,:CONTROL.CO_ORD,’DEPT_EMP’);
GO_BLOCK(‘EMP’);

Step 5

Call your field and event handler procedures in:
Trigger: WHEN-BUTTON-PRESSED on control.EMPLOYEE
control.EMP_PACK(’WHEN-BUTTON-PRESSED’);
Trigger: KEY-NXTBLK on ORDER:
control.EMP_PACK(’WHEN-BUTTON-PRESSED’);
Trigger: WHEN-CHECKBOX-CHANGED on control.CO_ORD:
control.CO_ORD_PACK(’WHEN-CHECKBOX-CHANGED’);
 Calendar: Properties
  1. In order to show the calendar in the date field   Raise Item level key-listval
Trigger and type the code
Calendar.show;
   in order to disable the date ranges then in the item level KEY-LISTVAL trigger write the >> syntax >>calendar.setup(<30 char="" identifying="" name="">, ,   ); >>> following code>>
calendar.setup(‘kamalakar’, ’02-MAY-00′,’10-MAY-00′);
calendar.show;
Disable Weekends in the Calendar Window
To disable weekends (where the weekend is defined as Saturday and
Sunday):
calendar.setup(’WEEKEND’);
 Display Only Mode
calendar.setup( ’DISPLAY ’ );

Adding 30 Days
Enter a date in demand_date Call this in the hiredate key-listval to add 30 days to
demand and assign to hiredate field >> calendar.show(:EMP.demand_date + 30);

Menus
If the menu item is not controlled by the default menu control, use any
trigger (typically PRE-BLOCK or WHEN-NEW-BLOCK-INSTANCE),
adding the code:
app_special.enable( ’ the menu item’, PROPERTY_OFF);
Turn the menu item back on when you leave (typically POST-BLOCK)
by calling:
app_special.enable(’ the menu item’, PROPERTY_ON);
 Include the full name of the menu item in this call, for example:
app_special.enable(’EDIT.CLEAR_FIELD’, PROPERTY_OFF);
 If the menu item is controlled by the default menu control, use the
trigger listed (either WHEN-NEW-BLOCK-INSTANCE,
WHEN-NEW-RECORD-INSTANCE, or WHEN-NEW-ITEM-INSTANCE).
 Make the trigger style ”Override” and add the following code:
 app_standard.event(’ TRIGGER_NAME’);
app_special.enable(’ Menu_item’, PROPERTY_OFF);
 If at any time you need to change a property and need to force a refresh of the menu (because the appropriate WHEN- trigger will not fire after the change you made), call APP_STANDARD.SYNCHRONIZE.
The Toolbar and menu are automatically updated by the standard form-level WHEN-NEW-RECORD-INSTANCE, WHEN-NEW-BLOCK-INSTANCE, and WHEN-NEW-ITEM-INSTANCE triggers. If you code these triggers at the item or block level, be sure to set execution style to ’Before.’
 10 – 7 Controlling the Toolbar and the Default Menu
The Special Menu
You can customize the menu to display application-specific values.
The menu supports up to fifteen entries under the ’Special’ entry.
APP_SPECIAL: Menu and Toolbar Control (See page 10 – 9)
 Step 1
Example Special Menu Entry
Suppose you have a special function called ’Book Order’ that you want to add to the menu and the Toolbar. To add ’Book Order’ as the first entry on the Special menu and as an icon on the Toolbar, such that they are only available in the ’Header’ block of a form, do the following: Modify the form level PRE-FORM trigger:

PRE-FORM

app_special.instantiate(’SPECIAL1’, ’&Book Order’, ’bkord’);
 If you plan to translate your form, you should use Message Dictionary, a parameter, or a static record group cell to store the Special Menu entry. You then retrieve the value (which is translated when the application is translated) into a variable and pass the variable to the APP_SPECIAL routine.
For example:
app_special.instantiate(’SPECIAL1’, my_menu_entry, ’bkord’);
 Step 2
Add a form-level PRE-BLOCK trigger:
PRE-BLOCK
app_special.enable(’SPECIAL1’,PROPERTY_OFF);
 Step 3
Add a block level PRE-BLOCK trigger to the block in which you want to enable your special menu entries:
PRE-BLOCK in HEADER block
app_special.enable(’SPECIAL1’,PROPERTY_ON);
Step 4
Add a block level SPECIAL1 user-named trigger that contains code to actually perform your ’Book Order’ function. It executes when the user chooses this menu entry.
 Disabling the Special Menu
To disable all special menu entries (for example, when entering Query-mode), call APP_SPECIAL.ENABLE(’SPECIAL’,PROPERTY_OFF);
 seE the APP_SPECIAL package to enable and customize buttons on the toolbar.
This call constructs the special menu according to your specifications.
Call this function in the PRE-FORM trigger, after the call to APP_STANDARD.EVENT(’PRE-FORM’).
 Example 1
APP_SPECIAL.INSTANTIATE(’SPECIAL3’,’&Book Order’, ’POBKORD’,TRUE);
 Query Find Window
  • Copy the object group called query_find from the appsstand form (c:\apps10\au10\res\forms\us\appsstand.fmb) so that the query_find block,canvas, window and corresponding triggers will be copied.
  • In that query_find block create your own search fields
And attach the respective property classes.,
  • Write the block level (pre-query)trigger in master block not in the control block
IF :parameter.G_query_find=’TRUE’ THEN
/IF u want specific range of values to query /
APP_FIND.QUERY_RANGE(:LOWDATE,:HIGHDATE,’EMP.HIREDATE’);
END IF;
/if u want specific values\
create parameter
if :parameter.g_query_find = ‘TRUE’ then
:emp.ename := :parameter.empname;
:p:parameter.g_query_find := ‘FALSE';
end if;
 IMPORTANT: CHANGE THE QUERY_LENGTH TO 255 AND MAX LENGTH TO 11 OR 9 FOR EACH DATE FIELD.
 Write user defined block level trigger named query_find
APP_FIND.QUERY_FIND(‘EMP_WIN’,’EMP_QF_WIN’,’EMP_QF’);
To attach calendar list to any of the date field :      
 Create a key-listval trigger on the field And just write
Calendar.show;
 Submitting a Transaction Worker Directly as a Concurrent Process The transaction worker can be directly called either from an Oracle Form or a c program. You can also launch a worker from the operating system using the Application Object library CONCSUB utility. You need to specify the following parameters in the given order. HEADER_ID This is the transaction_header_id that you want the worker to process. If no header id is passed the worker will assign itself.
 TABLE Pass 1 for the Interface table and 2 for the temp table.
SOURCE_HEADER_ID This column will be used to select rows to process if HEADER_ID is not specified.
SOURCE_CODE This column is used to select rows to process if header id is not specified.
 CODING ALTERNATE REGION
 1 Create a Control block based on the EMP Window and Create dummy text item with
width=0,length=1,height=0.navigable=false.create a list item with name lines_regions
Create a block based on the EMP table , EMP Canvas with class Content and EMP window
3 Create two canvases stacked in its property sheet DEPT and DETAIL
4   – Put ename and empno in EMP Canvas
– Put job,mgr,hiredate items in DETAIL Canvas
– Put Sal,comm,deptno items in the DEPT Canvas.
– Put these stacked canvas in appropriate place from view >Stacked view drag and put
in the list elements of the list item give the stacked canvas names in the list elements
and also same for the List item values.
– Write the procedure name
CONTROL PACKAGE BODY CONTROL IS
g_canvas_name VARCHAR2(30) := null;
PROCEDURE lines_regions(event varchar2) IS
target_canvas_name VARCHAR2(30);
curr_canvas_name VARCHAR2(30) :=
get_item_property(:system.cursor_item,ITEM_CANVAS);
BEGIN
IF (event = ‘WHEN-NEW-ITEM-INSTANCE’) THEN
IF ((curr_canvas_name in (‘DEPT’, ‘DETAIL’)) AND
(curr_canvas_name != :control.lines_regions)) THEN
:control.lines_regions := curr_canvas_name;
g_canvas_name := curr_canvas_name;
END IF;
ELSIF (event = ‘WHEN-LIST-CHANGED’) THEN
target_canvas_name := :control.lines_regions;
IF (:SYSTEM.MODE = ‘ENTER-QUERY’) THEN
null;
ELSE
IF (:EMP.EMPNO is null) THEN
FND_MESSAGE.SET_NAME(‘APP’, ‘EMPNO_ENTER_ITEM_FIRST’);
FND_MESSAGE.ERROR;
                   :control.lines_regions := g_canvas_name;
RAISE FORM_TRIGGER_FAILURE;
END IF;
END IF;
IF curr_canvas_name in (‘DEPT’,’DETAIL’) THEN
hide_view(curr_canvas_name);
END IF;
show_view(target_canvas_name);
IF (:system.cursor_block = ‘EMP’) THEN
IF (target_canvas_name = ‘DEPT’) THEN
go_item(‘EMP.SAL’);
ELSIF (target_canvas_name = ‘DETAIL’) THEN
go_item(‘EMP.JOB’);
END IF;
END IF;
g_canvas_name := target_canvas_name;
ELSE
fnd_message.debug(‘Invalid event passed to control.lines_regions’);
END IF;
END lines_regions;
END control;
Call this Procedure in the item handlers in the list item trigger >
“WHEN-LIST-CHANGED”
CONTROL.LINES_REGIONS(‘WHEN-LIST-CHANGED’);
Write a block level trigger on EMP >WHEN-NEW-ITEM-INSTANCE
CONTROL.LINES_REGIONS(‘WHEN-NEW-ITEM-INSTANCE’);
Write a block level trigger on EMP >KEY-MENU
IF APP_REGION.ALT_REGIONS(‘CONTROL.LINES_REGIONS’) THEN
CONTROL.LINES_REGIONS(‘WHEN-LIST-CHANGED’);
END IF;
In the form level write two triggers>W-N-F-I
GO_BLOCK(‘EMP’);
GO_BLOCK(‘CONTROL’);
In the form level write two triggers>KEY-CLRFRM
GO_BLOCK(‘EMP’);
GO_BLOCK(‘CONTROL’);
All the blocks and the canvas are dependent on the same EMP Window
CODING KEY FLEX FIELDS

Create a table for key flex fileds, which is based on the foreign key
  1. Create a table KEY_FLEX with the following columns as
CCID                                                                NOT NULL NUMBER(38) PRIMARY KEY
SEGMENT1                                        VARCHAR2(40)
SEGMENT2                                         VARCHAR2(40)
SUMMARY_FLAG                           VARCHAR2(1) default ‘Y’ not null
ENABLED_FLAG                             VARCHAR2(1) default ‘N’ not null
START_DATE_ACTIVE                     DATE
END_DATE_ACTIVE                         DATE
STID                                                    NOT NULL NUMBER(38)
CREATED_BY                                     NUMBER(15)
CREATION_DATE                             DATE
LAST_UPDATED_BY                         NOT NULL NUMBER(15)
LAST_UPDATE_DAT E                     NOT NULL DATE
LAST_UPDATE_LOGIN                    NUMBER(15)
  1. CREATE A SEQUENCE KEY_FLEX_S BASED ON THE KEY_FLEX TABLE.
 CREATE SEQUENCE KEY_FLEX_S START WITH 1 INCREMENT BY1
MAXVALUE 100000;
4 CREATE A FOREIGN KEY TABLE KFEMP WITH THE FOREIGN KEY FIELD
CCID REFERENCES KEY_FLEX(CCID)
EMPNO                                   NUMBER(4)
ENAME                                   VARCHAR2(10)
DEPTNO                                   NUMBER(10)
CCID                                         NUMBER(38) REFERENCES KEY_FLEX(CCID)
STID                                         NUMBER(38)
 Register your Tables in AOL
  • Register your KEY_FLEX TABLE TABLE_TYPE as Special Keyflex
  • Give The Unique id column (CCID),STRUCTURE COLUMN(STID).
  • SAVE IT u will get all the SEGMENTS1 TO SEGMENTn ENABLED.
  • Give the code for Flexfield KFX and Dynamic Insert Feasible YES
  • Register all the PRIMARY KEY KEY COLUMNS (CCID)
  • CREATE A INDEX on the same COLUMN (CCID)
  • Register CUSTOM Table KFEMP and the same SEQUENCE and TABLE TYPE as TRANSACTION TYPE
  • Register your FOREIGN KEY FIELD (CCID)
  • CREATE a FORM Based on the CUSTOM TABLE (KFEMP)
  • Put all the (CCID AND STID )COLUMNS in the NULL CANVAS
  • Add two NON BASE TABLE COLUMNS as (KFDESCRIPTION >>TEXT_ITEM AND DESCRIPTION>DISPLAY ITEM)
  • Write the HANDLERS
KFDESCRIPTION
WHEN-NEW-ITEM-INSTANCE
FND_FLEX.EVENT(‘WHEN-NEW-ITEM-INSTANCE’);
FND_FLEX.EVENT(‘KEY-EDIT’);
FORM LEVEL
PRE-QUERY
FND_FLEX.EVENT(‘PRE-QUERY’);
POST-QUERY
FND_FLEX.EVENT(‘POST-QUERY’);
WHEN -NEW-FORM-INSTANCE
FND_KEY_FLEX.DEFINE(
BLOCK=>’KFEMP’,
FIELD=>’KFDESCRIPTION’,* KFEMP code combination will come
DESCRIPTION=>’DESCRIPTION’,** KFEMP description will automatically come
ID=>’CCID’,
APPL_SHORT_NAME=>’INV’,
CODE=>’KFX’, **** KEY_FLEX
NUM=>’101′);   ****DEFAULT
CALL THIS IN THE FORM LEVEL
PRE-QUERY>>FND_FLEX.EVENT(’PRE-QUERY’);
POST-QUERY>> FND_FLEX.EVENT(’POST-QUERY’);
PRE-INSERT>> FND_FLEX.EVENT(’PRE-INSERT’);
PRE-UPDATE >>FND_FLEX.EVENT(’PRE-UPDATE’);
WHEN-VALIDATE-RECORD>>FND_FLEX.EVENT(’WHEN-VALIDATE-
RECORD’);
WHEN-NEW-ITEM-INSTANCE>>FND_FLEX.EVENT(’WHEN-NEW-ITEM-INSTANCE’);
WHEN-VALIDATE-ITEM>>FND_FLEX.EVENT(’WHEN-VALIDATE-ITEM’);
34 in keyflexfields registration > segments >Create a STRUCTURE for this KEY_FLEX AND ASSIGN ALL THE SEGMENTS1 TO SEGMENTn TO THIS STRUCTURE AND ASSIGN ALL THE VALUE SETS CREATED WITH VALUES TO THIS VALUE SET AND VALUE SET TO THE SEGMENTS1 to SEGMENTSn
 CODING DESCRIPTIVE FLEX FIELDS
 Create a table,for example ORDER_DETAIL for Descriptive Flex field as :
ORDER_NO                              NOT NULL NUMBER(5)
NAME                                         VARCHAR2(20)
ATTRIBUTE_CATEGORY         VARCHAR2(30)
ATTRIBUTE1                             VARCHAR2(150)
ATTRIBUTE2                             VARCHAR2(150)
ATTRIBUTE3                             VARCHAR2(150)
ATTRIBUTE4                             VARCHAR2(150)
ATTRIBUTE5                             VARCHAR2(150)
MY_CONTEXT                         VARCHAR2(30)
CREATED_BY                           NUMBER(15)
CREATION_DATE                     DATE
LAST_UPDATED_BY               NOT NULL NUMBER(15)
LAST_UPDATE_DATE             NOT NULL DATE
LAST_UPDATE_LOGIN           NUMBER(15)
 Grant all privileges to the table.
  1. In the form, create an item DESCFF for the Descriptive Flex field.
Change the properties of the item as :
Query length=2000, Base table=False,Class=Text_Item_Desc_Flex,
LOV=Enable_list_lamp, LOV_For_Validation=False.
  1. Modify the layout.
  2. Register the table created above.
  3. Register the Desc Flex field with AOL as:
App:AOL                                                             Name:MYDESC(User-defined)
Title:
Table App:AOL                                                 Table-name:ORDER_DETAIL
Struct Col:Attribute_Category(from your table)     Context_prompt:
 Attach Segments for MYDESC as:
     You can enter a default value for the Context field. In the Context field values, Global Data Elements is present by default, which can’t be disabled. Add one or more context field names and enable them. In the Segments window, attach the attributes1 to 5(created in table) and the Value Sets to the segments.
 save, Freeze and Compile the Flexfield.
 In the form create a new Program Unit :
    Order_detail package spec

PACKAGE ORDER_DETAIL IS
PROCEDURE DESCFF (EVENT VARCHAR2);
END;
 Order_detail package body

PACKAGE BODY ORDER_DETAIL IS
PROCEDURE DESCFF (EVENT VARCHAR2) IS
BEGIN
IF EVENT=’WHEN-NEW-FORM-INSTANCE’ THEN
FND_DESCR_FLEX.DEFINE(BLOCK=>’ORDER_DETAIL’,
FIELD=>’DESCFF’,APPL_SHORT_NAME=>’FND’,
DESC_FLEX_NAME=>’MYDESC’);
END IF;
END DESCFF;
END;

Form level W-N-F-I :
ORDER_DETAIL.DESCFF(‘WHEN-NEW-FORM-INSTANCE’);
Save and compile.
Form level W-N-I-I:
FND_FLEX.EVENT(‘WHEN-NEW-ITEM-INSTANCE’);
  1. Save and Generate the form.
 Register the form, Define form function, attach to a menu and run.

ENABLING THE FOLDERS FEATURE
 STEPS:
 Copy the Template form into your top directory and save with a different name.
 Create a window, a content canvas and a stacked canvas. Attach the content canvas to the window. In our example, our window is named as Folder and the canvases are named as Main and Folder respectively.
  1. Attach the respective class properties to the canvases and the window you created.
  1. Create one base table block and one non-base table block. In our example, the blocks are Folder and Prompt respectively. The base table block items are to be placed on the stacked canvas.
  1. Attach respective class properties to the blocks and their items. It may be noted here that the items in the Prompt block have a class of Dynamic Prompt.
  1. Delete the APPDAYPK library from your form. After this, copy the APPDAYPK and APPFLDR attached libraries from the APPSTAND form.
  1. Copy the object group Standard Folder from the APPSTAND form.
 Create an item called SWITCHER or FOLDER_SWITCHER in the FOLDER block with class property as SWITCHER. This item contains a WHEN_NEW_ITEM_INSTANCE trigger with the following code :
app_folder_move_cursor(‘1′);
           synchronize;
 Create the following buttons and other items in the Prompt block:
 Buttons:
a.)   Order_by1   (Class will be Folder_orderby).
b.)   Order_by2   ( – do -).
Order_by3 (-do-).
Folder_open (Class will be Folder Open).
Display Item:
Folder_title ( Class is Dynamic Title).
 Text Item :
Folder Dummy (Class is Folder Dummy).
 All the order_by items will go to the stacked canvas and the others will go to the
Main canvas.
  1. Check the Layouts of the blocks.
 Take changes to the following triggers :
 Form Level Triggers :
         WHEN_WINDOW_RESIZED – uncomment the code and fill in the
appropriate window name.
         FOLDER_ACTION - comment the message and uncomment the
app_folder.event call.
         KEY_CLRFRM – uncomment the app_folder.event call.
         PRE_FORM – enter your form name, your application shortname,
author name and also your first window name.
     WHEN_NEW_FORM_INSTANCE – Fill in the parameters for the
app_folder.define_folder_block procedure.
Block Level Triggers :
   KEY_NEXT_ITEM – write the following code :
app_folder.event(‘KEY-NEXT-ITEM’);
   KEY-PREV-ITEM – write the following code :
app_folder.event(‘KEY-PREV-ITEM’);
                     POST_BLOCK – write the following code :
app_folder.event(‘POST-BLOCK’);
                     PRE_BLOCK – write the following code :
app_folder.event(‘PRE-BLOCK’);
                     PRE-QUERY – write the following code :
app_folder.event(‘PRE-QUERY’);
                     WHEN_NEW_BLOCK_INSTANCE – write the following code :
   DECLARE
block_already_initialized   BOOLEAN := FALSE;
BEGIN
app_folder.event (‘WHEN-NEW-BLOCK-INSTANCE’);
IF ( (GET_BLOCK_PROPERTY (‘FOLDER’, Status) = ‘NEW’)
AND (NOT block_already_initialized))
THEN
EXECUTE_TRIGGER (‘QUERY_FIND’);
END IF;
block_already_initialized := TRUE;
END;
KEY_EXEQRY – write the following code :
FOLDER_EVENT.key_exeqry;

  1. Add the following program units :
  2. a) FOLDER_EVENT Package: write the following code :

PROCEDURE key_exeqry IS
BEGIN
app_folder.event(‘KEY-EXEQRY’);
— Save the query
IF (Form_Success) THEN
FOLDER_REQUERY.save;
END IF;
END key_exeqry;

  1. b) FOLDER_REQUERY Package : write the following code :

— PRIVATE VARIABLES
— Holds the where clause of the last query on the folder
— block
last_where VARCHAR2(3000) := null;
— Holds the default where clause of the folder
— block
folder_default_where VARCHAR2(3000) := null;
— Keeps track of whether or not we are in the process
— of requerying
doing_requery_flag BOOLEAN;

— PUBLIC FUNCTIONS

PROCEDURE requery IS
BEGIN
— If this is the first query, then do a blind query
IF (last_where IS NULL) THEN
Go_Block(‘FOLDER’);
Execute_Query;
RETURN;
END IF;
— Set everything up to execute the last query
Set_Block_Property(‘FOLDER’,
Default_Where, last_where);
— Execute the query. Set the doing requery flag
— so that pre-query does not modify the query
Go_Block(‘FOLDER’);
doing_requery_flag := TRUE;
Execute_Query;
doing_requery_flag := FALSE;
— Restore the default where clause
Set_Block_Property(‘FOLDER’,
Default_Where,
folder_default_where);
EXCEPTION
WHEN OTHERS THEN
— Restore the default where clause
Set_Block_Property(‘FOLDER’,
Default_Where,
folder_default_where);
app_debug.setpoint(‘FOLDER_REQUERY.requery’);
RAISE;
END requery;
FUNCTION doing_requery RETURN BOOLEAN IS
BEGIN
return(doing_requery_flag);
END doing_requery;
PROCEDURE save IS
pos       NUMBER;
query_text VARCHAR2(3000);
BEGIN
— Remove everything before the where clause
pos := instr(upper(:System.Last_Query), ‘WHERE’) + 5;
query_text := substr(:System.Last_Query, pos);
— Remove the order by, if there is one.
IF (length(Get_Block_Property(‘FOLDER’, Order_By))
> 0
) THEN
pos := instr(upper(query_text), ‘ORDER BY’, -1) – 1;
query_text := substr(query_text, 1, pos);
END IF;
— Remove any spaces before or after
query_text := ltrim(rtrim(query_text));
last_where := query_text;
END save;
PROCEDURE init IS
BEGIN
null;
END init;
FUNCTION initial_where RETURN VARCHAR2 IS
BEGIN
RETURN(folder_default_where);
END initial_where;
BEGIN
folder_default_where
:= Get_Block_Property(‘FOLDER’, Default_Where);
doing_requery_flag := FALSE;
END folder_requery;


CODING ZOOM


STEP1: CREATE TWO TABLES LIKE DEPT AND EMP
create table dept(
DEPTNO                           NUMBER(2) PRIMARY KEY,
DNAME                           VARCHAR2(14),
LOC                                 VARCHAR2(13))
/
create table emp(
EMPNO                          NUMBER(4) primary Key,
ENAME                           VARCHAR2(10),
JOB                                 VARCHAR2(9),
MGR                                 NUMBER(4),
HIREDATE                       DATE,
SAL                                 NUMBER(7,2),
COMM                             NUMBER(7,2),
DEPTNO                         NUMBER(2) references dept(deptno))
/
STEP2:REGISTER TABLES WITH AOL
EXECUTE ad_dd.register_table(‘SQLGL’, ‘EMP’, ‘T’, 8, 10, 90);

EXECUTE ad_dd.register_column(‘SQLGL’,’EMP’,’EMPNO’,1,’NUMBER’,4, ‘N’, ‘N’);
EXECUTE ad_dd.register_column(‘SQLGL’, ‘EMP’, ‘ENAME’,2, ‘VARCHAR2′,10, ‘Y’, ‘N’);
EXECUTE ad_dd.register_column(‘SQLGL’, ‘EMP’, ‘JOB’,3, ‘VARCHAR2′,9, ‘Y’, ‘N’);
EXECUTE ad_dd.register_column(‘SQLGL’, ‘EMP’, ‘MGR’,4, ‘NUMBER’,4, ‘Y’, ‘N’);
EXECUTE ad_dd.register_column(‘SQLGL’, ‘EMP’, ‘HIREDATE’,5, ‘DATE’,9, ‘Y’, ‘N’);
EXECUTE ad_dd.register_column(‘SQLGL’, ‘EMP’, ‘SAL’,6, ‘NUMBER’,9, ‘Y’, ‘N’);
EXECUTE ad_dd.register_column(‘SQLGL’, ‘EMP’, ‘COMM’,7, ‘NUMBER’,9, ‘Y’, ‘N’);
EXECUTE ad_dd.register_column(‘SQLGL’, ‘EMP’, ‘DEPTNO’,8, ‘NUMBER’,2, ‘N’, ‘N’);
EXECUTE ad_dd.register_table(‘SQLGL’, ‘DEPT’, ‘T’, 8, 10, 90);
EXECUTE ad_dd.register_column(‘SQLGL’, ‘DEPT’, ‘DEPTNO’,1, ‘NUMBER’,2, ‘N’, ‘N’);
EXECUTE ad_dd.register_column(‘SQLGL’, ‘DEPT’, ‘DNAME’,2, ‘varchar2′,14, ‘N’, ‘N’);
EXECUTE ad_dd.register_column(‘SQLGL’, ‘DEPT’, ‘LOC’,3, ‘varchar2′,13, ‘N’, ‘N’);
commit;
STEP3:
CREATE TWO FORMS BY COPYING TEMPLATE.FMB
1) FORM_NAME =ZDEPT | BLOCK_NAME =DEPT
2) FORM_NAME =ZEMP | BLOCK_NAME =EMP
  1. a) CREATE A PARAMETER IN DEPT BLOCK as DEPTNO
  2. b) Change the DEFAULT VALUE property of ZDEPT(DEPTNO)
         SET IT TO :PARAMETER.DEPTNO
  1. c) Change the default value property of dept(block level)
SET IT TO : WHERE (:parameter.DEPTNO is null or DEPT.DEPTNO
LIKE :parameter.DEPTNO)
  1. d) CREATE A PARAMETER IN EMP BLOCK as DEPTNO
  2. e) Change the DEFAULT VALUE property of ZEMP(DEPTNO)
SET IT TO :PARAMETER.DEPTNO
  1. f) Change the default value property of emp(block level)
SET IT TO : WHERE (EMP.DEPTNO LIKE :parameter.DEPTNO)
STEP4:
OPEN LIBRARY CUSTOM.PLL
Which is in C:\APPS10\AU10\RES\PLSQL\CUSTOM.PLL.
MODIFY IT AS :
package body custom is

— Customize this package to provide specific responses to events
— within Oracle Applications forms.

— Do not change the specification of the CUSTOM package in any way.
— You may, however, add additional packages to this library.

——————————————————————–
 FUNCTION zoom_available
RETURN BOOLEAN
IS
form_name    VARCHAR2 (30) := NAME_IN (‘system.current_form’);
block_name   VARCHAR2 (30) := NAME_IN (‘system.cursor_block’);
BEGIN
IF (form_name = ‘ZDEPT’ AND block_name = ‘DEPT’)
THEN
RETURN TRUE;
ELSE
RETURN FALSE;
END IF;
END zoom_available;

   ——————————————————————–
function style(event_name varchar2) return integer is
begin
if event_name = ‘ZOOM’ then
return custom.override;
else
return custom.standard;
end if;
return custom.standard;
end style;
——————————————————————–
PROCEDURE event (event_name VARCHAR2)
IS
form_name        VARCHAR2 (30) := NAME_IN (‘system.current_form’);
block_name       VARCHAR2 (30) := NAME_IN (‘system.cursor_block’);
param_to_pass1   VARCHAR2 (255);
BEGIN
IF (event_name = ‘ZOOM’)
THEN
IF (form_name = ‘ZDEPT’ AND block_name = ‘DEPT’)
THEN
param_to_pass1 := NAME_IN (‘DEPT.DEPTNO’);
fnd_function.execute (FUNCTION_NAME   => ‘ZEMP’,
OPEN_FLAG       => ‘Y’,
SESSION_FLAG    => ‘Y’,
OTHER_PARAMS    => ‘DEPTNO=’ || param_to_pass1);
END IF;
ELSIF (event_name = ‘OE_LINES_PRICING’)
THEN
NULL;
ELSIF (event_name = ‘WHEN-VALIDATE-RECORD’)
THEN
IF (form_name = ‘APXVENDR’)
THEN
IF (block_name = ‘VENDOR’)
THEN
COPY (UPPER (NAME_IN (‘VENDOR.NAME’)), ‘VENDOR.NAME’);
END IF;
END IF;
ELSE
NULL;
END IF;
NULL;
END event;
end custom;
STEP5:
Save CUSTOM.PLL and GENERATE it from FORMS GENERATE
[x] COMPILE ALL
NOTE :WHEN GENERATING LIBRARY CLOSE ALL FORMS WHICH MIGHT USE THE LIBRARY INCLUDING ORACLE APPS.
STEP6:
WHEN-NEW-BLOCK-INSTANCE: DEPT
DO_KEY(‘EXECUTE_QUERY’);

WHEN-NEW-BLOCK-INSTANCE: EMP
CLEAR_FORM;
EXECUTE_QUERY;

ATTACH CUSTOM.PLL TO ZDEPT FORM.

STEP7:
SAVE ,COMPILE AND GENERATE BOTH THE FORMS
IN APPS, REGISTER FORMS & DEFINE FORM FUNCTION
ATTACH IT TO A MENU .

NOTE: DO NOT GIVE NAVIGATOR PROMPT FOR DESTINATION FORM
ZEMP

————————————————————————————————————
Share on Google Plus

About sekhar

This is a short description in the author block about the author. You edit it by entering text in the "Biographical Info" field in the user admin panel.
    Blogger Comment
    Facebook Comment

0 comments :

Post a Comment