【ABAP】Code push down実装編

##目的
[前回](https://qiita.com/tami/items/12bfdaae112965250b31)の記事で、Code push downを実現する方法としてOpen SQL, AMDP, CDSを紹介しました。
今回は実装編として、あるシナリオをOpen SQL, AMDP, CDSのそれぞれで実現してみます。

##シナリオ
入出庫伝票のテーブル(MATDOC)から、品目、プラント、保管場所ごとに数量をサマリして出力します。従来のABAPなら、一旦内部テーブルに取得してから移動タイプによってプラマイを判断して集計していたと思います。

MATDOCテーブル（MKPF, MSEGの後継）
<img width="241" alt="matdoc.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276021/c6822281-f0f1-40ed-9c6e-6e0ec740d93e.png">

###方針
SQLで貸借フラグが'S'だったらプラスの数量（入庫）、'H'だったらマイナスの数量として集計します。


##1. Open SQLによる実装

```abap
SELECT matnr, werks, lgort,
       SUM(
         CASE shkzg
           WHEN 'S' THEN ( menge * 1 )
           WHEN 'H' THEN ( menge * -1 )
           END
       ) AS menge
       FROM matdoc
       INTO TABLE @DATA(itab)
       GROUP BY matnr, werks, lgort.

 cl_demo_output=>display(
   EXPORTING
     data = itab
 ).
```

CASE文を使い、貸借フラグ(shkzg)によって数量をプラマイします。
さらにその結果をSUMで集計します。

###結果
正しく集計できています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276021/bb60d961-68f3-4018-bb85-d8ab8be3c0e6.png)

##2. AMDPによる実装
###2.1 AMDPクラスの実装
####クラス定義
```abap
CLASS zcl_mob58_amdp_test DEFINITION
  PUBLIC
  FINAL
  CREATE PUBLIC .

PUBLIC SECTION.
  INTERFACES if_amdp_marker_hdb.
  CLASS-METHODS get_matdoc EXPORTING VALUE(et_result) TYPE zoutput_t_matdoc.
PROTECTED SECTION.
PRIVATE SECTION.
ENDCLASS.
```

AMDPクラスを定義するときの決まりとして、インターフェースif_amdp_marker_hdbを使用します。

####メソッドの実装

```abap
CLASS zcl_mob58_amdp_test IMPLEMENTATION.
  METHOD get_matdoc BY DATABASE PROCEDURE FOR HDB LANGUAGE SQLSCRIPT OPTIONS READ-ONLY
  USING matdoc.

    et_result = SELECT matnr, werks, lgort,
       SUM(
         CASE shkzg
           WHEN 'S' THEN ( menge * 1 )
           WHEN 'H' THEN ( menge * -1 )
           END
       ) AS menge
       FROM matdoc
       GROUP BY matnr, werks, lgort;

  ENDMETHOD.

ENDCLASS.
```

AMDPのメソッドは宣言部分に特徴があります。

|宣言       |意味 |
|:-----------------|:------------------|
|by DATABASE PROCEDURE|AMDPメソッドであるという印 |
|FOR \<db_type>　       |データベースを指定           |
|LANGUAGE \<db_language> |データベースを操作する言語を指定|
|OPTIONS \<db_options> |オプションで、READ-ONLYを指定。指定しない場合は書き込みが可能になる   |
|USING \<db_entity> |SQL Scriptの中で使用するテーブルをすべて宣言する              |

AMDPのメソッドはSQLスクリプトで書きます。一見Open SQLとあまり違いがないですが、命令の終わりはセミコロン(;)で終わるなどのルールがあります。
SQLスクリプトのリファレンスは[こちら](https://help.sap.com/viewer/de2486ee947e43e684d39702027f8a94/2.0.02/en-US)

###2.2 AMDPクラスを呼び出す

```abap
zcl_mob58_amdp_test=>get_matdoc(
  IMPORTING
    et_result = data(et_result)
).

cl_demo_output=>display(
  EXPORTING
    data = et_result
).
```
###結果
上記のプログラムを実行すると、以下の結果になります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276021/980719bb-c33f-0582-71f7-86ec2fccbafe.png)

##3.CDSによる実装
CDSの登録は以下の手順で行います。
※CDSを実装するときはEclipse ADT(ABAP Development Tool)を使用します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276021/b299147c-6ffe-2a95-ac82-754a39937cf7.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276021/6345a3ae-4bd3-d940-01e4-caf8bd058bd1.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276021/62452b2e-06a5-5a7d-5c6f-13ab0b95262e.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276021/9156d857-f947-3eb0-a660-a7f20114c521.png)
ここでテンプレートを選択します。テンプレートに応じて下のプレビューにあるコードを自動生成してくれます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276021/63c18b4c-a4f5-72e7-97d7-953d03ca4cad.png)

以下のコードを書きます。

```abap
@AbapCatalog.sqlViewName: 'ZMOB58_TRAIN_01'
@AbapCatalog.compiler.compareFilter: true
@AbapCatalog.preserveKey: true
@AccessControl.authorizationCheck: #NOT_REQUIRED
@EndUserText.label: 'Basic CDS'
define view ZMOB58_CDS_TRAIN_01 as select from matdoc
{
  key matnr, 
  key werks, 
  key lgort,      
       sum(
         case shkzg
           when 'S' then ( menge * 1 )
           when 'H' then ( menge * -1 )
           end
       ) as menge
       
}group by matnr, werks, lgort
```

上の@から始まる部分はアノテーションと呼ばれます。目的によって必要なアノテーションを設定する必要があります。アノテーションの定義については[こちら](https://help.sap.com/doc/abapdocu_752_index_htm/7.52/en-us/abencds_annotations_abap_tables.htm#@@ITOC@@ABENCDS_ANNOTATIONS_ABAP_TABLES_2)を参照してください。

なお、最初MSEGを使ってビューを定義したところ、データが取得できませんでした。S/4になってからはMATDOCが入出庫伝票の正データなので、こちらを使用する必要があるようです。

###結果
有効化後、F8を押すとビューが実行されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276021/5be0f3b3-532a-b51c-0435-88186dbefd3c.png)

##まとめ
今回はOpen SQL, AMDP, CDSの実装方法に焦点を当てました。簡単にするため、SQLは全て同じにしました。AMDPならでは、CDSならではのできることがもっとあるので、それぞれの特徴が出るシナリオも考えてみたいと思います。