Sometimes you need to display a summary of a number of fields, and in such as add, delete, modify records when the value of the summary of the item to be changed accordingly, if used directly in the Form SUM belong ×××, for clearing and other operations to perform complex processing. Oracle provides APP_CALCULATE.RUNNING_TOTAL to achieve this requirement, the packages in APPCORE.PLL.
For Example:
To summarize ITEM is: LINES.QUANTITY, to show aggregated results for BLOCK HEADERS
1.HEADERS established to be displayed in the summary results ITEM, such as QTY_SUM
2.HEADERS in the establishment of two non-database entries were named QTY_SUM_RTOT_OLD and QTY_SUM_RTOT_DB (Number type)
3.LINES established in two non-database entries, and named QUANTITY_RTOT_OLD QUANTITY_RTOT_DB (Number type)
4. Create a stored procedure to wrap APP_CALCULATE.RUNNING_TOTAL
EXAMPLE:
pROCEDURE RUNNING_TOTAL_QUANTITY (the EVENT VARCHAR2) the iS
the BEGIN
APP_CALCULATE.RUNNING_TOTAL (the EVENT, 'LINES.QUANTITY', 'HEADERS.QTY_SUM');
the END;
- call TRIGGER RUNNING_TOTAL_QUANTITY in the calculation processing is performed
WHEN-VALIDATE-ITEM Trigger 5.:LINES.QUANTITY the write RUNNING_TOTAL_QUANTITY ( 'WHEN-VALIDATE -ITEM ');
If you want to summarize the operational fields from multiple fields, we need to re-write operation to calculate the value assigned to the field you want to summarize in each field of WHEN-VALIDATE-ITEM.
POST-QUERY Trigger 6.:HEADERS the initial crawl in the summary values from the database, for example:
Declare
V_SUM NUMBER;
BEGIN
SELECT NVL(SUM(QUANTITY), 0)
INTO V_SUM
FROM LINES
WHERE HEADER_ID = :HEADERS.HEADER_ID;
:HEADERS.QTY_SUM := V_SUM;
:HEADERS.QTY_SUM_RTOT_DB := V_SUM;----------------------注①
END;
It follows the write TRIGGER 7.:LINES corresponding code:
--key-DELREC
RUNNING_TOTAL_QUANTITY ( 'KEY-DELREC');
DELETE_RECORD;
RUNNING_TOTAL_QUANTITY('UNDELETE');----------------------注③
--KEY-DUPREC
RUNNING_TOTAL_QUANTITY('KEY-DUPREC');
DUPLICATE_RECORD;
CLRREC---key
RUNNING_TOTAL_QUANTITY ( 'KEY-CLRREC');
CLEAR_RECORD; - (Online examples: APP_FOLDER.EVENT ( 'KEY-CLRREC' );)
--POST-QUERY
RUNNING_TOTAL_QUANTITY( 'POST-QUERY' );
--WHEN-CLEAR-BLOCK
RUNNING_TOTAL_QUANTITY( 'WHEN-CLEAR-BLOCK' );----------------------注②
注:网上例子中还有post_insert,post_update,pre_record中写,我目前没写,测试OK,不知道会有什么漏洞,暂时没测出来。
另外上面的链接中,作者的例子会有问题,像链接文章评论所说,作者需增加 注① 的代码 ,即 WHEN-CLEAR-BLOCK的代码需和注①同时存在(查询发现EBS中PO的画面也是这么做的)。
最初我没有写 注② 和 注① 的代码 ,后经测试, 缺少这两部分会出现问题 ,还是举个例子说吧:
※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※
例: Line项只有一条记录,值为100,
1)正常查询出来记录后,汇总栏显示100;
2)修改记录值为99,汇总栏变为99;
3)按F11,会提示“是否保存记录”,选择“否”;
--此时汇总栏值为99(正常情况下此时汇总栏显示100)。
4)执行Ctrl+F11;
--此时汇总栏值依然为99(正常情况下此时汇总栏显示100,(且很大问题是此时Line值为100,汇总为99))。
※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※
所以:注② + 注①一定要写。
注③: Block的Delete Allowed设置为No,由于种种原因,Delete按钮是亮的。这种情况下,点击 Delete按钮 的时候会提示
FRM-41049:You cannot delete this record.但是汇总量会被减掉,一直点下去,会一直减掉..直至负NNNN...
所以加上 注③,以避免这种情况时汇总量的错误。
至于其它在 APP_CALCULATE.RUNNING_TOTAL 中涉及到的 Trigger中是否要写以及如何写,还未测试,目前为止,应用正常。
(有一点问题,即"新增一条记录,保存,然后点击clear-record按钮",数量会减掉,还未解决,其余Trigger应该也需要加上,但是有几个Trigger好像在Block下面没有,但又有其它Trigger调用在它们中产生的全局变量,暂时未过多测试。。Busy。。)
另外,如果汇总结果要拿来与其它值作比较,比如超过了某个值则raise error,则要注意running_total和比较大小两者的先后顺序。
如在when-validate-item时比较,则在此trigger中先running_total,后比较,否则...
--------------------------------------------------------------------------------------------------------------------------------------------------
附APP_CALCULATE.RUNNING_TOTAL原代码:
PACKAGE BODY app_calculate IS
PROCEDURE running_total(event VARCHAR2,
source_field VARCHAR2,
total_field VARCHAR2) IS
Last_Val_Field VARCHAR2(61) := Source_Field || '_RTOT_OLD';
DB_Source_Field VARCHAR2(61) := Source_Field || '_RTOT_DB';
DB_Total_Field VARCHAR2(61) := Total_Field || '_RTOT_DB';
Last_Value NUMBER;
Source_Value NUMBER;
DB_Source_Value NUMBER;
Total_Value NUMBER := NVL(name_in(Total_Field), 0);
DB_Total_Value NUMBER := NVL(name_in(DB_Total_Field), 0);
New_Total NUMBER;
Form_Id FORMMODULE;
BEGIN
COPY('Entering app_calculate.running_total. Event is ' || event || '.',
'global.frd_debug');
IF (event <> 'WHEN-CLEAR-BLOCK') THEN
Last_Value := NVL(name_in(Last_Val_Field), 0);
Source_Value := NVL(name_in(Source_Field), 0);
DB_Source_Value := NVL(name_in(DB_Source_Field), 0);
END IF;
IF (event = 'POST-QUERY') THEN
copy(to_char(Source_Value), DB_Source_Field);
copy(to_char(Source_Value), Last_Val_Field);
ELSIF (event = 'WHEN-CLEAR-BLOCK') THEN
IF (Total_Value <> DB_Total_Value) THEN
copy(to_char(DB_Total_Value), Total_Field);
END IF;
ELSIF (event = 'WHEN-VALIDATE-ITEM') THEN
IF (Source_Value <> Last_Value) THEN
New_Total := Total_Value - Last_Value + Source_Value;
copy(to_char(New_Total), Total_Field);
copy(to_char(Source_Value), Last_Val_Field);
END IF;
ELSIF (event = 'KEY-DELREC') THEN
IF (Last_Value <> 0) THEN
New_Total := Total_Value - Last_Value;
copy(to_char(New_Total), Total_Field);
END IF;
copy(to_char(Source_Value), Last_Val_Field);
ELSIF (event IN ('POST-INSERT', 'POST-UPDATE')) THEN
IF (Source_Value <> DB_Source_Value) THEN
copy(to_char(DB_Source_Value), Last_Val_Field);
copy(to_char(Source_Value), DB_Source_Field);
END IF;
ELSIF (event = 'PRE-RECORD') THEN
IF (Source_Value <> Last_Value) THEN
Form_Id := Find_Form(Get_Application_Property(Current_Form_Name));
IF (Name_In('GLOBAL.RTOT_' ||
substr(source_field,
1,
least(instr(source_field, '.') - 1, 15)) ||
to_char(Form_id.id)) = 'N') THEN
copy(to_char(Last_Value), DB_Source_Field);
END IF;
copy(to_char(Source_Value), Last_Val_Field);
END IF;
ELSIF (event = 'PRE-COMMIT') THEN
Form_Id := Find_Form(Get_Application_Property(Current_Form_Name));
copy('N',
'GLOBAL.RTOT_' ||
substr(source_field, 1, least(instr(source_field, '.') - 1, 15)) ||
to_char(Form_id.id));
ELSIF (event = 'POST-FORMS-COMMIT') THEN
Form_Id := Find_Form(Get_Application_Property(Current_Form_Name));
copy('Y',
'GLOBAL.RTOT_' ||
substr(source_field, 1, least(instr(source_field, '.') - 1, 15)) ||
to_char(Form_id.id));
IF (Total_Value <> DB_Total_Value) THEN
copy(to_char(Total_Value), DB_Total_Field);
END IF;
郑州不孕不育医院:http://byby.zztjyy.com/yiyuanzaixian/zztjyy//
ELSIF (event = 'UNDELETE') THEN
New_Total := Total_Value + Source_Value;
copy(to_char(New_Total), Total_Field);
copy(to_char(Source_Value), Last_Val_Field);
ELSIF (event = 'KEY-DUPREC') THEN
New_Total := Total_Value + Source_Value;
copy(to_char(New_Total), Total_Field);
copy(to_char(Source_Value), Last_Val_Field);
copy(NULL, DB_Source_Field);
ELSIF (event = 'KEY-CLRREC') THEN
IF (Last_Value <> DB_Source_Value) THEN
New_Total := Total_Value - Last_Value + DB_Source_Value;
copy(to_char(New_Total), Total_Field);
END IF;
ELSE
message('Invalid event ' || event ||
' in app_calulate.running_total');
END IF;
COPY('Completed app_calculate.running_total. Event is ' || event || '.',
'global.frd_debug');
END running_total;
END app_calculate;