IBM i 基礎理解からRPG開発までの学習ステップ
- 第4回:ILE RPG開発について①( ILE RPGとは、プログラム作成の基本 C仕様書・D仕様書 ) -
はじめに
松田:「IBM i のプログラミング言語としてはRPG、CL、SQL、COBOLが多く利用されています。CLは、 IBM i 上でバッチ処理やジョブ制御を行うための高水準プログラミング言語です。オープン系の方々にとってはUNIX/Linux におけるシェルスクリプトに相当するプログラム言語といえます。RPGやCOBOLは業務プログラムに使用されることが多いのが特徴です。その中でも多くの企業で、RPGプログラムが利用されています。」
渡邊:「RPGはどのような言語なのでしょうか?」
松田:「RPGは、IBM i 専用のプログラム言語で、「Report Program Generator」の略称です。当初は、名前の通り報告書を作るための簡易言語として発表されたのですが、その後拡張が続けられ、業務システムとして必要なデータベース処理、帳票処理、画面処理、バッチ処理を作成できます。ちなみに、RPG言語に世代の概念があるのをご存知でしょうか?」
渡邊:「RPGⅢとRPGⅣがあるのは知っています。」
松田:「はい、そうです。現在のIBM i の最新IBM i バージョン 7.6においても、RPGⅢ、RPGⅣともにサポートされているんですよ。RPGⅢについては、 2008 年を最後に以降の機能強化はありません。現在の RPG の機能強化は ILE RPG(RPGⅣ) のみを対象にしています。2つの違いについても、解説しますね。」
渡邊:「すごいですね。過去の資産が使い続けられるのですね!RPGⅣとILE RPGって何か違うのですか?」
松田:「どちらも同じものです。RPG世代を意識した呼び方が RPGⅣ、プログラム構造を意識した呼び方がILE RPGです。ILE RPGには初期の固定フォームのILE RPGと、2013 年に登場した機能強化版としてのフリーフォームのILE RPGがあります。」
渡邊:「なるほど、フリーフォームのRPGもILE RPGなのですね。勉強になりました。ILE RPGは次々と進化を遂げているのですね。」
松田:「そうなんです。RPG 言語はレガシーと言われることもありますが、実態としては現在も多くのお客様が基幹業務のプログラムとして使っていらっしゃるケースが多いです。RPG言語を学ぶことは現在でも重要ですのでしっかり学んでいきましょう!」
渡邊:「はい、業務用のプログラムを作れるようになりたいので、楽しみです。」
松田:「まず、RPGのコーディングでは、プログラムを構成する要素を、ロジック、入力データ、データベース・ファイルなどの 7種類に分類し、単一の文書の中で、それぞれの行を独自の仕様に基づいて記述してゆくことで RPG プログラムができあがります。ここで各仕様に基づいて記述された行のかたまりを「仕様書」と呼んでいます。後ほど詳細に説明しますが、例えばファイル仕様書では、このプログラムで使用するDB等のファイルを指定したり、演算仕様書では、DBを読取って計算したりしますね。」
渡邊:「処理の種類ごとに仕様書があるのですね、それは見た目も分かりやすくなりそうですね。具体的にはどのように書いていくのですか?」
松田:「今回は古い方の RPG、すなわち固定フォーム ILE RPGについて説明します。なお、固定フォームは、各桁数に記載する内容が決まっています。全仕様書共通の記入項目を説明しますね。以下の図にあるように、1-5桁目は行番号で、IBM i 上のエディタであるSEU(Source Entry Utility )を使ってILE RPGの仕様書を入力する時に、行番号が振られます。6桁目に仕様書コード(7 種類ある仕様書のタイプを表す 1 文字のアルファベット)を入力します。ファイル仕様書であればFを入力します。7-80桁は各仕様書で記載内容が変わりますが、7桁目に*(アスタリスク)を入れると、その行はコメント行となります。81~100桁はコメント行になります。」
渡邊:「なるほど、通常1桁目から入力しそうなものですが、開発者がコーディングする時は6桁目から入力するのですね。まず、6桁目に仕様書コードを書き入れるところからスタートですね。」
RPGⅢとILE RPGの違い
渡邊:「RPGⅢとILE RPGにはどのような違いがあるのでしょうか。」
松田:「実は、仕様書、命令文をはじめ多くの違いがありますが、技術的に最も大きな相違はプログラム構造が変わったことでした。構造的観点でいうと、RPGⅢと ILE RPG(RPGⅣ)はそれぞれ OPMとILE と呼ばれています。OPMはコンパイルすると実行コードが生成されるのに対して、ILE ではコンパイルによってモジュールが生成され、それをバインド(Windows でいうとリンクに相当)することで実行コードが生成されます。つまり、このILEの構造は現代のオープン系コンパイラ言語と同様になっています。
RPG を含む IBM i の言語モデル自体がオープン化していることがわかると思います。さらに FF RPG に進化することによって、RPG言語構文のオープン化が図られているといえます。
さらに、他のプログラムを呼び出す際に、OPM だと動的リンクを前提にするため、パフォーマンス維持の観点からモノリシック(一枚岩的)プログラムになる傾向があるのに対して、ILE は静的リンクを前提にするためモジュール構造化できる、といった違いが出てきます。これはプログラムの保守性に影響を与えます。
さらに、構文的観点に着目すると、先ほど説明したように、ILE RPGは100桁ですが、RPGⅢは80桁でした。桁数が増えた分、ファイル名の長さが8桁から10桁になっています。以下は、RPGⅢと固定フォーム ILE RPGの違いを大まかにまとめたものです。演算命令も桁数が増えた分、分かりやすく記載できるようになり、拡張されています。モダナイゼーションとしては、欠かせないAPIやJSONにも対応しました。」
渡邊:「なるほど、他のシステムとの連携の主流となっているAPIにも、ILE RPGから対応したのですね。フリーフォームにもとても興味があります。もともと私がオープン系出身なので、固定フォームは抵抗がありますね。」
松田:「確かにその通りですよね。ただ日本のユーザーの間におけるシェアを調べてみると、固定フォームの方がより大きいんです。ですので FF RPG の説明は後日するとして、今回は固定フォームのILE RPGを対象として、詳しく説明していきます。開発環境も前回ご説明したPDM(Program Development Manager)を使います。固定フォームの場合、RDi(Rational Developper for i)でも対応可能ですね。一方フリーフォームの場合は、RDiかVS Code(Visual Studio Code)が可能です。RDiとAPIについては、以下の記事をご覧ください。」
「RPG開発者のためのIBM i モダナイゼーション入門!RDi とWeb APIで新しい開発の世界を楽しもう - 第 1 回 -」
https://www.e-bellnet.com/category/knowledges/doc/2502-01.php
ILE RPG言語の仕様書について
松田:「先ほど少し触れましたが、RPGのソースを作る際は、仕様書に従って作成する必要があります。ILE RPGの仕様書は以下の通りです。記載の順序も以下の通り決まっていて、必要のない仕様書は省略できます。」
渡邊:「色々な仕様書があるのですね。各仕様書はどのように呼ぶのですか?」
松田:「例えば、プログラムの内容を記述する演算仕様書は、C仕様書と呼びます。他の仕様書も同様に、F仕様書やD仕様書と呼びますね。それぞれの仕様書毎に記載する内容の桁数が決まっています。例として、一番よく利用するC仕様書のレイアウトを見てみましょう。以下のように、先ほどお話しした仕様書コードは6桁目で、『C』が入ります。また、演算の命令は26~35桁目に入りますよ。」
渡邊:「演算項目2は、2種類あるのですね。」
松田:「そうなんです。SEUの設定により、通常は演算項目2は、36~49桁目ですが、設定を変えると、36~80桁まで広げることができます。後ほど出てきますが、計算式を入れるとき等は便利です。広げない場合は一覧表には記載されていませんが、実は77~80桁も存在します。ですが、ユーザーが入力することはできません。」
松田:「実際のSEU画面でC仕様書を見てみましょう。このプログラムにおける0011行目のコマンドでは、CAT(concatenate から来ている)すなわち文字列を連結するコマンドで、変数名 WORK1(演算項目 1)の文字列の後に WORK2(演算項目 2)文字列を連結し、その結果を WORK3(結果フィールド)文字列に格納しています。以下の正しいパターンを見ると、5行目以降は、行により入力内容が違いますが、桁位置が揃っています。例えば、11行目の項目1(演算項目1)に入っている【WORK1】は12桁目から始まっており、先ほどお見せしたレイアウトとも合っていますね。一方で誤ったパターンを見ると【WORK1】が本来【*ENTRY】の下にあるべきですが、左にずれてしまっており正しい位置にないのでプロンプト画面と11行目が反転し、下部にエラーが出ています。」
渡邊:「1行入力するごとに、エラーが出るのですか?」
松田:「そうです。1行入力するごとに桁位置をチェックしてくれて、エラーの場合は反転になり、コンパイルまで進めません。だからこそ、桁位置を正しく入力することが重要なんです。」
SEUの操作手順については、以下リンクの前回記事に添付されている「SEU操作手順.pdf」をご覧ください。
https://www.e-bellnet.com/category/knowledges/doc/2603-01.php
渡邊:「とはいえ、仕様書毎にこのような書式があると思うと、大変ですね。」
松田:「いえいえ、SEU 起動時に何(RPGⅢ・固定フォーム ILE RPG のソースメンバー、物理ファイル、論理ファイルなど)を作成しようとしているのかを指定すれば、それに合致した桁位置チェック機能が働き、さらにSEU画面でF4キーを押して表示されるプロンプトやF1キーで表示されるヘルプを使って容易に入力していけますよ。」
渡邊:「なるほど。便利機能も充実してるのですね。」
<前回復習>ILE RPGソースファイル作成・メンバー追加
渡邊:「前回までは、物理ファイルを例に挙げてソースファイルを作成し、実際のデータ更新まで行いました。確かプログラムもソースファイルを作成して、メンバーを追加するところまでは同じ手順でしたよね。」
松田:「その通りです!早速メンバーを追加するところまでやってみましょう。」
渡邊:「まずは枠となるソースファイルだけ作成しました。」
コマンド:
CRTSRCPF FILE(SAMPLE1/QRPGLESRC) RCDLEN(112) IGCDTA(*YES) TEXT('RPGLEソースファイル')
松田:「コマンドのポイントとして、レコード長(RCDLEN)はILE RPGの場合は『112』にします。また、DBCSデータ(IGCDTA)は2バイト文字の入力を可能にするため『YES』でしたね。メンバー(MBR)については任意の名前で後から追加できるので、ソースファイル作成時はNONEのままで問題ありません。」
渡邊:「あれ、先ほどILE RPGは100桁とお聞きしましたが、レコード長(RCDLEN)は112なのですね。」
松田:「そうなんです。差分の12桁は、SEU が順序番号(行番号)と日付を管理するために使用します。」
渡邊:「理解できました。ファイルができあがっていることを確認しました。次はメンバー追加ですね。」
松田:「まずは、物理ファイルと同様に上記画面からソースファイル【QRPGLESRC】に対してOPTに『12』(12番は処理のオプション)を入れて実行キーを押し、さらに『F6』キーを押してください。そうすると、メンバーが追加できます。今回は、PGM1としましょう。ソース仕様タイプは任意ではなく、ILE RPG(固定フォーム ILE RPG と FF RPG のどちらの場合も)の場合は RPGLE とするルールですので、今回は『RPGLE』と入力します。テキスト内容は任意です。」
渡邊:「メンバー追加まで理解できました。早速コーディングに進みましょう!」
DSPLY命令のプログラム①(メッセージ表示)
※以降、入力の仕様上、一部の画像で順序番号(行番号)が見えていない画面があります。ご了承ください。
松田:「では始めに、画面にHELLOと表示してみましょう。C仕様書を使って、DSPLYという命令で表示します。」
渡邊:「C仕様書の行をプロンプトを出して追加したいときは、『IPC』と入力して実行キーですね。プロンプトが表示されました。」
松田:「項目1に『'HELLO'』を、演算命令に『DSPLY』を入力して実行キーを押します。ちなみに、『HELLO』のように文字定数や文字列定数を表現する際には必ずシングルクォーテーション('')で変数の前後を括る必要があります。」
渡邊:「はい、実行しました。1行目として表示されています。」
松田:「つづけましょう。プログラムを終了する時のお作法として、演算命令には『SETON』を、HIには『LR』を入力して実行キーを押してください。その次の行に演算命令に『RETURN』を入れて実行キーを押してください。」
渡邊:「入力しました。これで完了ですね。」
松田:「はい、そうです。保存してコンパイルしてみましょう。保存するには『F3』キーを押し、終了してください。」
渡邊:「『F3』キーを押しました。メンバーの変更/作成がYになっています。実行キーを押します。」
渡邊:「入力しました。これで完了ですね。」
松田:「はい。先ほど『F6キー』を押してメンバー追加を行ったPDMの画面に戻りましたね。(もし、戻らない場合は、コマンド『WRKOBJPDM LIB(SAMPLE1) OBJ(QRPGLESRC) OBJTYPE(*FILE) 』を入力、実行キーを押してPDMの画面を表示します。)ソースメンバー【PGM1】ができていますね。では、コンパイルする前に、コンパイルの設定を確認するために、『F18』キーを押しましょう。」
渡邊:「『F18』のキーは画面上に説明が見えませんがどの操作したら見えますか。」
松田:「『SHIFT』キー+『F12』キーを同時に押すことを2回繰り返してみてください。下のメニューに【F18=省略時値の変更】というメニューが表示されるかと思います。」
渡邊:「『F18』は『SHIFT』キー+『F6』でしたね。押すと、【省略時の値の変更】の画面が出ました。いくつかパラメーターがありますが、念のために確認しておきべきものは何ですか?」
松田:「バッチでコンパイルに着目しましょう。バッチでコンパイルが【Y】になっていると、コンパイルがバッチ処理で行われて、即時実行されません。【Y】になっている場合は、『N』に変更して、『F3』で終了しましょう。この設定は、変更しない限りその後も適用されます。よって、以降のプログラム作成時には、【省略時の値の変更】の操作は不要です。ちなみに、コンパイルが【N】になっている状態は直ちにコンパイルするように指示することになります。」
渡邊:「今回は【N】になっていたので、『F3』で終了します。」
松田:「それではいよいよコンパイルです。先ほど作成したソースメンバーのOPTに『14』を入れて(以下画面)、『F4』を押してください。」
渡邊:「CRTBNDRPGの画面が出ました。」
松田:「コンパイルして作成されるプログラムとライブラリー、またソースファイルとライブラリー、ソースメンバーの全ての名前を確認して実行キーを押しましょう。コンパイルが完了すると、プログラムとライブラリーで指定した内容で、RPGプログラムが作成されます。冒頭で、、ILE 言語モデルでは、コンパイルの後にバインド(リンク)を経ることで実行コードが生成されるとお伝えしましたが、実はコマンド【CRTBNDRPG】では、内部でコンパイルとリンクの両方の処理を一度に実行します。このため、ユーザーは個別にコマンドを入力する必要がなく、コマンドの完了後にはプログラムが出来上がっているという状況になります。」
渡邊:「なるほど、コマンド【CRTBNDRPG】は非常に便利なコマンドなのですね!確認して、実行キーを押しました。画面の下部にメッセージが表示されています。」
松田:「『F10』キーを2回押して、コマンド入力画面でこのメッセージの詳細を確認しましょう。」
渡邊:「コマンド入力画面に戻りました。先ほど表示されていたメッセージの続きが出ていますね。【プログラムPGM1がライブラリーSAMPLE1に入れられました。最高の重大度は00】と出ています。」
松田:「コンパイル成功です。【最高の重大度は00】の部分がポイントなのですが、詳細を確認してみましょう。『WRKJOB』を入力し、実行してください。」
渡邊:「【ジョブの処理】画面が表示されました。」
松田:「ここで、コマンド入力行に『4』を入れて実行しましょう。コンパイルの詳細な結果がスプールファイルに出力されています。」
渡邊:「入力しました。OPTに『5』を入れて表示で良いですか?」
松田:「そうです。スプールファイルの中身が表示されますね。これをコンパイルリストと呼びます。コンパイル時の詳細な情報が表示されるのですが、最終結果は最下部に表示されるので、制御に『B』を入れて実行を押してください。Bはボトムを意味しています。」
渡邊:「押しました、メッセージ合計が表示されています。」
松田:「そうです、コンパイルに対してのメッセージが表示されます。メッセージは00~99まであり、20以上が発生すると、エラーとなりコンパイルができません。先ほどの最高の重大度は00でしたね。このメッセージの中の一番高いものが00であったことを表示していました。」
渡邊:「なるほど、今回はコンパイルが成功したということですね。もしエラーが出たら、どのように対処するのですか。」
松田:「例としては、以下のような表示になることがあります。この例では、項目1に前後をシングルクォーテーションで括る『'HELLO'』と入力すべき所をシングルクォーテーションの括りなしで『HELLO』と入力してしまった時のコンパイル結果です。シングルクォーテーションで前後を括っていない場合だと、変数としての宣言が内ことになってしまいます。よって、重大度30以上のエラーが1つ出ていますね。」
松田:「少し上にスクロールするために制御に『-3』を入れると、3行上にスクロールします。メッセージの要約にエラーの内容が表示されます。この例では重大度(SV)が1行ですが、複数出ている場合は、重大度の高いものから対処します。理由として、重大度の高いエラーが原因となって、重大度が低いエラーも同時に引き起こされているケースが多いためです。次に、メッセージIDの7030を検索します。制御の欄の『-3』を消して、検索に『7030』を入れて、『F16』を押しましょう。」
渡邊:「エラーの具体的な内容が見えてきましたね。」
松田:「はい、【名前または標識がHELLOが定義されていない。】とあるので、HELLOが文字列ではなく、変数として認識されていることを示しています。このようにメッセージに沿ってプログラムが正しく入力されているかを確認していきます。SEUで修正後に改めてコンパイルして、コンパイルログ(コンパイル時に出力されるログ情報)の確認までをセットで実施しましょう。」
渡邊:「分かりました。ここまでが、プログラム作成からコンパイルまでの流れということですね。」
松田:「そうです。では実行してみましょう。コンパイルリストの画面で『F3』を押すことで、コマンド入力の画面に戻ります。コマンド入力行に『CALL』と入力してF4を押してください。」
渡邊:「プログラム呼び出しの画面が出ました。プログラムに『PGM1』、ライブラリーに『SAMPLE1』を入力して実行ですね。」
松田:「そうです。【DSPLY HELLO】と表示されましたね。この調子で続けてゆきましょう。」
MOVE命令のプログラム(D仕様書)
松田:「プログラムを使ってメッセージ表示ができるようになりましたね。先ほどのプログラムはあくまで文字の表示のみでしたが、次に作成するプログラムでは変数を扱っていきたいと思います。具体的には、MOVE命令を使って値を代入していきます。文字タイプの2つの変数にそれぞれテキストデータをMOVE命令で代入し、最終的には2つの変数を結合して画面上に表示させます。MOVE命令は基本的に文字の代入にのみ使います。数字の場合はEVAL命令や組み込み関数を使います。」
渡邊:「変数を使うということは、D仕様書を使うということですね。」
松田:「その通りです、早速作成してみましょう。」
渡邊:「まずは、ソースメンバーの追加を行い、SEU画面を開きました。画面右上を見ると、今回作成したプログラムが【PGM2】であることがわかります。ちなみに、プログラム名は作成者が任意で名前を付けます。」
松田:「最初にD仕様書で変数を宣言する必要があるので、『IPD』と入力してください。」
渡邊:「入力するとこの画面になりました。D仕様書のプロンプトが出ていますね。」
松田:「今回は2つの文字変数を設定します。1つ目は、5桁の文字変数であるWK1です。2つ目は、1桁の文字変数であるWK2です。早速、それぞれパラメーターに必要な値を入力していきます。設定を詳しく見ると、名前に『WK1』、宣言タイプには変数、配列、テーブルを定義することを示す『S』、長さは『5』、内部データ・タイプは文字型データのため『A』と設定します。続けて、WK2も同様に入力してみましょう。」
渡邊:「WK2の入力が完了しました。これでD仕様書は完了でしょうか。」
松田:「さらにもう一つWKという変数も設定していきます。WK1とWK2をつなげてメッセージを表示する際に登場します。桁は10桁で文字フィールドになります。」
渡邊:「これであっていますか?」
松田:「ばっちりです。これでD仕様書での変数宣言が完了しました。続いては、2つの変数に実際のデータを代入していきます。代入に使う命令文の1つが【MOVE】です。」
渡邊:「MOVE命令はC仕様書なので続いてC仕様書の入力ですね。」
松田:「そうです。演算命令に『MOVE』、項目2には演算対象となるデータを入れてください。今回は『TEST』と入力します。その際には文字なので''(シングルクォーテーション)でデータを囲むようにしましょう。また、D仕様書で宣言したWK1に『'TEST'』を代入していくイメージです。WK2には文字『'1'』を代入したいです。同じように入力してみてください。」
渡邊:「WK2に『'1'』をMOVE命令で代入しました。」
松田:「今回、WK1とWK2の内容を連結させてWKに代入したいです。連結の場合は先ほど説明したCAT命令を使用します。」
渡邊:「CAT命令でWK1とWK2の内容を連結し、WKに代入しました。」
松田:「その通りです!さらにメッセージ表示プログラムを見本に、WKをメッセージ表示してみましょう。」
渡邊:「DSPLY命令を使ってWKを表示するので、項目1に『WK』、演算命令には『DSPLY』ですね。」
松田:「プログラムを終了する時のお作法も忘れず入れておきましょう。」
渡邊:「はい、【PGM2】が完成しました。編集内容を保存し、【PGM2】のソースメンバーのOPTに『14』を入れて『F4』を押し実行です。このまま、コンパイルを行っていきます。」
渡邊:「コンパイル時のメッセージが出力されて、【最高の重大度は00】と表示されました。念のため、コンパイルリストも確認します。」
松田:「では、早速出来上がったプログラムを実行してみましょう。」
渡邊:「実行しました。【DSPLY TEST1】という結果が表示されていますね。期待通りの結果になっています。」
松田:「はい、これでD仕様書の使い方もばっちりですね!」
次回予告
松田:「次回は、RPGLE開発における第二弾としてファイルを読むプログラムを作成していきたいと思います。企業の基幹システムでは必須となるプログラムになりますので、しっかりと理解していきましょう!」
渡邊:「ファイルを読むということは新たな仕様書も登場しそうですね。知識が増えて書けるプログラムが増えるのは非常に嬉しいです。次回もよろしくお願いします!!」
次号へつづく
渡邊 隆
ベル・データ株式会社 アプリケーションマネージメントサービス本部 AMSデジタルイノベーション部
ネットワーク、オープン、セキュリティ、DX関連のプリセールス、構築、サポートを経て、現在はAMSデジタルイノベーション部に所属。工場DXソリューションを担当しながら、初挑戦のIBM i に格闘中。休日は、クラッシックピアノの練習や仲間との弾き合い会を楽しんでいます。
松田 三奈
ベル・データ株式会社 アプリケーションマネージメントサービス本部 AMSデジタルイノベーション部
新卒よりインフラエンジニアとしてPowerサーバーのリプレイスに従事し、現在はAMSデジタルイノベーション部に所属。休日は、カフェ巡りや旅行など天候に関わらず外に出てアクティブに活動することが好きです。
