2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

[ABAP]ABAP OOでALVを作成してみる(Let's try codeing ALV in ABAP OO) (2/N)

Last updated at Posted at 2020-04-05

こんにちは。

ABAP OOによるALV作成の2回目です。前回が長くなりましたので内容を分けました。
まだの方は1回目から見ていただけると幸いです。
[ABAP]ABAP OOでALVを作成してみる(Let's try codeing ALV in ABAP OO) (1/N)

参照

[HELP.SAP.COMのSAP List Viewer (ALV)]
(https://help.sap.com/viewer/b1c834a22d05483b8a75710743b5ff26/1709%20002/en-US/4ec38f8788d22b90e10000000a42189d.html)
ABAPサンプルプログラム:SALV_DEMO_TABLE_COLUMNS

ゴール

・ALVのアドオン設計・コード作成において、現在汎用モジュールベースの機能の多くをABAP OOにて置き換えられるようにする

制約事項(前回と同じ)

・業務用途として多い「単純2次元リスト」に絞る
・当方が調査してうまく動かなかったものはスルーします(調べ出すと終わらなくなってしまうので)
・「ALV with IDA(Integrated Data Access)」については次回以降にやりたいですね(…と遠い略)。

今回の対象

今回は、AGGREGATION(合計その他)、フィルタ、イベント(ダブルクリック)と、項目の色付けの補足です。

AGGREGATION 総計・個数・平均等を表示する項目の設定

総計、ソートでの小計指定におけるによる小計や、個数・平均などを表示する項目を指定します。
通貨や数量の項目が指定される場合、参照している通貨コードや数量単位ごとに集計が行われます。
ただ、実際の要件定義では「Excelで行う方が対応できる方が多いですよね」などと提案して、
ALVでのこれらのロジック実装は避けるパターンの方が多いと思います。

インスタンスの参照先クラス インスタンス生成メソッド
CL_SALV_AGGREGATIONS (CL_SALV_TABLE)->GET_AGGREGATIONS( )
AGGREGATION
  DATA: lr_aggrs TYPE REF TO cl_salv_aggregations.
  lr_aggrs = gr_table->get_aggregations(  ).
生成されたインスタンスのメソッド 機能
ADD_AGGREGATION 対象項目と、表示内容(合計・個数など)を指定
SET_AGGREGATION_BEFORE_ITEMS 結果行を先頭に表示する(見づらい…)
SET_AGGREGATION_ALLOWED 特定項目のAGGREGATION設定可否

フィルタ

AGGREGATIONやソートなどと同じく、標準機能で使用できるのであえてロジックで設定する
必要は少ないと思います。ただし、あくまで机上での考えですが、
実行トランザクションごとに見せるデータを絞りたい場合に、
ロジックでフィルタを設定+フィルタボタンを使用不可
といった対応でSQLを変更せずに対応できるケースなどもできると思います。

インスタンスの参照先クラス インスタンス生成メソッド
CL_SALV_FILTERS (CL_SALV_TABLE)->GET_FILTERS( )
FILTER
  DATA: lr_filters TYPE REF TO cl_salv_filters.
  lr_filters = gr_table->get_filters(  ).
生成されたインスタンスのメソッド 機能
ADD_FILTER フィルタ設定(SELECT-OPTIONSと似たような設定)を行う
SET_FILTER_ALLOWED 特定項目のフィルタ設定可否

イベント

インスタンスの参照先クラス インスタンス生成メソッド
CL_SALV_EVENTS_TABLE (CL_SALV_TABLE)->GET_EVENT( )
EVENTS
  DATA: lr_events TYPE REF TO cl_salv_events_table.
  lr_events = gr_table->get_event( ).

こちらはほかのメソッドと種類が違って、別途イベントメソッドとイベントハンドラが必要です。
理解不足のところがあるので恐縮ですが、
・イベントが発生した際に実行される、イベント用クラスとメソッドの定義と実装
・イベント用のオブジェクトを生成して、各種イベントを登録
を行うことで、
イベント発生→イベントハンドラが判断して対応するイベントメソッドに引継ぎ→イベントメソッドを実行
する流れになる…と思います(違うぞという方、ぜひコメントでご指摘ください)。
ただ、ALVでは決め打ち的に使うのみだと思いますので、サンプルコードに倣っておけばいいのかなと:sweat_smile:

色設定の補足

色の付け方について、前回は項目ごとの固定色の設定について説明しました。
要件によくある「特定の条件を満たしていたらその行や、その項目に色を付ける」といった仕様は、
一覧に色情報の項目を持っておき、色情報以外の一覧内容をSELECTで取得。
→特定条件を満たすレコードに色情報を書き込み、項目全体の設定時にその色情報を取り込む、ことで対応が可能です。

※色情報用項目を定義する際の参照型:LVC_T_SCOLの項目名と用途

項目名 設定内容
NAME 色を付ける項目名を指定。指定なしの場合は、行全体が色付け対象となる
COLOR-COL 色を指定。※「INCLUDE <COLOR>」の事前指定で「COL_BACKGROUND」などの定義語で定義可能)
COLOR-INT 強調表示指定(0:色が薄くなる、1:初期設定値)
COLOR-INV 判定表示設定(0:通常、1:反転表示)

色を付ける条件が複数存在する場合は、この色情報項目に内容をAPPENDしていきます(テーブルデータ型)。
また、この項目全体での色情報設定と、項目ごとの設定で色を設定した内容を両方定義すると、
項目全体での色情報設定が優先されるようです。
サンプルソースを見てみてください。

サンプルコード

上記をまとめたサンプルコードと画面ショットを添えておきます。
今回2つあり長くなるので、折り畳み表示としました。

サンプルコード(AGGREGATIONS、フィルタ、イベント)
SAMPLE02_AGGREGATIONS、フィルタ、イベント
REPORT Y_TEST_GOHTA07.

* 記事の参考に使用したURL
* https://help.sap.com/viewer/b1c834a22d05483b8a75710743b5ff26/1709%20002/en-US/4ec1f117076868b8e10000000a42189e.html
* 参考プログラム SALV_DEMO_TABLE_COLUMNS

*&---------------------------------------------------------------------*
*& Report Y_TEST_GOHTA10
*&---------------------------------------------------------------------*
*&
*&---------------------------------------------------------------------*
REPORT y_test_gohta10.

TYPES: BEGIN OF typ_mard,
         matnr TYPE mard-matnr,
         werks TYPE mard-werks,
         lgort TYPE mard-lgort,
         labst TYPE mard-labst,
         meins TYPE mara-meins,
       END OF typ_mard.
DATA: gt_mard TYPE TABLE OF typ_mard.
DATA: gr_table  TYPE REF TO cl_salv_table.

*... §6 Definition is later
CLASS lcl_handle_events DEFINITION DEFERRED.

*... §6 object for handling the events of cl_salv_table
* CL_SALV_TABLEのイベントハンドラを定義
DATA: gr_events TYPE REF TO lcl_handle_events.

*---------------------------------------------------------------------*
*       CLASS lcl_handle_events DEFINITION
*---------------------------------------------------------------------*
* §6.1 define a local class for handling events of cl_salv_table
* CL_SALV_TABLEのイベントを処理するためのイベントメソッドの定義
*---------------------------------------------------------------------*
CLASS lcl_handle_events DEFINITION.
  PUBLIC SECTION.
    METHODS:
      on_double_click FOR EVENT double_click OF cl_salv_events_table
        IMPORTING row column.
*      on_single_click for event link_click of cl_salv_events_table
*        importing row column.

ENDCLASS.                    "lcl_handle_events DEFINITION

*---------------------------------------------------------------------*
*       CLASS lcl_handle_events IMPLEMENTATION
*---------------------------------------------------------------------*
* §6.2 implement the events for handling the events of cl_salv_table
* CL_SALV_TABLEのイベントを処理するためのイベントメソッドの実装
*---------------------------------------------------------------------*
CLASS lcl_handle_events IMPLEMENTATION.
  METHOD on_double_click.
    PERFORM show_cell_info USING 0 row column TEXT-i05.
  ENDMETHOD.                    "on_double_click

*  method on_single_click.
*    perform show_cell_info using 0 row column text-i04.
*  endmethod.                    "on_single_click
ENDCLASS.                    "lcl_handle_events IMPLEMENTATION

*----------------------------------------------------------------------*
* START-OF-SELECTION                                                   *
*----------------------------------------------------------------------*
START-OF-SELECTION.

*... Select data
  SELECT  FROM mard AS t1
      INNER JOIN mara  AS t2
      ON t1~matnr = t2~matnr
      FIELDS
         t1~matnr,
         t1~werks,
         t1~lgort,
         t1~labst,
         t2~meins
      INTO CORRESPONDING FIELDS OF TABLE @gt_mard .

*... Create Instance
  CALL METHOD cl_salv_table=>factory
    EXPORTING
      list_display = abap_false "abap_true:classic abap_false:fullscreen
    IMPORTING
      r_salv_table = gr_table
    CHANGING
      t_table      = gt_mard.

* ボタン表示・使用有無等
  DATA: lr_functions TYPE REF TO cl_salv_functions_list.
  lr_functions = gr_table->get_functions(  ).
  lr_functions->set_all(  if_salv_c_bool_sap=>true  ).

* 項目全体の設定、特定項目の順番指定
  DATA: lr_columns TYPE REF TO cl_salv_columns_table.
  lr_columns = gr_table->get_columns( ).
  lr_columns->set_optimize( abap_true ).

* 項目ごとの設定
  DATA: lr_column TYPE REF TO cl_salv_column_table.
  TRY.
      lr_column ?= lr_columns->get_column( 'LABST' )."lr_columnsからlr_columnへのダウンキャスト
      lr_column->set_quantity_column(  value = 'MEINS' ). "数量単位参照項目の設定
    CATCH cx_salv_not_found.                            "#EC NO_HANDLER
  ENDTRY.

* 合計/小計、平均、個数などを表示する項目の設定
  DATA: lr_aggrs TYPE REF TO cl_salv_aggregations.
  lr_aggrs = gr_table->get_aggregations(  ).
  lr_aggrs->add_aggregation( columnname   = 'LABST'
                             aggregation = if_salv_c_aggregation=>total ). "合計表示
*  lr_aggrs->SET_AGGREGATION_BEFORE_ITEMS( abap_true ). "見づらい

* ソートの設定
  DATA: lr_sorts TYPE REF TO cl_salv_sorts.
  lr_sorts = gr_table->get_sorts(  ).
  lr_sorts->add_sort(  columnname = 'MATNR'
                       position = 1
                       sequence = if_salv_c_sort=>sort_up "昇順・降順
                       subtotal = if_salv_c_bool_sap=>true ). "小計表示設定あり

* フィルタの設定
  DATA: lr_filters TYPE REF TO cl_salv_filters.
  lr_filters = gr_table->get_filters(  ).
  lr_filters->add_filter(  columnname = 'WERKS' "SELECT-OPTIONSのように指定
                                          sign = 'I'  option = 'CP'  low = '*' ).

*... §7 register to the events of cl_salv_table
* CL_SALV_TABLEのイベントを登録
  DATA: lr_events TYPE REF TO cl_salv_events_table.
  lr_events = gr_table->get_event( ).
  CREATE OBJECT gr_events.

*... §7.2 register to the event DOUBLE_CLICK
* ダブルクリックイベントへ登録
  SET HANDLER gr_events->on_double_click FOR lr_events.
**... §7.3 register to the event LINK_CLICK
*  set handler gr_events->on_single_click for lr_events.

  gr_table->display(  ).

*&---------------------------------------------------------------------*
*&      Form  show_cell_info
*&---------------------------------------------------------------------*
*       ダブルクリック時にカーソル位置の情報を表示する
*----------------------------------------------------------------------*
FORM show_cell_info USING i_level  TYPE i
                          i_row    TYPE i
                          i_column TYPE lvc_fname
                          i_text   TYPE string.

  DATA: l_row_string TYPE string,
        l_col_string TYPE string,
        l_row        TYPE char128.

  WRITE i_row TO l_row LEFT-JUSTIFIED.

  DATA(lc_matnr) = gt_mard[ i_row ]-matnr. "内部テーブルのインデックス読み
  CONCATENATE TEXT-i02 l_row INTO l_row_string SEPARATED BY space.
  CONCATENATE TEXT-i03 i_column INTO l_col_string SEPARATED BY space.

  IF i_level IS INITIAL.
    MESSAGE i000(0k) WITH i_text lc_matnr l_row_string l_col_string.

  ENDIF.

ENDFORM.                    " show_cell_info

image.png

サンプルコード(色の設定)
SAMPLE03_色の設定
*&---------------------------------------------------------------------*
*& Report Y_TEST_GOHTA09
*&---------------------------------------------------------------------*
*&
*&---------------------------------------------------------------------*
REPORT y_test_gohta09.

INCLUDE <color>.

TYPES: BEGIN OF typ_mard,
         matnr TYPE mard-matnr,
         werks TYPE mard-werks,
         lgort TYPE mard-lgort,
         labst TYPE mard-labst,
         meins TYPE mara-meins,
         r_col TYPE lvc_t_scol, "色情報(行・項目)
       END OF typ_mard.
DATA: gs_mard TYPE typ_mard.
DATA: gt_mard TYPE TABLE OF typ_mard.
DATA: gr_table  TYPE REF TO cl_salv_table.

*----------------------------------------------------------------------*
* START-OF-SELECTION                                                   *
*----------------------------------------------------------------------*
START-OF-SELECTION.

*... Select data
  SELECT  FROM mard AS t1
      INNER JOIN mara  AS t2
      ON t1~matnr = t2~matnr
      FIELDS
         t1~matnr,
         t1~werks,
         t1~lgort,
         t1~labst,
         t2~meins
      INTO CORRESPONDING FIELDS OF TABLE @gt_mard .

  DATA: s_scol TYPE lvc_s_scol.
  DATA: itab_col TYPE lvc_t_scol.

* 在庫数が10未満かつ数量単位が「PC」でないデータの行に色を付ける
  s_scol-fname = ''. "行全体:項目名を設定しない
  s_scol-color  = VALUE lvc_s_colo( col = col_negative int = 0 inv = 0 ) .
  APPEND s_scol TO itab_col.
  s_scol-fname = 'MEINS'. "特定項目
  s_scol-color  = VALUE lvc_s_colo( col = col_group int = 0 inv = 0 ) .
  APPEND s_scol TO itab_col.

  gs_mard-r_col = itab_col.
  MODIFY gt_mard FROM gs_mard
      TRANSPORTING r_col
      WHERE labst < 10 AND
                  meins <> 'PC'.

*... Create Instance
  CALL METHOD cl_salv_table=>factory
    EXPORTING
      list_display = abap_false "abap_true:classic abap_false:fullscreen
    IMPORTING
      r_salv_table = gr_table
    CHANGING
      t_table      = gt_mard.

*ボタン表示・使用有無等
  DATA: lr_functions TYPE REF TO cl_salv_functions_list.
  lr_functions = gr_table->get_functions(  ).
  lr_functions->set_all(  if_salv_c_bool_sap=>true  ).

* 項目全体の設定、特定項目の順番指定
  DATA: lr_columns TYPE REF TO cl_salv_columns_table.
  lr_columns = gr_table->get_columns( ).
  lr_columns->set_optimize( abap_true ).
*  行単位での色付け (色情報のある項目を指定)
  TRY.
      lr_columns->set_color_column(  'R_COL'  ).
    CATCH cx_salv_data_error.
  ENDTRY.

* 項目ごとの設定
  DATA: lr_column TYPE REF TO cl_salv_column_table.
  DATA: lst_colcolor TYPE  lvc_s_colo.
  TRY.
      lr_column ?= lr_columns->get_column( 'LABST' )."lr_columnsからlr_columnへのダウンキャスト
      lr_column->set_quantity_column(  value = 'MEINS' ). "数量単位参照項目の設定
* 項目単位での色付け
      lst_colcolor-col = col_normal.
      lst_colcolor-int = 1.
      lst_colcolor-inv = 1.
      lr_column->set_color(  lst_colcolor ).
    CATCH cx_salv_not_found.                            "#EC NO_HANDLER
  ENDTRY.

  gr_table->display(  ).

image.png

今回の内容は以上です、ありがとうございました。

2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?