oracle application form

119
1 MỤC LỤC MỤC LỤC................................................................................................................1 Kiến trúc ứng dụng .................................................................................................4 Tổng quan về kiến trúc ứng dụng. .................................................................................. 4 Mô hình phát triển và triển khai Oracle Application. ..................................................... 7 Các chuẩn cho việc Customize ứng dụng .............................................................8 Tổng quan về việc customize Oracle Applications......................................................... 8 Customization theo cách mở rộng. ................................................................................. 9 Customize theo cách mở rộng......................................................................................... 9 Customize bằng cách chỉnh sửa .................................................................................... 11 Customize cơ sở dữ liệu Oracle Applications............................................................... 12 Nâng cấp và chỉnh sửa Oracle Applications ................................................................. 12 Tích hợp Custom Objects và Schemas ......................................................................... 12 Nâng cấp các form được customize lên Release 11i .................................................... 12 Tổng quan về Coding Standard trong ứng dụng ...............................................13 Theo dõi các thay đổi về dữ liệu vi Record History ( WHO ) .................................... 13 Các ràng buộc khai báo ( declarative constraint ) : ....................................................... 15 View : ............................................................................................................................ 16 Sequence : ..................................................................................................................... 16 API đăng kí bảng : ........................................................................................................ 16 Tổng quan về việc sử dụng PL/SQL trong các ứng dụng : ........................................... 17 Thuật ngữ : .................................................................................................................... 17 Các chuẩn chung trong lập trình PL/SQL : ................................................................... 18 Định dạng mã PL/SQL : ............................................................................................... 19 Xử lý lỗi : ...................................................................................................................... 20 Một vài hướng dẫn khi coding SQL : ........................................................................... 21 Các trigger trong form : ................................................................................................ 22 Những sự thay thế cho các built-in trong Oracle Forms ............................................... 22 Lập trình các handler cho item, event và table : ........................................................... 23 Lập trình các handler cho item : ................................................................................... 24 Lập trình các handler cho event : .................................................................................. 25 Lập trình các handler cho table : ................................................................................... 25 Form TEMPLATE ................................................................................................40 Giới thiệu về form TEMPLATE : ................................................................................. 40 Các thư viện trong form TEMPLATE .......................................................................... 40 Các trigger trong form TEMPLATE............................................................................. 42 Thiết lập các thuộc tính của các đối tượng chứa(ContainerObject) ................49 Các đối tượng chứa : ..................................................................................................... 49 Module : ........................................................................................................................ 49 Window :....................................................................................................................... 49 Canvas : ......................................................................................................................... 51

Upload: doan-hong-nhat

Post on 11-Jun-2015

3.141 views

Category:

Documents


5 download

TRANSCRIPT

Page 1: Oracle Application Form

1

MỤC LỤC

MỤC LỤC ................................................................................................................ 1

Kiến trúc ứng dụng ................................................................................................. 4

Tổng quan về kiến trúc ứng dụng. .................................................................................. 4

Mô hình phát triển và triển khai Oracle Application. ..................................................... 7

Các chuẩn cho việc Customize ứng dụng ............................................................. 8 Tổng quan về việc customize Oracle Applications......................................................... 8

Customization theo cách mở rộng. ................................................................................. 9

Customize theo cách mở rộng ......................................................................................... 9

Customize bằng cách chỉnh sửa .................................................................................... 11

Customize cơ sở dữ liệu Oracle Applications ............................................................... 12

Nâng cấp và chỉnh sửa Oracle Applications ................................................................. 12

Tích hợp Custom Objects và Schemas ......................................................................... 12

Nâng cấp các form được customize lên Release 11i .................................................... 12

Tổng quan về Coding Standard trong ứng dụng ............................................... 13

Theo dõi các thay đổi về dữ liệu với Record History ( WHO ) .................................... 13

Các ràng buộc khai báo ( declarative constraint ) : ....................................................... 15

View : ............................................................................................................................ 16

Sequence : ..................................................................................................................... 16

API đăng kí bảng : ........................................................................................................ 16

Tổng quan về việc sử dụng PL/SQL trong các ứng dụng : ........................................... 17

Thuật ngữ : .................................................................................................................... 17

Các chuẩn chung trong lập trình PL/SQL : ................................................................... 18

Định dạng mã PL/SQL : ............................................................................................... 19

Xử lý lỗi : ...................................................................................................................... 20

Một vài hướng dẫn khi coding SQL : ........................................................................... 21

Các trigger trong form : ................................................................................................ 22

Những sự thay thế cho các built-in trong Oracle Forms ............................................... 22

Lập trình các handler cho item, event và table : ........................................................... 23

Lập trình các handler cho item : ................................................................................... 24

Lập trình các handler cho event : .................................................................................. 25

Lập trình các handler cho table : ................................................................................... 25

Form TEMPLATE ................................................................................................ 40 Giới thiệu về form TEMPLATE : ................................................................................. 40

Các thư viện trong form TEMPLATE .......................................................................... 40

Các trigger trong form TEMPLATE............................................................................. 42

Thiết lập các thuộc tính của các đối tượng chứa(ContainerObject) ................ 49

Các đối tượng chứa : ..................................................................................................... 49

Module : ........................................................................................................................ 49

Window : ....................................................................................................................... 49

Canvas : ......................................................................................................................... 51

Page 2: Oracle Application Form

2

Block : ........................................................................................................................... 51

Region : ......................................................................................................................... 54

Thiết lập các thuộc tính của các đối tượng Widget ........................................... 55

Text Item : ..................................................................................................................... 55

Display Item : ................................................................................................................ 56

Poplist : ......................................................................................................................... 56

Option Group : .............................................................................................................. 56

Check Box :................................................................................................................... 56

Button ( Nút ) : .............................................................................................................. 56

List of Values ( LOV ) .................................................................................................. 57

Thiết lập các thuộc tính cho item : ................................................................................ 57

Một số lưu ý : ................................................................................................................ 60

Điều khiển hoạt động của Window, Block, và Region ....................................... 61

Điều khiển hoạt động của Window ............................................................................... 61

Lập trình cho các Tabbed Regions................................................................................ 69

Hành động của tabbed region : ..................................................................................... 70

3 mức khó trong lập trình : ........................................................................................... 70

Cho phép hoạt động truy vấn .............................................................................. 73

Query Find : .................................................................................................................. 73

Triển khai Row-LOV .................................................................................................... 73

Triển khai Find Window ............................................................................................... 74

Lập trình các hành động cho item ....................................................................... 78 Mối quan hệ giữa các Item ............................................................................................ 78

Item phụ thuộc có điều kiện .......................................................................................... 81

Các item đa phụ thuộc................................................................................................... 82

2 Master Item và 1 Dependent Item .............................................................................. 83

Kiểu phụ thuộc Cascading ............................................................................................ 85

Các item loại trừ lẫn nhau (Mutually Exclusive Items) ................................................ 86

Các item đồng hành với nhau (Mutually Inclusive Items) ............................................ 88

Mutually Inclusive Item liên hệ với Dependent Item ................................................... 89

Các item bắt buộc điều kiện (Conditionally Mandatory Items) .................................... 91

Các mặc định (Defaults) ............................................................................................... 93

Kiểm tra tính toàn vẹn (Integrity Checking) ................................................................. 94

Đối tượng Calendar ....................................................................................................... 97

Các lựa chọn cấp cao của Calendar .............................................................................. 98

Điều khiển Toolbar và Default Menu ...............................................................100

Pulldown Menu và Toolbar ........................................................................................ 100

Các lựa chọn có trên thanh công cụ ( toolbar ) : ......................................................... 101

Các mục chỉ có trong Menu ........................................................................................ 102

Điều khiển menu động ................................................................................................ 103

Tạo các biểu tượng trên toolbar cho các form bạn customize .................................... 104

Các menu đặc biệt ....................................................................................................... 105

Customize các Right–Mouse Menu (Popup Menus) .................................................. 105

Message Dictionary .............................................................................................108

Tổng quan về Message Dictionary ............................................................................. 108

Các điểm đặc trưng của Message Dictionary ............................................................ 108

Page 3: Oracle Application Form

3

Các bước cần tiến hành khi xác định Message Dictionary ......................................... 109

Thiết lập Message Dictionary ..................................................................................... 109

Phương pháp đối với Database Server–side Messaging. ............................................ 110

USER PROFILE .................................................................................................112

Các mức của User Profile: .......................................................................................... 112

Định nghĩa mới các tùy chọn của user profile ............................................................ 113

Thiết lập giá trị tùy chọn user profile .......................................................................... 113

Thiết lập user profile riêng của bạn ............................................................................ 113

Xác định trước tùy chọn user profile .......................................................................... 113

Profile Window ........................................................................................................... 114

FOLDER ..............................................................................................................116

Tổng quan về Folder. .................................................................................................. 116

Lập trình với Folder trên form ứng dụng. ................................................................... 116

Page 4: Oracle Application Form

4

Kiến trúc ứng dụng

Tổng quan về kiến trúc ứng dụng.

Kiến trúc ứng dụng của hệ thống Oracle Application theo mô hình tập trung 3 lớp,

đó là các lớp Desktop Client, Middle Tier (Form Server) và Data Base Server. Mọi thao

tác ở Client đều thực hiện dựa trên hệ thống Java nhúng. Dữ liệu nhập liệu được truyền

về Application Server, việc xử lí các chức năng được thực hiện ở Application Server.

Việc thao tác xử lí dữ liệu thực hiện ở Database Server. Kiến trúc tổng thể được mô tả

như hình vẽ dưới đây:

Desktop Client :

• Giao diện đồ họa, sử dụng trên các Web browser chuẩn có hỗ trợ Java

nhúng chạy Jinitiator.

• Oracle JInitiator là phiên bản Oracle của JavaSoft‟s Java Plug-In, cho

phép xử lý JVM tại Web client thay vì dựa vào JVM default của browser.

Page 5: Oracle Application Form

5

• Có thể tương thích với mọi PC,network computer hoặc trên bất cứ giao

diện nào có Java.

Middle Tier (Form Server):

• Xử lý các đáp ứng logic của Form.

• Là nơi lưu giữ các dữ liệu cache cục bộ.

• Trung gian giữa hai tầng.

Page 6: Oracle Application Form

6

Database Server:

• Sử dụng các lời hàm từ xa (RPC) để giao tiếp với DB khi cần thiết (có thể

thực hiện nhiều DB action cùng một lúc – các câu lệnh SQL).

• Xử lý thao tác dữ liệu trên ứng dụng.

• Lưu các thủ tục trên DB nên giao tiếp giữa các stored procedure và DB

xảy ra trong bộ nhớ chứ không phải trên mạng.

• Tương thích với DB từ 8i trở lên.

Page 7: Oracle Application Form

7

Mô hình phát triển và triển khai Oracle Application.

Hiện tại tại trung tâm sử dụng môi trường Window để thiết kế giao diện, dịch Form bằng

Form Server trên hệ điều hành Linux.

Quá trình phát triển form bao gồm ba bước chính là:

• Build

• Generate

• Run/Test

Build Form :

Access to Libraries and Referenced Forms

Thiết lập FORMS60_PATH.

Referenced Objects and the ORACLE_APPLICATIONS V ariable

Generating Your Form : (dịch Form trên Forms Server)

Moving the File fmb

Dịch file : f60gen module=demo.fmb userid=apps/apps

Running Your Form for Testing : test trên môi trường Web chứ không phải trên Form

developer

Sau khi hoàn thành các bước trên chuyển đến Deployment : Nếu đang phát triển và triển

khai trên cùng một platform thì chỉ cần copy file .fmx đến đích còn không phải dịch file

trên platform đích.

Page 8: Oracle Application Form

8

Các chuẩn cho việc Customize

ứng dụng

Để có thể phát triển ứng dụng trên sản phẩm Oracle Applications bạn phải sử dụng Oracle

Application Object Library cùng với các công cụ khác như Form và Report.

Các chủ đề chính :

Tổng quan về việc customize Oracle Applications

Customize theo cách mở rộng

Customize theo cách chỉnh sửa

Customize cơ sở dữ liệu Oracle Applications

Nâng cấp và chỉnh sửa Oracle Applications

Nâng cấp Custom Forms lên Release 11i

Upgrade Utility và Standards Compliance Checker: flint60

Tổng quan về việc customize Oracle Applications

Các công việc sau bạn có thể làm để phát triển trên ứng dụng :

Thay đổi các Form trên ứng dụng :

– Giao diện (appearance)

– Mã kiểm tra (validation logic)

– Hành động (behavior)

Thay đổi Report hay chương trình :

– Giao diện (appearance)

– Mã (logic)

Thay đổi cơ sở dữ liệu của ứng dụng :

– Thêm vào các read–only schema

– Thêm mã vào các database trigger

Biên dịch lại toàn bộ ứng dụng.

Page 9: Oracle Application Form

9

Customization theo cách mở rộng.

Phát triển các thành phần mới cũng như ứng dụng mới trên nền có sẵn sử dụng

Oracle Application Object Library.

Điều này có thể đơn giản bằng cách copy một thành phần có sẵn tới một thư mục

khác và tiến hành sửa đổi nó.

Customization theo cách chỉnh sửa

Cách này gọi là thay đổi ngay tại chỗ. Tuy nhiên theo khuyến cáo ta nên

tránh cách làm này vì có thể gặp sự cố khi nâng cấp hoặc khi sửa đổi.

Các thành phần (Component)

Component có thể là module code (như form, report hoặc SQL script)

hay các đối tượng Oracle Application Object Library (như menus,

responsibilities, messages) hay kể cả đối tượng CSDL(tables,

views, packages, or functions).

Một ứng dụng phát triển phải được đăng ký với Oracle Application Object

Library và phải có thư mục riêng cùng với component của nó.

Các đối tượng cơ sở dữ liệu

Một table, index, view, sequence, database trigger, package, grant, hoặc

synonym.

Application Short Name

Là tên tham chiếu của ứng dụng không có dấu cách.

Application Basepath

Là tên của một biến môi trường được chuyển thành top directory của cây thư mục

của ứng dụng.

Oracle Application Object Library sẽ tìm các đường dẫn tới các thư mục ở mức dưới

để thực hiện các file chạy trong ứng dụng kể cả form file.

Cấu trúc thư mục của Application

Là sự sắp sếp thứ tự các thư mục trong ứng dụng. Thủ mục của Oracle Applications

được tạo ra khi cài đặt ứng dụng hay khi nâng cấp ứng dụng.

Với các ứng dụng tự tạo bạn phải tạo riêng các thư mục cho nó.

Các file môi trường (Environment Files) của ứng dụng

Xác định biến môi trường khi cài đặt ứng dụng. Biến môi trường bao gồm

<dbname>.env và adovars.env (đối với UNIX platforms).

Customize theo cách mở rộng

Định nghĩa ứng dụng được customize của bạn

Page 10: Oracle Application Form

10

Tạo cấu trúc thư mục cho ứng dụng được customize

Thêm ứng dụng được customize vào trong file Environment của

ứng dụng

Thêm các thành phần mới vào trong ứng dụng được customize của

bạn

Lập tài liệu cho các thành phần mới

Lập tài liệu cho các thành phần mới

Với mỗi thành phần mới, lập tài liệu cho ít nhất là các nội dung sau :

Mục đích

Các tham số đầu vào (cho report và program)

Các đầu ra ví dụ (cho report và program)

Xử lý mã

Các đối tượng CSDL được sử dụng và kiểu truy cập (select, update, insert,delete).

Nếu các component tự của bạn là sửa từ bản copy của một component

trong ứng dụng bạn phải liệt kê chúng trong file applcust.txt ( nằm ở

$APPL_TOP/admin directory

Oracle Applications sẽ sử dụng file này trong quá trình patch hay upgrade

Định nghĩa ứng dụng được customize của bạn

Sử dụng Applications window để đăng ký custom application (bao gồm

name và short name theo tiêu chuẩn đặt tên thông thường)

Tạo cấu trúc thư mục cho ứng dụng được customize

Tự tạo cho ứng dụng của bạn một cấu trúc thư mục hợp lý.

Sửa đổi Applications Environment File

Sửa đổi file biến môi trường cho hợp lý sau đó khởi động lại Forms Server

và Internal Concurrent Manager rồi chạy file biến môi trường để

Oracle Application Object Library tìm thấy các component.

Thêm mới các thành phần

Mỗi khi tạo một component mới lưu ý là để chúng ở trong thư mục con

hợp lý của ứng dụng.

Thêm một form mới

Sử dụng file Template khi bắt đầu tạo một form mới để có thể tương thích

Page 11: Oracle Application Form

11

với ứng dụng hoặc sửa đổi một form đã có sẵn trên ứng dụng rồi đăng ký lại

với ứng dụng.

Các bước tiếp theo là :

Thêm một Report hoặc một Concurrent Program

Thêm một Report Submission Form

Thêm Online Help

Thêm Menus

Thêm Responsibilities

Thêm các thông báo trong Message Dictionary

Customize bằng cách chỉnh sửa

Các bước tiến hành để sửa đổi một form có sẵn trong ứng dụng :

Với Release 11i, tất cả các form đêu đặt trong thư mục

$AU_TOP/forms/<language>. Copy Oracle Applications

form để tiến hành sử đổi ( Lưu ý không sửa đổi trực tiếp lên form).

Sử dụng Oracle Forms Developer and Oracle Application Object Library :

1. Xác định một file

2. Copy file vào trong custom application và đổi tên file

3. Bảo toàn file nguyên bản

4. Thực hiện các chỉnh sửa

5. Chú thích cho form

6. Dịch form

7. Đăng kí ứng dụng được customize trong applcust.txt

8. Lập tài liệu cho việc customize

Chú thích cho form

Để ghi thông tin về ngày và người sửa của form sử dụng PRE–FORM trigger

Oracle Forms.

FND_STANDARD.FORM_INFO(‟$Revision: <Number>$‟,

‟<Form Name>‟,

‟<Application Shortname>‟,

‟$Date: <YY/MM/DD HH24:MI:SS> $‟,

‟$Author: <developer name> $‟);

Page 12: Oracle Application Form

12

Lưu ý để có thể sử dụng Help oline thì phải giữ nguyên Application short

Name .

Chỉnh sửa một Report đã có sẵn

Các bước tiến hành đối với Oracle Reports .rdf file cũng tương tự như dưới đây :

1. Xác định file

2. Thực hiện chỉnh sửa

3. Chú thích cho report

4. Tạo 1 concurrent program sử dụng file của bạn

Customize cơ sở dữ liệu Oracle Applications

Nếu thực hiên việc này phải đặc biệt lưu ý không làm ảnh hưởng tới toàn bộ ứng dụng .

Nâng cấp và chỉnh sửa Oracle Applications

Kiểm tra các chỉnh sửa đối với CSDL

Xác định các chỉnh sửa cũ

Luân chuyển các chỉnh sửa

Chạy lại Grant và Synonym Scripts

Test tất cả các sự sửa đổi

Tích hợp Custom Objects và Schemas

Để thực hiện điều này tốt nhất nên hỏi chuyên gia.

Nâng cấp các form được customize lên Release 11i

Page 13: Oracle Application Form

13

Tổng quan về Coding

Standard trong ứng dụng

Theo dõi các thay đổi về dữ liệu với Record History ( WHO )

Tính năng Record History ( WHO ) cung cấp thông tin về người đã tạo mới hay cập

nhật các hàng trong các bảng Oracle Applications. Nếu bạn thêm các cột WHO đặc

biệt vào bảng và các mã WHO vào form và stored procedure, người dùng có thể theo

dõi được những thay đổi với dữ liệu của họ. Bạn sử dụng các trường ẩn ( hidden field

) trong mỗi block đại diện cho các cột WHO. Gọi FND_STANDARD.SET_WHO

trong các trigger PRE-INSERT, PRE-UPDATE để cung cấp giá trị cho các trường

này.

Các cột WHO :

Page 14: Oracle Application Form

14

Page 15: Oracle Application Form

15

Các ràng buộc khai báo ( declarative constraint ) :

NOT NULL

DEFAULT

UNIQUE

CHECK

PRIMARY KEY

Tránh tạo các bảng với kiểu dữ liệu : LONG, LONG RAW, RAW. Sử dụng kiểu

VARCHAR2(2000) để thay thế. Với các bảng có tên cột trùng với từ khoá, tạo view đến bảng đó với

tên cột được thay bằng tên khác không trùng từ khoá. Có thể thực hiện INSERT, UPDATE, DELETE

qua view kiểu này được.

Page 16: Oracle Application Form

16

View :

Các block phức tạp thì dựa trên các view, các block đơn giản thì dựa trên các table. Bạn cũng

nên tạo các LOV dựa trên view.

Cột đầu tiên trong view nên chọn là cột giả (pseudo-column) ROWID (đặt tên là ROW_ID),

rồi đến các cột của bảng ( kể cả các cột WHO ).

Đặt thuộc tính Key Mode của block là Non-Updatable để tắt tham chiếu mặc định đến

ROWID của Oracle Forms cho các block dựa trên view. Đặt thuộc tính Primary Key của item

là True với item là khoá chính của view.

Lập trình các trigger để thực hiện insert, update, delete và lock : khi tạo 1 block dựa trên

view, phải lập trình các trigger ON-INSERT, ON-UPDATE, ON-DELETE và ON-LOCK để

insert, update, delete và lock bảng gốc thay vì view.

Với view trên 1 bảng, không cần đến các trigger để insert, update, delete hay lock. Đặt Key

Mode của block là Unique. Các view trên 1 bảng không cần đến cột ROW_ID.

Sequence :

Tạo sequence : để cung cấp các giá trị ID không trùng nhau cho 1 cột của 1 bảng.

Không nên giới hạn phạm vi của sequence ( không sử dụng CYCLE hoặc MAXVALUE ).

Sử dụng kiểu dữ liệu Number để lưu các giá trị của sequence.

Không sử dụng bảng FND_UNIQUE_IDENTIFIER_CONTROL

API đăng kí bảng :

Bạn đăng kí các bảng ứng dụng tự tạo của mình bằng 1 PL/SQL routine trong package

AD_DD.

Các bảng ( và mọi cột của nó ) chỉ phải đăng kí khi chúng sử dụng flexfield hoặc Oracle

Alert.

Có thể sử dụng AD_DD API để xoá các đăng kí của bảng và cột

Khi thay đổi cấu trúc bảng, đăng kí lại bằng cách xoá đăng kí cũ ( cột trước rồi đến bảng ),

sau đó đăng kí lại.

AD_DD API không kiểm tra sự tồn tại của bảng cần đăng kí. Vì vậy, cần biết chắc bảng cần

đăng kí có tồn tại và mô tả đúng các định dạng của nó khi sử dụng AD_DD API.

Không cần phải đăng kí cho view.

Các thủ tục trong package AD_DD :

procedure register_table (p_appl_short_name in varchar2,

p_tab_name in varchar2,

Page 17: Oracle Application Form

17

p_tab_type in varchar2,

p_next_extent in number default 512,

p_pct_free in number default 10,

p_pct_used in number default 70);

procedure register_column (p_appl_short_name in varchar2,

p_tab_name in varchar2,

p_col_name in varchar2,

p_col_seq in number,

p_col_type in varchar2,

p_col_width in number,

p_nullable in varchar2,

p_translate in varchar2,

p_precision in number default null,

p_scale in number default null);

procedure delete_table (p_appl_short_name in varchar2,

p_tab_name in varchar2);

procedure delete_column (p_appl_short_name in varchar2,

p_tab_name in varchar2,

p_col_name in varchar2);

Ví dụ về sử dụng package AD_DD để đăng kí 1 bảng flexfield và các cột của nó :

EXECUTE ad_dd.register_table(‟FND‟, ‟CUST_FLEX_TEST‟, ‟T‟,

8, 10, 90);

EXECUTE ad_dd.register_column(‟FND‟, ‟CUST_FLEX_TEST‟,

‟APPLICATION_ID‟, 1, ‟NUMBER‟, 38, ‟N‟, ‟N‟);

Tổng quan về việc sử dụng PL/SQL trong các ứng dụng :

Bạn có thể sử dụng các thủ tục PL/SQL như một phần của ứng dụng bạn xây dựng

nằm trong Oracle Applications. Bằng cách tuân theo các chuẩn lập trình, bạn có thể

tạo ra 1 thủ tục PL/SQL tích hợp hoàn toàn với ứng dụng.

Bạn có thể sử dụng PL/SQL viết các đoạn mã mở rộng có tính thủ tục để custom

form và report. PL/SQL cũng giúp module hoá form code của bạn, hoặc phát triển

các chương trình chạy đồng thời ( concurrent program ).

Thuật ngữ :

Server-side : chỉ các thủ tục lưu trên cơ sở dữ liệu Oracle .

Client-side : chỉ các thủ tục chạy trong các chương trình là client của CSDL Oracle.

Page 18: Oracle Application Form

18

Các chuẩn chung trong lập trình PL/SQL :

Luôn sử dụng package : định nghĩa các thủ tục PL/SQL trong package

Kích thước package : mã nguồn của 1 đơn vị chương trình ( 1 package ) client-side

không được vượt quá 10K, và tổng kích thước source code và compiled code phải

nhỏ hơn 64K. Nếu 1 đơn vị chương trình quá lớn, có thể chia ra thành các đơn vị con

được liên kết với nhau. Server-side package không bị giới hạn về kích thước.

Thêm các thủ tục mới vào các package đã tồn tại : thêm vào cuối của mỗi package.

Nếu thêm vào giữa package ( specification hay body ), phải dịch lại các form có tham

chiếu đến package, nếu không sẽ bị lỗi.

Sử dụng tên trường trong các client-side package : luôn dùng tên trường đầy đủ (

BLOCK_NAME.FIELD_NAME ) để khoanh vùng tìm kiếm ( chỉ tìm trong block đó

), và tránh trường hợp xung đột khi có 2 trường trùng tên.

Tên trường trong các tham số của thủ tục : không dùng kiểu tham số OUT hoặc IN

OUT vì có thể làm thay đổi các giá trị của trường truyền vào khi kết thúc thủ tục. Với

danh sách tham số quá dài, sử dụng “ => “ để truyền đúng tham số.

Sử dụng DEFAULT : sử dụng DEFAULT để khởi tạo giá trị mặc định cho tham số

thay vì “:=”, để cho giá trị truyền vào có thể ghi đè lên giá trị mặc định. Ngược lại,

với hằng, sử dụng “:=” để giá trị không thể bị ghi đè lên.

Sử dụng ID của object : các đoạn code thay đổi nhiều thuộc tính của 1 đối tượng

bằng SET_<OBJECT>_PROPERTY, nên sử dụng ID của đối tượng. Dùng

FIND_<OBJECT> để lấy ID, sau đó truyền ID vào thủ tục được dựng sẵn

SET_<OBJECT>_PROPERTY.

Xử lý giá trị NULL : bất kì biểu thức so sánh nào có chứa phần tử NULL đều trả về

giá trị FALSE. Để kiểm tra một phần tử có NULL hay không, sử dụng “IS”.

Các biến global : có 3 loại

. Oracle Form global : biến nằm trong pseudo-block ( khối giả ) “global” của form.

. PL/SQL package global : biến được định nghĩa trong package specification

. Oracle Form Parameter : biến được tạo như một tham số trong Oracle Forms

Designer.

Page 19: Oracle Application Form

19

Định dạng mã PL/SQL :

Trong 1 package, định nghĩa các biến private trước, sau đó đến các thủ tục private,

cuối cùng là các thủ tục public.

Luôn kết thúc thủ tục hoặc package bằng End Procedure_name; hoặc End

Package_name; để dễ theo dõi, nhận dạng.

Hàng lệnh dưới lùi vào trong 2 dấu cách để dễ đọc code, ví dụ :

Sử dụng “--“ để thêm dòng chú thích và “/* … */” để bao đoạn chú thích.

Căn lề chú thích và lệnh được chú thích thẳng hàng.

Page 20: Oracle Application Form

20

Sử dụng chữ hoa ( với các từ khoá ) và chữ thường ( các từ còn lại ) để dễ đọc code

( vì PL/SQL không phân biệt chữ hoa chữ thường ).

Dùng IF-THEN-ELSIF thay cho các cấu trúc IF-THEN-ELSE lồng nhau.

Chỉ tạo các khối PL/SQL lồng nhau trong 1 thủ tục khi phải xử lý những lỗi cụ thể

phát sinh.

Xử lý lỗi :

Lỗi trong thủ tục PL/SQL trong Oracle Form : sử dụng FND_MESSAGE để hiển

thị thông báo lỗi, sau đó gọi RAISE FORM_TRIGGER_FAILURE để dừng việc

xử lý lại.

Lỗi trong các stored procedure : sử dụng FND_MESSAGE.SET_NAME để hiển

thị thông báo lỗi, sau đó gọi APP_EXCEPTION.RAISE_EXCEPTION để dừng xử

Page 21: Oracle Application Form

21

Kiểm tra FORM_SUCCESS, FORM_FAILURE và FORM_FATAL : các giá trị

của chúng có thể bị thay đổi bởi một trigger nào đó. Xem ví dụ sau :

Tránh sử dụng RAISE_APPLICATION_ERROR vì nó gây xung đột trong quá

trình xử lý lỗi ở phía server.

Một vài hướng dẫn khi coding SQL :

Sử dụng “select from DUAL” thay vì “select from SYS.DUAL”. Không sử dụng

SYSTEM.DUAL.

Tất cả các lệnh SELECT nên sử dụng một cursor (con trỏ) tự định nghĩa từ trước.

Một lệnh SELECT bình thường thực hiện 2 xử lý : 1 để lấy dữ liệu và 1 để kiểm tra

Page 22: Oracle Application Form

22

có bị lỗi TOO_MANY_ROWS không. Ta có thể tránh điều này bằng việc chỉ lấy

về 1 bản ghi từ cursor mà ta định nghĩa trước.

Nếu bạn muốn SELECT vào trong 1 tham số thủ tục, khai báo tham số là IN OUT,

cho dù có sử dụng hay không giá trị của tham số ( trừ trường hợp tham số là trường

).

1 single-row SELECT khi không trả về hàng nào sẽ sinh ra lỗi

NO_DATA_FOUND. 1 INSERT, UPDATE, hay DELETE khi không tác động lên

hàng nào sẽ không báo lỗi. Bạn phải tự kiểm tra giá trị của SQL%NOTFOUND để

biết được có bị lỗi không.

Để xử lý NO_DATA_FOUND, viết một đoạn bắt lỗi (exception handler), thay vì

dùng COUNT để đếm số hàng hiện thời.

Khi kiểm tra giá trị của một trường hoặc một biến để bắt lỗi sai, kiểm tra trong

PL/SQL code, chứ không phải trong mệnh đề WHERE.

Các trigger trong form :

Kiểu xử lý : Kiểu xử lý cho tất cả các trigger ở mức block hay field nên là Overide

(đè lên trigger mức form) hoặc Before (thực hiện trước trigger mức form). Thông

thường là sử dụng kiểu Before, vì phiên bản trigger ở mức form cũng cần được

thực hiện. Trường hợp ngoại lệ là khi bạn có một lời gọi flexfield trong trigger

POST-QUERY mức form, nhưng bạn đặt lại query status của block trong trigger

POST-QUERY ở mức block, thì bạn nên đặt kiểu xử lý cho trigger mức block là

After.

Trigger WHEN-CREATE-RECORD vẫn kích hoạt khi block không cho phép

insert. Vì vậy, nên kiểm tra xem 1 block có cho phép insert không trước khi thực

hiện xử lý nào đó trong trigger này :

Những sự thay thế cho các built-in trong Oracle Forms

Không sử dụng CALL_FORM : vì built-in này không tương thích với

OPEN_FORM (được sử dụng bởi các Oracle Application routine). Sử dụng

FND_FUNCTION.EXECUTE thay cho CALL_FORM hoặc OPEN_FORM khi

muốn mở form bằng lập trình.

Page 23: Oracle Application Form

23

Những Oracle Forms built-in sau có các APPCORE routine tương đương với

chúng :

+ EXIT_FORM : các form Oracle Applications có xử lý đóng đặc biệt. Không

gọi trực tiếp EXIT_FORM, mà luôn gọi do_key(„EXIT_FORM‟). Để đóng toàn

bộ Oracle Applications, trước tiên gọi :

copy(‘Y’, ’GLOBAL.APPCORE_EXIT_FLAG’);

sau đó gọi : do_key(‘EXIT_FORM’);

+ SET_ITEM_PROPERTY : thay bằng

APP_ITEM_PROPERTY.SET_PROPERTY và

APP_ITEM_PROPERTY.SET_VISUAL_ATTRIBUTE.

Những APPCORE routine này đặt các thuộc tính trong Oracle Applications theo

chuẩn.Có một số thuộc tính sử dụng SET_ITEM_PROPERTY.

+ GET_ITEM_PROPERTY : sử dụng

APP_ITEM_PROPERTY.GET_PROPERTY khi lấy các thuộc tính cụ thể của

Oracle Applications. Khi đặt hoặc lấy các thuộc tính còn lại, sử dụng các built-in

của Oracle Forms.

+ OPEN_FORM : sử dụng FND_FUNCTION.EXECUTE để thay thế. Cả 2 cách

gọi này đều làm cho các trigger POST-RECORD và POST-BLOCK kích hoạt.

+ CLEAR_FORM : sử dụng do_key(„CLEAR_FORM‟). Routine này sẽ báo lỗi

FORM_TRIGGER_FAILURE nếu có 1 bản ghi không hợp lệ.

+ COMMIT : sử dụng do_key(„COMMIT_FORM‟). Routine này sẽ báo lỗi

FORM_TRIGGER_FAILURE nếu có 1 bản ghi không hợp lệ.

+ EDIT_FIELD / EDIT_TEXTITEM : sử dụng do_key(„edit_field‟). Routine

này sẽ gọi calendar khi item hiện tại là date.

+ VALIDATE : sử dụng APP_STANDARD.APP_VALIDATE để thay thế.

Routine này sẽ chuyển focus đến bất kì item nào làm phát sinh lỗi navigation.

Lập trình các handler cho item, event và table :

Người lập trình có thể gọi các handler (chương trình xử lý) từ trong trigger để xử

lý các mã cần thiết để validate một item hoặc đảm bảo cho 1 hành động được thực

hiện đúng trong tình huống cụ thể.

1 form điển hình có từng package cho mỗi block, và 1 package cho bản thân form.

Lập trình cho các thủ tục trong mỗi package, và gọi thủ tục (hay handler đó) từ các

trigger có liên quan. Với handler liên quan đến nhiều block hay đáp ứng cho

trigger mức form, đặt nó vào trong package của form.

Page 24: Oracle Application Form

24

Việc viết các handler ( cho item, event, table ), và gọi chúng trong trigger sẽ giúp

cho khối lượng mã trong trigger ở mức tối thiểu.

Lập trình các handler cho item :

Các item handler là các thủ tục chứa đựng tất cả các đoạn mã dùng để validate một item cụ

thể nào đó. Một item handler package chứa tất cả các thủ tục dùng để validate các item trong 1 block

hoặc 1 form. Nên đặt tên package theo tên block ( hoặc tên form ) và đặt tên các thủ tục trong package

theo tên các item trong block đó (VD : block EMP, item EMPNO -> package EMP, procedure

EMPNO) để dễ xác định code nào đi với item nào. Mỗi item handler luôn có 1 tham số tên là EVENT,

kiểu là VARCHAR2, thường để truyền tên của trigger gọi item handler đó. Các EVENT thông dụng

và xử lý tương ứng là :

PRE-RECORD : đặt lại các item attribute cho bản ghi mới. EVENT này thường

được sử dụng cho các APPCORE routine (loại enable hoặc disable các trường độc

lập). Bạn cũng có thể dùng WHEN-NEW-RECORD-INSTANCE ( thay cho PRE-

RECORD ) trong một vài trường hợp.

INIT : khởi tạo ( initialize ) item. INIT chỉ thị cho item handler kiểm tra các điều

kiện hiện tại của form và đặt lại các giá trị mặc định và các thuộc tính động cho

item nếu cần thiết. EVENT này được gửi đi bởi các handler khác và là đầu vào cho

nhiều APPCORE routine. Trường hợp thông thường nhất là khi 1 item phụ thuộc

vào 1 item khác. Khi 1 master item thay đổi, handler của item phụ thuộc sẽ được

gọi với sự kiện INIT.

VALIDATE : được sử dụng với nhiều APPCORE routine khi item cần được

validate. Sử dụng VALIDATE thay cho WHEN–VALIDATE–ITEM, WHEN–

CHECKBOX–CHANGED, WHEN–LIST–CHANGED, hoặc WHEN–RADIO–

CHANGED.

Page 25: Oracle Application Form

25

Lập trình các handler cho event :

Event handler thực hiện các hành động phức tạp trên nhiều item có liên quan với

nhau, trong khi item handler thực hiện các hành động đơn giản trên 1 item. Trong

event handler, ta có thể gọi các item handler.

Event handler chỉ xử lý 1 sự kiện ( trên nhiều item ), nên không cần tham số

EVENT, và cũng không cần bất kì tham số nào.

Event handler được đặt tên theo trigger, nhưng thay dấu gạch ngang bằng dấu gạch

dưới (VD: trigger PRE-QUERY -> handler PRE_QUERY).

Một số event handler thông dụng :

. PRE_QUERY : cung cấp các giá trị cần cho các item để lấy được các bản ghi mong

muốn.

. POST_QUERY : cung cấp giá trị cho các item không liên quan đến bảng dữ liệu.

. WHEN_CREATE_RECORD : cung cấp các giá trị mặc định khi tạo bản ghi mới (

khi mà sử dụng thuộc tính default value là chưa đủ )

. WHEN_VALIDATE_RECORD : kiểm tra các quan hệ phức tạp có trong item.

Lập trình các handler cho table :

Một table handler là 1 server-side package hoặc 1 client-side package cung cấp

một API cho 1 bảng. Các table handler được sử dụng để insert, update, delete hoặc

lock một bản ghi, hoặc để kiểm tra xem 1 record ở bảng khác có tham chiếu đến

record ở trong bảng này ko. Vì hầu hết các form trong Oracle Applications đều dựa

trên các view nên cần phải có các table handler này để xử lý những tương tác với

các bảng có trong view.

Page 26: Oracle Application Form

26

Các table handler chứa một vài hoặc tất cả các thủ tục sau :

. CHECK_UNIQUE : kiểm tra xem có giá trị lặp trong cột unique hay không

. CHECK_REFERENCES : kiểm tra tính toàn vẹn tham chiếu

. INSERT_ROW

. UPDATE_ROW

. DELETE_ROW

. LOCK_ROW

INSERT_ROW, UPDATE_ROW, DELETE_ROW và LOCK_ROW thường được

sử dụng để thay thế xử lý giao dịch mặc định của Oracle Forms trong các trigger

ON-INSERT, ON-UPDATE, ON-DELETE và ON-LOCK.

Trong thủ tục xử lý bảng INSERT_ROW, nếu một cột khoá chính cho phép giá trị

NULL, cần thêm “OR (primary_key IS NULL AND X_col IS NULL)” vào mệnh

đề WHERE của câu lệnh SELECT ROWID.

Trong thủ tục xử lý bảng LOCK_ROW, nếu 1 cột không được phép NULL, gỡ bỏ

điều kiện ”OR (RECINFO.col IS NULL AND X_col IS NULL)” ra khỏi lệnh IF.

Tác động lên 1 bảng thứ hai : để thực hiện 1 hành động trên 1 bảng khác, gọi thủ

tục xử lý tương ứng của bảng đó thay cho việc thực hiện hành động trực tiếp. Ví

dụ, trong thủ tục DELETE_ROW của bảng master, ta xoá bản ghi master và gọi

thủ tục DELETE_ROW của bảng detail để xoá các bản ghi detail tương ứng, chứ

không thực hiện lệnh DELETE trực tiếp xoá chúng trong handler của master.

Ví dụ về client-side table handler : handler này cung cấp các thủ tục

INSERT_ROW, UPDATE_ROW, DELETE_ROW, and LOCK_ROW cho bảng

EMP. Bạn lập trình client–side table handler trực tiếp trong form

Package spec you would code for your EMP block

PACKAGE EMP IS

PROCEDURE Insert_Row;

PROCEDURE Lock_Row;

PROCEDURE Update_Row;

PROCEDURE Delete_Row;

END EMP;

Package body you would code for your EMP block

PACKAGE BODY EMP IS

PROCEDURE Insert_Row IS

Page 27: Oracle Application Form

27

CURSOR C IS SELECT rowid FROM EMP

WHERE empno = :EMP.Empno;

BEGIN

INSERT INTO EMP(

empno,

ename,

job,

mgr,

hiredate,

sal,

comm,

deptno

) VALUES (

:EMP.Empno,

:EMP.Ename,

:EMP.Job,

:EMP.Mgr,

:EMP.Hiredate,

:EMP.Sal,

:EMP.Comm,

:EMP.Deptno

);

OPEN C;

FETCH C INTO :EMP.Row_Id;

if (C%NOTFOUND) then

CLOSE C;

Raise NO_DATA_FOUND;

end if;

CLOSE C;

END Insert_Row;

PROCEDURE Lock_Row IS

Page 28: Oracle Application Form

28

Counter NUMBER;

CURSOR C IS

SELECT empno,

ename,

job,

mgr,

hiredate,

sal,

comm,

deptno

FROM EMP

WHERE rowid = :EMP.Row_Id

FOR UPDATE of Empno NOWAIT;

Recinfo C%ROWTYPE;

BEGIN

Counter := 0;

LOOP

BEGIN

Counter := Counter + 1;

OPEN C;

FETCH C INTO Recinfo;

if (C%NOTFOUND) then

CLOSE C;

FND_MESSAGE.Set_Name(‟FND‟,

‟FORM_RECORD_DELETED‟);

FND_MESSAGE.Error;

Raise FORM_TRIGGER_FAILURE;

end if;

CLOSE C;

if (

(Recinfo.empno = :EMP.Empno)

Page 29: Oracle Application Form

29

AND ( (Recinfo.ename = :EMP.Ename)

OR ( (Recinfo.ename IS NULL)

AND (:EMP.Ename IS NULL)))

AND ( (Recinfo.job = :EMP.Job)

OR ( (Recinfo.job IS NULL)

AND (:EMP.Job IS NULL)))

AND ( (Recinfo.mgr = :EMP.Mgr)

OR ( (Recinfo.mgr IS NULL)

AND (:EMP.Mgr IS NULL)))

AND ( (Recinfo.hiredate = :EMP.Hiredate)

OR ( (Recinfo.hiredate IS NULL)

AND (:EMP.Hiredate IS NULL)))

AND ( (Recinfo.sal = :EMP.Sal)

OR ( (Recinfo.sal IS NULL)

AND (:EMP.Sal IS NULL)))

AND ( (Recinfo.comm = :EMP.Comm)

OR ( (Recinfo.comm IS NULL)

AND (:EMP.Comm IS NULL)))

AND (Recinfo.deptno = :EMP.Deptno)

) then

return;

else

FND_MESSAGE.Set_Name(‟FND‟,

‟FORM_RECORD_CHANGED‟);

FND_MESSAGE.Error;

Raise FORM_TRIGGER_FAILURE;

end if;

EXCEPTION

When APP_EXCEPTIONS.RECORD_LOCK_EXCEPTION then

IF (C% ISOPEN) THEN

close C;

Page 30: Oracle Application Form

30

END IF;

APP_EXCEPTION.Record_Lock_Error(Counter);

END;

end LOOP;

END Lock_Row;

PROCEDURE Update_Row IS

BEGIN

UPDATE EMP

SET

empno = :EMP.Empno,

ename = :EMP.Ename,

job = :EMP.Job,

mgr = :EMP.Mgr,

hiredate = :EMP.Hiredate,

sal = :EMP.Sal,

comm = :EMP.Comm,

deptno = :EMP.Deptno

WHERE rowid = :EMP.Row_Id;

if (SQL%NOTFOUND) then

Raise NO_DATA_FOUND;

end if;

END Update_Row;

PROCEDURE Delete_Row IS

BEGIN

DELETE FROM EMP

WHERE rowid = :EMP.Row_Id;

if (SQL%NOTFOUND) then

Raise NO_DATA_FOUND;

end if;

END Delete_Row;

END EMP;

Page 31: Oracle Application Form

31

- Ví dụ về server-side table handler : handler này cung cấp các thủ tục INSERT_ROW,

UPDATE_ROW, DELETE_ROW và LOCK_ROW cho bảng EMP. Handler của bạn sẽ bao gồm 1

package trong form và 1 server–side package trong cơ sở dữ liệu. Package trong form sẽ gọi sever-

side package và truyền tất cả giá trị của các trường như là các đối số.

Package spec you would code in your form for your EMP

block

PACKAGE EMP IS

PROCEDURE Insert_Row;

PROCEDURE Update_Row;

PROCEDURE Lock_Row;

PROCEDURE Delete_Row;

END EMP;

Package body you would code in your form for your EMP

block

PACKAGE BODY EMP IS

PROCEDURE Insert_Row IS

BEGIN

EMP_PKG.Insert_Row(

X_Rowid => :EMP.Row_Id,

X_Empno => :EMP.Empno,

X_Ename => :EMP.Ename,

X_Job => :EMP.Job,

X_Mgr => :EMP.Mgr,

X_Hiredate => :EMP.Hiredate,

X_Sal => :EMP.Sal,

X_Comm => :EMP.Comm,

X_Deptno => :EMP.Deptno);

END Insert_Row;

PROCEDURE Update_Row IS

BEGIN

Page 32: Oracle Application Form

32

EMP_PKG.Update_Row(

X_Rowid => :EMP.Row_Id,

X_Empno => :EMP.Empno,

X_Ename => :EMP.Ename,

X_Job => :EMP.Job,

X_Mgr => :EMP.Mgr,

X_Hiredate => :EMP.Hiredate,

X_Sal => :EMP.Sal,

X_Comm => :EMP.Comm,

X_Deptno => :EMP.Deptno);

END Update_Row;

PROCEDURE Delete_Row IS

BEGIN

EMP_PKG.Delete_Row(:EMP.Row_Id);

END Delete_Row;

PROCEDURE Lock_Row IS

Counter Number;

BEGIN

Counter := 0;

LOOP

BEGIN

Counter := Counter + 1;

EMP_PKG.Lock_Row(

X_Rowid => :EMP.Row_Id,

X_Empno => :EMP.Empno,

X_Ename => :EMP.Ename,

X_Job => :EMP.Job,

X_Mgr => :EMP.Mgr,

X_Hiredate => :EMP.Hiredate,

X_Sal => :EMP.Sal,

X_Comm => :EMP.Comm,

Page 33: Oracle Application Form

33

X_Deptno => :EMP.Deptno);

return;

EXCEPTION

When APP_EXCEPTIONS.RECORD_LOCK_EXCEPTION then

APP_EXCEPTION.Record_Lock_Error(Counter);

END;

end LOOP;

END Lock_Row;

END EMP;

Package spec for the server–side table handler (SQL script)

SET VERIFY OFF

DEFINE PACKAGE_NAME=”EMP_PKG”

WHENEVER SQLERROR EXIT FAILURE ROLLBACK;

CREATE or REPLACE PACKAGE &PACKAGE_NAME as

/* Put any header information (such as $Header$) here.

It must be written within the package definition so that the

header information will be available in the package itself.

This makes it easier to identify package versions during

upgrades. */

PROCEDURE Insert_Row(X_Rowid IN OUT VARCHAR2,

X_Empno NUMBER,

X_Ename VARCHAR2,

X_Job VARCHAR2,

X_Mgr NUMBER,

X_Hiredate DATE,

X_Sal NUMBER,

X_Comm NUMBER,

X_Deptno NUMBER

);

PROCEDURE Lock_Row(X_Rowid VARCHAR2,

X_Empno NUMBER,

Page 34: Oracle Application Form

34

X_Ename VARCHAR2,

X_Job VARCHAR2,

X_Mgr NUMBER,

X_Hiredate DATE,

X_Sal NUMBER,

X_Comm NUMBER,

X_Deptno NUMBER

);

PROCEDURE Update_Row(X_Rowid VARCHAR2,

X_Empno NUMBER,

X_Ename VARCHAR2,

X_Job VARCHAR2,

X_Mgr NUMBER,

X_Hiredate DATE,

X_Sal NUMBER,

X_Comm NUMBER,

X_Deptno NUMBER

);

PROCEDURE Delete_Row(X_Rowid VARCHAR2);

END &PACKAGE_NAME;

/

show errors package &PACKAGE_NAME

SELECT to_date(‟SQLERROR‟) FROM user_errors

WHERE name = ‟&PACKAGE_NAME‟

AND type = ‟PACKAGE‟

/

commit;

exit;

Package body for the server–side table handler (SQL script)

SET VERIFY OFF

DEFINE PACKAGE_NAME=”EMP_PKG”

Page 35: Oracle Application Form

35

WHENEVER SQLERROR EXIT FAILURE ROLLBACK;

CREATE or REPLACE PACKAGE BODY &PACKAGE_NAME as

/* Put any header information (such as $Header$) here.

It must be written within the package definition so the

header information is available in the package itself.

This makes it easier to identify package versions during

upgrades. */

PROCEDURE Insert_Row(X_Rowid IN OUT VARCHAR2,

X_Empno NUMBER,

X_Ename VARCHAR2,

X_Job VARCHAR2,

X_Mgr NUMBER,

X_Hiredate DATE,

X_Sal NUMBER,

X_Comm NUMBER,

X_Deptno NUMBER

) IS

CURSOR C IS SELECT rowid FROM emp

WHERE empno = X_Empno;

BEGIN

INSERT INTO emp(

empno,

ename,

job,

mgr,

hiredate,

sal,

comm,

deptno

) VALUES (

X_Empno,

Page 36: Oracle Application Form

36

X_Ename,

X_Job,

X_Mgr,

X_Hiredate,

X_Sal,

X_Comm,

X_Deptno

);

OPEN C;

FETCH C INTO X_Rowid;

if (C%NOTFOUND) then

CLOSE C;

Raise NO_DATA_FOUND;

end if;

CLOSE C;

END Insert_Row;

PROCEDURE Lock_Row(X_Rowid VARCHAR2,

X_Empno NUMBER,

X_Ename VARCHAR2,

X_Job VARCHAR2,

X_Mgr NUMBER,

X_Hiredate DATE,

X_Sal NUMBER,

X_Comm NUMBER,

X_Deptno NUMBER

) IS

CURSOR C IS

SELECT *

FROM emp

WHERE rowid = X_Rowid

FOR UPDATE of Empno NOWAIT;

Page 37: Oracle Application Form

37

Recinfo C%ROWTYPE;

BEGIN

OPEN C;

FETCH C INTO Recinfo;

if (C%NOTFOUND) then

CLOSE C;

FND_MESSAGE.Set_Name(‟FND‟, ‟FORM_RECORD_DELETED‟);

APP_EXCEPTION.Raise_Exception;

end if;

CLOSE C;

if (

(Recinfo.empno = X_Empno)

AND ( (Recinfo.ename = X_Ename)

OR ( (Recinfo.ename IS NULL)

AND (X_Ename IS NULL)))

AND ( (Recinfo.job = X_Job)

OR ( (Recinfo.job IS NULL)

AND (X_Job IS NULL)))

AND ( (Recinfo.mgr = X_Mgr)

OR ( (Recinfo.mgr IS NULL)

AND (X_Mgr IS NULL)))

AND ( (Recinfo.hiredate = X_Hiredate)

OR ( (Recinfo.hiredate IS NULL)

AND (X_Hiredate IS NULL)))

AND ( (Recinfo.sal = X_Sal)

OR ( (Recinfo.sal IS NULL)

AND (X_Sal IS NULL)))

AND ( (Recinfo.comm = X_Comm)

OR ( (Recinfo.comm IS NULL)

AND (X_Comm IS NULL)))

AND (Recinfo.deptno = X_Deptno)

Page 38: Oracle Application Form

38

) then

return;

else

FND_MESSAGE.Set_Name(‟FND‟, ‟FORM_RECORD_CHANGED‟);

APP_EXCEPTION.Raise_Exception;

end if;

END Lock_Row;

PROCEDURE Update_Row(X_Rowid VARCHAR2,

X_Empno NUMBER,

X_Ename VARCHAR2,

X_Job VARCHAR2,

X_Mgr NUMBER,

X_Hiredate DATE,

X_Sal NUMBER,

X_Comm NUMBER,

X_Deptno NUMBER

) IS

BEGIN

UPDATE emp

SET

empno = X_Empno,

ename = X_Ename,

job = X_Job,

mgr = X_Mgr,

hiredate = X_Hiredate,

sal = X_Sal,

comm = X_Comm,

deptno = X_Deptno

WHERE rowid = X_Rowid;

if (SQL%NOTFOUND) then

Raise NO_DATA_FOUND;

Page 39: Oracle Application Form

39

end if;

END Update_Row;

PROCEDURE Delete_Row(X_Rowid VARCHAR2) IS

BEGIN

DELETE FROM emp

WHERE rowid = X_Rowid;

if (SQL%NOTFOUND) then

Raise NO_DATA_FOUND;

end if;

END Delete_Row;

END &PACKAGE_NAME;

/

show errors package body &PACKAGE_NAME

SELECT to_date(‟SQLERROR‟) FROM user_errors

WHERE name = ‟&PACKAGE_NAME‟

AND type = ‟PACKAGE BODY‟

/

commit;

exit;

Page 40: Oracle Application Form

40

Form TEMPLATE

Giới thiệu về form TEMPLATE :

Form TEMPLATE là điểm khởi đầu cần có đối với mọi sự phát triển form mới. Bắt

đầu tạo 1 form mới bằng cách copy form TEMPLATE về 1 thư mục trong máy rồi

thay tên nó bằng một tên form mới

Form TEMPLATE bao gồm :

Các tham chiếu tới các nhóm đối tượng trong form APPSTAND

(STANDARD_PC_AND_VA, STANDARD_TOOLBAR, và

STANDARD_CALENDAR)

Các kết nối (attachment) đến một số thư viện (FNDSQF, APPCORE, và

APPDAYPK)

Một số trigger mức form cần phải thêm code.

Các đơn vị chương trình, trong đó có package APP_CUSTOM

(specification và body), chứa các hành động mặc định cho các sự kiện

đóng và mở window. Bạn thường phải sửa code trong package này khi

phát triển form theo yêu cầu.

Bảng màu của ứng dụng

Rất nhiều đối tượng được tham chiếu ( nằm trong các nhóm đối tượng ),

để hỗ trợ cho calendar, toolbar, alternative region và menu. Ví dụ như các

LOV, block, parameter, property class.

Một số đối tượng ví dụ đưa ra các item và layout điển hình. Để bỏ chúng

đi, xóa các đối tượng sau trong form :

Block : BLOCKNAME, DETAILBLOCK

Canvas : BLOCKNAME

Window : BLOCKNAME

Các thư viện trong form TEMPLATE

Form TEMPLATE chứa các attachment đến một số thư viện. 3 thư viện được

attach trực tiếp là : FNDSQF, APPCORE, APPDAYPK. Các thư viện khác được

attach đến 3 thư viện này. Trong Oracle Forms, ta không biệt được thư viện được

attach theo kiểu nào.

Page 41: Oracle Application Form

41

Thư viện APPCORE :

Chứa các thủ tục nằm trong các package mà mọi form đều cần để hỗ trợ

menu, toolbar, và các hành động chuẩn theo yêu cầu.

Chứa các package được gọi để lưu các hành động cụ thể khi đang chạy

ứng dụng.

Chứa các package cung cấp các thủ tục để xử lý lỗi, thông báo theo các

mức…

Các package trong APPCORE thường có tên bắt đầu bằng “APP”.

Thư viện APPDAYPK : chứa các package xử lý tính năng Oracle Applications

Calendar.

Thư viện FNDSQF :

Chứa các thủ tục và package cho Message Dictionary, flexfield, profile,

xử lý đồng thời (concurrent processing).

Cung cấp các tiện ích cho navigation, multicurrency, WHO

Các package trong FNDSQF thường có tên bắt đầu bằng “FND”.

Thư viện CUSTOM :

Thư viện CUSTOM cho phép mở rộng các form của Oracle Applications

mà không phải thay đổi code trong Oracle Applications. Bạn có thể sử

dụng thư viện CUSTOM để customize, áp đặt các quy tắc (chẳng hạn tên

hãng phải viết hoa), hoặc disable những trường không cần.

Bạn viết code trong thư viện CUSTOM, bên trong những procedure shell

được cung cấp. Oracle Applications gửi các sự kiện tới thư viện

CUSTOME. Những đoạn code bạn viết có hiệu lực dựa vào những sự

kiện này.

Thư viện GLOBE : cho phép người phát triển Oracle Applications tập hợp các tính

năng chung hoặc riêng vào trong form Oracle Applications mà không phải thay đổi

form Oracle Applications gốc. Oracle Applications gửi các sự kiện tới thư viện

GLOBE. Các đoạn code bên trong có hiệu lực dựa vào các sự kiện này. Thư viện

GLOBE gọi đến các routine trong các thư viện JA, JE và JL.

Thư viện JA : chứa code đặc trưng cho khu vực Asia/Pacific và được gọi bởi thư

viện GLOBE.

Thư viện JE : chứa code đặc trưng cho khu vực EMEA (Europe/Middle

East/Africa) và được gọi bởi thư viện GLOBE.

Thư viện JL : chứa code đặc trưng cho khu vực Latin America và được gọi bởi thư

viện GLOBE.

Page 42: Oracle Application Form

42

Các trigger trong form TEMPLATE

Form TEMPLATE chứa một số trigger mức form. Các trigger này cần phải có để

các routine khác hoạt động đúng. Text trong trigger thường được giữ nguyên,

người sử dụng sẽ thêm các đoạn text của mình vào trước hoặc sau chúng.

Các trigger chuẩn :

KEY–CLRFRM

KEY–COMMIT

KEY–DUPREC

KEY–EDIT

KEY–EXIT

KEY–HELP

KEY–LISTVAL

KEY–MENU

ON–ERROR

POST–FORM

PRE–FORM

WHEN–FORM–NAVIGATE

WHEN–NEW–BLOCK–INSTANCE

WHEN–NEW–FORM–INSTANCE

WHEN–NEW–ITEM–INSTANCE

WHEN–NEW–RECORD–INSTANCE

WHEN–WINDOW–CLOSED

WHEN–WINDOW–RESIZED

Các trigger do người dùng định nghĩa :

ACCEPT

CLOSE_THIS_WINDOW

CLOSE_WINDOW

EXPORT

FOLDER_ACTION

FOLDER_RETURN_ACTION

LASTRECORD

MENU_TO_APPCORE

QUERY_FIND

STANDARD_ATTACHMENTS

Page 43: Oracle Application Form

43

ZOOM

Các trigger thường phải chỉnh sửa :

ACCEPT

APP_STANDARD.EVENT(‟ACCEPT‟);

Trigger này xử lý chức năng ”Action, Save and Proceed” trên

menu hoặc toolbar. Nó lưu những thay đổi và chuyển tới bản ghi

tiếp theo của block được xác định là First Navigation Block.

Thay thế code trong trigger này, hoặc tạo trigger mức block với

kiểu xử lý là „Override‟

FOLDER_RETURN_ACTION null;

Trigger này cho phép customize các folder event xác định.

Thay thế text bởi code cần thiết để xử lý các hành động cho folder.

KEY–DUPREC

APP_STANDARD.EVENT(‟KEY–DUPREC‟);

Trigger này disable tính năng nhân đôi bản ghi mặc định của

Oracle Forms.

Để xử lý tính năng ”Edit, Duplicate Record Above” trên menu

được đúng, tạo 1 trigger KEY–DUPREC mức block với kiểu xử lý

„Override‟. Viết code cho trigger này để nó thực hiện việc nhân đôi

bản ghi, sau đó validate hoặc xoá các trường cần thiết.

KEY–CLRFRM

APP_STANDARD.EVENT(‟KEY–CLRFRM‟);

Trigger này validate bản ghi trước khi thử xoá form.

Thêm code cần thiết bên dưới code có sẵn. Thường thì bạn sẽ thêm

các lời gọi GO_BLOCK nếu có các alternative region trong form

của bạn, và cung cấp lại các giá trị cho region control poplist của

bạn sau hành động Clear Form.

KEY–MENU

Page 44: Oracle Application Form

44

APP_STANDARD.EVENT(‟KEY–MENU‟);

Trigger này disable lệnh Block Menu của Oracle Forms.

Để enable hoạt động của Alternative Region bằng bàn phím từ 1

block cụ thể, tạo trigger KEY–MENU mức block với kiểu xử lý là

„Override‟. Trigger này nên mở ra 1 LOV với các sự lựa chọn

giống như Alternative Region control poplist.

KEY–LISTVAL

APP_STANDARD.EVENT(‟KEY–LISTVAL‟);

Trigger này thực hiện các hoạt động của flexfield hoặc gọi LOV.

Tạo trigger mức block hoặc item với kiểu xử lý „Override‟ trên các

trường sử dụng đối tượng Calendar, hoặc các trường gọi flexfield

khi chương trình đang chạy.

ON–ERROR

APP_STANDARD.EVENT(‟ON–ERROR‟);

Trigger này xử lý tất cả các lỗi, từ server hoặc từ client, sử dụng

các lời gọi của Message Dictionary.

Để bẫy các lỗi cụ thể, kiểm tra các lỗi cụ thể bạn mắc trước khi gọi

APP_STANDARD

declare

original_mess varchar2(80);

begin

IF MESSAGE_CODE = <your message number> THEN

original_mess := MESSAGE_TYPE||‟–‟||

to_char(MESSAGE_CODE)||‟: ‟||MESSAGE_TEXT;

––– your code handling the error goes here

message(original_mess);

ELSE

APP_STANDARD.EVENT(‟ON_ERROR‟);

END IF

end;

POST–FORM

APP_STANDARD.EVENT(‟POST–FORM‟);

Trigger này được dành cho những sử dụng trong tương lai.

Page 45: Oracle Application Form

45

Thêm code cần thiết vào trước code có sẵn.

PRE–FORM

FND_STANDARD.FORM_INFO(‟$Revision: <Number>$‟,

‟<Form Name>‟,

‟<Application Shortname>‟,

‟$Date: <YY/MM/DD HH24:MI:SS> $‟,

‟$Author: <developer name> $‟);

APP_STANDARD.EVENT(‟PRE–FORM‟);

APP_WINDOW.SET_WINDOW_POSITION(‟BLOCKNAME‟,

‟FIRST_WINDOW‟);

Trigger này khởi tạo các giá trị bên trong Oracle Applications và

menu. Các giá trị bạn nhập vào sẽ được nhìn thấy khi chọn ”Help,

About Oracle Applications” từ menu của Oracle Applications.

Bạn phải sửa lại short name của Application. Application

Shortname điều khiển file trợ giúp online nào của Application được

truy cập khi người dùng chọn nút Help trên toolbar.

Form name là tên form của người dùng. Nó chỉ có mục đích để bạn

tham khảo, và không được sử dụng ở chỗ nào khác nữa.

Oracle sử dụng 1 hệ thống điều khiển mã nguồn cho phép tự động

cập nhật các giá trị bắt đầu với “$”.

Bạn cũng phải sửa lời gọi APP_WINDOW để đưa tên block của

bạn vào.

QUERY_FIND

APP_STANDARD.EVENT(‟QUERY_FIND‟);

Trigger này đưa ra 1 thông báo mặc định cho biết Query Find

không được dùng.

Sửa code trong trigger này, hoặc tạo trigger mức block với kiểu xử

lý „Override‟ khi bạn tạo 1 Find Window hoặc 1 Row-LOV trong

form của bạn

WHEN–NEW–FORM–INSTANCE

Page 46: Oracle Application Form

46

FDRCSID(‟$Header: ... $‟);

APP_STANDARD.EVENT(‟WHEN–NEW–FORM–

INSTANCE‟);

–– app_folder.define_folder_block(‟template test‟,

‟folder_block‟, ‟prompt_block‟, ‟stacked_canvas‟,

‟window‟, ‟disabled functions‟);

–– app_folder.event(‟VERIFY‟);

Lời gọi APP_STANDARD.EVENT trong trigger này hỗ trợ chế độ

query-only được gọi bởi FND_FUNCTION.EXECUTE. Lời gọi

FDRCSID hỗ trợ hệ thống điều khiển mã nguồn của Oracle

Applications. Các lời gọi APP_FOLDER chỉ cho các sử dụng bên

trong của Oracle Applications. Các custom form không cần đến

FDRCSID hay APP_FOLDER, nhưng giữ lại chúng trong trigger

cũng không ảnh hưởng gì.

Thêm những code cần thiết trước code đã có.

WHEN–NEW–RECORD–INSTANCE

APP_STANDARD.EVENT(‟WHEN–NEW–RECORD–

INSTANCE‟);

Trigger này quản lý trạng thái của menu và toolbar của Oracle

Applications

Tạo trigger mức block nếu cần ( kiểu xử lý „Before‟ )

WHEN–NEW–BLOCK–INSTANCE

APP_STANDARD.EVENT(‟WHEN–NEW–BLOCK–

INSTANCE‟);

Trigger này quản lý trạng thái của menu và toolbar của Oracle

Applications

Tạo trigger mức block nếu cần ( kiểu xử lý „Before‟ )

WHEN–NEW–ITEM–INSTANCE

APP_STANDARD.EVENT(‟WHEN–NEW–ITEM–INSTANCE‟);

Trigger này quản lý trạng thái của menu và toolbar của Oracle

Applications

Nếu thêm vào 1 lời gọi đến flexfields routine, thêm nó vào trước

lời gọi APP_STANDARD.EVENT. Nói chung không nên thêm các

code khác vào trong trigger này, vì sẽ tác động đến mọi item trong

form. Nếu cần thì tạo 1 trigger mức block hoặc item với kiểu xử lý

là „Before‟.

Page 47: Oracle Application Form

47

Các trigger không được chỉnh sửa

CLOSE_THIS_WINDOW

Trigger này gọi APP_CUSTOM.CLOSE_WINDOW khi chọn

“Action –> Close Window” trên menu.

CLOSE_WINDOW

APP_CUSTOM.CLOSE_WINDOW(:SYSTEM.EVENT_WINDO

W);

Trigger này xử lý tất cả các sự kiện đóng window. Các code xử lý

nằm trong package APP_CUSTOM.CLOSE_WINDOW

EXPORT

app_standard.event(‟EXPORT‟);

Trigger này xử lý lời gọi ”Action, Export” từ menu

FOLDER_ACTION

app_folder.event(:global.folder_action);

Trigger này xử lý khi gọi các mục trên menu Folder.

KEY–COMMIT

APP_STANDARD.EVENT(‟KEY–COMMIT‟);

Trigger này xử lý các commit trong các form bình thường hoặc các

form được gọi.

KEY–EDIT

APP_STANDARD.EVENT(‟KEY–EDIT‟);

Trigger này thực hiện các hoạt động của flexfield, hoặc gọi

Calendar hay Editor.

KEY–EXIT

APP_STANDARD.EVENT(‟KEY–EXIT‟);

Trigger này xử lý các sự kiện Close và rời khỏi chế độ enter-query.

KEY–HELP

APP_STANDARD.EVENT(‟KEY–HELP‟);

Trigger này gọi hệ thống Window Help.

LASTRECORD

APP_STANDARD.EVENT(‟LASTRECORD‟);

Page 48: Oracle Application Form

48

Trigger này xử lý sự kiện menu “Go–>Last Record”.

MENU_TO_APPCORE

APP_STANDARD.EVENT(:global.menu_to_appcore);

Trigger này hỗ trợ menu Special

STANDARD_ATTACHMENTS

atchmt_api.invoke;

Trigger này xử lý lời gọi của mục menu Attachments hoặc của nút

Attachments trên toolbar.

WHEN–WINDOW–CLOSED

execute_trigger(‟CLOSE_WINDOW‟);

Trigger này tập trung các sự kiện đóng window từ Oracle

Applications hoặc menu Window Manager.

WHEN–FORM–NAVIGATE

Bạn không thể sửa trigger này. Nó enable các hành động tiêu chuẩn

chính, như normalize 1 form đang được minimize khi form này

được navigate.

Để sử dụng sự kiện form này, gán cho biến global có tên là

GLOBAL.WHEN_FORM_NAVIGATE giá trị là tên của 1 trigger

do người dùng định nghĩa. Thường thì việc gán này được thực hiện

ngay trước khi gọi GO_FORM.

ZOOM

appcore_custom.event(‟ZOOM‟);

Trigger này xử lý lời gọi của mục menu ”Action, Zoom” hoặc của

nút trên toolbar.

Page 49: Oracle Application Form

49

Thiết lập các thuộc tính của

các đối tượng

chứa(ContainerObject)

Các đối tượng chứa :

module

window ( modal và non-modal )

canvas ( content và stacked )

block

region

Module :

Lớp thuộc tính : form TEMPLATE tự động áp dụng lớp thuộc tính MODULE cho

module. Các thiết lập cho lớp này biến đổi tùy theo nền GUI.

Tên module : tên module phải giống tên form. VD : tên module là GL01 thì tên

form là GL01.fmb

Thuộc tính First Navigation Data Block : đặt cho thuộc tính này tên của block đầu

tiên mà người sử dụng tiếp xúc khi form chạy. ( không đặt theo tên của block

WORLD hay block CONTROL ). Thuộc tính này cũng quy định điểm đến của con

trỏ sau CLEAR_FORM hoặc sau hành động “Action -> Save and Proceed “ mặc

định.

Window :

Window sẽ tự động kế thừa các chuẩn giao diện của nền GUI mà chúng đang

chạy trên đó từ form APPSTAND ( như các tính năng của frame, các font trên title

bar, các nút quản lý window ).

Page 50: Oracle Application Form

50

ROOT_WINDOW là một window đặc biệt, không được sử dụng vì sẽ làm ảnh

hưởng đến toolbar và các đối tượng chuẩn khác của Oracle Application.

Non-modal Window : cho phép người sử dụng tương tác với các window khác,

với thanh công cụ hay menu. Non-modal Window được dùng để thể hiện hầu hết

các thành phần trong ứng dụng.

. Lớp thuộc tính : mọi non-modal window đều áp dụng lớp thuộc tính

WINDOW.

. Thuộc tính Primary Canvas : nhập vào tên content canvas gắn với

window này.

. Xác định tọa độ ( X,Y ) : lập trình định vị tọa độ window trong thủ tục

APP_CUSTOM.OPEN_WINDOW.

. Tiêu đề ( Title ) : có thể thiết lập để thay đổi tùy theo nội dung window

hiển thị.

. Kích thước : kích thước tối đa của window là 7.8 x 5 ( rộng x cao )

inches.

. Đóng window : Bạn phải lập trình để thực hiện hành động đóng

window. Đóng window đầu tiên của một form sẽ đóng lại toàn bộ form

và các hành động khác. Lập trình hành động đóng này trong thủ tục

APP_CUSTOM.CLOSE_WINDOW.

. Mở window : nếu bạn có đoạn mã nào muốn được thực hiện khi mở

window, đặt nó trong thủ tục APP_CUSTOM.OPEN_WINDOW. Bạn

phải thêm đoạn mã để điều khiển tọa độ block và định vị window. Khi

chuyển đến một khối nào đấy ( bằng GO_BLOCK ), window chứa block

đó sẽ tự động mở ra.

. Nếu muốn tắt ( disable ) chức năng nào đó của menu, sử dụng

APP_SPECIAL.

Modal Window : buộc người sử dụng chỉ thao tác trong cửa sổ đó (không thể

tương tác được với các cửa sổ khác), sau khi chấp nhận hoặc huỷ bỏ những thay

đổi đã thực hiện mới thoát được ra khỏi cửa sổ.

. Lớp thuộc tính : sử dụng lớp thuộc tính WINDOW_DIALOG để tạo một

modal window.

. Thuộc tính Primary Canvas : nhập vào tên content canvas gắn với

window này.

. Vị trí window : modal window khi mở luôn ở chính giữa màn hình

Page 51: Oracle Application Form

51

. Đóng window : modal window có thể đóng bằng cơ chế đóng cửa sổ

GUI ( kích chuột vào ô có dấu X góc trên bên phải ) hoặc đóng bằng lập

trình.

Canvas :

Content Canvas :

. Lớp thuộc tính : CANVAS

. Kích thước : nên đặt kích thước canvas bằng với kích thước window

chứa nó.

Stacked Canvas :

. Lớp thuộc tính : CANVAS_STACKED

. Thuộc tính Raise on Entry luôn đặt là Yes

Block :

Lớp thuộc tính : BLOCK ( với những block trên non-modal window ),

BLOCK_DIALOG ( với những block trên modal window ).

Nếu block dựa trên một bảng hoặc một view đơn ( view trên một bảng ), đặt thuộc

tính Key-Mode là Unique. Nếu block dựa trên view liên kết ( view trên nhiều bảng

), đặt Update Allowed là No. Phải có ít nhất một item trong block được đánh dấu là

primary key ( đặt thuộc tính Primary Key của nó là Yes ).

Đặt thuộc tính Delete Allowed là No để không cho xoá trong block.

Next and Previous Navigation Data Block : đặt các thuộc tính này của khối bằng

tên các khối có thứ tự duyệt sau ( next ) và trước ( previous ) khối đó. Với khối đầu

tiên, previous là chính nó, với khối sau cùng, next là chính nó.

Context Block : được thể hiện trong các detail window, cung cấp ngữ cảnh và sao

chép các trường được thể hiện trong master window. Để tạo 1 context block, tạo

các display item trong cùng block giống như master block và đồng bộ trường

context theo trường master.

Dialog Block : được thể hiện trong modal window, đòi hỏi user phải tương tác với

chúng trước khi chuyển qua cửa sổ khác.

Page 52: Oracle Application Form

52

Xử lý các KEY – trigger : mặc dù trong modal window không thể tương tác với

menu và toolbar, ta vẫn có thể gọi một số tính năng bằng nhấn một số phím chức

năng trên bàn phím. Để tránh điều này, ta disable các Key – trigger cho block bằng

cách lập trình một KEY-OTHERS trigger gọi APP_EXCEPTION.DISABLED để

tắt mọi chức năng. Sau đó, ta có thể cho phép một vài chức năng có thể được thực

hiện bằng việc lập trình lại một số KEY – trigger, như :

( Với block cho phép nhiều bản ghi )

. Ta cũng có thể để enable cho các KEY - trigger của block, và chỉ

disable một số bằng cách gọi APP_EXCEPTION.DISABLED trong

những KEY – trigger nào ta muốn disable.

. Navigation ( điều hướng ): ngăn cản việc chuyển focus ra bên ngoài

modal window bằng cách : không được đặt Navigation Style là Change

Data Block, next và previous của block đặt là chính block đó.

Page 53: Oracle Application Form

53

Data Block không có bảng cơ sở ( base table ) : sử dụng các trigger giao dịch (

ON-INSERT, ON-LOCK …) nếu các block này phải xử lý commit.

Data Block một bản ghi : cho phép user xem được các bản ghi của một thực thể,

nhưng tại mỗi thời điểm chỉ nhìn thấy một bản ghi.

Data Block nhiều bản ghi : cho phép user xem được các bản ghi của một thực thể,

nhưng tại mỗi thời điểm có thể thấy nhiều bản ghi.

. Tạo Current Record Indicator : tạo một text item trong block không có

detail block ứng với nó. Thiết lập lớp thuộc tính cho nó là

CURRENT_RECORD_INDICATOR và tạo trigger WHEN-NEW-

ITEM-INSTANCE cho nó, trong trigger đó gọi

GO_ITEM(tên_block.tên_field). Mỗi lần indicator này được click thì con

trỏ sẽ chuyển đến trường đầu tiên của bản ghi tương ứng.

. Tạo Drill-down Indicator : tương tự như Current Record Indicator

nhưng là cho block có một hoặc nhiều detail block ứng với nó.

Combination Block : một kiểu định dạng các trường lai giữa kiểu định dạng đơn

bản ghi và đa bản ghi, trong đó mỗi kiểu định dạng tồn tại trên window riêng của

chúng, nhưng tất cả các trường của cả 2 kiểu định dạng nằm trong cùng một block.

Quan hệ Master – Detail :

. Đặt thuộc tính Coordination là Prevent Masterless Operation để các bản

ghi chi tiết luôn luôn tương ứng với bản ghi chính của nó.

. Đặt thuộc tính Master Deletes là Non-Isolated nếu không cho phép xóa

các bản ghi ở cả master table và detail table, Isolated nếu chỉ cho xoá ở

bảng master, và Cascading nếu cho phép xoá ở cả 2 bảng. Tuy nhiên

không nên sử dụng Cascading mà nên dùng Isolated để xóa ở bảng

master, sau đó viết một thủ tục cho bảng master thực hiện lệnh xoá các

bản ghi detail tương ứng.

. Nếu ( master ) block đầu tiên của form không tự động truy vấn, gọi

do_key(„execute_query‟); trong trigger WHEN-NEW-FORM-

INSTANCE.

Page 54: Oracle Application Form

54

Thiết lập thuộc tính WHERE Clause động : mỗi lần truy vấn đưa vào điều kiện lọc

khác nhau.

Region :

Region là 1 nhóm các trường ( field ). Hầu hết các region chỉ đơn thuần là sự trình

bày thẩm mĩ, ví như một frame ( box ) bao lấy nhóm các trường liên quan, hoặc

một frame ( line ) kẻ bên trên nhóm các trường có quan hệ với nhau. Khi con trỏ ở

trong một region, nó sẽ duyệt theo thứ tự đi qua tất cả các item trong region đó

trước khi chuyển qua các field khác ngoài region.

. Tabbed Region : xuất hiện trên tab canvas

. Alternative Region : xuất hiện trên stacked canvas

. Overflow Region

Page 55: Oracle Application Form

55

Thiết lập các thuộc tính của

các đối tượng Widget

Text Item :

Các lớp đối tượng :

TEXT_ITEM : thường dùng nhất

TEXT_ITEM_DISPLAY_ONLY : dùng cho các trường không cho phép

người dùng nhập vào

TEXT_ITEM_MULTILINE

TEXT_ITEM_DATE : dùng cho các trường date

Thuộc tính Query Length : thiết lập độ dài cho xâu truy vấn.

WHEN-VALIDATE-ITEM : trigger này kích hoạt khi giá trị của trường có sự thay

đổi.

Các trường date : Các trường date người dùng nhập vào nên sử dụng Calendar.

Kiểu dữ liệu : DATE ( user không cần nhập giờ phút ) , DATETIME (

user phải nhập cả ngày và giờ phút ), TIME ( user chỉ được nhập giờ ).

Đặt giá trị mặc định cho trường bằng ngày hiện tại mà không tính đến giờ

bằng $$DBDATE$$, đặt giá trị bằng cả ngày và giờ hiện tại bằng

$$DBDATETIME$$, đặt giá trị bằng giờ hiện tại mà bỏ qua ngày bằng

$$DBTIME$$.

Độ dài trường : 11 kí tự ( chỉ nhập ngày ) và 20 kí tự ( nhập cả ngày và

giờ ). Oracle Forms mặc định kiểu định dạng ( format ) của trường dựa

Page 56: Oracle Application Form

56

theo biến môi trường NLS_DATE_FORMAT.

Validation trường date : nên validate trường date ở mức bản ghi thay vì

mức item, nó sẽ giúp việc sửa lỗi dễ hơn.

Display Item :

Không cho phép người sử dụng tương tác với nó, chỉ đơn thuần hiển thị dữ liệu và không nhận focus.

Lớp thuộc tính : DYNAMIC_TITLE, DYNAMIC_PROMPT, DISPLAY_ITEM

Poplist : lưu dữ liệu dưới dạng danh sách ( kích cỡ nhỏ ) các giá trị có thể.

Lớp thuộc tính : LIST

Giới hạn : độ rộng của một phần tử list tối đa là 30 kí tự.

Có thể tha đổi nội dung phần tử trong list khi chạy

Option Group :

Lớp thuộc tính : RADIO_GROUP ( cho nhóm ) và RADIO_BUTTON ( cho các đối tượng

trong nhóm )

Check Box :

Lớp thuộc tính : CHECKBOX ( thông dụng ), CHECKBOX_COORDINATION ( cho check

box tọa độ ).

Button ( Nút ) :

Nút có thể là nút chữ, hoặc nút hình. Nút nên được đặt cùng block với các đối

tượng mà nó tương tác.

Lớp thuộc tính : BUTTON ( nút chữ ) , BUTTON_ICONIC ( nút hình )

Nút hình không thể kích hoạt từ bàn phím.

Hầu hết các nút không thể kích hoạt trong chế độ Enter-Query

Các nút nên gọi APP_STANDARD.APP_VALIDATE và truyền một scope ( vùng

validate ) trước khi thực hiện hành động của chúng. Điều này đảm bảo các bản ghi

được kiểm tra tính hợp lệ trước khi hành động được thực hiện, và nút thực hiện

hành động trên block mà nó mong muốn.

Page 57: Oracle Application Form

57

List of Values ( LOV )

Lớp thuộc tính : LOV

Nên tạo LOV theo view.

Đặt title cho LOV theo tên đối tượng mà nó chứa. Độ rộng cột phải đủ để thể hiện

giá trị trường.

Nếu một item có LOV, có thể đặt thuộc tính Validate from List của nó là Yes để

chỉ chấp nhận những giá trị nhập vào có trong LOV.

Để LOV luôn tự cập nhật những giá trị mới mỗi khi được gọi, đặt Automatic

Refresh là Yes. Nếu LOV có nhiều bản ghi, đặt Filter Before Display là Yes để

nhắc user giới hạn phạm vi tìm kiếm mỗi lần gọi LOV.

Để gọi được LOV trong chế độ Enter-Query, tạo 1 trigger KEY-LISTVAL trên đối

tượng gọi LOV:

Trong chế độ Enter-Query, giá trị trả về của LOV phải được trả về trường mà từ đó LOV được gọi

Thiết lập các thuộc tính cho item :

Sử dụng APP_ITEM_PROPERTY.SET_PROPERTY : dùng để thiết lập các thuộc

tính : ALTERABLE, ALTERABLE_PLUS, ENTERABLE, DISPLAYED,

ENABLED, REQUIRED. Các thuộc tính khác dùng thủ tục gốc

SET_ITEM_PROPERTY của Oracle Form.

Thuộc tính ALTERABLE cho phép ( hoặc không cho phép ) thay đổi một

instance ( hàng ) của item mặc cho bản ghi là mới hoặc là bản ghi truy

vấn từ CSDL.

. Thủ tục :

app_item_property.set_property ( itemid, ALTERABLE, PROPERTY_ON);

tương đương với

set_item_instance_property(itemid, CURRENT_RECORD,

INSERT_ALLOWED, PROPERTY_ON);

set_item_instance_property(itemid, CURRENT_RECORD, UPDATEABLE,

PROPERTY_ON);

set_item_property(itemid, INSERT_ALLOWED, PROPERTY_ON);

set_item_property(itemid, UPDATEABLE, PROPERTY_ON);

Page 58: Oracle Application Form

58

. Thủ tục :

app_item_property.set_property(itemid, ALTERABLE,PROPERTY_OFF);

tương đương với

set_item_instance_property(itemid, CURRENT_RECORD,

INSERT_ALLOWED, PROPERTY_OFF);

set_item_instance_property(itemid, CURRENT_RECORD, UPDATEABLE,

PROPERTY_OFF);

Thuộc tính ALTERABLE_PLUS cho phép hoặc không cho phép thay

đổi tất cả các instance ( hàng ) của item, mặc cho bản ghi là mới hoặc

được truy vấn từ cơ sở dữ liệu.

. Thủ tục :

app_item_property.set_property(itemid, ALTERABLE_PLUS,

PROPERTY_ON);

tương đương với :

set_item_property(itemid, INSERT_ALLOWED, PROPERTY_ON);

set_item_property(itemid, UPDATEABLE, PROPERTY_ON);

. Thủ tục :

app_item_property.set_property(itemid, ALTERABLE_PLUS,

PROPERTY_OFF);

tương đương với :

set_item_property(itemid, INSERT_ALLOWED, PROPERTY_OFF);

set_item_property(itemid, UPDATEABLE, PROPERTY_OFF);

Thuộc tính ENTERABLE dùng để enable hoặc disable một instance của

item, là sự mở rộng của ALTERABLE bằng việc điều khiển thêm thuộc

tính NAVIGALBE.

. Thủ tục :

app_item_property.set_property(itemid,ENTERABLE,

PROPERTY_ON);

tương đương với :

set_item_instance_property(itemid,CURRENT_RECORD,

INSERT_ALLOWED, PROPERTY_ON);

set_item_instance_property(itemid,CURRENT_RECORD,

UPDATEABLE, PROPERTY_ON);

Page 59: Oracle Application Form

59

set_item_instance_property(itemid,CURRENT_RECORD,

NAVIGABLE, PROPERTY_ON);

set_item_property(itemid, INSERT_ALLOWED, PROPERTY_ON);

set_item_property(itemid, UPDATEABLE, PROPERTY_ON);

set_item_property(itemid, NAVIGABLE, PROPERTY_ON);

( đặt giá trị cho cả item và item-instance để tạo hiệu quả đồng nhất )

. Thủ tục :

app_item_property.set_property(itemid,ENTERABLE,

PROPERTY_OFF);

tương đương với :

set_item_instance_property(itemid,CURRENT_RECORD,

INSERT_ALLOWED, PROPERTY_OFF);

set_item_instance_property(itemid,CURRENT_RECORD,

UPDATEABLE, PROPERTY_OFF);

set_item_instance_property(itemid,CURRENT_RECORD,

NAVIGABLE, PROPERTY_Off);

Thuộc tính DISPLAY điều khiển việc ẩn, hiện item cũng như reset lại

các thuộc tính cụ thể mà Oracle Form tự động thiết lập khi ẩn một item

nào đó.

. Thủ tục sau :

app_item_property.set_property(itemid, DISPLAYED,

PROPERTY_ON);

tương đương với :

set_item_property(itemid, DISPLAYED, PROPERTY_ON);

nếu item không phải là display item thì thiết lập thêm :

set_item_property(itemid, ENABLED, PROPERTY_ON);

set_item_property(itemid, NAVIGABLE, PROPERTY_ON);

nếu item không phải là display item hay nút, thiết lập thêm :

set_item_property(itemid, QUERYABLE, PROPERTY_ON);

set_item_property(itemid, INSERT_ALLOWED, PROPERTY_ON);

set_item_property(itemid, UPDATEABLE, PROPERTY_ON);

. Thủ tục sau :

app_item_property.set_property(itemid, DISPLAYED,

PROPERTY_OFF);

Page 60: Oracle Application Form

60

tương đương với

set_item_property(itemid, DISPLAYED, PROPERTY_OFF);

Thuộc tính ENABLE dùng để enable hay disable một item nào đó, xử lý

với APP_ITEM_PROPERTY.SET_PROPERTY khác với xử lý gốc (

native behavior ) của Oracle Forms ở chỗ khi re-enable thì sẽ reset lại các

thuộc tính liên quan đã được Oracle Forms đặt tự động khi disable.

. Thủ tục : app_item_property.set_property(itemid,

ENABLED,PROPERTY_ON);

tương đương với ( nếu item là text hoặc list ) :

set_item_property(itemid, INSERT_ALLOWED, PROPERTY_ON);

set_item_property(itemid, UPDATEABLE, PROPERTY_ON);

set_item_property(itemid, NAVIGABLE, PROPERTY_ON);

tương đương với ( nếu item là button ) :

set_item_property(itemid, ENABLED, PROPERTY_ON);

Thuộc tính REQUIRED quyết đinh một item có bắt buộc phải được nhập

dữ liệu hay không, là một thuộc tính ở item-level, tức là tác động lên tất

cả các instance của item. Nếu chỉ muốn tác động lên một instance cụ thể

nào đó của item, ta có thể dùng thủ tục dựng sẵn của Oracle Forms là :

SET_ITEM_INSTANCE_PROPERTY.

. app_item_property.set_property(itemid, REQUIRED, PROPERTY_ON);

. app_item_property.set_property(itemid, REQUIRED, PROPERTY_OFF);

Một số lưu ý :

Gọi APP_ITEM_PROPERTY.SET_PROPERTY tương đương với một tập các xử

lý thuộc tính có liên quan với nhau nếu thiết lập từng bước.

Một số thuộc tính như ALTERABLE hay ENTERABLE chỉ có thể thiết lập khi

chạy ( runtime ) vì nó tác động lên từng instance.

Hầu hết các Visual Attribute được triển khai tự động bởi các APPCORE routine,

trừ một số visual attribute sau ( mà người phát triển phải tự lập trình để thực hiện )

: DATA_DRILLDOWN, DATA_SPECIAL, DATA_REQUIRED

Page 61: Oracle Application Form

61

Điều khiển hoạt động của

Window, Block, và Region

Điều khiển hoạt động của Window

Định vị window khi nó được mở :

CASCADE : cửa sổ con chồng lên cửa sổ chính, lệch chéo xuống 0.3‟‟.

Thường dùng cho các cửa sổ detail.

RIGHT, BELOW : cửa sổ con mở bên phải, hoặc bên dưới cửa sổ chính,

không che cửa sổ chính.

OVERLAP : cửa sổ detail chồng lên cửa sổ chính, lệch xuống dưới 0.3‟‟.

CENTER : cửa sổ mở chính giữa cửa sổ khác, thường dùng cho modal

window.

FIRST_WINDOW : định vị cửa sổ ngay dưới toolbar, thường dùng cho

cửa sổ chính.

Page 62: Oracle Application Form

62

Đóng Window :

Các sự kiện đóng non-modal window ( không phải là modal window )

đều chuyển tới APP_CUSTOME.CLOSE_WINDOW. Code mặc định

được viết trong form TEMPLATE thực hiện những việc sau :

. Nếu form đang ở chế độ Enter-Query, APP_CUSTOM sẽ gọi :

APP_EXCEPTION.DISABLED.

. Trường hợp ngược lại, nếu con trỏ đang ở trong window chuẩn bị đóng,

APP_CUSTOM thực hiện do_key(„PREVIOUS_BLOCK‟) để đưa con

trỏ thoát khỏi window hiện tại.

. Cuối cùng, APP_CUSTOM ẩn window bằng

HIDE_WINDOW(„<name>‟)

Nếu con trỏ vẫn nằm trong window, window sẽ tự động mở lại sau khi

được đóng. Để đóng window đầu tiên ( tức là đóng form ), gọi

APP_WINDOW.CLOSE_FIRST_WINDOW

Example :

In a form with windows ”Header,” ”Lines,” and ”Shipments,” where

Lines is a detail of Header, and Shipments is a detail of Lines, the logic

to close the windows is as follows:

PROCEDURE close_window (wnd VARCHAR2)

IS

IF wnd = ‟HEADER‟ THEN

––

–– Exit the form

––

app_window.close_first_window;

ELSIF wnd = ‟LINES‟ THEN

––

–– Close detail windows (Shipments)

––

app_custom.close_window(‟SHIPMENTS‟);

––

–– If cursor is in this window,

–– move it to the HEADER block

Page 63: Oracle Application Form

63

––

IF (wnd =

GET_VIEW_PROPERTY(GET_ITEM_PROPERT

Y(

:SYSTEM.CURSOR_ITEM,ITEM_CANVAS),

WINDOW_NAME)) THEN

GO_BLOCK(‟HEADER‟);

END IF;

ELSIF wnd = ‟SHIPMENTS‟ THEN

––

–– If cursor is in this window,

–– move it to the LINES block

––

IF (wnd =

GET_VIEW_PROPERTY(GET_ITEM_PROPERT

Y(

:SYSTEM.CURSOR_ITEM, ITEM_CANVAS),

WINDOW_NAME)) THEN

GO_BLOCK(‟LINES‟);

END IF;

END IF;

––

–– THIS CODE MUST REMAIN HERE. It ensures

–– the cursor is not in the window that will

–– be closed by moving it to the previous block.

––

IF (wnd =

GET_VIEW_PROPERTY(GET_ITEM_PROPERT

Y(

:SYSTEM.CURSOR_ITEM, ITEM_CANVAS),

WINDOW_NAME)) THEN

Page 64: Oracle Application Form

64

DO_KEY(‟PREVIOUS_BLOCK‟);

END IF;

––

–– Now actually close the designated window

––

HIDE_WINDOW(wnd);

END close_window;

Thiết lập title động cho window :

Nếu muốn thay đổi base title của một window, gọi :

SET_WINDOW_PROPERTY(…TITLE…). Bất kì lời gọi

APP_WINDOW.SET_TITLE nào trong tương lai sẽ bảo toàn base title

mới đó.

Điều khiển hoạt động của Block

Lập trình cho các quan hệ Master-Detail : Khi detail block và master

block nằm trong 2 cửa sổ khác nhau (đều là non-modal window), detail

block phải cung cấp một cơ cấu cho phép user chuyển đổi giữa

coordination tức thì và coordination trì hoãn. Khi detail block là visible,

chọn coordination tức thì sẽ cho phép các detail record thay đổi khi

master record thay đổi. Còn khi detail block là không visible, nên chọn

coordination là trì hoãn. Sử dụng thủ tục

APP_WINDOW.SET_COORDINATION để coordinate các block.

Ví dụ : trong ví dụ sử dụng các đối tượng sau :

• Master block ORDERS, trong window ORDERS

• Detail Block LINES, trong window LINES

• Relation : ORDERS_LINES

Page 65: Oracle Application Form

65

• Coordination check box : CONTROL.ORDERS_LINES

• Nút để navigate tới LINES block : CONTROL.LINES

+ Bước 1 : tạo 1 nút để navigate tới detail block

+ Bước 2 : tạo 1 coordination check box ( đặt trong control block )

trong cửa sổ detail cho phép người dùng chọn coordination tức thì

hoặc coordination trì hoãn khi cửa sổ được mở.

+ Bước 3 : tạo 1 thủ tục xử lý item như sau :

PACKAGE BODY control IS

PROCEDURE lines(EVENT VARCHAR2)

IS

BEGIN

IF (EVENT = ‟WHEN–BUTTON–

PRESSED‟) THEN

app_custom.open_window(‟LINES‟);

END IF;

END lines;

PROCEDURE orders_lines(EVENT

VARCHAR2) IS

BEGIN

IF (EVENT = ‟WHEN–CHECKBOX–

CHANGED‟) THEN

APP_WINDOW.SET_COORDINATION(E

VENT,

:control.orders_lines, ‟ORDERS_LINES‟);

END IF;

END orders_lines;

END control;

Bước 4 : sửa package APP_CUSTOM như sau :

Page 66: Oracle Application Form

66

Bước 5 : Gọi các thủ tục xử lý sự kiện và trường đã viết ở trên trong các

trigger :

Triển khai một Combination Block : Mỗi item trong 1 block có thuộc tính Number

of Items Display của riêng nó, nên bạn có thể tạo một single block chứa vài item

là các single-record ( detail ) và vài item khác là multi-record ( Summary ). Khi

triển khai một combination block, hầu hết các item xuất hiện 2 lần, nên

coordination của các giá trị trong các item này phải được quản lý. Thuộc tính

Synchronize with Item tự động thực hiện điều này. Bạn điều khiển việc navigate

tới các phần của block trong các tình huống khác nhau bằng cách sử dụng một

trường gọi là Switcher, là trường được navigate đầu tiên trong block. Khi con trỏ

chuyển tới Switcher, nó ngay lập tức sẽ được chuyển đến item đầu tiên trong phần

Detail hoặc phần Summary của block.

Các bước triển khai :

Bước 1 : Thiết lập Combination Block

Tạo 2 cửa sổ và các canvas để chứa các phần khác nhau của block của bạn.

Với phần Summary, sử dụng các non-mirror item. Nhân đôi các item này để

tạo phần Detail. Phần Detail của Combination Block nên có thứ tự đầu tiên.

Page 67: Oracle Application Form

67

Như thế khi user không điền vào 1 required item và thử commit block, Oracle

Forms sẽ đặt con trỏ vào item đó trong block Detail.

Bước 2 : Thiết lập các thuộc tính cho item

. Với các đối tượng ảnh (là bản sao của đối tượng gốc), đổi tên chúng để phán

ánh mối quan hệ với đối tượng gốc (ví dụ đối tượng gốc tên là status thì đối

tượng ảnh tên là status_mir). Thiết lập thuộc tính Synchronize with Item

property và đảm bảo là thuộc tính Database Item được đặt là Yes nếu các đối

tượng được đồng bộ ứng với các cột của bảng cơ sở.

. Thiết lập thuộc tính Number of Records Displayed ở mức block cho phần

Summary. Các item trong block sẽ cùng nhận giá trị này, nếu như không đặt

lại thuộc tính đó của chúng. Đặt lại thuộc tính Number of Records Displayed

bằng 1 cho các đối tượng trong phần Detail.

. Để ngăn người dùng chuyển tab ra khỏi Detail và vào trong Summary, thiết

lập thuộc tính Previous Navigation Item cho đối tượng Detail đầu tiên và

thuộc tính Next Navigation Item cho đối tượng Detail cuối cùng.

. Để chuyển tab đồng thời với chuyển bản ghi trong 1 block nhiều bản ghi, gọi

APP_COMBO.KEY_PREV_ITEM trong trigger KEY–PREV–ITEM của đối

tượng đầu tiên trong Summary và gọi next_record trong trigger KEY–NEXT–

ITEM của đối tượng cuối cùng của phần Summary.

. Nếu chuyển đổi 1 block đã có thành combination block, phải thay đổi các

tham chiếu trong các trigger đã có, vì bây giờ mỗi trường đều tồn tại 2 phiên

bản.

Bước 3 : Drilldown Record Indicator

Thêm 1 Drilldown Record Indicator thực hiện lệnh :

execute_trigger(‟SUMMARY_DETAIL‟);

Bước 4 : Tham số Record Count

. Tạo 1 tham số để lưu số bản ghi của phần block (Summary hay Detail) mà

bạn đang ở trong. Đặt tên tham số là <block>_RECORD_COUNT, trong đó

<block> là tên của combination block. Chuẩn đặt tên này có liên quan đến

code trong APPCORE. Kiểu dữ liệu của tham số là number, và giá trị mặc

định là 2 (để con trỏ ban đầu đặt trong Summary) hoặc 1 (để con trỏ ban đầu

đặt trong Detail).

. Tạo trigger mức block WHEN–NEW–ITEM–INSTANCE (Execution

Hierarchy: Before) chứa code :

:PARAMETER.<block>_RECORD_COUNT :=

Page 68: Oracle Application Form

68

GET_ITEM_PROPERTY(:SYSTEM.CURSOR_ITEM,

RECORDS_DISPLAYED);

Bước 5 : Switcher

Tạo 1 text item và gán cho nó lớp thuộc tính SWITCHER. Nó là item được

navigate đầu tiên trong block. Đặt nó vào trong toolbar canvas. Tạo 1 trigger

WHEN–NEW–ITEM–INSTANCE mức item cho nó (Execution Hierarchy :

Override) chứa code :

IF(:PARAMETER.<block>_RECORD_COUNT > 1)

THEN

GO_ITEM(‟<first Summary field>‟);

ELSE

APP_WINDOW.SET_WINDOW_POSITION(‟<Detail

window>‟,

‟OVERLAP‟, ‟<Summary window>‟);

GO_ITEM(‟<first Detail field>‟);

END IF;

Bước 6 : Summary/Detail Menu Item

. Tạo 1 trigger SUMMARY_DETAIL mức block (Execution Hierarchy:

Override) chứa code :

IF GET_ITEM_PROPERTY(:SYSTEM.CURSOR_ITEM,

RECORDS_DISPLAYED) > 1 THEN

:PARAMETER.<block>_RECORD_COUNT := 1;

ELSE

:PARAMETER.<block>_RECORD_COUNT := 2;

END IF;

GO_ITEM(‟<block>.Switcher‟);

Đoạn code này thay đổi giá trị trong tham số <block>_RECORD_COUNT

để Switcher chuyển con trỏ tới phần còn lại trong block. Nó được thực thi

khi người dùng chọn “Go -> Summary/Detail”.

. Tạo 1 trigger mức block PRE–BLOCK (Execution Hierarchy:

Override) chứa code :

Page 69: Oracle Application Form

69

APP_SPECIAL.ENABLE(‟SUMMARY_DETAIL‟,

PROPERTY_ON);

. Cuối cùng, tạo 1 trigger mức form PRE–BLOCK (Execution

Hierarchy:Override) chứa code :

APP_SPECIAL.ENABLE(‟SUMMARY_DETAIL‟,

PROPERTY_OFF);

. Nếu tất cả các block đều là combination, bật SUMMARY_DETAIL ở

mức form, bỏ qua trigger mức block. Nếu có nhiều block là combination,

bật SUMMARY_DETAIL ở mức form, và tắt nó ở mức block với các

block không phải combination.

Bước 7 : Định vị window và con trỏ khi mở form

Nếu combination block của bạn là block đầu tiên trong form, định vị 2 cửa sổ

của nó trong trigger PRE-FORM với những lời gọi sau :

APP_WINDOW.SET_WINDOW_POSITION(’<Summary window>’,

’FIRST_WINDOW’);

APP_WINDOW.SET_WINDOW_POSITION(’<Detail window>’,

’OVERLAP’, ’<Summary window>’);

Thường thì người dùng vào Summary trước, tuy nhiên nếu muốn vào Detail

trước, thiết lập tham số <block>_RECORD_COUNT bằng 1 trong trigger

PRE-FORM.

Lập trình cho các Tabbed Regions

Một số khái niệm :

Tabbed Region : một nhóm các tab liên quan với nhau, còn gọi là tab

canvas.

Tab Page : trang tab trong tabbed region, nơi thể hiện một nhóm các item

liên quan.

Topmost tab page : trang tab trên cùng, hay trang tab đang được chọn và

đang thể hiện.

Fixed Field : là trường hay item xuất hiện trên nhiều, hoặc trên tất cả, các

tab page.

Alternative Region Field : là trường chỉ xuất hiện duy nhất trên môt tab

page nào đó và không có mặt trên các tab page khác.

Page 70: Oracle Application Form

70

Control : là cách gọi khác cho field, item hay widget.

Hành động của tabbed region :

Hành động mong muốn là mở ra một tab page và chuyển focus tới một trường thích hợp khi

tab đó được click. Hành động này cần được lập trình vì hành động mặc định của Oracle Forms là mở

tab và đặt focus trên chính đối tượng tab đó.

Keyboard-only Operation : người dùng truy cập vào tab qua phím nóng

trên keyboard.

Dynamic Tab Layouts : ẩn hay hiện một tab linh động tuỳ theo dữ liệu

Other Behavior : các tab nên vận hành được trong chế độ enter-query.

3 mức khó trong lập trình :

Simple (đơn giản) : không cần scrollbar, không có fixed field. Mỗi tab sẽ tương

ứng với 1 block riêng biệt trong form.

Medium (trung bình) : có scrollbar, nhưng không có fixed field. Mỗi tab sẽ có một

thanh cuốn ngang để xem các trường và thanh cuốn dọc để xem tất cả các bản ghi.

Mỗi tab sẽ tương ứng với một multi-row block riêng biệt.

Difficult ( khó ) : có fixed field ( và có hoặc không có scrollbar ) : một multi-row

block có thể dàn trải trên nhiều tab page. Với fixed field, nên đặt các item vào

trong stacked-canvas nằm bên trên tab page.

Các bước triển khai tabbed region :

Bước 1 : Tạo tab canvas. Đặt tên cho tab canvas theo chuẩn

TAB_ENTITY_REGIONS (ví dụ với thực thể LINES, đặt tên cho tab

canvas là TAB_LINES_REGIONS). Thiết lập lớp thuộc tính là

TAB_CANVAS. Thiết lập thuộc tính Window cho tab canvas để đặt nó

vào đúng cửa sổ. Nếu đặt sai, bạn sẽ không sử dụng được “View ->

Stacked Views” trong Form Builder để hiển thị tab canvas trên content

canvas.

Bước 2 : Điều chỉnh tab canvas. Thiết lập thứ tự của tab canvas sau

content canvas và trước bất kì stacked canvas nào sẽ xuất hiện đằng trước

nó. Điều chỉnh viewport của tab canvas trong Layout Editor. Hiển thị

content canvas cùng lúc để dễ định vị tab canvas.

Page 71: Oracle Application Form

71

Bước 3 : Tạo các tab page. Với mức trung bình và mức khó, tên của các

tab page phải phù hợp với tên của các stacked canvas “alternative region”

tương ứng với chúng.

Bước 4 : Hiệu chỉnh các tab page. Thiết lập lớp thuộc tính là

TAB_PAGE. Đặt label cho mỗi tab page. Thiết lập thứ tự cho các tab

page trong Object Navigator.

Bước 5 : Riêng với mức khó, tạo fixed field stacked canvas. Đặt tên nó là

tab_canvas_FIXED. Thiết lập thứ tự cho nó sau tab canvas nhưng trước

bất kì stacked canvas “alternative region” nào mà bạn tạo cho mức khó.

Thiết lập lớp thuộc tính cho nó là

CANVAS_STACKED_FIXED_FIELD. Chỉnh để viewport của fixed

field canvas nằm trong viewport của tab canvas.

Bước 6 : Với mức trung bình và mức khó, tạo các stacked canvas

“alternative region”. Tất cả các canvas này phải có cùng vị trí và kích

thước viewport. Kiểm tra thuộc tính Visible của các stacked canvas

“alternative region”, chỉ để canvas nào xuất hiện đầu tiên có thuộc tính

này là Yes.

Với mức khó, các canvas “alternative region” này sẽ che khuất một phần

(chứ không phải là tất cả) của canvas fixed field. Cần đảm bảo là vị trí và

kích thước viewport của alternative region canvas liên hệ phù hợp với fixed

field canvas. )

Bước 7 : Đặt các item của bạn vào các tab page hay stacked canvas thích

hợp. Đặt các scrollbar của block (nếu có) ở gần cạnh phải canvas. Nếu

đang sử dụng stacked canvas, đảm bảo rằng stacked canvas không chồng

lên các trường được đặt trực tiếp vào trong tab page. Tương tự, các

stacked canvas “alternative region” cũng không được chồng lên các item

trong stacked canvas fixed field.

Bước 8 : Hiệu chỉnh layout của bạn. Đặt các tiêu đề tương ứng cho các

trường. Khi hiệu chỉnh, lưu ý căn chỉnh các đối tượng hợp lý để đảm bảo

tính thẩm mĩ, dễ nhìn.

Bước 9 : Lập trình cho tab handler. Oracle cung cấp 2 file mẫu giúp lập

trình cho handler dễ hơn :

. FNDTABS.txt cho mức dễ và mức trung bình

. FNDTABFF.txt cho trường hợp fixed field (mức khó)

Hai file này nằm trong thư mục Resource (trong thư mục FND). Copy text

từ file vào trong form rồi sửa lại code cho phù hợp với các đối tượng và các

Page 72: Oracle Application Form

72

hành động trong form. Tham khảo các comment có trong file để sửa code

được dễ hơn.

Bước 10 : Gọi các tab handler từ trigger. Tạo 1 trigger mức form

WHEN–TAB–PAGE–CHANGED, và gọi handler từ trigger này. Trigger

nên truyền sự kiện WHEN–TAB–PAGE–CHANGED tới handler, ví dụ :

MY_PACKAGE.TAB_MY_ENTITY_REGIONS(‟WHEN–

TAB–PAGE–CHANGED‟);

Tạo 1 trigger mức block (Execution Hierarchy Style: Before) WHEN–

NEW–ITEM–INSTANCE để gọi tới handler của bạn, ví dụ :

MY_PACKAGE.TAB_MY_ENTITY_REGIONS(‟WHEN–

NEW–ITEM–INSTANCE‟);

Page 73: Oracle Application Form

73

Cho phép hoạt động truy vấn

Query Find :

Có 2 hình thức triển khai cho Query Find. Một sẽ hiển thị một Row-LOV trong đó

có các hàng để bạn chọn một. Một sẽ mở ra cửa sổ tìm kiếm ( Find window ), trong

đó có các trường mà người sử dụng có thể muốn dùng để chọn dữ liệu. Chỉ sử

dụng 1 hình thức triển khai cho mỗi block cụ thể. Tất cả các block có thể truy vấn

trong form nên hỗ trợ Query Find.

Gọi Query Find khi mở form : nếu muốn một Row-LOV hoặc Find Window hiện

ngay lập tức khi mở form, gọi EXECUTE_TRIGGER( „QUERY_FIND‟ ); ở cuối

trigger WHEN-NEW-FORM-INSTANCE.

Triển khai Row-LOV

Để triển khai một Row-LOV, tạo 1 LOV để chọn ra khoá chính của hàng (mà

người sử dụng muốn) để đưa vào trong 1 tham số form, sau đó copy giá trị này vào

trong trường khoá chính của block chứa kết quả truy vấn ngay trước lúc thực hiện

truy vấn.

Xét 1 ví dụ với block DEPT dựa trên bảng DEPT với các cột DEPTNO, DNAME,

LOC. Các bước triển khai như sau :

Bước 1 : Tạo 1 tham số cho khoá chính.

Tạo 1 tham số form để lưu khoá chính chọn từ LOV. Nếu Row-LOV là dành

cho detail block, bạn không cần tạo tham số để lưu khoá ngoại, mà hãy thêm

vào mệnh đề WHERE của nhóm bản ghi ( sẽ được tạo ở bước sau ) tên cột kết

nối. Thiết lập kiểu dữ liệu và độ dài thích hợp cho tham số.

Ví dụ ta tạo tham số DEPTNO_QF tương ứng với block DEPT.

Bước 2 : Tạo 1 LOV

Tạo 1 LOV chứa các cột cần thiết để người dùng có thể xác định đuợc hàng

mình muốn chọn. Nếu Row-LOV là cho detail block, thêm cột kết nối ( khoá

ngoại ) vào mệnh đề WHERE của nhóm bản ghi ứng với LOV. Khoá chính (

chọn từ LOV ) sẽ được trả về cho tham số.

Ví dụ ta tạo 1 LOV là DEPT_QF chứa 2 cột là DEPTNO và DNAME. Đặt

Page 74: Oracle Application Form

74

đối tượng nhận giá trị trả về của DEPTNO là DEPTNO_QF.

Bước 3 : Tạo 1 trigger PRE-QUERY

Tạo 1 trigger PRE-QUERY ở mức block (Execution Hierarchy: Before) chứa

đoạn mã sau :

IF :parameter.G_query_find = ‟TRUE‟ THEN

<Primary Key> := :parameter.<Your parameter>;

:parameter.G_query_find := ‟FALSE‟;

END IF;

Với khoá chính gồm nhiều thành phần, bạn cần nhiều lệnh gán cho khoá

chính. Tham số G_query_find đã có sẵn trong form TEMPLATE.

Ví dụ ta tạo trigger PRE-QUERY chứa đoạn mã sau :

IF :parameter.G_query_find = ‟TRUE‟ THEN

:DEPT.DEPTNO := :parameter.DEPTNO_QF

:parameter.G_query_find := ‟FALSE‟;

END IF;

Bước 4 : Tạo 1 trigger QUERY_FIND

Cuối cùng, tạo 1 trigger ( loại trigger tự tạo ) mức block tên là

QUERY_FIND (Execution Hierarchy: Override) chứa mã :

APP_FIND.QUERY_FIND(‟<Your LOV Name>‟);

Ví dụ ta tạo trigger chứa : APP_FIND.QUERY_FIND(‟DEPT_QF‟);

Triển khai Find Window

Để triển khai 1 Find Window, tạo thêm 1 window chứa các trường mà người dùng

thường hay chọn khi bắt đầu thực hiện tìm kiếm và copy tất cả các giá trị của item

từ block đó vào trong block chứa kết quả truy vấn ngay trước khi thực hiện truy

vấn.

Trong ví dụ mà ta sẽ xem xét, có 1 block dựa trên bảng EMP, là block chứa kết quả

truy vấn. Khoá chính của bảng EMP là EMPNO. Block còn chứa một trường kiểu

date là HIREDATE. Find Window được thiết kế để xác định các bản ghi bằng

EMPNO hoặc HIREDATE.

Các bước triển khai :

Bước 1 : Copy nhóm đối tượng QUERY_FIND từ form APPSTAND

. Copy nhóm đối tượng QUERY_FIND từ form APPSTAND vào form của

bạn. Nó chứa 1 window, 1 block và 1 canvas mà từ đó xây dựng nên Find

Window của bạn.

Page 75: Oracle Application Form

75

. Sau khi copy, xoá nhóm đối tượng QUERY_FIND đi. Window, canvas và

block vẫn còn, và bạn lại có thể copy lại nhóm đối tượng nếu cần thêm Find

Window nữa.

Bước 2 : Đổi tên block, canvas và window

. Đổi tên block, canvas và window. Đặt thuộc tính queryable của block là No.

. Trong ví dụ, đổi tên block, canvas và window thành : EMP_QF,

EMP_QF_CANVAS, and EMP_QF_WINDOW.

Bước 3 : Viết code cho trigger của nút NEW

. Viết code cho trigger WHEN–BUTTON–PRESSED của nút NEW trong

block của Find Window để nó truyền đi tên của block Result như 1 tham số.

Thông tin này cho phép Oracle Applications chuyển con trỏ tới block Result

và đặt con trỏ tại vị trí bản ghi mới. Sở dĩ có nút NEW là bởi vì khi bạn mở 1

form, Find Window có thể tự động mở ra, và nếu bạn muốn thêm mới ngay 1

bản ghi thì chỉ việc chọn nút NEW.

. Trong ví dụ, sửa dòng code app_find.new(‟<Your results blockname

here>‟); trong trigger thành app_find.new(‟EMP‟);

Bước 4 : Viết code cho trigger của nút FIND

. Viết code cho trigger WHEN–BUTTON–PRESSED của nút FIND để nó

truyền đi tên của block Results. Thông tin này cho phép Oracle Applications

chuyển focus tới block Results và thực hiện truy vấn.

. Trong ví dụ, sửa dòng code app_find.find (‟ <Your results blockname here>

‟); thành app_find.find(‟EMP‟);

. Nếu bạn cần phải validate các item trong Find Window, đặt đoạn code của

bạn trước lời gọi APP_FIND.FIND. Bạn có thể đưa ra lời nhắc nếu người

dùng chưa nhập điều kiện lọc, hoặc điều kiện lọc đó có thể phải mất nhiều

thời gian để xử lý.

Bước 5 : Thiết lập thuộc tính Navigation Data Block

. Thiết lập thuộc tính Previous Navigation Data Block của block Find là block

Results. Điều này cho phép người dùng thoát khỏi Find Window mà không

cần thực hiện truy vấn.

. Từ block Result, next và previous data block của nó là các đối tượng khác,

chứ không bao giờ quay về Find Window.

Bước 6 : Viết code cho trigger KEY–NXTBLK

Viết code cho trigger KEY–NXTBLK của block Find để nó có tính năng

giống như nút FIND. Khi người dùng chọn “Go–>Next

Block”, hành động xảy ra giống như khi nhấn nút FIND.

Page 76: Oracle Application Form

76

Bước 7 : Đặt title cho Find Window

Đặt title cho Find Window. Trong ví dụ, đặt title là “Find Employees”.

Bước 8 : Tạo các item cần thiết

. Tạo các item mà người dùng truy vấn trong block Find Window. Đơn giản

nhất là copy các item từ block Result vào block Find Window.

. Các thao tác với những item trong Find Window :

> Đặt thuộc tính Required là No

> Đặt giá trị mặc định là NULL

> Nếu bạn copy các item từ block Results, đặt thuộc tính Database Item là

No, và loại bỏ các trigger kèm với chúng. Nếu cần giữ lại 1 trigger nào đấy,

cần sửa các tham chiếu của nó tới các trường trong block Find Window

> Thông thường item trong block Find Window có LOV gắn với nó để

người dùng luôn có thể chọn đúng giá trị hợp lệ cho item. Các trường date

có thể sử dụng Calendar và trigger KEY-LISTVAL có liên quan.

> Các item là check box hay option group trong block Results nên chuyển

thành poplist trong block Find Window. Khi chúng NULL, truy vấn không

chịu một giới hạn nào.

Bước 9 : Căn chỉnh Find Window trong form

Điều chỉnh Find Window của bạn : chỉnh lại kích thước, vị trí, các trường…

Bước 10 : Lập trình trigger PRE-QUERY

. Tạo trigger PRE-QUERY cho block Results (Execution Hierarchy :

Before) để copy điều kiện lọc truy vấn từ block Find Window sang block

Results (là nơi truy vấn thực sự xảy ra).

. Bạn có thể sử dụng built-in COPY của Oracle Forms để copy giá trị hoặc

có thể gán giá trị trực tiếp bằng “ := ”.

IF :parameter.G_query_find = ‟TRUE‟ THEN

COPY (<find Window field>,‟<results field>‟);

:parameter.G_query_find := ‟FALSE‟;

END IF;

. Một kiểu lọc thường dùng đó là truy vấn trong phạm vi các số (hoặc các

ngày, hoặc các kí tự) nào đó. Có thể sử dụng thủ tục

APP_FIND.QUERY_RANGE để thực hiện điều này. Tham số một và hai

là giá trị thấp và giá trị cao, tham số ba là tên của trường dữ liệu được truy

vấn thực sự.

. Trong ví dụ :

IF :parameter.G_query_find = ‟TRUE‟ THEN

Page 77: Oracle Application Form

77

COPY(:EMP_QF.EMPNO, ‟EMP.EMPNO‟);

APP_FIND.QUERY_RANGE(:EMP_QF.Hiredate_from,

:EMP_QF.Hiredate_to, ‟EMP.Hiredate‟);

:parameter.G_query_find := ‟FALSE‟;

END IF;

Bước 11 : Tạo trigger QUERY_FIND

. Tạo trigger QUERY_FIND (loại trigger tự tạo) cho block Results

(Execution Hierarchy: Override) chứa code :

APP_FIND.QUERY_FIND(‟<results block window>‟,

‟<Find window>‟, ‟<Find window block>‟);

. Trong ví dụ :

APP_FIND.QUERY_FIND(‟EMP_WINDOW‟, ‟EMP_QF_WINDOW‟,

‟EMP_QF‟);

Page 78: Oracle Application Form

78

Lập trình các hành động cho

item

Các chủ đề chính

Mối quan hệ các Item

Defaults

Kiểm tra tính toàn vẹn

Calendar

CALENDAR: Calendar Package

Mối quan hệ giữa các Item

Các Item phụ thuộc.

Các Item phụ thuộc vào điều kiện.

Các Item đa phụ thuộc.

Hai Master Items & Một Dependent Item

Phụ thuộc tầng.

Các Item loại trừ lẫn nhau.

Các Item bao gồm lẫn nhau.

Mutually Inclusive Items with Dependents

Các Item có tính điều kiện bắt buộc.

Các hành động chính đối với các Item như sau:

Disabled Items and WHEN–VALIDATE–ITEM Trigger

Trong hầu hết mối quan hệ giữa các Item bạn phải tự động enable hoặc

disable các Item.

WHEN–VALIDATE–ITEM luôn xảy ra tại thời điểm đầu tiên khi một

user di chuyển qua mỗi trường của một record mới, thậm chí không thay

đổi giá trị gì

Các item phụ thuộc

Để tạo một text item, check box, hoặc poplist mà chỉ enabled khi một

master item được tính toán, sử dụng procedure APP_FIELD.SET_

Page 79: Oracle Application Form

79

DEPENDENT_FIELD. Điều này cho phép :

- Các item phụ thuộc hoặc được clear hoặc là invalid khi master thay đổi.

- Nếu master item là NULL hoặc điều kiện là FALSE, thì item phụ thuộc

disabled.

Trong ví dụ dưới đây ta có hai item là item_type và item_name.

Item_name phụ thuộc vào item_type, do đó item_name chỉ enable khi

item_type là NOT NULL.

Bước 1 Tạo một thủ tục điều khiển procedures như dưới đây:

PACKAGE BODY ORDER IS

PROCEDURE ITEM_TYPE(EVENT VARCHAR2) IS

BEGIN

IF (EVENT = ‟WHEN–VALIDATE–ITEM‟) THEN

-- Any validation logic goes here.

ITEM_NAME(‟INIT‟);

ELSE

fnd_message.debug(‟Invalid event passed to

ORDER.ITEM_TYPE: ‟ || EVENT);

END IF;

END ITEM_TYPE;

PROCEDURE ITEM_NAME(EVENT VARCHAR2) IS

BEGIN

IF ((EVENT = ‟PRE–RECORD‟) OR

(EVENT = ‟INIT‟)) THEN

APP_FIELD.SET_DEPENDENT_FIELD(EVENT,

‟ORDER.ITEM_TYPE‟,

‟ORDER.ITEM_NAME‟);

ELSE

fnd_message.debug(‟Invalid event passed to

ORDER.ITEM_NAME: ‟ || EVENT);

END IF;

END ITEM_NAME;

END ORDER;

Bước 2: Gọi thủ tục điều khiển item trong :

Page 80: Oracle Application Form

80

Trigger: WHEN–VALIDATE–ITEM on item_type:

order.item_type(‟WHEN–VALIDATE–ITEM‟);

Trigger: PRE–RECORD on order (Fire in Enter–Query Mode: No):

order.item_name(‟PRE–RECORD‟);

Bước 3 :

Nếu master và dependent item đều trong một multi–row block, hoặc chúng

là các items trong một single–row block là detail của một master block, ta

phải gọi SET_DEPENDENT_FIELD cho sự kiện POST–QUERY thay vào đó.

PROCEDURE ITEM_NAME(EVENT VARCHAR2) IS

BEGIN

IF ((EVENT = ‟PRE–RECORD‟) OR

(EVENT = ‟INIT‟) OR

(EVENT = ‟POST–QUERY‟)) THEN

APP_FIELD.SET_DEPENDENT_FIELD(EVENT,

‟ORDER.ITEM_TYPE‟,

‟ORDER.ITEM_NAME‟);

ELSE

fnd_message.debug(‟Invalid event passed to

ORDER.ITEM_NAME: ‟ || EVENT);

END IF;

END ITEM_NAME;

Thêm một điều khiển trong:

ORDER.ITEM_NAME(’POST–QUERY’);

Chú ý : Trong một multi–record block, nếu item phụ thuộc là

Item cuối cùng của record, con trỏ chuột đến record tiếp theo

Khi di chuyển từ master. Để làm việc với điều khiển này

, thêm vào KEY–NEXT–ITEM trigger mà xảy ra một

VALIDATE(Item_scope) tiếp theo là NEXT_ITEM.

Chú ý: Nếu item phụ thuộc là một required list hoặc option

group, thiết lập ”invalidate” parameter trong lời gọi

APP_FIELD.SET_DEPENDENT_FIELD thành TRUE. Khi

flag là TRUE, item phụ thuộc được thiết lập như là invalid hơn

là cleared.

Page 81: Oracle Application Form

81

Item phụ thuộc có điều kiện

Trong ví dụ này , block orderc có hai là item_type và item_size.

Item_size is enabled chỉ khi item_type là ”SHOES.”

Bước 1:

Tạo một thủ tục điều khiển item dưới đây . Tương tự như trong trường hợp

simple master/dependent, nhưng phải thiết lập điều kiện thay vì tên của

master item.

PACKAGE BODY order IS

PROCEDURE ITEM_TYPE(EVENT VARCHAR2) IS

BEGIN

IF (EVENT = ‟WHEN–VALIDATE–ITEM‟) THEN

size(‟INIT‟);

ELSE

fnd_message.debug(‟Invalid event passed to

ORDER.ITEM_TYPE: ‟ || EVENT);

END IF;

END item_type;

END IF;

END size;

PROCEDURE size(EVENT VARCHAR2) IS

BEGIN

IF ((EVENT = ‟PRE–RECORD‟) OR

(EVENT = ‟INIT‟)) THEN

APP_FIELD.SET_DEPENDENT_FIELD(EVENT,

(:order.item_type = ‟SHOES‟),

‟ORDER.SIZE‟);

ELSE

fnd_message.debug(‟Invalid event passed to

ORDER.SIZE: ‟ || EVENT);

END order;

Page 82: Oracle Application Form

82

Bước 2 Gọi thủ tục điều khiển trong :

Trigger: PRE–RECORD on order (Fire in Enter–Query Mode: No):

order.item_size(‟PRE–RECORD‟);

Trigger: WHEN–VALIDATE–ITEM on item_type:

order.item_type(‟WHEN–VALIDATE–ITEM‟);

Các item đa phụ thuộc

Đây là trường hợp mà nhiều item phụ thuộc vào một master

item. Ví dụ, item_types chắc chắn có thể định rõ color và size.

Do đó, trường color và size là phụ thuộc vào the master field

item_type, và chỉ enabled khi item_type là ”RAINCOAT.”

Bước 1

Tạo các thủ tục xử lý item như sau :

PACKAGE BODY order IS

PROCEDURE item_type(EVENT VARCHAR2) IS

BEGIN

IF (EVENT = ‟WHEN–VALIDATE–ITEM‟) THEN

color(‟INIT‟);

size(‟INIT‟);

ELSE

fnd_message.debug(‟Invalid event passed to

ORDER.ITEM_TYPE: ‟ || EVENT);

END IF;

END item_type;

PROCEDURE color(EVENT VARCHAR2) IS

BEGIN

IF (EVENT = ‟PRE–RECORD‟) OR

(EVENT = ‟INIT‟) THEN

APP_FIELD.SET_DEPENDENT_FIELD(EVENT,

(:order.item_type = ‟RAINCOAT‟),

‟ORDER.COLOR‟);

Page 83: Oracle Application Form

83

ELSE

fnd_message.debug(‟Invalid event passed to

ORDER.COLOR: ‟ || EVENT);

END IF;

END color;

PROCEDURE size(EVENT VARCHAR2) IS

BEGIN

IF (EVENT = ‟PRE–RECORD‟) OR

(EVENT = ‟INIT‟) THEN

APP_FIELD.SET_DEPENDENT_FIELD(EVENT,

(:order.item_type = ‟RAINCOAT‟),

‟ORDER.SIZE‟);

ELSE

fnd_message.debug(‟Invalid event passed to

ORDER.SIZE: ‟ || EVENT);

END IF;

END size;

END order;

Bước 2 Gọi các thủ tục trong :

Trigger: WHEN–VALIDATE–ITEM on order.item_type:

order.item_type(‟WHEN–VALIDATE–ITEM‟);

Trigger: PRE–RECORD (Fire in Enter–Query Mode: No):

order.color(‟PRE–RECORD‟);

order.size(‟PRE–RECORD‟);

2 Master Item và 1 Dependent Item

Giả sử các size khác nhau của những chiếc mũ tương ứng với các color khác nhau.

Bạn không thể điền vào color của chiếc mũ đến khi nào bạn đã điền vào cả hai

item_type và size. Sự hợp lệ của block phụ thuộc được điều khiển bởi nội dung

của cả hai master_1 and master_2.

Bước 1 Tạo các thủ tục dưới đây :

PACKAGE BODY order IS

PROCEDURE item_type(EVENT VARCHAR2) IS

BEGIN

IF (EVENT = ‟WHEN–VALIDATE–ITEM‟) THEN

Page 84: Oracle Application Form

84

color(‟INIT‟):

ELSE

fnd_message.debug(‟Invalid event passed to

ORDER.ITEM_TYPE: ‟ || EVENT);

END IF;

END item_type;

PROCEDURE size(EVENT VARCHAR2) IS

BEGIN

IF (EVENT = ‟WHEN–VALIDATE–ITEM‟) THEN

color(‟INIT‟);

ELSE

fnd_message.debug(‟Invalid event passed to

ORDER.SIZE: ‟ || EVENT);

END IF;

END size;

PROCEDURE color(EVENT VARCHAR2) IS

BEGIN

IF (EVENT = ‟PRE–RECORD‟) OR

(EVENT = ‟INIT‟) THEN

APP_FIELD.SET_DEPENDENT_FIELD(EVENT,

((:order.item_type IS NOT NULL) AND

(:order.size IS NOT NULL)),

‟ORDER.COLOR‟);

ELSE

fnd_message.debug(‟Invalid event passed to

ORDER.COLOR: ‟ || EVENT);

END IF;

END color;

END order;

Bước 2 Gọi các thủ tục điều khiển trong :

Trigger: WHEN–VALIDATE–ITEM on order.item_type:

order.item_type(‟WHEN–VALIDATE–ITEM‟);

Trigger: WHEN–VALIDATE–ITEM on order.size:

order.size(‟WHEN–VALIDATE–ITEM‟);

Trigger: PRE–RECORD (Fire in Enter–Query Mode: No):

Page 85: Oracle Application Form

85

order.color(‟PRE–RECORD‟);

Kiểu phụ thuộc Cascading

Với kiểu phụ thuộc cascading, item_3 phụ thuộc vào item_2, item_2

phụ thuộc vào item_1. Thông thường tất cả các item trong cùng một block.

Ví dụ , block order bao gồm các items vendor, site, và contact.

Danh sách list tương ứng của sites phụ thuộc vào vendor hiện tại .

- Khi vendor được thay đổi, site bị cleared.

- Bất cứ khi nào vendor là null, site là disabled.

Danh sách list của các contacts phụ thuộc vào site hiện tại.

- Bất cứ khi nào site thay đổi, contact là cleared.

- Bất cứ khi nào site là null, contact là disabled.

Bước 1 Tạo thủ tục dưới đây :

PACKAGE BODY order IS

PROCEDURE vendor(EVENT VARCHAR2) IS

BEGIN

IF (EVENT = ‟WHEN–VALIDATE–ITEM‟) THEN

SITE(‟INIT‟);

ELSE

fnd_message.debug(‟Invalid event passed to

ORDER.VENDOR: ‟ || EVENT);

END IF;

END VENDOR;

PROCEDURE SITE(EVENT VARCHAR2) IS

BEGIN

IF (EVENT = ‟WHEN–VALIDATE–ITEM‟) THEN

CONTACT(‟INIT‟);

ELSIF (EVENT = ‟PRE–RECORD‟) OR

(EVENT = ‟INIT‟) THEN

APP_FIELD.SET_DEPENDENT_FIELD(EVENT,

‟ORDER.VENDOR‟,

‟ORDER.SITE‟);

CONTACT(EVENT);

ELSE

fnd_message.debug(‟Invalid event passed to

Page 86: Oracle Application Form

86

ORDER.SITE: ‟ || EVENT);

END IF;

END SITE;

PROCEDURE CONTACT(EVENT VARCHAR2) IS

BEGIN

IF (EVENT = ‟PRE–RECORD‟) OR

(EVENT = ‟INIT‟) THEN

APP_FIELD.SET_DEPENDENT_FIELD(EVENT,

‟ORDER.SITE‟,

‟ORDER.CONTACT‟);

ELSE

fnd_message.debug(‟Invalid event passed to

ORDER.CONTACT: ‟ || EVENT);

END IF;

END CONTACT;

END ORDER;

Bước 2 Gọi các thủ tục trong :

Trigger: WHEN–VALIDATE–ITEM on vendor:

order.vendor(‟WHEN–VALIDATE–ITEM‟);

Trigger: WHEN–VALIDATE–ITEM on site:

order.site(‟WHEN–VALIDATE–ITEM‟);

Trigger: PRE–RECORD on order (Fire in Enter–Query Mode: No):

order.site(‟PRE–RECORD‟);

order.contact(‟PRE–RECORD‟);

Trường VENDOR được validate như sau:

- VENDOR được validate, gọi SITE (‟INIT‟).

- SITE (‟INIT‟) làm trạng thái của SITE thay đổi và gọi CONTACT (‟INIT‟).

- CONTACT (‟INIT‟) làm trạng thái của CONTACT thay đổi.

Các item loại trừ lẫn nhau (Mutually Exclusive Items)

Sử dụng thủ tục APP_FIELD.SET_EXCLUSIVE_FIELD để viết mã 2

item khi mà chỉ 1 item là hợp lệ tại một thời điểm.

Page 87: Oracle Application Form

87

Nếu một item không được null, đặt thuộc tính REQUIRED của cả 2 item

là Yes trong Oracle Forms Developer. Nếu cả 2 item có thể là null, đặt

thuộc tính REQUIRED của cả 2 item là No. APP_FIELD.SET_

EXCLUSIVE_FIELD đọc thuộc tính REQUIRED bên trong và tự động

thay đổi thuộc tính REQUIRED của cả 2 item.

Bạn cũng có thể sử dụng APP_FIELD.SET_EXCLUSIVE_FIELD

với tập hợp của 3 mutually exclusive item. Nếu là nhiều hơn 3 item,

bạn phải tự viết mã logic cho chúng.

Chú ý : Các mutually exclusive check box và required list

đều yêu cầu được kích hoạt bằng chuột.

Ví dụ, một block lines có các mutually exclusive items là credit & debit.

Bước 1

PACKAGE BODY lines IS

PROCEDURE credit_debit(EVENT VARCHAR2) IS

BEGIN

IF ((EVENT = ‟WHEN–VALIDATE–ITEM‟) OR

(EVENT = ‟PRE–RECORD‟)) THEN

APP_FIELD.SET_EXCLUSIVE_FIELD(EVENT,

‟LINES.CREDIT‟,

‟LINES.DEBIT‟);

ELSIF (EVENT = ‟WHEN–CREATE–RECORD‟) THEN

SET_ITEM_PROPERTY(‟lines.credit‟, ITEM_IS_VALID,

PROPERTY_TRUE);

SET_ITEM_PROPERTY(‟lines.debit‟, ITEM_IS_VALID,

PROPERTY_TRUE);

ELSE

fnd_message.debug(‟Invalid event passed to

Lines.credit_debit: ‟ || EVENT);

END IF;

END credit_debit;

END lines;

Bước 2

Page 88: Oracle Application Form

88

Trigger: WHEN–VALIDATE–ITEM on credit:

lines.credit_debit(‟WHEN–VALIDATE–ITEM‟);

Trigger: WHEN–VALIDATE–ITEM on debit:

lines.credit_debit(‟WHEN–VALIDATE–ITEM‟);

Trigger: PRE–RECORD on lines (Fire in Enter–Query Mode: No):

lines.credit_debit(‟PRE–RECORD‟);

Trigger: WHEN–CREATE–RECORD on lines:

lines.credit_debit(‟WHEN–CREATE–RECORD‟);

Bạn chỉ cần trigger WHEN–CREATE–RECORD nếu kết quả của một trong

trường mutually–exclusive được yêu cầu. Trigger này vào lúc đầu thiết lập

tất cả các trường mutually–exclusive của tập hợp thành required. Tất cả

các trường được reset thích hợp mỗi lần một user nhập giá trị vào một trong các

trường đó.

Các item đồng hành với nhau (Mutually Inclusive Items)

Sử dụng APP_FIELD.SET_INCLUSIVE_FIELD để viết mã của tập hợp các

item trong trường hợp nếu bất cứ item nào là không null, thì tất cả các item là required.

Giá trị của các item được nhập vào theo bất cứ thứ tự nào. Nếu tất cả các item là

null, thì các item là tùy ý không bất buộc.

Bạn có thể dùng APP_FIELD.SET_INCLUSIVE_FIELD đối với không quá

5 mutually inclusive items. Nếu số item là lớn hơn 5 bạn phải tự viết mã logic.

Ví dụ dưới gồm 1 block payment_info với các mutually inclusive items là

payment_type và amount.

Bước 1:

PACKAGE BODY payment_info IS

PROCEDURE payment_type_amount(EVENT VARCHAR2) IS

BEGIN

IF ((EVENT = ‟WHEN–VALIDATE–ITEM‟) OR

(EVENT = ‟PRE–RECORD‟)) THEN

APP_FIELD.SET_INCLUSIVE_FIELD(EVENT,

‟PAYMENT_INFO.PAYMENT_TYPE‟,

‟PAYMENT_INFO.AMOUNT‟);

ELSE

Page 89: Oracle Application Form

89

fnd_message.debug(‟Invalid event to

payment_info.payment_type_ amount: ‟ || EVENT);

END IF;

END payment_type_amount;

END payment_info;

Bước 2:

Trigger: WHEN–VALIDATE–ITEM on payment_info.payment_type:

payment_info.payment_type_amount(‟WHEN–VALIDATE–ITEM‟);

Trigger: WHEN–VALIDATE–ITEM on payment_info.amount:

payment_info.payment_type_amount(‟WHEN–VALIDATE–ITEM‟);

Trigger: PRE–RECORD on payment_info (Fire in Enter–Query Mode:

No):

payment_info.payment_type_amount(‟PRE–RECORD‟);

Mutually Inclusive Item liên hệ với Dependent Item

Đây là trường hợp các items là phụ thuộc vào master items, trong khi

master items là mutually inclusive.

Ví dụ dưới với block payment_info với các mutually inclusive items là

payment_type and amount, như trong ví dụ trước, Block này bao gồm

2 regions, một cái cho check information và 1 cho credit

card information. Check Information has a single item, check_number.

Credit Card Information gồm 5 item: credit_type, card_holder, number,

expiration_date, and approval_code.

Payment Type có thể là Cash, Check, hoặc Credit

- Khi Payment Type là Check, thì Check Information region được enabled.

- When Payment Type là Credit, the Credit Card Information region được enabled.

Bước 1 :

PACKAGE BODY payment_info IS

PROCEDURE payment_type_amount(EVENT VARCHAR2) IS

BEGIN

IF (EVENT = ‟WHEN–VALIDATE–ITEM‟) THEN

APP_FIELD.SET_INCLUSIVE_FIELD(EVENT,

‟PAYMENT_INFO.PAYMENT_TYPE‟,

Page 90: Oracle Application Form

90

‟PAYMENT_INFO.AMOUNT‟);

IF (:SYSTEM.CURSOR_ITEM =

‟payment_info.payment_type‟) THEN

check_info(‟INIT‟);

credit_info(‟INIT‟);

END IF;

ELSIF (EVENT = ‟PRE–RECORD‟) THEN

APP_FIELD.SET_INCLUSIVE_FIELD(EVENT,

‟PAYMENT_INFO.PAYMENT_TYPE‟,

‟PAYMENT_INFO.AMOUNT‟);

ELSE

fnd_message.debug(‟Invalid event in

payment_info.payment_type_amount: ‟ || EVENT);

END IF;

END payment_type_amount;

PROCEDURE check_info IS

BEGIN

IF ((EVENT = ‟PRE–RECORD‟) OR

(EVENT = ‟INIT‟)) THEN

APP_FIELD.SET_DEPENDENT_FIELD(EVENT,

(:payment_info.payment_type = ‟Check‟),

‟PAYMENT_INFO.CHECK_NUMBER‟);

ELSE

fnd_message.debug(‟Invalid event in

payment_info.check_info: ‟ || EVENT);

END IF;

END check_info;

PROCEDURE credit_info IS

CONDITION BOOLEAN;

BEGIN

IF ((EVENT = ‟PRE–RECORD‟) OR

(EVENT = ‟INIT‟)) THEN

CONDITION := (:payment_info.payment_type = ‟Credit‟);

APP_FIELD.SET_DEPENDENT_FIELD(EVENT,

CONDITION,

‟PAYMENT_INFO.CREDIT_TYPE‟);

Page 91: Oracle Application Form

91

APP_FIELD.SET_DEPENDENT_FIELD(EVENT,

CONDITION,

‟PAYMENT_INFO.NUMBER‟);

APP_FIELD.SET_DEPENDENT_FIELD(EVENT,

CONDITION,

‟PAYMENT_INFO.CARD_HOLDER‟);

APP_FIELD.SET_DEPENDENT_FIELD(EVENT,

CONDITION,

‟PAYMENT_INFO.EXPIRATION_DATE‟);

APP_FIELD.SET_DEPENDENT_FIELD(EVENT,

CONDITION,

‟PAYMENT_INFO.APPROVAL_CODE‟);

ELSE

fnd_message.debug(‟Invalid event in

payment_info.credit_info: ‟ || EVENT);

END IF;

END credit_info;

END payment_info;

Bước 2

Trigger: WHEN–VALIDATE–ITEM on payment_info.payment_type:

payment_info.payment_type_amount(‟WHEN–VALIDATE–ITEM‟);

Trigger: WHEN–VALIDATE–ITEM on payment_info.amount:

payment_info.payment_type_amount(‟WHEN–VALIDATE–ITEM‟);

Trigger: PRE–RECORD on payment_info (Fire in Enter–Query Mode:

No):

payment_info.payment_type_amount(‟PRE–RECORD‟);

payment_info.check_info(‟PRE–RECORD‟);

payment_info.credit_info(‟PRE–RECORD‟);

Các item bắt buộc điều kiện (Conditionally Mandatory Items)

Sử dụng APP_FIELD.SET_REQUIRED_FIELD nếu 1 item yêu cầu cả 2 điều kiện và

Phụ thuộc, thì gọi APP_FIELD.SET_DEPENDENT_FIELD trước

APP_FIELD.SET_REQUIRED_FIELD.

Page 92: Oracle Application Form

92

Trong ví dụ sau một block purchase_order bao gồm 2 item total và vp_approval.

Vp_approval được yêu cầu khi total lớn hơn $10,000. (Chú ý :

quantity * unit_price = total.)

Bước 1: Viết thủ tục sau :

PACKAGE BODY purchase_order IS

PROCEDURE vp_approval(EVENT VARCHAR2) IS

BEGIN

IF ((EVENT = ‟PRE–RECORD‟) OR

(EVENT = ‟INIT‟)) THEN

APP_FIELD.SET_REQUIRED_FIELD(EVENT,

(:purchase_order.total > 10000),

‟PURCHASE_ORDER.VP_APPROVAL‟);

ELSE

fnd_message.debug(‟Invalid event in

purchase_order.vp_approval: ‟ || EVENT);

END IF;

END vp_approval;

PROCEDURE total(EVENT VARCHAR2) IS

BEGIN

IF (EVENT = ‟INIT‟) THEN

:purchase_order.total := :purchase_order.quantity *

:purchase_order.unit_price;

vp_approval(‟INIT‟);

ELSE

fnd_message.debug(‟Invalid event in purchase_order.total:

‟ || EVENT);

END total;

PROCEDURE quantity(EVENT VARCHAR2) IS

BEGIN

IF (EVENT = ‟WHEN–VALIDATE–ITEM‟) THEN

total(‟INIT‟);

ELSE

fnd_message.debug(‟Invalid event in

purchase_order.quantity: ‟ || EVENT);

END IF;

Page 93: Oracle Application Form

93

END quantity;

PROCEDURE unit_price(EVENT VARCHAR2) IS

BEGIN

IF (EVENT = ‟WHEN–VALIDATE–ITEM‟) THEN

total(‟INIT‟);

ELSE

fnd_message.debug(‟Invalid event in

purchase_order.unit_price: ‟ || EVENT);

END IF;

END unit_price;

END purchase_order;

Bước 2: Gọi các thủ tục sau trong :

Trigger: PRE–RECORD on purchase_order (Fire in Enter–Query

Mode: No):

purchase_order.vp_approval(‟PRE–RECORD‟);

Trigger: WHEN–VALIDATE–ITEM on quantity:

purchase_order.quantity(‟WHEN–VALIDATE–ITEM‟);

Trigger: WHEN–VALIDATE–ITEM on unit_price:

purchase_order.unit_price(‟WHEN–VALIDATE–ITEM‟);

Các mặc định (Defaults)

Các mặc định trên 1 bản ghi mới

Để thiết lập giá trị mặc định khi user tạo một bản ghi, sử dụng

thuộc tính Default values trong the Oracle Forms Designer. Với những

Default phức tạp hơn có thể tham khảo tại đây:

Bước 1: Khai báo Package

PACKAGE block IS

PROCEDURE WHEN_CREATE_RECORD IS

BEGIN

:block.item1 := default_value1;

:block.item2 := default_value2;

...

END WHEN_CREATE_RECORD;

Page 94: Oracle Application Form

94

END block;

Bước 2: Gọi trong trigger sau :

Trigger: WHEN–CREATE–RECORD:

block.WHEN_CREATE_RECORD;

Áp dụng các Default khi đang truy cập vào bản ghi

Khi muốn thiết lập giá trị mặc định cho một item mà phụ thuộc và một item

khác thì thiết lập giá trị mặc định trong item phụ thuộc sử dụng sự kiện INIT.

Kiểm tra tính toàn vẹn (Integrity Checking)

Kiểm tra tính duy nhất (Uniqueness Checks)

Kiểm tra toàn vẹn tham chiếu (Referential Integrity Checks)

Kiểm tra tính duy nhất

Trường hợp này có thể thấy khi duplicate một hàng của block dữ liệu.

Ta dùng WHEN–VALIDATE–ITEM cho trường đó.

PROCEDURE CHECK_UNIQUE(X_ROWID VARCHAR2,

pkey1 type1, pkey2 type2, ...) IS

DUMMY NUMBER;

BEGIN

SELECT COUNT(1)

INTO DUMMY

FROM table

WHERE pkeycol1 = pkey1

AND pkeycol2 = pkey2

...

AND ((X_ROWID IS NULL) OR (ROWID != X_ROWID));

IF (DUMMY >= 1) then

FND_MESSAGE.SET_NAME(‟prod‟, ‟message_name‟);

APP_EXCEPTION.RAISE_EXCEPTION;

END IF;

END CHECK_UNIQUE;

Tạo thủ tục xử lý item như sau :

Page 95: Oracle Application Form

95

PACKAGE BODY block IS

PROCEDURE item(EVENT VARCHAR2) IS

BEGIN

IF (EVENT = ‟WHEN–VALIDATE–ITEM‟) THEN

table_PKG.CHECK_UNIQUE(:block.row_id,

:block.pkey1, :block.pkey2, ...);

ELSE

message(‟Invalid event in block.item‟);

END IF

END item;

END block;

Kiểm tra toàn vẹn tham chiếu

Khi xóa một record, ta phải chú ý đến các record mà có thể tham chiếu

đến record đó . Các giải pháp được đưa ra là:

- Không cho phép xóa item đó.

- Xóa đồng thời item mà nó tham chiếu đến.

- Cho phép xóa item , và đặt item tham chiếu đến nó là null..

Thông thường ta sẽ xử ly theo cách đầu.

Đưa ra cảnh báo trước khi xoá các bản ghi detail

Để cảnh báo khi xóa một detail record, tạo

CHECK_REFERENCES là 1 hàm trả lại giá trị FALSE nếu các bản ghi detail

tồn tại (CHECK_REFERENCES cần phải raise 1 exception nếu

khi xóa một hàng mà có liên quan đến lỗi tham chiếu).

Ví dụ :

Bước 1 :

CREATE OR REPLACE PACKAGE BODY table_PKG AS

PROCEDURE CHECK_REFERENCES(pkey1 type1, pkey2 type2, ...)

IS

MESSAGE_NAME VARCHAR2(80);

DUMMY credit;

BEGIN

MESSAGE_NAME := ‟message_name1‟;

SELECT 1 INTO DUMMY FROM DUAL WHERE NOT EXISTS

(SELECT 1 FROM referencing_table1

Page 96: Oracle Application Form

96

WHERE ref_key1 = pkey1

AND ref_key2 = pkey2

...

);

MESSAGE_NAME := ‟message_name2‟;

SELECT 1 INTO DUMMY FROM DUAL WHERE NOT EXISTS

(SELECT 1 FROM referencing_table2

WHERE ref_key1 = pkey1

AND ref_key2 = pkey2

...

);

EXCEPTION

WHEN NO_DATA_FOUND THEN

FND_MESSAGE.SET_NAME(‟prod‟, MESSAGE_NAME);

APP_EXCEPTION.RAISE_EXCEPTION;

END CHECK_REFERENCES;

END table_PKG;

Bước 2 :

PACKAGE BODY block IS

PROCEDURE key_delete IS

BEGIN

––

–– First make sure its possible to delete this record.

–– An exception will be raised if its not.

––

table_PKG.CHECK_REFRENCES(pkey1, pkey2, ...);

––

–– Since it is possible to delete the row, ask the

–– user if they really want to,

–– and delete it if they respond with ‟OK‟.

––

app_record.delete_row;

END key_delete;

END block;

Bước 3 :

Page 97: Oracle Application Form

97

Trigger: KEY–DELETE:

block.dey_delete;

Gợi ý : Bạn cần phải làm các bước tương tự với trigger

ON–DELETE. Có thể xảy ra tình huống là trong khoảng thời gian

1 user yêu cầu delete, thậm chí đã saved giao dịch, một

record được đưa vào ở đâu đó sẽ gây ra lỗi tham chiếu .

Cần phải nhớ rằng KEY–DELETE thực hiện tại thời điểm

đầu tiên khi một user thực hiện delete, nhưng không thực sự

thực hiện hành động delete; nó chỉ đánh dấu record nào sé xóa và

clear nó trên màn hình . Trigger ON–DELETE thực hiện tại thời

điểm commit và mới thực sự thực hiện xóa .

Đối tượng Calendar

Calender là một đối tượng cho phép lựa chọn ngày tháng một cách trực quan

Đối tượng này có sẵn ở trong form template.

Để có thể sử dụng đối tượng này ta phải khai báo một số thủ tục trong các

trigger tương ứng

LOV cho các trường Date và Datetime

Trường date và datetime phải đặt thuộc tính List lamp. Khi user mở

list của trường đó form sẽ mở Calendar window.

Trường date phải sử dụng ENABLE_LIST_LAMP LOV, trong

TEMPLATE form. Đặt ‟Validate fromList” to No cho trường

mà sử dụng LOV. Nếu để ”Validate from

List” là Yes, bạn sẽ thấy LOV sẽ không có cột nào.

Các lời gọi cần phải có

Mỗi trường date trong form phải sử dụng lời gọi sau :

Trigger: KEY–LISTVAL:

calendar.show([first_date]);

hoặc

calendar.show;

Page 98: Oracle Application Form

98

Các lựa chọn cấp cao của Calendar

Một số thuộc tính của Calendar có thể thực hiện thêm như sau :

Không hiển thị các ngày cuối tuần trong cửa sổ Calendar

Để không hiện ngày cuối tuần (Chú ý ở đây là Thứ 7 và CN), gọi

calendar.setup(‟WEEKEND‟);

Không hiển thị một chuỗi các ngày nào đó

calendar.setup(<30 char identifying name>, <low_date>,

<high_date>);

Không hiển thị một chuỗi các ngày nào đó lấy từ 1 bảng

calendar.setup(<30 char identifying name>, null, null,

<SQL>);

Gọi đối tượng Calendar từ các trường non–DATE

Có thể gọi Calendar trên các trường không phải là kiểu date-time như kiểu char

,text.Cách gọi vẫn như bình thường. Khi lựa chọn giá trị ngày tháng sẽ trả về

trường dưới format dạng ”DD–MON–YYYY.”

Tạo một trigger ở mức item và thêm các lệnh để xử lý giá trị đó.

Một số ví dụ về Calendar

Ví dụ : Chỉ hiển thị những ngày làm việc trong tuần ( thứ 2 -> thứ 6 )

Trigger: KEY–LISTVAL:

calendar.setup(‟WEEKEND‟);

calendar.show;

Ví dụ : Chỉ hiển thị những ngày làm việc trong năm ( không tính thứ 7, chủ

nhật, các ngày lễ )

Giả sử có trường SHIP_BY_DATE trong một form, bạn muốn dùng

Calendar và đặt tùy chọn cho nó :

- Không hiển thị tất cả holiday được xác định trong bảng ORG_HOLIDAYS

- Không hiển thị 2 ngày nghỉ cuối tuần

- Hiện tháng tương ứng với ngày trong trường “LINES.NEED_BY_DATE” khi mở Calendar

Trigger: KEY–LISTVAL:

calendar.setup(‟WEEKEND‟);

calendar.setup(‟Manufacturing Holidays‟, null, null,

‟select action_date LOW_DATE,

action_date HIGH_DATE ‟||

‟from org_holidays where

Page 99: Oracle Application Form

99

date_type = ‟‟HOLIDAY‟‟‟);

calendar.show(:lines.need_by_date);

Ví dụ : Hiển thị một chuỗi các ngày

Trong trường NEED_BY_DATE, bạn muốn Calendar hiện ra tháng

tương ứng với ngày trong trong trường LINES.CREATED_DATE + 30 days

Bạn đồng thời cũng disable tất cả các ngày

trước đó kể cả: LINES.CREATED_DATE.

Trigger: KEY–LISTVAL:

calendar.setup(‟After created date‟, null,

lines.created_date);

calendar.show(:lines.need_by_date + 30);

Ví dụ : Chỉ hiển thị Calendar để xem

Trên form có một nút HOLIDAYS chỉ ra tất cả các ngày nghỉ cho phép.

Tháng hiện tại được cho trước đó, và calendar tìm

những ngày này trong ORG_DATES table.

Trigger: WHEN–BUTTON–PRESSED on HOLIDAYS:

calendar.setup(‟TITLE‟, null, null,

‟<translated text for ”Manufacturing Holidays”>‟);

calendar.setup(‟Manufacturing Holidays‟, null, null,

‟select action_date LOW_DATE, action_date HIGH_DATE ‟||

‟from org_dates where date_type = ‟‟HOLIDAY‟‟‟);

calendar.show;

Page 100: Oracle Application Form

100

Điều khiển Toolbar và Default

Menu

Trong chương này sẽ đề cập đến cách custom menu, toolbar, pupup menu trên form.

Các thuộc tính này đều có ở form Template.

Các mục chính :

Menu kéo xuống (Pulldown Menu) và Toolbar

Các menu đặc biệt

Customize loại menu xuất hiện khi click chuột phải (Popup Menu, hay Right–

Mouse Menu )

APP_POPUP: Điều khiển Right–Mouse Menu

APP_SPECIAL: Điều khiển Menu và Toolbar

Pulldown Menu và Toolbar

Menu bar

Tool bar

Page 101: Oracle Application Form

101

Các lựa chọn có trên thanh công cụ ( toolbar ) :

Các lựa chọn và các trigger tương ứng với nó ( theo thứ tự xuất hiện trên toolbar ) :

New (Thêm mới bản ghi) (WHEN–NEW–BLOCK–INSTANCE)

Có hiệu lực nếu block cho phép insert.

Find... (WHEN–NEW–RECORD–INSTANCE)

Có hiệu lực khi block cho phép truy vấn và chưa ở trong chế độ enter–query.

Show Navigator (WHEN–NEW–RECORD–INSTANCE)

Save

Luôn có hiệu lực.

Next Step

Print...

Luôn có hiệu lực.

Close Form

Cut/Copy/Paste

Các đối tượng menu và toolbar sau được xử lý bởi Oracle Forms

Clear Record

Luôn có hiệu lực.

Delete Record (tương ứng với Edit / Delete trên menu)

(WHEN–NEW–RECORD–INSTANCE)

Có hiệu lực khi block cho phép xoá.

Edit Field... (WHEN–NEW–ITEM–INSTANCE)

Có hiệu lực khi item hiện tại là text item.

Zoom (WHEN–NEW–BLOCK–INSTANCE)

Có hiệu lực nếu khách hàng định nghĩa 1 zoom cho block hiện tại

Translations

Mặc định là không có hiệu lực. Người phát triển có thể enable/disable nó theo yêu

cầu bằng cách sử dụng APP_SPECIAL.ENABLE.

Attachments (WHEN–NEW–RECORD–INSTANCE và

WHEN–NEW–BLOCK–INSTANCE)

Folder Tools

Page 102: Oracle Application Form

102

Có hiệu lực nếu con trỏ ở trong 1 folder block; người phát triển phải viết code

trong combination folder block.

• Window Help

Luôn có hiệu lực.

Các mục chỉ có trong Menu

• Clear Form

Luôn có hiệu lực.

• Summary/Detail

Mặc định là không có hiệu lực. Người phát triển có thể enable/disable theo

yêu cầu bằng cách sử dụng APP_SPECIAL.ENABLE.

• Save and Proceed

Luôn có hiệu lực.

• File / Exit Oracle Applications

(WHEN–NEW–RECORD–INSTANCE)

Có hiệu lực nếu không ở trong chế độ enter–query.

• Edit / Duplicate / Field Above (WHEN–NEW–ITEM–INSTANCE)

Có hiệu lực nếu bản ghi hiện tại không phải là bản ghi đầu tiên

• Edit / Duplicate / Record Above

(WHEN–NEW–RECORD–INSTANCE)

hiệu lực nếu bản ghi hiện tại không phải là bản ghi đầu tiên và trạng thái bản

ghi là ‟NEW‟. Người phát triển phải customize hành động Duplicate

Record trong trigger KEY–DUPREC mức form hoặc mức block.

• Edit, Clear, Field (WHEN–NEW–ITEM–INSTANCE)

Có hiệu lực khi item hiện tại là text item.

• Edit, Clear, Block (WHEN–NEW–ITEM–INSTANCE)

Luôn có hiệu lực

• Edit, Clear, Form (WHEN–NEW–ITEM–INSTANCE)

Luôn có hiệu lực

• Edit, Select All

• Edit, Deselect All

• Edit, Preferences, Change Password

• View, Find All (WHEN–NEW–RECORD–INSTANCE)

Có hiệu lực nếu block cho phép truy vấn và chưa ở trong chế độ enter–

query.

Page 103: Oracle Application Form

103

• View, Query by Example, Enter

(WHEN–NEW–BLOCK–INSTANCE)

Có hiệu lực nếu block cho phép truy vấn.

• View, Query by Example, Run

(WHEN–NEW–BLOCK–INSTANCE)

Có hiệu lực nếu block cho phép truy vấn.

• View, Query by Example, Cancel

(WHEN–NEW–RECORD–INSTANCE)

Có hiệu lực nếu ở trong chế độ enter-query

• View, Query by Example, Show Last Criteria

(WHEN–NEW–RECORD–INSTANCE)

Có hiệu lực nếu ở trong chế độ enter-query

• View, Query by Example, Count Matching Records

(WHEN–NEW–RECORD–INSTANCE)

Có hiệu lực nếu block cho phép truy vấn.

• View, Record, First

Có hiệu lực nếu bản ghi hiện tại không phải là bản ghi đầu tiên

• View, Record, Last

Có hiệu lực nếu bản ghi hiện tại không phải là bản ghi đầu tiên

• View, Requests

• Window, Cascade

• Window, Tile Horizontally

• Window, Tile Vertically

• Help, Oracle Applications Library

• Help, Keyboard Help

• Help, Diagnostics

Điều khiển menu động

Để có thể tự điều khiển các menu trong các trường hợp đặc biệt

Sử dụng thủ tục sau app_special.enable.

Thủ tục này được thêm vào trong các trigger PRE–BLOCK hoặc

WHEN–NEW–BLOCK–INSTANCE, WHEN–NEW–RECORD– INSTANCE

WHEN–NEW–ITEM–INSTANCE

Page 104: Oracle Application Form

104

app_standard.event(‟TRIGGER_NAME‟);

app_special.enable(‟Menu_item‟, PROPERTY_OFF|ON);

Ví dụ : app_special.enable(‟CLEAR.FIELD‟, PROPERTY_OFF);

Ví dụ :

Giả sử bạn có một chức năng là ‟Book Order‟mà bạn muốn thêm vào

Menu và toolbar.

Để thêm ‟Book Order‟là mục đầu tiên tương ứng với 1 icon trên toolbar

Mà chỉ có hiệu lực với block Header trên form :

Bước 1

Sửa trong trigger PRE–FORM mức form:

PRE–FORM

app_special.instantiate(‟SPECIAL1‟, ‟&Book Order‟, ‟bkord‟);

Bước 2

Thêm 1 trigger PRE–BLOCK mức form:

PRE–BLOCK

app_special.enable(‟SPECIAL1‟,PROPERTY_OFF);

Bước 3

Thêm 1 trigger PRE–BLOCK mức block trong block nào bạn muốn

enable các mục menu mới của bạn :

PRE–BLOCK trong HEADER block

app_special.enable(‟SPECIAL1‟,PROPERTY_ON);

Bước 4

Thêm 1 trigger SPECIAL (loại tự định nghĩa) mức block chứa code thực

hiện chức năng ‟Book Order ‟ của bạn. Nó sẽ được thực thi khi người dùng

chọn mục menu chức năng này.

Các item sẽ được reset lại trong các block khác bởi default menu

Mà ta không phải tự reset mỗi khi rời một block, record, item

Tạo các biểu tượng trên toolbar cho các form bạn customize

Ta cũng có thể tạo icon riêng cho menu bằng các file .gif đặt tại thư mục

Được tạo bởi virtual directory OA_MEDIA

Page 105: Oracle Application Form

105

Các menu đặc biệt

Disable các menu đặc biệt

Để disable tất cả các mục đặc biệt trên menu( như trong trường hợp query–mode)

Sử dụng APP_SPECIAL.ENABLE(‟SPECIAL‟,PROPERTY_OFF);

Customize các Right–Mouse Menu (Popup Menus)

Thêm các mục vào Right–Mouse Menu

Dạng default của menu popup là như sau :

Ta hoàn toàn có thể thay đổi dạng mặc định của menu popup bằng cách thêm

Cut

Copy

Paste

––––––

Folder

––––––

Help

Page 106: Oracle Application Form

106

Vào các entry mới gồm cả các đường ngăn cách như sau :

Sử dụng thủ tục sau :

procedure APP_POPUP.INSTANTIATE(

option_name varchar2, ---

„POPUP1‟=>‟POPUP10‟

txt varchar2, --- tên nhãn

initially_enabled boolean default true, ----

„TRUE‟/‟FALSE‟

separator varchar2 default null); -------

„LINE‟)

Các entry sẽ được thêm vào sau FOLDER và trước HELP.

Ví dụ :

Bước 1

Cut

Copy

Paste

––––––––––––

Folder

––––––––––––

First Entry

Second Entry

––––––––––––

Third Entry

––––––––––––

Help

Page 107: Oracle Application Form

107

Sửa trigger PRE–POPUP–MENU mức item trên trường Requisition

Number (Execution Hierarchy : After).

app_popup.instantiate(‟POPUP1‟, ‟Approve‟);

Bước 2

Thêm 1 trigger POPUP1 mức item (loại tự tạo) chứa code thực hiện chức

năng của bạn.

Nó thực thi khi user chọn mục menu tương ứng.

Ví dụ

APP_POPUP.INSTANTIATE(‟POPUP1‟,‟First Entry‟);

APP_POPUP.INSTANTIATE(‟POPUP2‟,‟Second Entry‟, TRUE,

‟LINE‟);

APP_POPUP.INSTANTIATE(‟POPUP3‟,‟Third Entry‟, FALSE);

Kết quả sẽ là như sau :

––––––––––––

Cut

Copy

Paste

––––––––––––

Folder

––––––––––––

First Entry

––––––––––––

Second Entry

Third Entry (disabled, so greyed

out)

––––––––––––

Help

––––––––––––

Page 108: Oracle Application Form

108

Message Dictionary

Tổng quan về Message Dictionary

Thiết lập về Message Dictionary

Message Dictionary API đối với PL/SQL Procedures

Message Window.

Tổng quan về Message Dictionary

Cho phép phân loại các message sẽ được đưa ra của form hay của ứng dụng

Với Message Dictionary bạn có thể làm :

- Xác định các message tiêu chuẩn mà form hay ứng dụng sử dụng đến.

- Cung cấp một cách nhìn và cảm nhận thống nhất đối với các message

trong và giữa các ứng dụng.

- Xác định các messge động có thể bao gồm context–sensitive variable

text

- Giúp dế dàng thay đổi và mà không phải biên dịch lại nội dung message

trong ứng dụng.

Các điểm đặc trưng của Message Dictionary

Có thể sửa đổi nội dung của message:

- Dễ dang thay đổi thay đổi nội dung message trên một form duy nhất.

- Các message có thể hiển thị dưới dạng dialog box hoặc dòng.

Dễ dàng biên dịch

Chuẩn hóa message

- Mỗi lần xác định một message trong Message Dictionary bạn có thể quy

cho một form, concurrent

Program hoặc module trong ứng dụng khác sử dụng tên message mà bạn đã

xác định. Bạn có thể gọi

Message bao nhiêu lần tùy ý và từ bất cứ nơi nào trong ứng dụng. Nếu bạn

cần thay đổi nội dung message

Bạn chỉ cần thay đổi ngay tại chỗ.

Message text động

Page 109: Oracle Application Form

109

- Message có thể chấp nhận biến text động như trường hoặc tên module

Các bước cần tiến hành khi xác định Message Dictionary

Tên Message.

Message(<1800 ký tự)

Số Message : Số sẽ xuất hiện cùng với message. Nếu bạn xác định một

message number khác không

Cho message , Dictionary ẽ thêm vào message tiền tố APP-

Mã thông báo biến : Một từ khóa bạn tạo ra để miêu tả một giá trị khi

bạn xác định một message.

Bạn chỉ rõ cùng một mã thông báo biến và giá trị của nó, khi gọi

Message Dictionary từ một form

hay một module chương trình.

Message Dictionary sẽ thay thế mỗi mã thông báo biến trong message

với giá trị hiện tại bạn đã

Chỉ rõ sau đó là hiện ra thông báo.

Thiết lập Message Dictionary

1.Tạo các thư mục message

2.Xác định message.

3. Tạo các file message

Bước1 : Vào Application Developer responsibility vào cửa sổ Submit Requests

Bước2: Chọn Generate Messages trong trường Name.

Bước3: Trong cửa sổ Parameters, chọn ngôn ngữ cho file cần tạo.

Bước4: Chọn tên ứng dụng tương ứng với file cần tạo. Mỗi ứng dụng đều phải có file

message riêng của nó.

Bước5: Chọn kiểu cho chương trình. Để tạo file message lúc runtime chọn

DB_TO_RUNTIME.

Bước6: Để trống Filename Parameter, message generator sẽ tạo một file với tên mặc

định tiêu chuẩn trong thư mục mesg đối với ứng dụng trên phía server.

Bước7: Copy file vừa tạo đến thư mục mesg hợp của ứng dụng trên mỗi máy cần

thiết(concurrent processing servers, forms server machines). Tên file phải giữ nguyên

tại mọi nơi.

4.Viết mã cài đặt các message.

Page 110: Oracle Application Form

110

Từ tạo một message và đưa tới người sử dụng gồm hai quá trình : đầu tiên phải cài đặt

message( phía client) hoặc gọi nó từ phía server, sau đó trình bày tới người dùng (hoặc viết ra

file đối với một concurrent program).

Các hàm API phía client cho việc gọi và cài đặt các message:

Các hàm này nằm trong package FND_MESSAGE.

SET_NAME Gọi message từ Message Dictionary và đặt nó trong message stack

SET_STRING Lấy một input string và đặt nó trong message stack..

SET_TOKEN Thay thế một message token bằng giá trị bạn đã tạo.

RETRIEVE Gọi một message từ buffer message phía server dịch và thay thế các

token và đặt nó vào message stack.

GET(hàm) Gọi một message từ stack message và trả về giá trị VARCHAR2.

CLEAR Clear message stack.

Các hàm API phía server:

Chỉ có một message được đặt trong bộ đệm phía server.

SET_NAME Đặt một tên message trong khu vực global.

SET_TOKEN Thêm một cặp token/value vào khu vực global.

CLEAR Clear message stack.

5. Viết mã display message.

Mỗi lần bạn cài đặt hoặc gọi message và thay thế bất cứ token nào, tiếp theo display tới

người dùng (trên form) hoặc viết ra file (database phía server đối với một concurrent

program).

Các hàm API để trình bày các message ở Form Server.

Các hàm sau dùng trong các PL\SQL thủ tục trong form và trong các thư viện để trình bày

các message : FND_MESSAGE.SET_NAME, FND_MESSAGE.RETRIEVE. Nếu cần thêm

các icon để trình bày dùng các hàm sau : FND_MESSAGE.ERROR,

FND_MESSAGE.SHOW, FND_MESSAGE.WARN, FND_MESSAGE.QUESTION

Phương pháp đối với Database Server–side Messaging.

Có 3 phương pháp khác nhau không thể thay đổi để trình bày các message được thiết lập phía

server:

Phương pháp1 : Đặt một message error phía server, sẽ được trình bày phía client form mà

gọi thủ tục phía server.

Page 111: Oracle Application Form

111

Trên phía server, sử dụng FND_MESSAGE.SET_NAME và

FND_MESSAGE.SET_TOKEN để thiết lập message. Sau đó gọi

APP_EXCEPTION.RAISE_EXCEPTION. Các lỗi này được trả về trigger ON–ERROR phía

client.

Phương pháp 2 : Đặt một message phía server, được trả về phía client

Trên phía server sử dụng FND_MESSAGE.SET_NAME,

FND_MESSAGE.SET_TOKEN. Phía client sử dụng FND_MESSAGE.RETRIEVE để lấy

message từ phía server, đặt message lên message stack của client. Tiếp đó client gọi

FND_MESSAGE.ERROR, FND_MESSAGE.SHOW, FND_MESSAGE.HINT,

FND_MESSAGE.WARN để trình bày message hoặc FND_MESSAGE.GET để đặt message

vào một buffer.

Phương pháp 3 :Lấy một message vào một buffer trên server.

Sử dụng FND_MESSAGE.SET_NAME, FND_MESSAGE.SET_TOKEN,

FND_MESSAGE.GET để lấy một message vào một buffer hoặc

FND_MESSAGE.GET_STRING để lấy một message đơn vào một sâu.

Page 112: Oracle Application Form

112

Application User

System Administrator

Site

Responsibility

Application

User

USER PROFILE

User profile là tập hợp các tùy chọn có thể thay đổi làm ảnh hưởng đến cách thực hiện

chương trình. Oracle Application Object Library đưa ra một giá trị cho mỗi tùy chọn trong một

profile người dùng khi người dùng log on hoặc khi thay đổi Responsibility.

Người dùng có thể thay đổi giá trị của tùy chọn profile bất cứ khi nào.

Với tư cách là một nhà phát triển bạn thậm chí có thể xác định thêm các tùy chọn. Bởi vì có

thể bạn không muốn người dùng có khả năng ghi đè giá trị lên giá trị bạn đã xác định, do đó bạn có

thể xác định tùy chọn tại một trong các mức sau : Site, Application, Responsibility và User.

Các mức của User Profile:

User có mức thứ thự cao nhất.

Giá trị tùy chọn ở mức cao hơn thì ghi đè lên mức dưới nó.

Mỗi tùy chọn user profile thông thường có ở tất cả các mức. Ví dụ Oracle Application Object Library

cung cấp tùy chọn mức site cũng như mức Application là Printer. Do đó nếu mức Site Printer có giá

trị là “New York” nhưng mức User có giá trị là “Boston” thì báo cáo sẽ được in ở Boston printer.

Page 113: Oracle Application Form

113

Định nghĩa mới các tùy chọn của user profile

Sử dụng Profile Window

Thiết lập giá trị tùy chọn user profile

Sử dụng System Administrator responsibility.

Thiết lập user profile riêng của bạn

Sử dụng form Update Personal Profile Options

Xác định trước tùy chọn user profile

Database Profile Options

Oracle Application Object Library cung cấp nhiều tùy chọn user profile mà Oracle

System Administrator hoặc người dùng có thể nhìn thấy cũng như cập nhật.

Các tùy chọn profile nội tại

Bạn có thể thay đổi giá trị của các tùy chọn profile trong Oracle Application

Object Library ở form hay chương trình tuy nhiên các ngoại trừ các profile

CONC_PRINT_OUTPUT và CONC_PRINT_STYLE kể cả System

administrators.

USERNAME Tên user Oracle Application Objec Library của

user hiện tại.

USER_ID user id

RESP_ID responsibility ID hiện tại của user.

APPL_SHRT_NAME short name của ứng dụng liên kết nối tới

responsibility.

RESP_APPL_ID application ID của ứng dụng kệt nối tới

responsibility hiện tại.

FORM_NAME tên của form hiện tại. Không tồn tại đối với

concurrent programs.

FORM_APPL_ NAME application ID của ứng dụng mà form được đăng

FORM_APPL_ID.

LOGON_DATE.

LAST_LOGON_

Page 114: Oracle Application Form

114

DATE.

LOGIN_ID

CONC_REQUEST_ID. equest ID tương ứng với một thể hiện của chương

trình hiện tại. Chỉ có thể dùng tùy chọn này trong

một concurrent program

CONC_PROGRAM_ID program ID tương ứng với một chương trình đang

chạy. Chỉ có thể dùng tùy chọn này trong một

concurrent program.

CONC_ PROGRAM_APPLICATION_ID

CONC_LOGIN_ID giá trị YES hoặc NO trong trường Print Output khi

đăng ký một concurrent program.

CONC_PRINT_ STYLE kiểu in đầu ra của concurrent program khi bạn

nhập vào trường Print Style khi đăng ký một

concurrent program.

Profile Window

Page 115: Oracle Application Form

115

Page 116: Oracle Application Form

116

FOLDER

Tổng quan về Folder.

Forlder là một chức năng hết sức đặt biệt trên form ứng dụng cho phép

người sử dụng thiết lập các thuộc tính riêng. Nó sẽ lưu giữ một profile cụ thể để

trình bày tên các promt cho các trường dữ liệu trên form bằng ngôn ngữ bản địa

có sử dụng được Unicode. Một chức năng thứ hai là tự động sắp xếp các trường

dữ liệu tự động (order by).

Lập trình với Folder trên form ứng dụng.

Cụ thể các bước để có thể sử dụng được chức năng này như sau :

Attach thư viện APPFLDR.

Thêm vào form chuẩn STANDARD_FOLDER Object group.

Tạo <BLOCKNAME>_RECORD_COUNT parameter: trong đó

BLOCKNAME là tên của Block chứa cột dữ liệu cần thể hiện,

Data Type là Number và giá trị default gán bằng 2.

Tạo 2 canvas : một cái là contain(VD đặt tên là FOLDER) một cái

là stack(VD đặt tên là STACK). Cả hai canvas này có cùng một

Window.

Tạo Block :

Block chính (BLOCKNAME) chứa các cột dữ liệu trong database.

Tạo các thủ tục trong các trigger tương ứng với block này như sau :

WHEN-NEW-BLOCK-INSTANCE

app_folder.event('WHEN-NEW-BLOCK-INSTANCE');

KEY-PREV-ITEM

if (:parameter.<blockname>_record_count = 1) then

previous_item;

else

Page 117: Oracle Application Form

117

app_folder.event('KEY-PREV-ITEM');

end if;

KEY-NEXT-ITEM

if (:parameter.<blockname>_record_count = 1) then

next_item;

else

app_folder.event('KEY-NEXT-ITEM');

end if;

PROMPT Block: tạo một block PROMPT ( đặt trên stack là

PROMPT_STACK kiểu là stack) chứa các promt cho các cột dữ liệu

trong block chính đã tạo ở trên. Trong block này chứa các item có tên

trùng với các tên cột trong block trên.

Các item này có property class là :

Ngoài ra cần phải tạo thêm các item khác là :

Item Name: FOLDER_OPEN, Item Type: Button, Canvas:

PROMPT_STACK

Item Name: FOLDER_DUMMY, Item Type: Text Item , Canvas:

TOOLBAR

Item Name: FOLDER_TITLE, Item Type: Display Item, Canvas:

PROMPT_STACK

Item Name: ORDER_BY1, Item Type: Button, Canvas:

PROMPT_STACK

Item Name: ORDER_BY2, Item Type: Button, Canvas:

PROMPT_STACK

Item Name: ORDER_BY3, Item Type: Button, Canvas:

PROMPT_STACK.

Trên trigger mức Form :

FOLDER_ACTION

--

-- Remove the message and uncomment the line after it

Page 118: Oracle Application Form

118

-- to activate the folder actions

--

-- message('You must modify the FOLDER_ACTION trigger in your

form!');

app_folder.event(:global.folder_action);

WHEN-NEW-FORM-INSTANCE

app_folder.define_folder_block('BLOCKNAME', -- 'Object Name'

'BLOCKNAME', -- 'folder_block',

'PROMPT', -- 'ten prompt_block',

' PROMPT_STACK, --'ten stacked_canvas',

„WINDOW1‟, --' ten window',

NULL); --'disabled functions');

Tuy nhiên khi sử dụng chức năng này của form thi khi di chuyển ra ngoài View port của

BLOCKNAME rồi mới thực hiện chức năng order by thi hệ thống sẽ báo lỗi và ta không

làm gì được nữa. (Qua tìm hiểu đây là lỗi của tất cả các Form trên ứng dụng sử dụng

chức năng này.

Page 119: Oracle Application Form

119

ATTACHMENTS

Đặc tính của Attachments

Attachments cho phép người dùng liên kết những dữ liệu không có cấu trúc như là ảnh,

tài liệu word, bảng tính, hoặc dữ liệu text với những dữ liệu của ứng dụng.