3

25 項目を表示する data_block を持つオラクル フォームがあります。

フォームには、スクロールバーと「削除」ボタンがあります。データ ブロック内のアイテムが選択され、[削除] ボタンが押されると、選択されたアイテムがデータベースから削除され、data_block クエリが実行されます。

デフォルトでは、これはユーザーをリストの一番上に戻します。

リストから削除されたレコードの直前のレコードに移動しようとしています。

これは、GO_RECORD(number) 組み込み関数 (BIF) を使用して行うことができます (number が :System.cursor_record の保存された値であると仮定します)。

そして、ここで私は問題に遭遇します。GO_RECORD BIF は、表示された項目リストの一番上または一番下にレコードを移動します。これにより、リストが警告なしに 20 アイテム上に移動する可能性があります。

つまり、たとえば、data_block のレコード 23 ~ 47 が表示されており、レコード 33 が選択されています。レコード 33 が削除され、関数 GO_RECORD(32) を使用すると、表示されるレコードは 32 ~ 56 になります (リストを実質的に 9 レコード下にシフトします)。

このシフトを回避するには、(data_block とは対照的に) 表示内のレコードの位置を特定する何らかの方法が必要になると想定しています。

この機能が存在するかどうかは誰にもわかりませんか?

または、同じ結果を得る可能性のある別のアプローチを誰かが持っていますか?

4

2 に答える 2

1

最初にこのプロシージャをプログラム単位として作成します

            PROCEDURE SYNC_BLOCK
            -----------------------------------------------------------------------*
            --  Synchronizes the display of any scrollable block.
            --  After running an edit that loops through all records, this will
            --  restore the block's display so that the same top record is again
            --  at the top of the block's display.
            --  Blk is the name of the block.
            --  Rec_Num is the desired target current record.
            --  Top_Rec is the original Top Record of the block captured
            --  before the looping process began.
            (BLK      VARCHAR2,
            REC_NUM  NUMBER,
            TOP_REC  NUMBER) IS
            BLK_ID    BLOCK;
            TOP_NEW   PLS_INTEGER;
            REC_N     PLS_INTEGER;
            --
            Procedure Check_success is begin
            If not form_success then
            Raise form_trigger_failure;
            End if;
            End Check_success;
            Procedure Go_Rec(rec_num number) is begin
            Go_Record(Rec_num);
            Check_Success;
            End Go_Rec;
            BEGIN
            BLK_ID := FIND_BLOCK(BLK);
            IF ID_NULL(BLK_ID) THEN
            Message('  U72_GO_REC_SYNC_BLOCK: CANNOT FIND BLOCK '''||BLK||'''');
            Raise Form_trigger_failure;
            END IF;
            IF BLK <> :SYSTEM.CURSOR_BLOCK THEN
            GO_BLOCK(BLK);
            Check_Success;
            END IF;
            IF :SYSTEM.CURSOR_RECORD <> REC_NUM THEN
            GO_REC(REC_NUM);
            END IF;
            -- may need to re-set the display to the rows originally shown
            TOP_NEW := GET_BLOCK_PROPERTY(BLK_ID, TOP_RECORD);
            IF TOP_REC <> TOP_NEW THEN
            IF TOP_REC < TOP_NEW THEN
            IF :SYSTEM.CURSOR_RECORD <> TOP_REC THEN
            GO_REC(TOP_REC);
            END IF;
            ELSE
            REC_N := GET_BLOCK_PROPERTY(BLK_ID, RECORDS_DISPLAYED)
            + TOP_REC - 1;
            IF :SYSTEM.CURSOR_RECORD <> REC_N THEN
            GO_REC(REC_N);
            END IF;
            END IF;
            SYNCHRONIZE;
            -- Found that Sync caused focus change to different block. Fix here.
            IF BLK <> :SYSTEM.CURSOR_BLOCK THEN
            GO_BLOCK(BLK);
            Check_Success;
            END IF;
            IF :SYSTEM.CURSOR_RECORD <> REC_NUM THEN
            GO_REC(REC_NUM);
            END IF;
            END IF;
            -- can't go_rec to NEW record, so need to test here
            IF  :SYSTEM.LAST_RECORD = 'TRUE'
            AND REC_NUM = 1 + :SYSTEM.CURSOR_RECORD THEN
            NEXT_RECORD;
            Check_Success;
            END IF;
            --
            END SYNC_BLOCK;

2番目のこの5行以下のコードは、あなたが望むものを正確に実行します

xx:=GET_BLOCK_PROPERTY('blk',TOP_RECORD);
xxx:=GET_BLOCK_PROPERTY('blk',CURRENT_RECORD );
go_block('blk');
execute_query();
SYNC_BLOCK('blk',xxx,xx);

さらに詳しい情報が必要な場合は、お気軽にお問い合わせください。

于 2013-10-29T11:55:05.060 に答える
1

-- トップレコードを保存

 l_top_rec:= GET_BLOCK_PROPERTY('EXP_DETAIL_BLK', TOP_RECORD);
 l_cur_rec:= :SYSTEM.CURSOR_RECORD;

-- あなたの行動

 execute_query; // or othres actions...

-- 最高記録を樹立

go_block(block_name);
--
first_record;
loop
  exit when GET_BLOCK_PROPERTY(block_name, TOP_RECORD) = l_top_rec;
  next_record;
end loop;
go_record(l_top_rec);
--
loop
  exit when :SYSTEM.CURSOR_RECORD = l_cur_rec or :SYSTEM.LAST_RECORD = 'TRUE';
  next_record;
end loop; 
于 2014-07-04T13:02:29.810 に答える