ABAPを思い出す(基本編)

Javaでお仕事できる！　はずが再びABAPを触ることになりました。

2ヶ月もABAPコード書いてないから、そりゃ忘れるよね。
備忘録。(備忘できているとは言っていない)

今度はR/3らしい。2025年問題。というかS/4しか触ったことないのですが…。

ABAP環境を再現するのは大変なので、基本文字だけです。
読みづらいと思います。ごめんなさい。でも、私は悪くないよねぇ？

用語など
・標準
　SAP標準、SAP社が提供するリソース(プログラム、テーブル)

・アドオン
　業務要件に合わせた追加開発(ADD-ON)
　SE38、SE11、SE91、SE24、SE37、SE01(09？)、SE80、SE16、SE16N、SM30、SM10、SE30

・PAI(Process After Input)
　画面上の機能を選択すると動く処理。PAIイベント。

・PBO(Process Before Output)
　PAIイベントの後に動く処理。PBOイベント。

・FM(FunctionModule)
　海外フォーラムでよく使われる略称。
　汎用モジュール、汎モ、汎用Modなどが日本では略称として使われてる気がする。
　SE37

・BAPI(Business Application Programming Interface)
　バピ、バッピなど。
　実態としてはFMです。FMと違うところは、これを使うことで外部から標準画面と同等の更新処理等を行えること。たとえば、Excel VBAからBAPIを呼び出して更新、など。
　SAPは、標準画面でデータを更新すると、裏で関連するテーブルすべてを更新します。
　なので、標準テーブルに対しCRUDのCUD処理を行うようなSQLを発行することは推奨されません。(Rは、テーブル構成/依存度を知っているのであれば好きにしたら良いです)
　標準テーブルを更新する際は、**「原則」**対応するBAPIを使うべきです。
　(原則なので、業務要件によっては例外もあり得ます)
　SE37

・トランザクションコード
　Tr-CD、TrCD、TCD、トランなどの略称。
　画面名(暴論)。このコードを、SAPメニューの上部にあるコマンド欄(正式名称なんていうのでしょうね？)に入力押下することで、該当画面へ遷移できる。べんり。
　このコードを知らなくても、SAPメニューからTreeを辿ることでもいける。めんどう。

・トランザクション割り当て
　作成したレポートプログラム、DYNPROに対してトランザクションコードを設定すること。
　SE93

・バリアント
　画面に入力された値を保存し、保存したバリアントを呼び出すことで再展開できる。
　レポートプログラムで、選択画面はなんでも入力OKにしておいて、実際にトラン割り当てる際に、特定の値で固定しておくなどの使い方。

・トラバリ
　トランザクションバリアント。
　標準画面の一部項目を隠したり、変更できなくしたり、初期値を設定したりできる。
　SHD0/SHD1

・環境
　一般的なシステム開発における環境とは意味が違うかも。
　開発環境(Development)、検証環境(Quality Control？)、本番環境(Production)のこと。
　開発環境でアドオン開発し、それを検証環境でテスト、問題がなければ本番環境へ適用する。
　いわゆる、3システムランドスケープ構成です。

・クライアント
　Clt、clが略称。
　1つの環境に対し、N個のクライアントが作成できます。
　SAPのデータ(テーブルレコードや、プログラムなど)はそれぞれ、クライアント依存とクライアント非依存のものがあります。
　クライアント依存は、該当クライアントにしか存在しないデータです。テーブルレコードなどです。
　それに対し、クライアント非依存のデータは、環境に依存するデータです。
　ですので、開発環境にクライアントがA、B、Cの3つある場合、非依存データをクライアントCに追加すると、クライアントA、Bにも同様のデータが作成されます。
　プログラムなどが該当します。

・移送
　データを、別の環境(クライアント)へ適用させること。
　基本的には、環境間への適用に対して使用される用語です。
　もちろん、クライアント依存データのものを別クライアントに適用させる場合にも使用されます。

・F1ヘルプ
　キーボードのF1キーを押下することで表示されるヘルプ。開発者向け。
　カーソルが合わせされている項目の属性などを閲覧できる。べんり。

・F3
　前画面へ戻るショトカキー。

・F4ヘルプ
　キーボードのF4キーを押下することで表示されるヘルプ。利用者向け。
　カーソルが合わせられている項目に入力できる値の一覧などを閲覧できる。
　FMを用いることで、自作することもできる。

・F8
　プログラム実行のショトカキー。

・F9
　バックグラウンド実行登録のショトカキー。

・F11
　画面を終了する感じのショトカキー。
　~~正直F3との違いがよくわかってない~~

# ABAPの基礎

## ABAPって、なぁーに？
Advanced Business Application Programmingの略称。
単に「ABAP(あばっぷ)」とだけ覚えていたら十分です。
受験したことないですが、もしかしたらSAPベンダー試験で出るかも。知らないけど。

一応、オブジェクト指向言語。なので、Classの概念そのものはある。
でも、それを有効活用した記憶がない。
というかR/3だと普通に構造化プログラミング言語な気がする。どーなんだろ。

## テーブルって、なぁーに？
ABAPを取り扱う上で「テーブル」は複数の意味がある。
・標準テーブル
・アドオンテーブル
・内部テーブル

### 標準テーブル
標準テーブルとは、SAPパッケージ標準で用意された、RDBテーブルのこと。
例：BKPF、BSEG、COBK、COEP、他COVPなどのビュー
(R/3だとACDOCAないのでしたっけ…FAGLLFLEXAとかかなぁ。というか次はPSじゃっけ…)

### アドオンテーブル
アドオンテーブルとは、SAP標準だと業務要件が満たせない場合、それを補うために新規に作成するテーブルのこと。(アドオン…追加開発)
大体、ZとかXとかY始まりのテーブル名になるはず。
ZVBAKなら、標準テーブル：VBAKの補助的なテーブルの意味合い。
実際は、上記のようなアドオンテーブルは作成されないと思う。
標準テーブルには拡張項目が事前に用意されているはずなので、VBAKに補助項目が必要な場合、そこに追加するケースが多いのかなぁ。
拡張項目を使うは使うで色々と面倒なのですけどね。Exitとか、BadIとか、暗黙のcommitとか…。

### 内部テーブル
内部テーブルとは、ABAPプログラムの内部で使用されるテーブル。
Listとか、配列とか、大体そんな感じ。

内部テーブルは3種類に分けられる。
・STANDARD TABLE(標準テーブル)
・SORTED TABLE(ソートテーブル)
・HASH TABLE(ハッシュテーブル)

#### STANDARD TABLE(標準テーブル)
STANDARD TABLEは特筆することはないです。
SORTやDELETEしない限り、内部の順序は保証されます。LinkedListみたいな。

#### SORTED TABLE(ソートテーブル)
SORTED TABLEは、事前に設定したキーで、自動的にSORTされるテーブル。
STANDARD TABLEと比較すると、制約は多いものの、テーブル走査の速度が速い。
ABAPは全体的に遅いので、こういう小さな積み重ねが重要。
※SELECT時にPROJ-PSPNRとPROJ-POSIDを同時に取得するように意識するとか。そんな感じ。

#### HASH TABLE(ハッシュテーブル)
HASH TABLEは、SORTED TABLEよりさらに速い。
どのぐらい速いかは使ったことがないので知りませんが。
ただ、かなり取り扱いづらいらしい。
少し間違えると、すぐショートダンプ(実行時エラー、ABEND)する諸刃の剣とか。
基本はSORTED TABLEで十分。たぶん。

## プログラムの種類って、いくつあるの？
REPORT、BatchInput、DYNPROを知っていたらいいです。

### REPORT(レポート)プログラム
帳票プログラム。だとそのままですね。

ABAPに、「これはレポートプログラムです」と教えてあげると、必要な画面情報などを自動的に生成してくれます。やさしい。

第1画面に、ユーザに入力させるパラメータ領域を用意した選択画面。
そこからプログラムを実行することで、第2画面である結果画面へ遷移という使い方が主でしょう。
SAP標準のものですと、第1画面なしでいきなりプログラムが実行される、というものもあります。
そういったものをアドオンすることはあまりない気はしますが。

そこから派生して、第1画面に指定された内容でデータを抽出、第2画面でその一覧を出力、そしてその一覧の中から一部(あるいは、すべて)を選択し更新処理を行うなど、ある程度の自由度はあります。
ただ、自動生成される都合上、UI(項目の配置位置)はあまり融通が利かないです。
頑張れば(SELECTION-SCREEN…だっけ)多少はいけますが、そこまでするコストと比較すると良いです。
あと、そこまでしてもどうにもならないことも多々ありますので。

#### おまけ(帳票)
ABAP、というかSAPにおける帳票は種類があります。
・ABAP一覧
・ALV一覧
・SmartForm(SVF)

##### ABAP一覧
単に、画面に処理結果を出すというだけのもの。
通常の夜間バッチ用の更新系プログラムだと、この形式が多いのかもしれません。

##### ALVリスト
出力形式を指定する必要はありますが、Excelのような表形式で一覧出力できます。
FMを3つぐらい経由しなきゃなので、使うまでがやや面倒です。
ですので、3つのFMをラップしたアドオンFMを作る方が、開発者にとってはやりやすいかも。まぁ、プロジェクト規則次第ですね、結局のところ。

##### SmartForm(SVF)
対外用の帳票出力を行うためのツール(機能)、でしょうか。
SmartFormはかなり使いづらいと個人的には思います。その分、自由度はかなり高いようですが。
SVFはSAPではなく、Java経由で触ったことがありますが、とても扱いやすかった印象です。
タブ区切り形式のファイルを読んで、それを必要な個所に当てはめて出力する、という動きだったはずです。

### BatchInput
簡単にいうと、Excelのマクロ記録機能です。
BatchInput記録機能(SHDB)を起動している状態で、標準画面(アドオン画面でもOK)に必要な項目を入力すると、どの項目にどのような値が入力されたのか、その操作が記録されます。
その内容を基に、CALL TRANSACTION命令を実行することで、その動きを再現できます。
定型的な業務(所定のフォーマットで入力されたExcelファイルより、SAPへ転記する等)や、データ移行等が主な使用方法です。
基本、標準画面に対して使われる(BatchInputする)ことが多いでしょう。

### DYNPRO
自分自身の手で、画面を手作りする。
それこそ、入力領域の位置から、ボタン配置など。すべて。

自由度の高さの極致であるとともに、難易度(≒コスト)もすさまじいです。
DYNPROを使うぐらいなら、別の代替案を検討する方が建設的です。
(トラバリとか)

そもそもSAPはパッケージシステムなのですから、DYNPROを要するような業務要件が出た段階で、相手とHANASHIAIして、業務フローを見直していただくよう"説得"するべきです。私コンサルじゃないので知りませんけど。
とはいえ、どうにもならないこともあります。その時は潔く諦めて苦死みましょ。

## ABAPディクショナリって、なぁーに？
Tr-CD：SE11より起動される、そのシステムで管理するディクショナリオブジェクトを管理する機能です。
DicObjとは、となると多岐にわたります。
・テーブル(標準テーブル、アドオンテーブル)
・データ型(構造、テーブルデータ型、エレメント、データ型グループ)
・ドメイン
・検索ヘルプ
・ロックオブジェクト

データ型グループは使ったことがないので、よくわからないです。

#### 補足(構造、テーブル、データ型、エレメント、ドメインの関係性)
図にするとたぶんこんな感じ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/584615/eda120ba-99b5-5c71-8fa7-9f484e97312a.png)

クラス図なのでちょっとあれですが。

1つのテーブルは、N個のデータ型、N個の構造を持つ。
1つのテーブルデータ型は、1個の構造を持つ。
1つの構造は、N個のデータ型を持つ。(列)
1つのデータ型は、1個のエレメントを持つ。
1つのエレメントは、1個のドメインを持つ。
そして、1つのドメインは1つのプリミティブ型を持つ。
オブジェクト指向だ！！！

### テーブル(標準テーブル、アドオンテーブル)
標準テーブル・アドオンテーブルがどのような列(データ型)を持つか定義、確認できる。
標準テーブルの定義は、変更禁止です。原則。
Map<列番号, 列名>
Integer 列番号
Object 列名　←　データ型or構造

### データ型(構造、テーブルデータ型、エレメント、データ型グループ)
テーブルの項目として使用されるのが主ですが、それぞれ単体としても使用できます。

### ドメイン
エレメントに使用されます。

### 検索ヘルプ
F4ヘルプを定義できます。
こっちはオブジェクトなので、再利用が容易です。

### ロックオブジェクト
アドオンテーブルに対して、テーブルロックを行うためのオブジェクトのことです。
ロックオブジェクトを作成すると、対応したENQUE_XXXXとDEQUE_XXXXのFMが生成されます。
レポートプログラムなどで上記FMを呼び出すことで、テーブルロックのON/OFFを実現しているのです。

## イベント
各イベントがトリガされることで、そのブロック(SECTION)に記述されたコードが実行されます。

- INITIALIZATION …… 変数の初期化などを行う。でも、グローバル変数きらい。
- AT SELECTION-SCREEN …… 画面に入力された値の妥当性をチェックしたりとか。
- START-OF-SELECTION …… 主処理を書きましょう。
- END-OF-SELECTION …… 後処理を書きましょう。リスト出力とか。

INITIALIZATIONは、画面展開時に1回だけトリガされます。
AT SELECTION-SCREENは、Enter押下などのPAIイベントでトリガされます。
START-OF-SELECTIONは、プログラム実行時にトリガされます。(必然的に、AT SELECTION-SCREENもトリガされる)
END-OF-SELECTIONは、START-OF-SELECTIONの処理終了後にトリガされます。

他にも、AT SELECTION-SCREEN ON VALUE-REQUEST(F4押下時)など色々あります。

# おわり
基本編はとりあえずこのぐらいにしておきます。長い。
ALEとかIDocとか、もう少し触れたいものもあるのですが、書き始めるとキリがないのです。

~~さてRubyで遊んじゃおーっと~~