FORM界面批量处理-全选框实现
全选框实现方法多种多样,这里只介绍两种
方法一:触发器式,优点程序简单,缺点颜色单调不突出
1. 在数据块和控制块上分别创建check box
2. 设置check box选中与为选中的值 Y/N和初始值
3.
在数据块check box下触发器WHEN-CHECKBOX-CHANGED中调用程序
PROCEDURE check_box IS BEGIN IF :HEADER.check_box = 'Y' THEN --:HEADER.count := 1; NULL;--特殊用途,可选 ELSE --:HEADER.count := 0; NULL; END IF; END check_box;
4. 在数据块下建立BLOCK级触发器CHECK_ALL_RECORDS调用程序
PROCEDURE check_all_records IS BEGIN --fnd_message.debug('PACKAGE BODY headers IS PROCEDURE check_all_records IS'); IF :control.check_header_all = 'Y' THEN IF :header.check_box = 'N' OR :header.check_box IS NULL THEN :header.check_box := 'Y'; -- :line.count := 1; END IF; ELSE IF :header.check_box = 'Y' THEN :header.check_box := 'N'; -- :line.count := 0; END IF; END IF; --fnd_message.debug('PACKAGE BODY headers IS PROCEDURE check_all_records IS'); END check_all_records;
5. 在控制块下的check box CHECK_HEADER_ALL下建立触发器WHEN-CHECKBOX-CHANGED调用程序
PROCEDURE check_header_all IS BEGIN app_record.for_all_records('HEADER', 'CHECK_ALL_RECORDS'); END check_header_all;
6. 在需要处理的地方循环判断处理
PROCEDURE apply IS v_count number; v_line_num number; BEGIN go_block('HEADER'); --跳到目的数据 first_record; --从第一条记录开始循环 LOOP IF :header.check_box = 'Y' THEN v_count := v_count + 1; --fnd_message.debug('循环处理次数'); AP_INVOICE_LINES_ALL_PRIVATE.INSERT_ROW (X_LINE_NUM =>v_line_num, P_FLAG =>'APPLY', P_AMOUNT =>:header.AMOUNT); AP_DISTRIBUTIONS_PRIVATE.INSERT_ROW (P_LINE_NUM =>v_line_num, P_FLAG =>'APPLY', P_AMOUNT =>:header.AMOUNT, P_INVOICE_ID => :parameter.G_INVOICE_ID); LINE_PRIVATE.insert_row (P_LINE_NUM =>v_line_num,P_FLAG =>'APPLY'); -- :line.CURRENT_RECORD_INDICATOR := 'Y'; --将指定行的复选框设置为选中 -- BATCH_PROCESSING. EVENT('WHEN-MOUSE-CLICK', 'LINE'); DOCOMMIT; END IF; EXIT WHEN :system.last_record = 'TRUE'; next_record; END LOOP; --fnd_message.debug('循环处理次数-----'); --commit; DOCOMMIT; first_record; go_block('HEADER'); :parameter.g_query_find := 'TRUE'; app_find.find('HEADER'); :parameter.g_query_find := 'FALSE'; END apply;
方法二:选中与未选中颜色不同,显示多样
- 在需要进行批量操作的数据块中,对于item——current_record_indicator将其项类型改为‘“复选框”。
- 包app_multi在库appcore中,确保有该库
- 根据以下列表创建trigger
- 在form级别下添加MULTI_RETURN_ACTION自定义trigger
DECLARE action VARCHAR2(64); blockname VARCHAR2(30); rec_count VARCHAR2(3); BEGIN blockname := :GLOBAL.APPCORE_MULTI_BLOCK; action := :GLOBAL.APPCORE_MULTI_ACTION; IF blockname = 'FORM-LEVEL' THEN IF action = 'KEY-CLRFRM' THEN NULL; END IF; ELSIF blockname = 'TRN_ORD_HEADERS_V_SUM' THEN IF action = 'LABEL_CHANGE' THEN NULL; ELSIF action = 'PRE-KEY-DELREC' THEN fnd_message.set_name('FND', 'MULTI_DELETE_RECORD'); rec_count := TO_CHAR( app_multi. get_group_count('TRN_ORD_HEADERS_V_SUM')); fnd_message.set_token('NUM_OF_RECS', rec_count); IF (not fnd_message.warn) THEN RAISE form_trigger_failure; END IF; ELSIF action = 'KEY-DELREC' THEN delete_record; IF NOT(FORM_SUCCESS) THEN RAISE form_trigger_failure; END IF; ELSIF action = 'KEY-CLRREC' THEN clear_record; IF NOT(FORM_SUCCESS) THEN RAISE form_trigger_failure; END IF; ELSIF action = 'RECORD_DESELECTED' then --fnd_message.debug('deselected'); null; ELSIF action = 'RECORD_SELECTED' then --fnd_message.debug('selected'); null; END IF; ELSE fnd_message.debug('There is no multi-select block ' || blockname ||'. Action: '||action); END IF; END;
5. 创建过程event
PROCEDURE event(event_name VARCHAR2 DEFAULT 'WHEN-MOUSE-CLICK', blockname VARCHAR2 DEFAULT NULL) IS cursor_blk VARCHAR2(30); cursor_blk_id BLOCK; groupname VARCHAR2(40); records_id RECORDGROUP; rec_num_col_id GROUPCOLUMN; anchors_id RECORDGROUP; block_col_id GROUPCOLUMN; anchor_col_id GROUPCOLUMN; added_rec_col_id GROUPCOLUMN; prev_wnri_col_id GROUPCOLUMN; wnri_col_id GROUPCOLUMN; anchors_row INTEGER; new_rec INTEGER; new_item VARCHAR2(60); rec_count INTEGER; modifier VARCHAR2(30); rec_num INTEGER; anchor INTEGER; i INTEGER; added_rec INTEGER; trig_block VARCHAR2(30); q_hits INTEGER; multi_block VARCHAR2(30); begin COPY('Entering app_multi.event. Event is '||event_name||'.','global.frd_debug'); anchors_id := find_group('anchors'); if event_name in ('KEY-CLRFRM') then -- -- This is the only form-level event -- if not(id_null(anchors_id)) then rec_count := get_group_row_count(anchors_id); for anchors_row in 1..rec_count LOOP groupname := get_group_char_cell('anchors.groupname', anchors_row); delete_group_row(groupname, ALL_ROWS); set_group_number_cell('anchors.anchor', anchors_row, 1); set_group_number_cell('anchors.added_rec', anchors_row, null); set_group_number_cell('anchors.previous_wnri_anchor', anchors_row, null); set_group_number_cell('anchors.wnri_anchor', anchors_row, null); end LOOP; app_multi_private.menu_refresh; -- -- Developer must call app_standard.event('KEY-CLRFRM') -- copy('FORM-LEVEL', 'GLOBAL.APPCORE_MULTI_BLOCK'); copy('KEY-CLRFRM', 'GLOBAL.APPCORE_MULTI_ACTION'); execute_trigger('MULTI_RETURN_ACTION'); else app_standard.event('KEY-CLRFRM'); end if; else -- -- Initialize or find group and column id's -- trig_block := name_in('SYSTEM.TRIGGER_BLOCK'); multi_block := nvl(upper(blockname), trig_block); copy(multi_block, 'GLOBAL.APPCORE_MULTI_BLOCK'); groupname := multi_block||'_MULTI'; records_id := find_group(groupname); if id_null(records_id) then records_id := create_group(groupname); rec_num_col_id := add_group_column(records_id, 'rec_num', NUMBER_COLUMN); else rec_num_col_id := find_column(groupname||'.rec_num'); end if; -- -- Store the select anchor in another group (use a record -- group to make the group specific to the form) -- if id_null(anchors_id) then anchors_id := create_group('anchors'); block_col_id := add_group_column(anchors_id, 'groupname', CHAR_COLUMN, 30); anchor_col_id := add_group_column(anchors_id, 'anchor', NUMBER_COLUMN); added_rec_col_id := add_group_column(anchors_id, 'added_rec', NUMBER_COLUMN); prev_wnri_col_id := add_group_column(anchors_id, 'previous_wnri_anchor', NUMBER_COLUMN); wnri_col_id := add_group_column(anchors_id, 'wnri_anchor', NUMBER_COLUMN); add_group_row(anchors_id, 1); anchors_row := 1; set_group_char_cell(block_col_id, anchors_row, groupname); set_group_number_cell(anchor_col_id, anchors_row, 1); set_group_number_cell(prev_wnri_col_id, anchors_row, null); set_group_number_cell(wnri_col_id, anchors_row, null); else block_col_id := find_column('anchors.groupname'); anchor_col_id := find_column('anchors.anchor'); prev_wnri_col_id := find_column('anchors.previous_wnri_anchor'); wnri_col_id := find_column('anchors.wnri_anchor'); anchors_row := get_group_record_number(block_col_id, groupname); if anchors_row = 0 then anchors_row := get_group_row_count(anchors_id) + 1; add_group_row(anchors_id, anchors_row); set_group_char_cell(block_col_id, anchors_row, groupname); set_group_number_cell(anchor_col_id, anchors_row, 1); set_group_number_cell(prev_wnri_col_id, anchors_row, null); set_group_number_cell(wnri_col_id, anchors_row, null); end if; end if; cursor_blk := upper(nvl(blockname,name_in('SYSTEM.CURSOR_BLOCK'))); cursor_blk_id := find_block(cursor_blk); if not id_null(cursor_blk_id) then new_rec := get_block_property(cursor_blk_id, CURRENT_RECORD); else new_rec := name_in('SYSTEM.CURSOR_RECORD'); cursor_blk := name_in('SYSTEM.CURSOR_BLOCK'); end if; if event_name like 'WHEN-MOUSE-CLICK%' then if get_item_property(name_in('SYSTEM.TRIGGER_ITEM'), ITEM_TYPE) = 'BUTTON' then COPY('Completed app_multi.event. Event is '||event_name|| '. Return from procedure, item type is button','global.frd_debug'); RETURN; end if; -- -- System.mouse_button_modifiers will contain a string like -- 'Shift+Control+' - should be platform/language-independent. -- modifier := name_in('SYSTEM.MOUSE_BUTTON_MODIFIERS'); -- -- In the case of Shift+Control+ we act like it's just Shift- -- if ( instr(modifier, 'Shift') <> 0 ) then null; elsif 1=1 then if get_record_property(new_rec, cursor_blk, status) <> 'NEW' then -- Determine the state of the current rec rec_num := get_group_record_number(rec_num_col_id, new_rec); if rec_num = 0 then app_multi_private.select_records(records_id, rec_num_col_id, new_rec); else app_record.highlight(''); delete_group_row(records_id, rec_num); copy('RECORD_DESELECTED', 'GLOBAL.APPCORE_MULTI_ACTION'); execute_trigger('MULTI_RETURN_ACTION'); app_multi_private.menu_refresh; copy('LABEL_CHANGE', 'GLOBAL.APPCORE_MULTI_ACTION'); execute_trigger('MULTI_RETURN_ACTION'); set_group_number_cell(anchor_col_id, anchors_row,new_rec); end if; end if; else -- No modifier key if get_group_number_cell(anchor_col_id, anchors_row) <> new_rec then app_multi_private.deselect_all(records_id, rec_num_col_id); end if; end if; set_group_number_cell(anchor_col_id, anchors_row, new_rec); set_group_number_cell(prev_wnri_col_id, anchors_row, null); elsif event_name = 'WHEN-NEW-RECORD-INSTANCE' then set_group_number_cell(prev_wnri_col_id, anchors_row, get_group_number_cell(wnri_col_id, anchors_row)); set_group_number_cell(wnri_col_id, anchors_row, new_rec); elsif event_name = 'KEY-CREREC' then app_multi_private.deselect_all(records_id, rec_num_col_id); -- Developer must call create_record; elsif event_name = 'WHEN-CLEAR-BLOCK' then app_multi.clear_group(multi_block); --elsif event_name = 'KEY-F2' then -- app_multi.event('WHEN-MOUSE-CLICK.Shift+',blockname); --elsif event_name = 'KEY-F3' then -- app_multi.event('WHEN-MOUSE-CLICK.Control+',blockname); elsif event_name = 'DESELECT_ALL' then app_multi_private.deselect_all(records_id, rec_num_col_id); elsif event_name = 'SELECT_ALL' then app_multi_private.select_all(records_id, rec_num_col_id); elsif event_name in ('POST-BLOCK', 'PRE-BLOCK') then app_multi_private.menu_refresh(event_name); elsif event_name in ('KEY-DELREC', 'KEY-CLRREC') then app_multi_private.action(records_id, event_name, multi_block); app_multi.clear_group(multi_block); else app_multi_private.action(records_id, event_name, nvl(blockname, cursor_blk)); end if; end if; COPY('Completed app_multi.event. Event is '||event_name||'.','global.frd_debug'); EXCEPTION WHEN OTHERS THEN set_application_property(CURSOR_STYLE, 'DEFAULT'); END event;
6.创建函数get_group_count
FUNCTION get_group_count(blockname VARCHAR2) RETURN NUMBER IS groupid RECORDGROUP; rec_count INTEGER; BEGIN COPY('Entering app_multi.get_group_count.','global.frd_debug'); groupid := find_group(blockname||'_MULTI'); if id_null(groupid) then fnd_message.debug('DEVELOPER ERROR: Invalid blockname '||blockname ||' in app_multi.get_group_count'); end if; rec_count := get_group_row_count(groupid); if rec_count = 0 then --COPY('Completed app_multi.get_group_count. RETURN 1.','global.frd_debug'); return 0; else COPY('Completed app_multi.get_group_count.RETURN rec_count.','global.frd_debug'); return rec_count; end if; END get_group_count;
7.在要进行批量操作的数据块下的current_record_indicator添加when-checkbox-changed
调用过程event
8.创建按钮,添加按钮的when-button-pressed
DECLARE l_num_group_count NUMBER; l_grp_group_col_id GROUPCOLUMN; l_num_rec_num NUMBER; l_chr_current_block VARCHAR2(80); --l_num_hike_percent NUMBER; BEGIN l_chr_Current_Block := :GLOBAL.APPCORE_MULTI_BLOCK; GO_BLOCK(l_chr_Current_Block); l_num_group_count := Get_Group_Count(l_chr_Current_Block); -- fnd_message.debug('count=' || l_num_group_count); if l_num_group_count > 0 then l_grp_Group_Col_Id := App_Multi.Get_Group_Col(l_chr_Current_Block); For i IN 1..l_num_group_count LOOP l_num_Rec_Num := Get_Group_Number_Cell(l_grp_Group_Col_Id,i); GO_RECORD(l_num_Rec_Num); fnd_message.debug('--' || name_in(l_chr_Current_Block||'.order_number')); --在这里循环选中的record,对其进行自己的逻辑 -- Copy (TO_CHAR(TO_NUMBER(name_in(l_chr_Current_Block || ‘.SALARY’) * (1 + l_num_hike_percent ))), l_chr_Current_Block || ‘.SALARY’); END LOOP; end if; EXCEPTION WHEN invalid_number THEN Fnd_message.debug ('Invalid Number format exception: Please Check the name of the button. The format is HIKE_PERCENT_<percentage>'); END;