2020年1月23日の午後、日本アイ・ビー・エム(株)箱崎事業所においてiBIアライアンス主催の第3回勉強会が開催されました。今回の勉強会は、まず初出席者のためのレベル合わせ及び前回までの復習を兼ねた簡単な復習講義の後、IBM i Access Client Solutions(以下ACSと略記)情報の再確認、ILE RPG及びSQLの活用法に関する新規の話題紹介と解説、最後に全体を通してのQ&Aという構成で進められました。復習講義の内容については第1回および第2回iBI勉強会レポートをご覧いただくことにして、当レポートではACS情報の再確認、ILE RPG及びSQLの活用法に関する新規の話題について当日紹介された内容をiWorld編集部が独自解説いたします。
情報の再確認
ACS(5733-XJ1)は2019年4月30日でサポートが終了したIBM i Access for Windows(5733-XE1)の後継となるIBM i Accessファミリーの製品になります。Windows 7/8だけでしか利用可能でなかったIBM i Access for Windowsに対し、Javaで実装されているACSはWindowsの他にMac、Linuxでも利用可能なマルチプラットフォーム対応の製品になっています。IBM i Access for Windows自身のサポートが終了している事に加え、Windows 7のサポートも2020年1月14日に終了したため、現在ACSへの切り替えが緊急の課題になっています。
ACS利用の前提条件
ACSを使用するためには、クライアントPC及びIBM iにそれぞれ以下のようなソフトウェアが必要になります。【クライアント側】
- OSとしてWindows、Mac、LinuxなどJavaが稼働する環境
- Javaバージョン8.0以上(注)
【IBM i側】
- IBM i 5.4以上
- ホストサーバー(SS1:Option12)
- TCP/IPユーティリティ(TC1)
- IBM i Accessファミリー・ライセンス(XW1: BASEおよび1)
ACSの入手および導入方法
ACSを入手するには、ESS(Entitled Software Support)サイトまたはACS_Webサイトのいずれかにアクセスし、IBM IDでサイン・インして必要なパッケージをダウンロードします。ACSを使用するには、ダウンロードしたパッケージを解凍(unzip)してインストール用のスクリプトを実行してACSを導入する方法と、導入作業を行わずに解凍したフォルダー内のjarファイルを直接起動する方法の2通りの方法があります。
ACSでサポートされない機能
IBM i Access for Windowsで提供されていた機能の中には、表1に示すようにACSではサポートされていない機能がいくつかあります。これらの機能を使用している場合には、表1に示すように別途回避策が必要になりますので移行に際しては注意が必要です。なお、懸案だったGraphics Device Interface (GDI)については、ACSのバージョン1.1.8.0以降これと同等の印刷機能がJava Print Service (JPS)によってサポートされるようになっています。
ACSでサポートされない機能 | 代替策 |
---|---|
データ転送Excelアドイン | クティブ・スプレッドシートへの入出力機能で代替する |
System i ナビゲーター | Navigator for iで代替する |
RUNRMTCMDによるWindowsプログラムの実行 | SSHを使用する |
5250接続中のPCスリープ回避 | スリープをオフにする。または十分に長い時間を設定する |
▲表1.ACSでサポートされない機能とその代替策
ACSについてはiWorldコラムの『【どうする5250】第1回 IBM I Access Cient Solutions』および『【どうする5250】第1回 IBM I Access Cient Solutions(ACS)1.1.8印刷機能の拡張』でも取り上げていますので、そちらも是非参考にしてください。
(注)
ご存知のように、商用利用におけるOracle Java SE 8無償サポートは2019年1月にサポート終了になっています。これに対し、ACSで使用するJDKとして何を選択するべきかについてのQ&AがIBMサイトに掲載されています。ユーザー企業各社で対応法に関する考え方はまちまちだと思われますが、上記Q&Aを参考に適切な方法を選択してください。
ILE RPGとSQLの有効活用
ILE RPGの活用
ILE RPGには多くの利点がありますが、最も簡単にその利点を活かすことができるのは、ILE RPGが提供する組み込み関数を活用することでしょう。組み込み関数を使うことで、複雑なアルゴリズムをプログラマー自身が考えてコーディングする必要がなくなると同時に、プログラムも簡潔で理解し易いものにすることができるというメリットがあります(例えば、以前の勉強会で紹介された日付計算など)。
今回の勉強会では、
- 命令の実行結果の状況を知るための組み込み関数
- 数値編集のための組み込み関数
- 数値計算のための組み込み関数
命令の実行結果の状況を取得する組み込み関数と利用例
表2のような命令の実行結果の状況を取得する組み込み関数を利用することで、標識の利用を減らすことができます。たとえば、図1のような標識を使った伝統的なRPGⅢプログラムを図2のようなILE RPGプログラムに書き換えることができます。
組み込み関数名 | 機能の概要 |
---|---|
%EOF | 直近の入出力命令の結果が、ファイルの終わり条件または先頭条件の場合’1’を返し、そうでない場合’0’を返す。 |
%EQUAL | SETLL命令で引数に一致するレコードが存在する場合’1’を返す。 LOOKUP命令で引数に一致する要素が見つかった場合’1’を返す。 |
%ERROR | 直近の拡張’E’が指定された命令の実行結果がエラーの場合’1’を返す。 |
%FOUND | 直近の命令で検索対象のレコードまたは文字列が見つかった場合’1’が、そうでない場合’0’を返す。 |
▲表2.命令の実行結果の状況を取得する組み込み関数
▲図1. 標識を使ったプログラム例
▲図2. 組み込み関数を使って標識の使用を回避したプログラム例
熟練のRPGプログラマーにとって標識の取り扱いは慣れたものかもしれません。しかし、ご存知のように演算命令のどのカラムに標識が定義されているかでその意味が違ってきますが、ソースコード上でそのカラム位置を即座に判別するのは容易ではありません。これはプログラムの理解し易さという観点で好ましいことではありませんし、RPG入門者にとって標識はRPGを取っ付き難い言語にする存在であることも事実です。図1と図2を見比べれば、どちらが理解し易いかは一目瞭然でしょう。
また、プログラムサイズが大きくなると標識が不足するなどの問題もあります。実際、本来は1本のプログラムで処理したいにもかかわらず標識の数が足りないために、プログラムを仕方なく分割したという事例すらあります。
こうしたことを考えると、標識を使う代わりにILE RPGの組み込み関数を使って構造化された演算ロジックを組み立てることのメリットは大きいと言えるでしょう。
数値編集のための組み込み関数と利用例
編集コードおよび編集語は印刷ファイル(または印刷出力)や表示装置ファイルでおなじみですが、表3に示した組み込み関数は数字フィールドを編集された文字フィールドに変換するためのものです。この命令はブラウザーのような出力先に対して予めRPG側で編集された文字列を送信するプログラムを書く場合に重宝します。これらの関数の使用法は図3に示す通りです。
組み込み関数名 | 機能の概要 |
---|---|
%EDITC | パラメータで指定した編集コードの形式でデータを編集する。 |
%EDITW | パラメータで指定した編集語の形式でデータを編集する。 |
▲表3. 数値編集のための組み込み関数
▲図3.%EDITCと%EDITWの使用例
数値計算用の関数と利用例
数値計算用の組み込み関数を表4に、その使用法を図4~図7に示します。%SQRT以外は自分でサブルーチンを作成して機能を実現することも可能ですが、組み込み関数の場合、図4の例のように組み込み関数の変数として式を代入でき、プログラムの可読性が高くなるというメリットがあります。
組み込み関数名 | 機能の概要 |
---|---|
%ABS | 式の絶対値を返す |
%REM | 整数同士の割り算の剰余を返す |
%SQRT | 式の平方根を返す(機能はSQRT命令と同じ) |
%UNS | 式の値を符号なし形式に変換する。小数点以下の値は切り捨てられる |
▲表4.数値計算用の関数
▲図4. %ABSの使用例
▲図5. %REMの使用例
▲図6. %SQRTの使用例
▲図7. %UNSの使用例
SQLの活用
今回のテーマは「論理ファイルをSQLで書き換える」ということで、実例を使ってアプリケーションでよく使われそうな様々なパターンの論理ファイルをSQL文でどのように置き換えればよいか解説が行われました。
例えば、図3のようなDDSで定義される論理ファイルは、図4のようなSQL文で置き換えることができます。
▲図8.論理ファイルの例
▲図9.図3の論理ファイルと等価なSQL文
図9の例で示したように、DDSにおける選択条件をSQL文のWHERE句で記述し、論理ファイルのキー項目はORDER BY句で記述することで、ほとんどの論理ファイルはSQL文で置き換えることが可能です。例外は図10に示すような、1つの論理ファイル中に複数のレコード様式を持ついわゆる複数様式論理ファイルと呼ばれるもので、これをSQL文で実現することはできません。なぜなら、SQLではテーブルやビューが複数のレコード様式を持つことを許していないからです。
複数様式論理ファイルのように、1つのファイル中のレコードが複数の異なるレコードを持つという考え方は現代のデータベース設計ではあり得ないものですが、このようなファイルは、50年程前に作られたS/3時代のパンチカード処理を前提としたプログラムをそのまま移植して使用できるようにするためのものであり、現在も複数様式論理ファイルを使っているケースは稀だと考えてよいでしょう。
ところで、複数様式論理ファイルに似たものに図11に示す結合論理ファイルがありますが、こちらは複数の物理ファイルをあたかも1つのファイルであるかのように扱うためのものであり、SQLにおける自然結合に相当します。したがって、これは図12に示すようにSQL文で置き換えることができます。
▲図10. 複数様式論理ファイルの例(SQLで等価なものは作れない)
▲図11. 結合論理ファイルの例
▲図12. 図11の結合論理ファイルと等価なSQL文
このように、論理ファイルをSQLで置き換えるメリットとしては、パフォーマンスの向上とシステム負荷の低減の二つがあげられます。
論理ファイルを使ったレコード単位のアクセスに比べSQLの方がデータアクセスは高速であり、レコード件数が増える程その差は幾何級数的に大きくなることが様々なパフォーマンステストでも明らかになっています。
また、論理ファイルを作成するとベースとなる物理ファイルに対する変更(追加、更新、削除)が発生するたびにアクセスパスの更新も同時に行われるというのがデフォルトの設定であるため、一般に論理ファイルの数が多くなると、その存在そのものが恒常的にシステム負荷を高めることに繋がります。これに対して、SQLは実行時の負荷はそれなりに高いものの、使用していないときにはシステムに負荷をかけることはありません。
Q&A
最後に全体を通してのQ&Aでは次のような質疑応答がありました。
Q:
ILE RPGには所謂RPGⅣレベルのILE化から全ソースコード自由形式というレベルのILE化まで幅があるが、どのレベルのILE化を目指すべきでしょうか?
A:
どのレベルのILE化を行うのが適切かはお客様の環境によって異なるので、一概にこのレベルのILE化を目指すべきであると答えるのは難しいが、一般論としてはRPGⅢを長く使用してきたユーザーには、RPGⅣレベルのILE化でC仕様書の部分だけ自由形式を採用するのが移行しやすいと思われます。JavaやCなどの言語に馴染んできたユーザーには全ソースコード自由形式の方が学習し易いと思われるし、立命館大学の例でもそのことは実証されています。
おわりに
第1回の勉強会でも紹介されたように、CVTRPGSRCというコマンドで容易にRPGⅢからILE RPG(RPGⅣ)へのソースコードの変換が行えます。この変換されたソースコードをベースに、今回紹介された組み込み関数を使ってプログラムロジック部分を適宜書き換えるだけでもILE RPGのメリットを享受することができますし、このレベルのILE化であれば、これまでのRPGⅢのスキルを十分活用することができます。ILE化と言ってもこの勉強会でお勧めしているものは決して敷居の高いものではありません。
ただし、SEUやPDMの開発は既に終了しているため、新たにILE RPGで強化された機能はSEUやPDMでは認識できずにエラーチェックに引っ掛ってしまいます。RPGⅢからILE RPGに移行してその機能をフルに活用するためには、SEUやPDMに代わってIBM Rational Developer for i(RDi)を使う必要があることに注意してください。
また、SQLについてはパフォーマンス上のメリットはもちろんですが、今後データベース関連の機能強化はSQLを中心に行われる流れになっていることも考え合わせると、伝統的なレコード単位の処理からSQLによる処理に移行することを検討するべきでしょう。
いずれにせよ、古くからIBM i 関連に携わられている代表的な開発会社が集まって、FF-RPGや脱DDSのSQLインターフェースの勉強会をしているというのは、IBM iによるOSSの使い方研究をしているOSS協議会と並び、注目に値する取り組みと言えるでしょう。この3回の勉強会レポートを通じて皆様のRPGアプリケーション刷新の参考になれば幸いです。
//php get_template_part('content', 'policy'); ?>