こんにちは。
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( ) |
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( ) |
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( ) |
DATA: lr_events TYPE REF TO cl_salv_events_table.
lr_events = gr_table->get_event( ).
こちらはほかのメソッドと種類が違って、別途イベントメソッドとイベントハンドラが必要です。
理解不足のところがあるので恐縮ですが、
・イベントが発生した際に実行される、イベント用クラスとメソッドの定義と実装
・イベント用のオブジェクトを生成して、各種イベントを登録
を行うことで、
イベント発生→イベントハンドラが判断して対応するイベントメソッドに引継ぎ→イベントメソッドを実行
する流れになる…と思います(違うぞという方、ぜひコメントでご指摘ください)。
ただ、ALVでは決め打ち的に使うのみだと思いますので、サンプルコードに倣っておけばいいのかなと
色設定の補足
色の付け方について、前回は項目ごとの固定色の設定について説明しました。
要件によくある「特定の条件を満たしていたらその行や、その項目に色を付ける」といった仕様は、
一覧に色情報の項目を持っておき、色情報以外の一覧内容をSELECTで取得。
→特定条件を満たすレコードに色情報を書き込み、項目全体の設定時にその色情報を取り込む、ことで対応が可能です。
※色情報用項目を定義する際の参照型:LVC_T_SCOLの項目名と用途
項目名 | 設定内容 |
---|---|
NAME | 色を付ける項目名を指定。指定なしの場合は、行全体が色付け対象となる |
COLOR-COL | 色を指定。※「INCLUDE <COLOR>」の事前指定で「COL_BACKGROUND」などの定義語で定義可能) |
COLOR-INT | 強調表示指定(0:色が薄くなる、1:初期設定値) |
COLOR-INV | 判定表示設定(0:通常、1:反転表示) |
色を付ける条件が複数存在する場合は、この色情報項目に内容をAPPENDしていきます(テーブルデータ型)。
また、この項目全体での色情報設定と、項目ごとの設定で色を設定した内容を両方定義すると、
項目全体での色情報設定が優先されるようです。
サンプルソースを見てみてください。
サンプルコード
上記をまとめたサンプルコードと画面ショットを添えておきます。
今回2つあり長くなるので、折り畳み表示としました。
サンプルコード(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
サンプルコード(色の設定)
*&---------------------------------------------------------------------*
*& 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( ).
今回の内容は以上です、ありがとうございました。