内部テーブルのパフォーマンスの改善

内部テーブルのコンテンツの処理

Objective

After completing this lesson, you will be able to 内部テーブルの内容を処理します。

SORT 文

標準内部テーブルでは、内容はソートされません。APPEND 文を使用してテーブルに追加する新規エントリは、テーブルの最後に追加されます。

標準内部テーブルのソート

このビデオでは、テーブルをそのキー、任意のフィールド、昇順および降順でソートする方法について説明します。

試行: SORT 命令

  1. インタフェース IF_OO_ADT_CLASSRUN を実装する新しいクラスを登録します。
  2. 以下のコードスニペットをメソッド if_oo_adt_classrun~main( ) の実装部分にコピーします。
    Code Snippet
    123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
    TYPES t_flights TYPE STANDARD TABLE OF /dmo/flight WITH NON-UNIQUE KEY carrier_id connection_id flight_date. DATA flights TYPE t_flights. flights = VALUE #( ( client = sy-mandt carrier_id = 'LH' connection_id = '0400' flight_date = '20230201' plane_type_id = '747-400' price = '600' currency_code = 'EUR' ) ( client = sy-mandt carrier_id = 'LH' connection_id = '0400' flight_date = '20230115' plane_type_id = '747-400' price = '600' currency_code = 'EUR' ) ( client = sy-mandt carrier_id = 'QF' connection_id = '0006' flight_date = '20230112' plane_type_id = 'A380' price = '1600' currency_code = 'AUD' ) ( client = sy-mandt carrier_id = 'AA' connection_id = '0017' flight_date = '20230110' plane_type_id = '747-400' price = '600' currency_code = 'USD' ) ( client = sy-mandt carrier_id = 'UA' connection_id = '0900' flight_date = '20230201' plane_type_id = '777-200' price = '600' currency_code = 'USD' ) ). out->write( 'Contents Before Sort' ). out->write( '____________________' ). out->write( flights ). out->write( ` ` ). * Sort with no additions - sort by primary table key carrier_id connection_id flight_date SORT flights. out->write( 'Effect of SORT with no additions - sort by primary table key' ). out->write( '____________________________________________________________' ). out->write( flights ). out->write( ` ` ). * Sort with field list - default sort direction is ascending SORT flights BY currency_code plane_type_id. out->write( 'Effect of SORT with field list - ascending is default direction' ). out->write( '________________________________________________________________' ). out->write( flights ). out->write( ` ` ). * Sort with field list and sort directions. SORT flights BY carrier_Id ASCENDING flight_Date DESCENDING. out->write( 'Effect of SORT with field list and sort direction' ). out->write( '_________________________________________________' ). out->write( flights ). out->write( ` ` ).
  3. CTRL + F3 を選択してクラスを有効化し、F9 を選択してコンソールアプリとして実行します。
  4. コンセプトを理解するために、ソースコードを使用します。

重複レコードの削除

場合によっては、内部テーブルから重複エントリを削除する必要があります。たとえば、この例では、carrier_idconnection_id の各組み合わせがテーブルに 1 回だけ表示されます。

命令 DELETE ADJACENT DUPLICATES を使用して、内部テーブルから重複エントリを削除することができます。ただし、この文は、エントリが隣接している (つまり、隣り合っている) 場合にのみ機能します。

最初に内部テーブルをソート

DELETE ADJACENT DUPLICATES 命令を使用する前に、重複値をスクリーニングする列 (この場合は carrier_id および connection_id) に従って内部テーブルをソートする必要があります。

ただし、重複するフライト番号が隣り合っている場合でも、このフォームの DELETE ADJACENT DUPLICATES 命令では何も削除されません。これは、基本書式の命令では、重複エントリの識別時にテーブルのすべてのキー項目が考慮され、2 つの LH 0400 接続の値が異なる flight_date であるため、重複エントリとしてカウントされないためです。

carrier_idconnection_id の組合せが同じであるエントリを削除するには、flight_date の値が異なる場合でも、DELETE ADJACENT DUPLICATES 命令の COMPARING オプションを使用する必要があります。ステートメントで COMPARING carrier_id connection_id を使用すると、重複エントリの識別時にこれらの項目のみを考慮するようにシステムに指示することができます。

COMPARING オプションでキー項目と非キー項目の任意の組合せを指定することができますが、最初に同じ項目に従ってテーブルをソートしておく必要があります。

COMPARING ALL FIELDS という追加もあります。これを使用する場合は、重複エントリが識別されるように、2 つのエントリのテーブル行全体が同じである必要があります。

試行: 重複レコードの削除

  1. インタフェース IF_OO_ADT_CLASSRUN を実装する新しいクラスを登録します。
  2. 以下のコードスニペットをメソッド if_oo_adt_classrun~main( ) の実装部分にコピーします。
    Code Snippet
    123456789101112131415161718192021222324252627282930313233343536373839
    TYPES t_flights TYPE STANDARD TABLE OF /dmo/flight WITH NON-UNIQUE KEY carrier_id connection_id flight_date. DATA: flights TYPE t_flights. flights = VALUE #( ( client = sy-mandt carrier_id = 'LH' connection_id = '0400' flight_date = '20230201' plane_type_id = '747-400' price = '600' currency_code = 'EUR' ) ( client = sy-mandt carrier_id = 'QF' connection_id = '0006' flight_date = '20230112' plane_type_id = 'A380' price = '1600' currency_code = 'AUD' ) ( client = sy-mandt carrier_id = 'AA' connection_id = '0017' flight_date = '20230110' plane_type_id = '747-400' price = '600' currency_code = 'USD' ) ( client = sy-mandt carrier_id = 'LH' connection_id = '0400' flight_date = '20230301' plane_type_id = '747-400' price = '600' currency_code = 'EUR' ) ( client = sy-mandt carrier_id = 'UA' connection_id = '0900' flight_date = '20230201' plane_type_id = '777-200' price = '600' currency_code = 'USD' ) ( client = sy-mandt carrier_id = 'QF' connection_id = '0006' flight_date = '20230210' plane_type_id = 'A380' price = '1600' currency_code = 'AUD' ) ). out->write( 'Contents Before DELETE ADJACENT DUPLICATES' ). out->write( '____________________' ). out->write( flights ). out->write( ` ` ). DELETE ADJACENT DUPLICATES FROM flights. out->write( 'Contents after DELETE ADJACENT DUPLICATES' ). out->write( 'Nothing deleted - key values are not adjacent' ). out->write( 'Sort the table before DELETE ADJACENT DUPLICATES'). out->write( flights ). out->write( ` ` ). SORT flights BY carrier_id connection_id flight_date. DELETE ADJACENT DUPLICATES FROM flights. out->write( 'Contents after DELETE ADJACENT DUPLICATES' ). out->write( 'Nothing deleted - ABAP compares all key values including flight_date, which is different for every entry' ). out->write( flights ). out->write( ` ` ). DELETE ADJACENT DUPLICATES FROM flights COMPARING carrier_id connection_id. out->write( 'Contents after DELETE ADJACENT DUPLICATES with COMPARING and field list' ). out->write( 'Entries with identical values of carrier_id and connection_id have been deleted' ). out->write( flights ).
  3. CTRL + F3 を選択してクラスを有効化し、F9 を選択してコンソールアプリとして実行します。
  4. コンセプトを理解するために、ソースコードを使用します。

テーブル包括性

多くの場合、内部テーブルに別の内部テーブルの値を入力する必要があります。1 つのテーブルから別のテーブルにデータをコピーする単純な問題である場合があります。また、ターゲットテーブルに書き込むために複数のソーステーブルからデータを読み込み、値を計算するために式を使用する必要が生じることもあります。

ABAP は、これらのタスクを実行するための手段を提供します。1 つのテーブルから別のテーブルにデータをコピーするだけの場合は、式 CORRESPONDING #( ) を使用できます。より複雑な操作では、テーブル理解を使用することができます。

2 つの内部テーブルの同じ名称の項目間でデータをコピーするには、CORRESPONDING 演算子を使用します。これは、構造の CORRESPONDING と同様に機能します。ソース内部テーブルの行ごとに、ターゲット内部テーブルに新規行が登録され、同じ名称の項目間でデータがコピーされます。ターゲットに同じ名称の項目がないソース項目はコピーされません。ソースに同じ名称の項目がないターゲット項目には、データ型固有の初期値が入力されます。

この例では、ソーステーブルキャリアに 3 つの行が含まれています。したがって、値割当後は、ターゲットの内部テーブル接続にも 3 つの行が含まれます。

項目 carrier_idcarrier_name が両方の内部テーブルに存在します。これらはソースからターゲットにコピーされます。項目 currency_code はソースにのみ存在します。これはコピーされません。項目 connection_idairport_from_id、および airport_to_id はターゲットにのみ存在します。初期値が入力されます。

注記:

割当前にターゲット内部テーブルにデータが含まれている場合、そのデータは削除されます。

次に、より複雑な例を考えてみましょう。プログラムには、フライト接続を含む内部テーブルと、空港の名称と場所を含む内部テーブルがあります。3 番目の内部テーブルには、接続テーブルの carrier_idconnection_id、および airport_from_id と、空港テーブルの空港 name を入力する必要があります。これは、テーブル理解を使用して行うことができます。

ある内部テーブルに別の内部テーブルを書き込むには、VALUE演算子に FOR 式を使用します。FOR は、ソーステーブルに対するループを実装し、各行を変数行に順次配置します。括弧内で、構文 component = VALUE を使用して新しい行のコンポーネントに値を割り当てます。これは、VALUE #( ) を使用して構造に書き込むときに使用する構文とまったく同じです。

以下は、この例のコードです。FOR line IN connections は connections テーブルを反復し、各行を変数行に順次配置します。括弧内で、テーブル result_table の各新規行を作成します。式の左側には result_table の列があり、右側には式に割り当てる値があります。列 carrier_idconnection_id、および departure_airport は、それぞれ行のコンポーネント carrier_idconnection_id、および airport_from_id を使用して入力されます。列 departure_airport_name に入力するには、テーブル式を使用して、行のコンポーネント airport_from_id を空港キーとして使用し、内部テーブルの空港で空港名を検索します。

WHERE を使用して論理条件 (特定の航空会社の接続のみなど) を指定するか、オプション FROM および TO を使用して行の範囲を指定することで、ソーステーブルでの反復を制限することができます。

試してみる: テーブル包括性

  1. インタフェース IF_OO_ADT_CLASSRUN を実装する新しいクラスを登録します。
  2. 以下のコードスニペットをメソッド if_oo_adt_classrun~main( ) の実装部分にコピーします。
    Code Snippet
    1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253
    TYPES: BEGIN OF t_connection, carrier_id TYPE /dmo/carrier_id, connection_id TYPE /dmo/connection_id, departure_airport TYPE /dmo/airport_from_id, departure_airport_Name TYPE /dmo/airport_Name, END OF t_connection. TYPES t_connections TYPE STANDARD TABLE OF t_connection WITH NON-UNIQUE KEY carrier_id connection_id. DATA connections TYPE TABLE OF /dmo/connection. DATA airports TYPE TABLE OF /dmo/airport. DATA result_table TYPE t_connections. * Aim of the method: * Read a list of connections from the database and use them to fill an internal table result_table. * This contains some data from the table connections and adds the name of the departure airport. SELECT FROM /dmo/airport FIELDS * INTO TABLE @airports. SELECT FROM /dmo/connection FIELDS * INTO TABLE @connections. out->write( 'Connection Table' ). out->write( '________________' ). out->write( connections ). out->write( ` ` ). * The VALUE expression iterates over the table connections. In each iteration, the variable line * accesses the current line. Inside the parentheses, we build the next line of result_table by * copying the values of line-carrier_Id, line-connection_Id and line-airport_from_id, then * loooking up the airport name in the internal table airports using a table expression result_table = VALUE #( FOR line IN connections ( carrier_Id = line-carrier_id connection_id = line-connection_id departure_airport = line-airport_from_id departure_airport_name = airports[ airport_id = line-airport_from_id ]-name ) ). out->write( 'Results' ). out->write( '_______' ). out->write( result_table ).
  3. CTRL + F3 を選択してクラスを有効化し、F9 を選択してコンソールアプリとして実行します。
  4. コンセプトを理解するために、ソースコードを使用します。

テーブル削減

内部テーブルを反復処理するときに、たとえば合計やローカウントを生成するために、情報の要約が必要になることがあります。

最も単純な削減形式は、内部テーブルで反復し、基本値を返します。減少の INIT 部分で可変合計が定義されます。変数の合計の型は、合計の型と互換性がある必要があります。FOR line IN flights は、各行が作業領域行に順次配置される内部テーブルフライトの反復です。NEXT 式では、各行の seats_occupied の内容が変数 total に追加されます。反復の最後に、合計の内容が変数の合計に割り当てられます。

注記

割当 total += line-seats_occupied は計算割当です。total = total + line-seats_occupied の省略形です。他の基本算術演算 (-= 、 *= 、 /= ) にも、類似の演算子が存在します。

削減の戻り値には、構造化データ型を含めることもできます。この例では、タイプ t_results は、占有されたコンポーネントと最大コンポーネントを含む構造です。削減の INIT セクションで、タイプ t_results の変数合計を宣言します。NEXT 式では、占有コンポーネントと最大コンポーネントをアドレス指定し、内部テーブル全体の各コンポーネントの合計をコンパイルします。

ターゲット変数のデータ型と REDUCE 式の結果のデータ型は互換性がある必要があります。

戻り値があるだけでなく、REDUCE 式でも追加のローカル変数を使用できます。この例では、式の INIT セクションに、戻り値を含む totals_avg と count の 2 つのデータ宣言が含まれています。count は整数値 1 で宣言されているため、型 I が割り当てられます。式の count セクションで NEXT を使用します。反復ごとに、これを使用してこれまでのすべてのフライトの平均占有率を計算し、各反復の最後に値に 1 を加算します。

試してみる: テーブルの縮小

  1. インタフェース IF_OO_ADT_CLASSRUN を実装する新しいクラスを登録します。
  2. 以下のコードスニペットをメソッド if_oo_adt_classrun~main( ) の実装部分にコピーします。
    Code Snippet
    1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253
    TYPES: BEGIN OF t_results, occupied TYPE /dmo/plane_seats_occupied, maximum TYPE /dmo/plane_seats_max, END OF t_results. TYPES: BEGIN OF t_results_with_Avg, occupied TYPE /dmo/plane_seats_occupied, maximum TYPE /dmo/plane_seats_max, average TYPE p LENGTH 16 DECIMALS 2, END OF t_results_with_avg. DATA flights TYPE TABLE OF /dmo/flight. SELECT FROM /dmo/flight FIELDS * INTO TABLE @flights. * Result is a scalar data type DATA(sum) = REDUCE i( INIT total = 0 FOR line IN flights NEXT total += line-seats_occupied ). out->write( 'Result is a scalar data type' ). out->write( '_____________ ______________' ). out->write( sum ). out->write( ` ` ). * Result is a structured data type DATA(results) = REDUCE t_results( INIT totals TYPE t_results FOR line IN flights NEXT totals-occupied += line-seats_occupied totals-maximum += line-seats_max ). out->write( 'Result is a structure' ). out->write( '_____________________' ). out->write( results ). out->write( ` ` ). * Result is a structured data type * Reduction uses a local helper variable * Result of the reduction is always the *first* variable declared after init out->write( 'Result is a structure. The average is calculated using a local helper variable' ). out->write( '______________________________________________________________________________' ). DATA(result_with_Average) = REDUCE t_results_with_avg( INIT totals_avg TYPE t_results_with_avg count = 1 FOR line IN flights NEXT totals_Avg-occupied += line-seats_occupied totals_avg-maximum += line-seats_max totals_avg-average = totals_avg-occupied / count count += 1 ). out->write( result_with_average ).
  3. CTRL + F3 を選択してクラスを有効化し、F9 を選択してコンソールアプリとして実行します。
  4. コンセプトを理解するために、ソースコードを使用します。

内部テーブルのコンテンツの処理

ローカルクラス LCL_PASSENGER_FLIGHT のメソッド GET_FLIGHTS_BY_CARRIER で、メソッド呼出ごとにバッファがリフレッシュされます。この演習問題では、メソッドの実装を調整して、すでにバッファされたフライトデータを保持します。

ローカルクラス LCL_CARRIER のメソッド GET_AVERAGE_FREE_SEATS では、データベースの集計もテーブル削減に置き換えます。

テンプレート:

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

ソリューション:

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

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

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

ステップ

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

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

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

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

    4. Next を選択します。

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

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

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

タスク 2: フライトバッファの調整

ローカルクラス LCL_PASSENGER_FLIGHT のメソッド GET_FLIGHTS_BY_CARRIER の実装を変更します。データベースからフライトデータを読み込む場合は、現在の内容を置き換えるのではなく、バッファ (静的属性 flights_buffer) にデータを追加してください。最初のアプローチでは、いずれの場合も新規エントリを追加してから、重複を削除します。2 つ目のアプローチでは、要求された航空会社のフライトがバッファにすでに含まれている場合は、SELECT 命令をスキップします。

ステップ

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

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

  2. 内部テーブル flights_buffer に対するループを調整します。インポートパラメータ i_carrier_id で指定された航空会社からのみフライトを読み込むフィルタを追加します。

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

      ABAP
      12
      LOOP AT flights_buffer INTO DATA(flight) WHERE carrier_id = i_carrier_id.
  3. SELECT 文を調整して、現在の内容を置き換えるのではなく、内部テーブル flights_buffer の内容に結果が追加されるようにします。

    ヒント

    INTO TABLE 句を APPENDING TABLE 句に置き換えます。
    1. SELECT 命令で、INTO を APPENDING に置き換えます。

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

      ABAP
      123456789101112131415161718
      SELECT FROM /lrn/passflight FIELDS carrier_id, connection_id, flight_date, plane_type_id, seats_max, seats_occupied, seats_max - seats_occupied AS seats_free, currency_conversion( amount = price, source_currency = currency_code, target_currency = @currency, exchange_rate_date = flight_date, on_error = @sql_currency_conversion=>c_on_error-set_to_null ) AS price, @currency AS currency_code WHERE carrier_id = @i_carrier_id ORDER BY flight_date ASCENDING * INTO TABLE @flights_buffer. APPENDING TABLE @flights_buffer.
  4. SELECT 文の後に、内部テーブル flights_buffer から重複エントリを削除する命令を追加します。

    1. SELECT 文の後に、以下のコードを追加します。

      ABAP
      123
      SORT flights_buffer BY carrier_id connection_id flight_date. DELETE ADJACENT DUPLICATES FROM flights_buffer COMPARING carrier_id connection_id flight_date.
  5. SELECT APPENDING のたびに flights_buffer の内容をソートするため、データベースの冗長ソートを省略することができます。

    1. SELECT 文で、ORDER BY 句を削除またはコメントします。

  6. グローバルクラスをコンソールアプリとして有効化してテストします。

    1. Ctrl + F3 を押します。

    2. F9 を押します。

  7. 次に、ロジックを調整します。重複を削除する代わりに、要求された航空会社のフライトが flights_buffer にすでに含まれている場合は、SELECT 命令をスキップします。

    1. 先ほど追加した DELETE 文にコメントを付けます。

    2. SELECT 命令と SORT 命令を IF … ENDIF で囲みます。

    3. IF 文で、述部関数 line_exists を使用して、flights_buffercarrier_id = i_carrier_id を含むローが含まれていないことを確認します。

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

      ABAP
      123456789101112131415161718192021222324
      IF NOT line_exists( flights_buffer[ carrier_id = i_carrier_id ] ). SELECT FROM /lrn/passflight FIELDS carrier_id, connection_id, flight_date, plane_type_id, seats_max, seats_occupied, seats_max - seats_occupied AS seats_free, currency_conversion( amount = price, source_currency = currency_code, target_currency = @currency, exchange_rate_date = flight_date, on_error = @sql_currency_conversion=>c_on_error-set_to_null ) AS price, @currency AS currency_code WHERE carrier_id = @i_carrier_id * ORDER BY flight_date ASCENDING * INTO TABLE @flights_buffer. APPENDING TABLE @flights_buffer. SORT flights_buffer BY carrier_id connection_id flight_date. * DELETE ADJACENT DUPLICATES FROM flights_buffer * COMPARING carrier_id connection_id flight_date. ENDIF.
  8. グローバルクラスをコンソールアプリとして有効化してテストします。

    1. Ctrl + F3 を押します。

    2. F9 を押します。

タスク 3: テーブル理解の使用

ローカルクラス LCL_PASSENGER_FLIGHT のメソッド GET_FLIGHTS_BY_CARRIER の実装を変更します。内部テーブル flights_buffer のループをテーブル理解に置き換えます。つまり、結果パラメータ r_result に VALUE 式を直接入力します。

ステップ

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

    1. 前と同じ方法でこのステップを実行します。

  2. メソッド実装の最後に LOOP … ENDLOOP ブロックにコメントを付けます。

    1. LOOP と ENDLOOP を含むコード行とその間のすべてのコード行を選択し、Ctrl + < を押して、選択した各行の先頭にコメント記号を挿入します。

    2. コードは、以下のようになります。

      ABAP
      12345678
      * LOOP AT flights_buffer INTO DATA(flight) * WHERE carrier_id = i_carrier_id. * * APPEND NEW lcl_passenger_flight( i_carrier_id = flight-carrier_id * i_connection_id = flight-connection_id * i_flight_date = flight-flight_date ) * TO r_result. * ENDLOOP.
  3. VALUE 式を実装し、結果をリターンパラメータ r_result に割り当てます。

    1. 以下のコードを追加します。

      ABAP
      123
      r_result = VALUE #( ).
  4. VALUE 式内で、内部テーブル flights_buffer にループを追加し、結果に新しい行を追加します (作業領域の推奨名: flight)。

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

      ABAP
      123
      r_result = VALUE #( FOR flight IN flights_buffer ( ) ).
  5. フィルタ条件を追加して、申請された航空会社のフライトのみが処理されるようにします。

    注記

    括弧のペアを追加して条件を囲むようにしてください。
    1. コードを以下のように調整します。

      ABAP
      123456
      r_result = VALUE #( FOR flight IN flights_buffer WHERE ( carrier_id = i_carrier_id ) ( ) ).
  6. 結果の各行にクラス LCL_PASSENGER_FLIGHT の新規インスタンスを入力します。flights_buffer の現在の行、つまり作業領域フライトからのデータをコンストラクタに提供します。

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

      ABAP
      123456789
      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 ) ) ).
  7. グローバルクラスをコンソールアプリとして有効化してテストします。

    1. Ctrl + F3 を押します。

    2. F9 を押します。

タスク 4: テーブル縮小の使用

ローカルクラス LCL_CARRIER で、メソッド GET_AVERAGE_FREE_SEATS の実装を調整します。SELECT 文の結果を計算する代わりに、テーブル削減を使用して、内部テーブル passenger_flights に格納されているインスタンスから結果を抽出します。

ステップ

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

    1. 前と同じ方法でこのステップを実行します。

  2. メソッド実装のソースコードを削除またはコメントします。

    1. METHOD get_average_free_seats. 命令と ENDMETHOD. 命令の間のコードをマークし、Ctrl + < を押します。

  3. REDUCE 式を実装し、結果をリターンパラメータ r_result に割り当てます。

    1. 以下のコードを追加します。

      ABAP
      123
      r_result = REDUCE #( ).
  4. REDUCE 式内で、テンポラリ変数を宣言し、値 0 で初期化します (推奨名: i)。

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

      ABAP
      123
      r_result = REDUCE #( INIT i = 0 ).
  5. REDUCE 式の閉じ括弧の前に、内部テーブル passenger_flights にループを追加します (作業領域の推奨名: flight)。

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

      ABAP
      1234
      r_result = REDUCE #( INIT i = 0 FOR flight IN passenger_flights ).
  6. 各反復で、現在の LCL_PASSENGER_FLIGHT インスタンスの空席数を一時変数に追加します。

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

      ABAP
      12345
      r_result = REDUCE #( INIT i = 0 FOR flight IN passenger_flights NEXT i = i + flight->get_free_seats( ) ).

      注記

      または、以下のような割当式を使用することができます。
      ABAP
      1
      NEXT i += flight->get_free_seats( )
  7. 最後に、平均を計算します。空席の合計数 (テーブル削減の結果) を passenger_flights のエントリ数で割ります。

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

      ABAP
      123456
      r_result = REDUCE #( INIT i = 0 FOR flight IN passenger_flights NEXT i = i + flight->get_free_seats( ) ) / lines( passenger_flights ).
  8. グローバルクラスをコンソールアプリとして有効化してテストします。

    1. Ctrl + F3 を押します。

    2. F9 を押します。