三崎レイナ
社会人1年目。新卒でITコンサルティングファームに就職。初配属がSAPプロジェクトにアサインされる。SAPがわからないことだらけで悩んでいたところ、会社の先輩にSAPラボの所長を紹介され、毎週末に所長とSAPのお勉強中!
博士
SAPラボの所長。SAP大好き博士!SAP導入プロジェクトを構想策定~運用保守まであらゆるフェーズを数多く経験。
いまは優しきおじいちゃんだが、プロマネバリバリの時代はかなり怖かったらしい。現在は引退し、SAPの後進育成と啓蒙活動に従事中!
登場人物紹介
三崎レイナ
社会人1年目。新卒でITコンサルティングファームに就職。初配属がSAPプロジェクトにアサインされる。SAPがわからないことだらけで悩んでいたところ、会社の先輩にSAPラボの所長を紹介され、毎週末に所長とSAPのお勉強中!
博士
SAPラボの所長。SAP大好き博士!SAP導入プロジェクトを構想策定~運用保守まであらゆるフェーズを数多く経験。
いまは優しきおじいちゃんだが、プロマネバリバリの時代はかなり怖かったらしい。現在は引退し、SAPの後進育成と啓蒙活動に従事中!
この記事を読むメリット
今回はABAPのデータ定義に焦点を当てて説明していくぞい!
データ定義はプログラムの基本となる要素で、プログラムがデータを理解して処理するための鍵なのじゃ。
データ定義を学ぶ上で、具体的にはデータ構造とデータ型について理解することが大事なのじゃ!
ABAPの基礎となる要素なんですね!
しっかり学んでいきます!よろしくお願いします!
新着のSAPフリーランス案件
【FI】
S/4HANAへのバージョンアップ支援(Jrコンサル可)
【PP】
メーカー向けSAP移行プロジェクト支援
【MM】
【SD】
製造業向けロジ領域の運用保守支援
【BASIS】
【MM】
【SD】
製造業向け運用保守支援支援
【CO】
【FI】
【MM】
【PP】
【SD】
大手メーカー社向けSAP導入支援
【FI】
商社向け基幹システムバージョン支援
【FI】
SAP運用業務支援
【FI】
SAP導入プロジェクト支援
【FI】
光学機器 S/4HANA導入テスト支援
【CO】
一般消費財メーカーS/4 HANAバージョンアップ
まずはデータ構造に焦点を当てるぞい。
データ構造の主な要素として、変数・構造・および内部テーブルがあるぞい。これらのデータオブジェクトを駆使して、データをより柔軟に取り扱うことが可能じゃ!
1、変数(Variable)
変数は単一のデータを格納するための入れ物で、1つの値(例:商品の名称、価格、数量)を表します。
2、構造(Structure)
構造は関連するデータを一つにまとめるための仕組みで、複数の変数を束ねて一つのデータオブジェクトを作ります(例: 一つの商品の名称、価格、数量)。ワークエリアや作業領域とも呼ばれることもあります。
3、内部テーブル(Internal Table)
内部テーブルは複数のデータをリストとして管理するための仕組みで、構造や変数をリスト化して一括で管理できます(例: 複数の商品情報を保持するリスト)。
※変数・構造・内部テーブルは「箱」のようなものでデータオブジェクトと呼びます。
※データオブジェクトの1つの項目のことをコンポーネントと呼びます。
まずはイメージ図を覚えるといいぞい。
これらのデータ構造の各要素が「どんな大きさか」や「文字列なのか数字なのか」など、どんなデータを持つかを指定するために使用されるのがデータ型じゃ!
データ型はプログラムを書く上での土台で、正しく理解して使うことが大切なのじゃ!
データ型を以下の3つに分けて説明するぞい!
SAPをインストールした際に事前に定義され、プログラム開発者が追加の定義を行わずに利用できる基本のデータ型です。これらのABAPデータ型はどのプログラムでも利用可能です。
事前定義のABAPデータ型を以下に記載するぞい。
データ型 | 意味 | 有効項目長 | 初期項目長 | 初期値 |
---|---|---|---|---|
数値データ型 | ||||
I | 整数 | 固定長(4バイト) | 4 | 0 |
F | 浮動小数点数 | 固定長(8バイト) | 8 | 0 |
P | パック数値 | 固定長(1~16バイト) | 8 | 0 |
文字データ型 | ||||
C | テキスト | 固定長(1~65535文字) | 1 | 空白 |
N | 数値テキスト | 固定長(1~65535文字) | 1 | 0埋め |
D | 日付 | 固定長(8文字) | 8 | 00000000 |
T | 時刻 | 固定長(6文字) | 6 | 000000 |
STRING | 文字列 | 可変長(文字列) | ‐ | 空白 |
XSTRING | X文字列 | 可変長(バイト文字列) | ‐ | 空白 |
16進データ型 | ||||
X | 16進項目 | 固定長(1~65535バイト) | 1 | X’00 |
データ宣言時のポイント
・I、F、D、T型:
詳細な技術属性(有効項目長、初期項目長、初期値)が全て定義されています。
・P、C、N、X型:
有効項目長が決まっていないため、DATA命令などで項目長を定義する必要があります。
上記の表の通りデータ型それぞれに「初期項目長」が定義されているので、項目長を設定しない場合は、「初期項目長」が自動的に設定されます。※P型の場合は項目長と小数点以下桁数を指定
・STRING、XSTRING型:
項目長が可変であるため、変数を宣言する際に特定の長さを指定する必要はありません。
プログラム実行時に値を割当てることで、動的に変化させることができます。
* 固定長での変数定義
DATA: lv_int TYPE I, " 整数型 (I型)
lv_pack TYPE P LENGTH 8 DECIMALS 2, " パック数値型 (P型)
lv_char TYPE C LENGTH 10. " テキスト型 (C型)
* 可変長での変数定義
DATA: lv_string TYPE STRING, " 可変長文字列型 (STRING型)
lv_xstring TYPE XSTRING. " バイナリデータ型 (XSTRING型)
DATA命令については後で詳しく説明するぞい!
ABAPディクショナリ(ABAP Dictionary、T-CODE:SE11)は、情報を一元的に管理するためのツールで、その一部としてABAPディクショナリデータ型が扱われます。開発者はこの機能を利用して、プログラム内のデータ型を定義できます。これらのデータ型はどのプログラムからでも呼び出し可能であり、データ型や桁数は参照元項目に準拠します。
* ABAPディクショナリデータ型を使用した変数を定義
DATA: lv_char_name TYPE char20, " char型変数、20文字
lv_char_description TYPE char50, " char型変数、50文字
lv_numc TYPE numc5. " char型変数、5桁
最初は理解は難しいかもしれんが、使いながら徐々に覚えていけば良いぞい。使っているうちに理解して使いこなせるようになるのじゃ!
プログラム開発者は、主にTYPES命令を使用してプログラム内でデータ型を定義できます。ただし、これらのデータ型は事前に定義されたABAPデータ型とは異なり、他のプログラムから参照して利用することはできません。
ユーザー定義のABAPデータ型(ローカルデータ型)は、変数・構造・内部テーブルのすべてのデータ型を宣言することができ、基本データ型・構造データ型・テーブルデータ型に分けられるぞい。各データ型で構文が異なる為、この流れでTYPES命令について主な構文を説明していくぞい!
構文
TYPES (データ型名) TYPE (データ型).
※データ型には1,事前定義のABAPデータ型または2,ABAPディクショナリデータ型を指定します。
* 基本データ型の定義(1,事前定義のABAPデータ型)
TYPES: ty_mfg_date TYPE D, " 製造日型のデータ型
ty_lot_number TYPE C LENGTH 15, " ロット番号型のデータ型
ty_phone_number TYPE STRING. " 電話番号型のデータ型
* 基本データ型の定義(2,ABAPディクショナリデータ型)
TYPES: ty_material TYPE MARA-MATNR, " MARAテーブルのMATNR項目に基づくデータ型
ty_customer TYPE KNA1-KUNNR. " KNA1テーブルのKUNNR項目に基づくデータ型
プログラム内でデータ型を使いまわす場合や、意味を持たせたい場合に使用するぞい!
もし使いまわす必要がない場合には後述のDATA命令だけでも事足りるぞい!
補足①:チェーン命令について
チェーン命令は同一の命令をまとめて記述することができ、コード全体がすっきりと見やすくなります。
ABAPのチェーン命令では、各命令の後に “:” を付け、命令が終わるごとに “,” を使用します。
最後の命令の後には必ずピリオドを付けます。
補足②:TYPES命令とTYPEオプションの違い
・TYPES命令:データ型を定義
・TYPEオプション:データ型を指定
構文
TYPES:
BEGIN OF (構造データ型名),
(項目名) TYPE (データ型),
(項目名) TYPE (データ型),
・・・・・・・
END OF (構造データ型名).
※「BEGIN OF」と「END OF」で開始と終わりを明確に指定します。
* 構造データ型の定義
TYPES: BEGIN OF ty_employee, " 従業員情報の構造データ型
employee_id TYPE I, " 従業員の一意の識別子(ID)
first_name TYPE STRING, " 従業員の名前
last_name TYPE STRING, " 従業員の姓
birthdate TYPE D, " 従業員の生年月日
END OF ty_employee.
「BEGIN OF」と「END OF」を書き忘れると、1,基本データ型を定義したこと同じになってしまうので、忘れないように注意するのじゃ!
構文
TYPES (データ型名) TYPE TABLE OF (構造データ型/DBテーブル).
※TYPEオプションの後に「TABLE OF」を記述します。
※DBテーブルはデータ型ではありませんが、SAPの仕様で構造データ型として使用可能です。
* テーブルデータ型の定義(2,構造データ型の使用例で定義した従業員情報の構造データ型を使用)
TYPES: ty_employee_table TYPE TABLE OF ty_employee.
TYPES命令の基本的な構文と使い方については以上じゃ。
データ型だけではプログラム内で実際に値を保持したり、処理したりすることはできないぞい。このデータ型を使用して変数・構造・内部テーブルを定義するのじゃ!
次は変数・構造・内部テーブルを定義するためのDATA命令について説明するぞい!
混乱しやすいTYPES命令とDATA命令の違い
・TYPES命令:変数/構造/内部テーブルの基となる新しい「データ型」を定義
・DATA命令:「データ型」を使用して変数/構造/内部テーブルを宣言
DATA型の構文は基本的には変数・構造・内部テーブルそれぞれ一緒に見えるが、使用するデータ型が異なるのじゃ!
構文
DATA (変数名) TYPE (データ型).
値の代入方法
(変数名) = 変数に格納するデータ.
* 基本データ型の定義(1,事前定義のABAPデータ型)
TYPES: ty_mfg_date TYPE D, " 製造日型のデータ型
ty_lot_number TYPE C LENGTH 15, " ロット番号型のデータ型
ty_phone_number TYPE STRING. " 電話番号型のデータ型
* 基本データ型の定義(2,ABAPディクショナリデータ型)
TYPES: ty_material TYPE MARA-MATNR, " MARAテーブルのMATNR項目に基づくデータ型
ty_customer TYPE KNA1-KUNNR. " KNA1テーブルのKUNNR項目に基づくデータ型
* DATA型で変数を定義
DATA: lv_mfg_date TYPE ty_mfg_date, " 製造日
lv_lot_number TYPE ty_lot_number, " ロット番号
lv_phone_number TYPE ty_phone_number, " 電話番号
lv_material TYPE ty_material, " 品目コード
lv_customer TYPE ty_customer. " 得意先コード
* 変数の使用例
lv_mfg_date = '20240401'. " 製造日の設定
lv_lot_number = 'L12345678901234'. " ロット番号の設定
lv_phone_number = '+1234567890'. " 電話番号の設定
lv_material = 'M000987654'. " 品目コードの設定
lv_customer = 'C000123456'. " 得意先コードの設定
* 変数の使用例を出力
WRITE: / '製造日:', lv_mfg_date,
/ 'ロット番号:', lv_lot_number,
/ '電話番号:', lv_phone_number,
/ '品目コード:', lv_material,
/ '得意先コード:', lv_customer.
実行したら以下の通り出力されました!
構文
DATA (構造名) TYPE (構造データ型/DBテーブル).
※DBテーブルはデータ型ではありませんが、SAPの仕様で構造データ型として使用可能です。
値の代入方法
(構造名)-(項目名) = 項目に格納するデータ.
* 構造データ型の定義
TYPES: BEGIN OF ty_employee,
employee_id TYPE I, " 従業員の一意の識別子(ID)
first_name TYPE STRING, " 従業員の名前
last_name TYPE STRING, " 従業員の姓
birthdate TYPE D, " 従業員の生年月日
END OF ty_employee.
* DATA型で構造を定義
DATA: ls_employee TYPE ty_employee.
* 構造の使用例(変数の設定)
ls_employee-employee_id = 1045. " 従業員IDの設定
ls_employee-first_name = '太郎'. " 名の設定
ls_employee-last_name = '山田'. " 姓の設定
ls_employee-birthdate = '19900316'. " 生年月日の設定
* 構造の使用例を出力
WRITE: / '従業員ID:', ls_employee-employee_id NO-GROUPING,
'名前:', ls_employee-last_name && ls_employee-first_name,
'生年月日:', ls_employee-birthdate.
実行したら以下の通り出力されるぞい!
構文
①DATA (内部テーブル名) TYPE (テーブルデータ).
②DATA (内部テーブル名) TYPE TABLE OF (構造データ型/DBテーブル).
※DBテーブルはデータ型ではありませんが、SAPの仕様で構造データ型として使用可能です。
※内部テーブルには複数の種類があり、上記はよく使われる標準テーブルを定義しています。
値の代入方法
※同じ型の構造を使用する
* 構造データ型の定義
TYPES: BEGIN OF ty_employee,
employee_id TYPE I, " 従業員の一意の識別子(ID)
first_name TYPE STRING, " 従業員の名前
last_name TYPE STRING, " 従業員の姓
birthdate TYPE D, " 従業員の生年月日
END OF ty_employee.
* テーブルデータ型の定義
TYPES: ty_employee_table TYPE TABLE OF ty_employee.
* 構造の宣言
DATA: ls_employee TYPE ty_employee.
* 内部テーブルの宣言
DATA: lt_employee_tab TYPE ty_employee_table.
" テーブルデータ型を使用して従業員情報を追加
ls_employee-employee_id = 1045. " 従業員1の情報を設定
ls_employee-first_name = '太郎'.
ls_employee-last_name = '山田'.
ls_employee-birthdate = '19900316'.
APPEND ls_employee TO lt_employee_tab.
ls_employee-employee_id = 1046. " 従業員2の情報を設定
ls_employee-first_name = '花子'.
ls_employee-last_name = '山田'.
ls_employee-birthdate = '19950128'.
APPEND ls_employee TO lt_employee_tab.
" テーブル内のデータ表示
LOOP AT lt_employee_tab INTO ls_employee.
WRITE: / '従業員ID:', ls_employee-employee_id NO-GROUPING,
'名前:', ls_employee-last_name && ls_employee-first_name,
'生年月日:', ls_employee-birthdate.
ENDLOOP.
2、構造の結果と同じ型で2名分の情報が出力されました!
APPEND命令やLOOP~ENDLOOP命令、WRITE命令についても別の記事で説明するぞい!
次に定数の宣言について説明するぞい!
定数はプログラム中で変えることのできない定まった値のことじゃ。定数を使用することで可読性と保守性が向上するぞい。
CONSTANTS命令で定数を定義することが可能じゃ!
構文
CONSTANTS (項目名) TYPE (データ型) VALUE (初期値).
※構文としてはDATA命令と一緒ですが、宣言時にVALUEオプションを利用して「初期値」を指定する必要があります。
* 定数の定義
CONSTANTS: c_discount_rate TYPE P DECIMALS 2 VALUE '0.15', " 割引率(15%)
c_percentage_value TYPE P VALUE '100'. " パーセンテージ変換用(100)
* データ宣言
DATA: lv_price TYPE P DECIMALS 2, " 商品価格
lv_discount_rate TYPE P, " 割引率(%)
lv_discount TYPE P DECIMALS 2. " 割引額
* 商品価格と割引の計算
lv_price = '150.00'. "商品価格に150を代入
lv_discount_rate = c_discount_rate * c_percentage_value.
lv_discount = lv_price * c_discount_rate.
* 結果の表示
WRITE: / '商品価格:', lv_price,
/ '割引率:', lv_discount_rate, '%',
/ '割引額:', lv_discount.
実行したら以下の通り出力されました!
次はフィールドシンボルを説明していくぞい!変数・構造・内部テーブルは物理的なメモリを確保しているが、フィールドシンボルは実体を持たない仮置き場のようなものじゃ!プログラム実行時に設定した変数・構造・内部テーブルのメモリ領域を割り当てることができ、直接参照することができるのじゃ。使用例を見た方がイメージしやすいぞい!
構文
FIELD-SYMBOLS <(フィールドシンボル名)> TYPE (データ型).
※フィールドシンボル名は<>で囲む必要があります。
※データ型を指定しない場合は「ANY」で宣言することができます。
割り当ての構文一例
①ASSIGN (データオブジェクト名) TO <(フィールドシンボル名)>.
②LOOP AT (内部テーブル名) ASSIGNING <(フィールドシンボル名)>. ~ ENDLOOP.
DATA: gv_string TYPE string VALUE 'Hello'.
FIELD-SYMBOLS: <fs_any> TYPE ANY.
" フィールドシンボルに文字列型変数の値を入力
ASSIGN gv_string TO <fs_any>.
" フィールドシンボルの値をWRITE
WRITE: / 'String value (Field Symbol):', <fs_any>.
" フィールドシンボルの値を変更し、本体側に反映
<fs_any> = 'New String'.
" 文字列型変数の値を表示
WRITE: / 'String value (Original):', gv_string.
実行したら以下のように出力されました!
1つ目のWRITE文では<fs_any>に割り当てられたgv_stringの値がそのまま出力されていますね!
その後<fs_any>の値の変更を介して、gv_stringも値が変更され、2つ目のWRITE文ではその変更が反映されたgv_stringの値が出力されているのですね!
その通りじゃ!
フィールドシンボルは割り当てられたデータオブジェクトを参照していると同時に、フィールドシンボルに何かしら処理を行った場合、その処理が自動的にデータオブジェクトにも反映されるのが利点じゃ!
その他にも作業領域の確保が不要なため、メモリ消費を削減でき、構造を使う通常のLOOPより処理速度が速くなるのじゃ!
選択画面(プログラムを実行するときに実行条件を入力したり選択する画面)からデータオブジェクトを作成することも可能だぞい!
最後に選択画面を作成するのに使用されるPARAMETERS命令とSELECT-OPTIONS命令を説明するぞい!
PARAMETERS命令は選択画面に1つの入力フィールドを作成することが可能じゃ!
構文
PARAMETERS (オブジェクト名) TYPE (データ型) (オプション).
※オブジェクト名は8文字までです。
※項目名を画面では日本語などで表示したい場合は、「ジャンプメニュー」→「テキストエレメント」→「選択テキスト」から設定が可能です。
PARAMETERS p_name TYPE string DEFAULT 'World'.
WRITE: / 'Hello', p_name, '! Welcome to the Greeting Program!'.
上記の使用例そのままでプログラムを作成して実行してみると下記のように出力されるぞい!
これが簡単な選択画面じゃ!この「World」を自分の名前に置き換えて「実行」ボタンを押下してみるのじゃ!
実行したら以下のように選択画面で入力した名前が出力されました!
SELECT-OPTIONS命令は開始(From)と終了(To)の値を指定する入力フィールドを作成することが可能じゃ!
今回は詳しく説明しないが、ここで入力した内容はレンジテーブルという内部テーブルに格納されるぞい!
構文
SELSECT-OPTIONS (オブジェクト名) FOR (変数).
※特徴としてはTYPEオプションではなくFORを使用することです。
※項目名を画面では日本語などで表示したい場合は、「ジャンプメニュー」→「テキストエレメント」→「選択テキスト」から設定が可能です。
TABLES: mara. " MARAテーブルを使用することを宣言
SELECT-OPTIONS: s_mat FOR mara-matnr, " 品目コードの範囲を持つ選択肢
s_lmd FOR mara-laeda. " 最終変更日付の範囲を持つ選択肢
START-OF-SELECTION.
SELECT * FROM mara
WHERE matnr IN s_mat " 選択された品目コードの範囲内にあるレコードを選択
AND laeda IN s_lmd. " 選択された最終変更日付の範囲内にあるレコードを選択
WRITE: / mara-matnr, mara-laeda, mara-mtart. " 選択されたレコードの情報を表示
ENDSELECT.
上記の使用例そのままでプログラムを作成して実行してみると下記のように出力されるぞい!
PARAMETERS命令と同じように選択画面が出力されるぞい!各項目に対して入力欄が2つ設けられているのじゃ。
これらの欄に適当な値を入れて実行してみるのじゃ!
実行したら以下のように選択画面で入力した品目コードと最終変更日に該当するデータが出力されました!
選択画面の
今回はデータ定義についての概要やデータ宣言する各種命令の基本的な使い方を説明したぞい!
今回説明した以外にも使用方法やオプションなど様々使い方があるので、基本に慣れてきたころに説明するぞい!
データ定義や宣言の方法についてイメージが出来ました!プログラムを組んでいく中でより理解を深めていきます!
新着のSAPフリーランス案件
【FI】
S/4HANAへのバージョンアップ支援(Jrコンサル可)
【PP】
メーカー向けSAP移行プロジェクト支援
【MM】
【SD】
製造業向けロジ領域の運用保守支援
【BASIS】
【MM】
【SD】
製造業向け運用保守支援支援
【CO】
【FI】
【MM】
【PP】
【SD】
大手メーカー社向けSAP導入支援
【FI】
商社向け基幹システムバージョン支援
【FI】
SAP運用業務支援
【FI】
SAP導入プロジェクト支援
【FI】
光学機器 S/4HANA導入テスト支援
【CO】
一般消費財メーカーS/4 HANAバージョンアップ
SAPラボでは、SAPの知識を活かして副業をしたい方を募集してるのじゃ!
SAPラボのライターの特徴
・ライティング初心者OK!
・報酬高単価!
・業務委託契約なので副業として最適!
SAP記事執筆者としての活動実績として利用可能なので、転職時や案件探しの際に企業へのアピール材料にもなります。
募集要項
・SAP導入や運用保守プロジェクトへの参画経験1年以上
ご応募/お問合せ先
info@sap-labo.com
少しでもご興味ある方、ぜひお気軽にご連絡下さい!
新卒でSAPエンジニアとしてABAPでの新規開発や保守業務を担当。
業務内容としてはロジ系(MM/SD)がメインで、ABAPの開発が最も得意。