コードの分析およびテスト
データ型およびデータ型変換の正しい使用
文字項目の処理
ABAP SQL でのコードプッシュダウンの使用
内部テーブルのパフォーマンスの改善
権限チェックの実装
効果的なオブジェクト指向コードの設計
例外クラスの定義と処理
ABAP コードへの文書の追加

フィールドシンボルを使用した内部テーブルの処理

Objective

After completing this lesson, you will be able to フィールドシンボルを使用して内部テーブルを処理します。

内部テーブルへのアクセスの項目シンボル

作業領域として構造を使用して内部テーブルを反復する方法を学習しました。この手法を使用すると、内部テーブルから作業領域にデータがコピーされます。その後、作業領域の内容を変更してから、MODIFY 命令を使用して内部テーブルにコピーして戻します。

この手法を使用して大きな内部テーブルを処理すると、データをコピーする手間がかかるため、パフォーマンスの問題が発生するリスクがあります。作業領域をフィールドシンボルに置き換えることで、これらのコストを削減することができます。

フィールドシンボルによる作業領域の置換

フィールドシンボルはポインタです。ポインタは、別のオブジェクトのメモリアドレスを認識し、そのオブジェクトを操作できるデータオブジェクトです。内部テーブルの場合、ポインタを使用すると、最初に作業領域にコピーしなくても、内部テーブルの行をアドレスすることができます。作業領域ではなくテーブル行を直接使用するため、変更を内部テーブルにコピーし直す必要はありません。

フィールドシンボルを定義するには、FIELD-SYMBOLS 命令を使用して、フィールドシンボルに名称を割り当てます。名前は山括弧で囲む必要があります。また、フィールドシンボルにタイプを割り当てます。フィールドシンボルを使用して内部テーブルを処理する場合は、作業領域と同様に、内部テーブルの行データ型でフィールドシンボルを定義します。

内部テーブルに対するループでフィールドシンボルを使用するには、LOOP 命令で ASSIGNING オプションを使用します。各ループパスで、ポインタが内部テーブルの対応する行をポイントするようになり、その内容を直接変更することができます。フィールドシンボルには内部テーブルの行データ型があるため、対応する構造と同様に処理することができます。フィールドシンボル名の後に、ダッシュを入力してから、変更するフィールドを入力することができます。

構造ではなく内部テーブルを直接使用しているため、MODIFY 命令は必要ありません。データのコピーを回避することで、ループのパフォーマンスを大幅に改善することができます。

実行時間比較

ここでは、MODIFY 命令を使用して内部テーブルが更新され、フィールドシンボルを使用して別の内部テーブルが更新された実行時間分析の結果を確認することができます。この場合、フィールドシンボルは modify 文よりも 40% 時間が短くなります。原則として、作業領域ではなくフィールドシンボルを使用して内部テーブルを更新すると、実行時間の 25 ~ 40% が節約されます。読込操作のパフォーマンス向上は小さくなります。

試してみる: 内部テーブルにアクセスするためのフィールドシンボル

  1. インタフェース IF_OO_ADT_CLASSRUN を実装する新しいクラスを登録します。
  2. 以下のコードスニペットをメソッド if_oo_adt_classrun~main( ) の実装部分にコピーします。
    Code Snippet
    12345678910111213
    METHOD if_oo_adt_classrun~main. * Execute this class using Profile As->ABAP Application * In the analysis, look at the comparative runtimes of * the methods loop_work_area( ) and loop_field_symbol( ) data(flights) = new lcl_demo( ). flights->use_work_area( ). flights->use_field_symbol( ). out->write( 'Done' ).
  3. Local Types タブに切り替えて、以下のコードスニペットをエディタにコピーします。
    Code Snippet
    12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061
    CLASS lcl_demo DEFINITION. PUBLIC SECTION. METHODS use_work_area. METHODS use_field_symbol. PRIVATE SECTION. TYPES t_flights TYPE STANDARD TABLE OF /dmo/flight WITH NON-UNIQUE KEY carrier_id connection_id flight_date. METHODS loop_field_symbol CHANGING c_flights TYPE t_Flights. METHODS loop_Work_area CHANGING c_flights TYPE t_flights. ENDCLASS. CLASS lcl_demo IMPLEMENTATION. METHOD use_field_symbol. DATA flights TYPE t_flights. SELECT FROM /dmo/flight FIELDS * INTO TABLE @flights. loop_field_symbol( CHANGING c_flights = flights ). ENDMETHOD. METHOD use_work_area. DATA flights TYPE t_flights. SELECT FROM /dmo/flight FIELDS * INTO TABLE @flights. loop_work_area( CHANGING c_flights = flights ). ENDMETHOD. METHOD loop_field_symbol. LOOP AT c_flights ASSIGNING FIELD-SYMBOL(). -seats_occupied += 1. ENDLOOP. ENDMETHOD. METHOD loop_work_area. LOOP AT c_flights INTO DATA(flight). flight-seats_occupied += 1. MODIFY c_flights FROM flight. ENDLOOP. ENDMETHOD. ENDCLASS.
  4. Ctrl + F3 キーを押して、クラスを有効化します。
  5. エディタを右クリックし、Profile As... を選択します。ABAP アプリケーション (コンソール)
  6. Details で、チェックボックス SQL database access のチェックを外し、Finish を選択します。
  7. ABAP プロファイラパースペクティブに切り替え、トレース項目をダブルクリックします (最初に表示をリフレッシュする必要がある場合があります)。
  8. 該当対象一覧を選択します。
  9. メソッド loop_Work_area( )loop_field_symbol( ) の実行時間を比較します。

ループでのフィールドシンボルの使用

ローカルクラス LCL_PASSENGER_FLIGHT のメソッド GET_FLIGHTS_BY_CARRIER の理解は、作業領域の 9 つのコンポーネントのうち 3 つにのみアクセスされます。パフォーマンスを改善するには、テーブル行全体を作業領域にコピーするのではなく、フィールドシンボルを割り当てます。

テンプレート:

  • /LRN/CL_S4D401_ITS_PROCESSING (グローバルクラス)

ソリューション:

  • /LRN/CL_S4D401_ITS_FSYM (グローバルクラス)

タスク 1: テンプレートのコピー (オプション)

テンプレートクラス /LRN/CL_S4D401_ITS_PROCESSING をコピーします。前の演習問題を完了した場合は、このタスクをスキップし、クラス ZCL_##_SOLUTION の編集を続行することができます。

ステップ

  1. クラス /LRN/CL_S4D401_ITS_PROCESSING を独自のパッケージのクラスにコピーします (推奨名: ZCL_##_SOLUTION、## はグループ番号)。

    1. Project Explorer で、クラス /LRN/CL_S4D401_ITS_PROCESSING を右クリックしてコンテンツメニューを開きます。

    2. コンテキストメニューから Duplicate.... を選択します。

    3. Package 項目にパッケージの名称を入力します。Name 項目に、ZCL_##_SOLUTION (## はグループ番号) と入力します。

    4. Next を選択します。

    5. 移送依頼を確認し、Finish を選択します。

  2. コピーを有効化します。

    1. Ctrl + F3 を押してクラスを有効化します。

タスク 2: フィールドシンボル使用

ローカルクラス LCL_PASSENGER_FLIGHT のメソッド GET_FLIGHTS_BY_CARRIER の実装を変更します。理解面では、作業領域をフィールドシンボルに置き換えます。

ステップ

  1. ローカルクラス LCL_PASSENGER_FLIGHT で、メソッド GET_FLIGHTS_BY_CARRIER の実装にナビゲートします。

    1. 前の演習問題と同じように、このステップを実行します。

  2. 各反復でフィールドシンボルが内部テーブルの現在の行に割り当てられるように VALUE 命令を調整します (フィールドシンボルの推奨名: <flight>)。

    1. コードを以下のように調整します。

      ABAP
      12345
      * r_result = VALUE #( * FOR flight IN flights_buffer r_result = VALUE #( FOR <flight> IN flights_buffer
  3. VALUE 式内のコードを調整します。作業領域 (フライト) の用途をフィールドシンボル (<flight>) の用途に置き換えます。

    1. コードを以下のように調整します。

      ABAP
      12345678910111213141516171819
      * r_result = VALUE #( * FOR flight IN flights_buffer * WHERE ( carrier_id = i_carrier_id ) ( * NEW lcl_passenger_flight( * i_carrier_id = flight-carrier_id * i_connection_id = flight-connection_id * i_flight_date = flight-flight_date ) * ) * ). r_result = VALUE #( FOR <flight> IN flights_buffer WHERE ( carrier_id = i_carrier_id ) ( NEW lcl_passenger_flight( i_carrier_id = <flight>-carrier_id i_connection_id = <flight>-connection_id i_flight_date = <flight>-flight_date ) ) ).
  4. グローバルクラスをコンソールアプリとして有効化してテストします。

    1. Ctrl + F3 を押します。

    2. F9 を押します。