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

こんにちは。

今回はABAP OOの学習の一環としてALVを題材にして記事を作成してみました。
私自身、ABAP OOを使った設計も開発も書いたことはなく今回独学した内容ですので、
間違いやTipsなどありましたら、適時コメントをいただけますと幸いです。

※内容が多いので記事を分けました。AGGREGATION、フィルタ、イベント、色付けの補足はこちらをどうぞ
[[ABAP]ABAP OOでALVを作成してみる(Let's try codeing ALV in ABAP OO) (2/N)]
(https://qiita.com/Go_Ohta/items/ef0d25555b3ef8749495)

###更新履歴
v.1.1
デモプログラム：SALV_DEMO_TABLE_COLUMNS の内容を取り込み、メソッドの記述を追加

###参照したURL
[HELP SAPのSAP List Viewer (ALV)]
(https://help.sap.com/viewer/b1c834a22d05483b8a75710743b5ff26/1709%20002/en-US/4ec38f8788d22b90e10000000a42189d.html)

###ゴール

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

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


###基本のコード

簡単なテーブルの一覧であれば、以下だけでもコードできます。

```ABAP:YTEST_ALV_OO_01

REPORT YTEST_ALV_OO_01.

data: gt_marc type table of marc,
      gr_table  type ref to cl_salv_table.

*... Select data
  select * from marc into table gt_marc.

*... Create Instance
  call method cl_salv_table=>factory
*    exporting
*      list_display = abap_true
    IMPORTING
      R_SALV_TABLE = gr_table
     changing
     t_table      = gt_marc.

*... Display table
  gr_table->display( ).
```

テーブルMARCのデータを取得後、CL_SALV_TABLEのFACTORYメソッドで
インスタンスGR_TABLEを生成し、DISPLAYメソッドでALV一覧を表示するコードです。
ただ、この状態だと一覧の装飾も少なく標準ボタンもありません。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/326392/be4a0f07-1ac7-6e9b-76b6-897c47a146bc.png)

ここからいろいろ追加していきますが、判定系メソッド(IS*)の記述は省略します。
全体の内容はSE24で「参照先クラス」のクラスを参照してください
※単純二次元一覧では使用できない、効果がないメソッドもあります。

###表全体の設定

|インスタンスの参照先クラス|インスタンス生成メソッド|
|:------------|:---------------------------|
|CL_SALV_DISPLAY_SETTINGS|(CL_SALV_TABLE)->GET_DISPLAY_SETTINGS( )|

コードで書くとこうなります。

```abap:01
  data: lr_disp_settings type ref to CL_SALV_DISPLAY_SETTINGS.
  lr_disp_settings = gr_table->GET_DISPLAY_SETTINGS( ).
```

|生成されたインスタンスのメソッド  |機能                                      |
|:-------------|:----------------------------------------------------------|
|SET_NO_MERGING |項目をソートしたときに、同一値の複数セルを結合しているように表示する処理の有無|
|SET_STRIPED_PATTERN |この表のように、1行ごとに行の色を置き換える設定有無（＝「ZEBRA」）                 |
|SET_HORIZONTAL_LINES|水平線(横線)の有無                                |
|SET_VERTICAL_LINES  |垂直線(縦線)の有無
|SET_LIST_HEADER|ALV一覧表示時の**タイトル**|

###アプリケーションツールバー ALV標準機能のボタン表示設定

1つ1つの機能(ボタン)を都度有効化するのは手間なので、「SET_ALL」か「SET_DEFAULT」で多めに有効化しておき、
不要な機能を「SET_XXXXXXXX」にて不要な機能を無効化するというパターンが多いと思います。

|インスタンスの参照先クラス|インスタンス生成メソッド|
|:------------|:---------------------------|
|CL_SALV_FUNCTIONS_LIST|(CL_SALV_TABLE)->GET_FUNCTIONS( )|

```abap:02
  data: lr_functions type ref to cl_salv_functions_list.
  lr_functions = gr_table->get_functions(  ).
```

|生成されたインスタンスのメソッド  |機能                                      |
|:-------------|:----------------------------------------------------------|
|SET_ALL |すべてのALV標準機能の有効化有無                                       |
|SET_DEFAULT |一般的なALV標準機能の有効化有無※SEL_ALLよりは少ない|
|SET_XXXXXX|特定機能の有効化有無(「SET_EXPORT_LOCALFILE」など)|

###項目全体の定義

項目全体の共通定義となります。
各項目の設定はここで生成したインスタンスからさらに各項目別のインスタンスを生成して行います。

|インスタンスの参照先クラス|インスタンス生成メソッド|
|:------------|:---------------------------|
|CL_SALV_COLUMNS_TABLE|(CL_SALV_TABLE)->GET_COLUMNS( )|

```abap:03
  data: lr_columns type ref to cl_salv_columns_TABLE.
  lr_columns = gr_table->get_columns( ).
```

|生成されたインスタンスのメソッド  |機能                                      |
|:-------------|:----------------------------------------------------------|
|GET|各項目の情報を格納したインスタンスの生成|
|SET_COLOR_COLUMN |セルや行の色情報を指定した項目を指定|
|SET_COLUMN_POSITION|指定項目の表示位置指定|
|SET_COUNTER_COLUMN |件数を指定した項目を指定|
|SET_HEADERS_VISIBLE |項目見出しの表示有無|
|SET_KEY_FIXATION |キー項目を固定|
|SET_OPTIMIZE |項目幅の自動調整有無|
|SET_CELL_TYPE_COLUMN |セルのタイプを指定した項目を指定|

GETメソッドを使用すると、各項目の設定内容を内部テーブル形式で取得できます。

```abap:04
  data: itab_columns_info type SALV_T_COLUMN_REF.
  itab_columns_info =  lr_columns->get( ).
```
この後、各項目の設定内容について記述しますが、上記のように内部テーブルで
取得しておいて、LOOPやREADで必要な項目のデータを取得し変更する記述方法も可能だと思われます。

###各項目の設定

項目全体の定義用インスタンスから生成用メソッドを呼び出します。

|インスタンスの参照先クラス|インスタンス生成メソッド|
|:------------|:---------------------------|
|CL_SALV_COLUMN_TABLE|(CL_SALV_COLUMNS)->GET_COLUMNS( 項目名 ) |

```abap:05
  data: lr_column type ref to cl_salv_column_table.
  lr_column ?= lr_columns->get_column( 'WERKS' ).
```

|生成されたインスタンスのメソッド  |機能                                      |
|:-------------|:----------------------------------------------------------|
|SET_ALIGNMENT|セル内での表示位置(左寄せ・右寄せなど)を指定(→IF_SALV_C_ALIGNMENT)|
|SET_CELL_TYPE|項目のタイプ(テキスト・チェックボックス・ボタンなど)を指定(IF_SALV_C_CELL_TYPE)|
|SET_COLOR|セルの色を指定(LVC_S_COLO)|
|SET_CURRENCY|通貨コードを指定|
|SET_CURRENCY_COLUMN|通貨コード参照項目を指定|
|SET_DDIC_REFERENCE|項目の参照先項目を指定(指定項目と同じヘッダや項目長で定義される)|
|SET_DECIMALS_COLUMN|小数点位参照先項目を指定|
|SET_DECIMALS|小数点位を指定|
|SET_EDIT_MASK|表示用エディットマスクを指定|
|SET_F1_ROLLNAME|項目のF1ヘルプで参照するデータエレメントを指定|
|SET_F4|F1(F4の記述間違い？)ヘルプの有無を指定|
|SET_ICON|アイコン項目として指定|
|SET_KEY|キー項目として指定|
|SET_LEADING_ZERO|数字項目値の先頭のゼロ付与有無|
|SET_LONG_TEXT|テキスト(長)を指定|
|SET_LOWERCASE|テキスト項目にて小文字を許容するか ※コード値には影響なしの模様|
|SET_MEDIUM_TEXT|テキスト(中)を指定|
|SET_OPTIMIZED|項目長の自動調整|
|SET_OUTPUT_LENGTH|出力長を指定|
|SET_QUANTITY|数量単位を指定|
|SET_QUANTITY_COLUMN|数量単位参照項目を指定|
|SET_ROUND|丸めの設定(不明)|
|SET_ROUND_COLUMN|丸め参照項目を指定|
|SET_SHORT_TEXT|テキスト(小)を指定|
|SET_SIGN|数量項目の符号表示有無|
|SET_TECHNICAL|技術用項目として設定 ※設定した場合、ALV一覧上での表示・使用不可|
|SET_TOOLTIP|ツールチップ(マウスカーソルを合わせた際に表示されるテキスト)の内容を指定|
|SET_VISIBLE|一覧初期表示時の項目表示有無 ※表示無と設定しても、レイアウト変更から表示が可能|
|SET_ZERO|数量項目の値がゼロの場合「0」と表示するか空白とするかの有無|

####項目の色指定

特定の項目に固定の色を付ける場合はこのようにします。
※値の条件などにより色を変える場合は、項目全体の設定から変更します

```abap:06
    lr_column ?= lr_columns->get_column( 'DISMM' ).
    ls_color-col = col_positive. "色
    ls_color-int = 0.            "強調表示 0/1 1が初期値、0にすると色が薄くなる
    ls_color-inv = 0.            "反転表示 0/1
    lr_column->set_color(  ls_color ).
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/326392/54dfdf85-02d4-d19c-91a3-171f78012a37.png)

###ソート

ソート情報および、合計対象項目がある場合の小計対象とするかの設定を行います。

|インスタンスの参照先クラス|インスタンス生成メソッド|
|:------------|:---------------------------|
|CL_SALV_SORTS|(CL_SALV_COLUMNS)->GET_SORTS( )|

```abap:07
DATA: lr_sorts TYPE REF TO cl_salv_sorts.
lr_sorts = gr_table->get_sorts(  ).
lr_sorts->add_sort( columnname = 'MATNR'
                    subtotal = if_salv_c_bool_sap=>true
                    sequence = if_salv_c_sort=>sort_up ).
```

|生成されたインスタンスのメソッド  |機能                                      |
|:-------------|:----------------------------------------------------------|
|ADD_SORT|ソート情報(項目・ソートの向き)、小計対象の有無を設定|


###まとめ・・・続きます(えっ）
上記をまとめたサンプルコードと画面ショットを添えておきます。

```abap:SAMPLE01
REPORT Y_TEST_GOHTA07.

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

INCLUDE <color>.

DATA: gt_marc  TYPE TABLE OF marc,
      gr_table TYPE REF TO cl_salv_table.
*... Select data
SELECT * FROM marc INTO TABLE gt_marc.
*... 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_marc.

*… DISPLAY SETTINGS
DATA: lr_disp_settings TYPE REF TO cl_salv_display_settings.
lr_disp_settings = gr_table->get_display_settings(  ).
lr_disp_settings->set_list_header( 'ALV LIST TITLE' ).
lr_disp_settings->set_no_merging(  abap_true ).
lr_disp_settings->set_striped_pattern(  abap_true ). "旧 ZEBRA
*  lr_disp_settings->set_fit_column_to_table_size(  abap_true ).
*  lr_disp_settings->set_horizontal_lines(  abap_false ).
lr_disp_settings->set_vertical_lines(  abap_false ).

*... §3 Functions
*... §3.1 activate ALV generic Functions
* ボタン表示・使用有無等
DATA: lr_functions TYPE REF TO cl_salv_functions_list.
lr_functions = gr_table->get_functions(  ).
*  lr_functions->set_default( IF_SALV_C_BOOL_SAP=>TRUE ).
lr_functions->set_all(  if_salv_c_bool_sap=>true  ).
lr_functions->set_export_localfile( abap_false ).

** 項目全体の設定、特定項目の順番指定
*... set the columns technical
DATA: lr_columns TYPE REF TO cl_salv_columns_table.
lr_columns = gr_table->get_columns( ).
lr_columns->set_optimize( abap_true ).
lr_columns->set_column_position( columnname = 'DISMM'
                                                               position = 4 ).

DATA: itab_columns_info TYPE salv_t_column_ref.
itab_columns_info =  lr_columns->get( ).

* 項目ごとの設定
DATA: lr_column TYPE REF TO cl_salv_column_table.
TRY.
    lr_column ?= lr_columns->get_column( 'MANDT' ).
    lr_column->set_technical( if_salv_c_bool_sap=>true ).
  CATCH cx_salv_not_found.                              "#EC NO_HANDLER
ENDTRY.
TRY.
    lr_column ?= lr_columns->get_column( 'WERKS' ).
    lr_column->set_tooltip( 'TOOLTIPテスト' ).
    lr_column->set_key_presence_required( if_salv_c_bool_sap=>true  ).
  CATCH cx_salv_not_found.                              "#EC NO_HANDLER
ENDTRY.
TRY.
    lr_column ?= lr_columns->get_column( 'LVORM' ).
    lr_column->set_visible( if_salv_c_bool_sap=>false ).
  CATCH cx_salv_not_found.                              "#EC NO_HANDLER
ENDTRY.
* セルの色付け
DATA: ls_color TYPE lvc_s_colo.
TRY.
    lr_column ?= lr_columns->get_column( 'DISMM' ).
    ls_color-col = col_positive.
    ls_color-int = 0.
    ls_color-inv = 0.
    lr_column->set_color(  ls_color ).
  CATCH cx_salv_not_found.                              "#EC NO_HANDLER
ENDTRY.

* ソート
DATA: lr_sorts TYPE REF TO cl_salv_sorts.
lr_sorts = gr_table->get_sorts(  ).
lr_sorts->add_sort( columnname = 'MATNR'
                    subtotal = if_salv_c_bool_sap=>true
                    sequence = if_salv_c_sort=>sort_up ).

*... Display table
gr_table->display( ).
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/326392/4c67abd1-2480-480d-f4ca-c9520c2f4579.png)


まだイベントなども残っていますが、ボリュームが多すぎて調査が間に合わないので:sweat_smile:、今回はここまでにします。
別の記事にするか、この記事をアップデートするかで対応します。

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