対象: IBM i(AS/400)上でのRPGプログラムの本番運用
基本文法は RPG 文法基礎、モジュール化は RPG モジュール設計 を参照
COBOL版は COBOL 本番運用 を参照
目次
1. 開発環境と本番環境の違い
開発環境(PUB400等) 本番環境(顧客のAS/400)
────────────────────────── ──────────────────────────
ライブラリ = 個人用 ライブラリ = 本番/開発/テスト分離
ファイル = テスト用少量データ ファイル = 数百万〜数千万レコード
実行 = CALL で直接 実行 = ジョブキューに投入
印刷 = スプールで確認 印刷 = 実プリンタに出力
セキュリティ = *PGMR権限 セキュリティ = オブジェクト権限管理
バックアップ = なし バックアップ = 日次/週次 SAVLIB
本番のライブラリ構成(典型例)
PRODLIB — 本番プログラム(*PGM, *SRVPGM)
PRODDATA — 本番データ(物理ファイル)
DEVLIB — 開発用プログラム
DEVDATA — 開発用データ
TSTLIB — テスト用プログラム
TSTDATA — テスト用データ
QGPL — 共有オブジェクト(使用注意)
2. 帳票出力(PRTF)
AS/400の帳票はPRTF(印刷ファイル)で定義する。COBOLのFD + O仕様書に相当。
PRTF定義(DDS)
A R HDRREC SKIPB(1)
A SPACEA(1)
A RPTDATE 10A 2 2COLHDG('印刷日')
A RPTTITLE 40A 2 20COLHDG('タイトル')
A PAGENO 4S 0 2 70COLHDG('頁')
A EDTCDE(Z)
A R DTLREC SPACEA(1)
A CUSTID 8A 1 2COLHDG('得意先CD')
A CUSTNM 30A 1 12COLHDG('得意先名')
A AMOUNT 11P 2 1 45COLHDG('金額')
A EDTCDE(J)
A R TOTALREC SPACEB(2)
A TOTALAMT 13P 2 1 45COLHDG('合計')
A EDTCDE(J)
RPGからの帳票出力
dcl-f RPTPRT printer(*ext) oflind(overflow);
dcl-s overflow ind;
dcl-s pageNo packed(4:0) inz(1);
// ヘッダ出力
rptDate = %char(%date());
rptTitle = '得意先別売上一覧';
pageno = 1;
write HDRREC;
// 明細ループ
read CUSTFILE;
dow not %eof(CUSTFILE);
// オーバーフロー(ページ送り)
if overflow;
pageNo += 1;
write HDRREC;
overflow = *off;
endif;
write DTLREC;
read CUSTFILE;
enddo;
// 合計出力
write TOTALREC;
モダナイゼーションへの示唆
帳票出力はPDF生成ライブラリ(iText、QuestPDF等)に変換する。PRTFのレコード形式(HDRREC/DTLREC/TOTALREC)がPDFのテンプレートセクションに対応。overflow(ページ送り)はPDFの改ページに変換。
3. 画面プログラム(DSPF)
5250端末の画面はDSPF(画面ファイル)で定義する。Angular UIに変換する対象。
DSPF定義(DDS)の基本
A DSPSIZ(24 80)
A R SELSCR
A 1 2'得意先照会'
A CUSTID 8A B 3 2COLHDG('得意先CD')
A ACTION 1A B 3 15COLHDG('処理')
A VALUES('1' '2' '3')
A ERRMSG 40A O 23 2DSPATR(RI)
A R DTLSCR
A D_CUSTID 8A O 3 2
A D_CUSTNM 30A O 3 12
A D_ADDR 50A O 5 2
A D_BAL 11Y 2O 7 2EDTCDE(J)
RPGでの画面操作
dcl-f CUSTDSP workstn(*ext) usage(*input:*output);
// 画面表示&入力待ち
exfmt SELSCR;
// ファンクションキー判定
if *inkc; // F3 = 終了
*inlr = *on;
return;
endif;
if *inkd; // F4 = リスト表示
exsr showList;
endif;
5250画面 → Angular UIへの変換マッピング
| 5250(DSPF) | Angular | 備考 |
|---|---|---|
R SELSCR レコード形式 | コンポーネント | 1画面 = 1コンポーネント |
B(入出力フィールド) | <input> / <mat-form-field> | 入力項目 |
O(出力フィールド) | {{ value }} / テキスト | 表示項目 |
VALUES('1' '2') | <mat-select> / バリデーション | 選択肢制約 |
DSPATR(RI) リバースイメージ | CSS class(エラースタイル) | エラーメッセージ |
EXFMT | HTTP POST → レスポンス表示 | リクエスト/レスポンス |
| F3キー | 「戻る」ボタン / ルーティング | ナビゲーション |
| F4キー | 検索ダイアログ | ルックアップ |
| サブファイル(SFL) | <mat-table> / データグリッド | 一覧表示 |
4. トランザクション処理
ジャーナリング(AS/400のトランザクションログ)
ジャーナル = トランザクションログ
ジャーナル構成:
QSQJRN(ジャーナル)
└─ QSQJRN0001(ジャーナルレシーバー) ← 実データが入る
ファイルにジャーナリングを開始:
STRJRNPF FILE(MYLIB/CUSTPF) JRN(MYLIB/QSQJRN)
COMMIT / ROLLBACK
ctl-opt dftactgrp(*no) actgrp(*caller) commit(*yes);
dcl-f ORDHDR disk(*ext) usage(*output) keyed commit;
dcl-f ORDDTL disk(*ext) usage(*output) commit;
// ヘッダ書込
write ORDHDRF ordHdrRec;
// 明細書込
for i = 1 to lineCount;
write ORDDTLF ordDtlRec(i);
endfor;
// 全て成功したらコミット
if noErrors;
commit;
else;
rolbk; // ロールバック
endif;
5. エラー処理とリカバリ
プログラム内エラーハンドリング
// MONITOR(try-catch相当)
monitor;
result = dividend / divisor;
on-error;
result = 0;
errMsg = 'ゼロ除算エラー';
endmon;
// ファイルI/Oエラー
chain custId CUSTFILE;
if %error;
errMsg = 'ファイルアクセスエラー';
endif;
ジョブログとメッセージ
// メッセージ送信(ジョブログに記録)
dcl-pr sendPgmMsg extpgm('QMHSNDPM');
msgId char(7) const;
msgFile char(20) const;
msgData char(256) const;
msgDtaL int(10) const;
msgType char(10) const;
callStkE char(10) const;
callStkC int(10) const;
msgKey char(4);
errorDs likeds(errDs);
end-pr;
異常終了コード
| コード | 意味 | 対処 |
|---|---|---|
| CPF0000 | 汎用エスケープメッセージ | MONMSG で捕捉 |
| CPF4131 | ファイルメンバが見つからない | ファイル存在チェック |
| CPF5027 | ファイルがロックされている | リトライ or 待機 |
| MCH1211 | ゼロ除算 | MONITOR で捕捉 |
| RPG0000 | RPG実行時エラー | ジョブログ確認 |
6. CL(ジョブ制御言語)
RPGプログラムの実行を制御する「シェルスクリプト」。バッチジョブはCLから起動される。
日次バッチCLの典型例
PGM
/* ジョブログ設定 */
CHGJOB LOG(4 00 *SECLVL) LOGCLPGM(*YES)
/* ライブラリリストの設定 */
ADDLIBLE LIB(PRODLIB) POSITION(*FIRST)
ADDLIBLE LIB(PRODDATA)
/* ファイルのオーバーライド */
OVRDBF FILE(CUSTFILE) TOFILE(PRODDATA/CUSTPF) SHARE(*YES)
/* 1. 受注データ取込 */
CALL PGM(PRODLIB/ORD001R)
MONMSG MSGID(CPF0000) EXEC(GOTO CMDLBL(ERROR))
/* 2. 在庫引当処理 */
CALL PGM(PRODLIB/INV001R)
MONMSG MSGID(CPF0000) EXEC(GOTO CMDLBL(ERROR))
/* 3. 出荷指図作成 */
CALL PGM(PRODLIB/SHP001R)
MONMSG MSGID(CPF0000) EXEC(GOTO CMDLBL(ERROR))
/* 4. 帳票出力 */
CALL PGM(PRODLIB/RPT001R)
/* 正常終了 */
SNDMSG MSG('日次バッチ正常終了') TOUSR(QSYSOPR)
GOTO CMDLBL(ENDPGM)
/* エラー処理 */
ERROR:
SNDMSG MSG('日次バッチ異常終了') TOUSR(QSYSOPR)
ENDPGM:
DLTOVR FILE(*ALL)
ENDPGM
CL主要コマンド
| コマンド | 意味 | モダナイゼーションでの対応 |
|---|---|---|
CALL PGM() | プログラム実行 | Cloud Workflows のステップ |
SBMJOB | ジョブをキューに投入 | Pub/Sub メッセージ発行 |
MONMSG | エラー捕捉 | try-catch / エラーハンドリング |
OVRDBF | ファイルのオーバーライド | 環境変数 / 設定ファイル |
ADDLIBLE | ライブラリリスト追加 | search_path / スキーマ切替 |
SNDMSG | メッセージ送信 | Slack通知 / Cloud Logging |
DLYJOB | ジョブ遅延(待機) | sleep / Workflows の wait |
CHGVAR | 変数変更 | 変数代入 |
AI解析でのCLの重要性
CLプログラムから抽出すべき情報:
CALLの順序 → JOBネットワーク(実行依存関係グラフ)OVRDBF→ 実行時のDB接続先切替(環境依存の特定)SBMJOB→ 非同期ジョブの投入パターン(並列処理の特定)MONMSG→ エラーハンドリング構造ADDLIBLE→ ライブラリリスト構成(本番/テスト環境の判別)
7. ジョブ管理とスケジューリング
ジョブの種類
対話型ジョブ(QINTER)
= 5250端末からのオンライン操作
→ モダナイゼーション: Webアプリ(Angular + .NET API)
バッチジョブ(QBATCH)
= ジョブキューに投入して実行
→ モダナイゼーション: Cloud Workflows / Cloud Scheduler
即時実行ジョブ
= SBMJOB で即座に投入
→ モダナイゼーション: Pub/Sub + Cloud Run
ジョブスケジューリング
// 毎日 22:00 に日次バッチを実行
ADDJOBSCDE JOB(NIGHTBATCH)
CMD(CALL PGM(PRODLIB/DAILYBAT))
FRQ(*WEEKLY)
SCDDATE(*NONE)
SCDDAY(*ALL)
SCDTIME('220000')
→ モダナイゼーション: Cloud Scheduler → Pub/Sub → Cloud Workflows
ジョブキュー
ジョブキュー(JOBQ)
QBATCH — 標準バッチ(優先度50)
QNIGHTQ — 夜間バッチ(優先度30)
QPRIORQ — 優先バッチ(優先度10)
→ モダナイゼーション: Pub/Sub のトピック分割で優先度制御
8. 本番運用の設計パターン
パターン1: チェックポイント / リスタート
大量データのバッチ処理で、途中で失敗しても再開できるようにする。
dcl-s checkpoint packed(10:0);
dcl-s processedCount packed(10:0) inz(0);
// 前回のチェックポイントを読む
exec sql
SELECT LAST_KEY INTO :checkpoint
FROM BATCHCTL
WHERE JOBNAME = 'INV001R';
// チェックポイント以降から処理再開
setgt checkpoint ORDFILE;
read ORDFILE;
dow not %eof(ORDFILE);
// 処理...
processedCount += 1;
// 100件ごとにチェックポイント保存
if %rem(processedCount : 100) = 0;
exec sql
UPDATE BATCHCTL
SET LAST_KEY = :currentKey, PROCESSED = :processedCount
WHERE JOBNAME = 'INV001R';
commit;
endif;
read ORDFILE;
enddo;
→ モダナイゼーション: Cloud SQL のバッチ制御テーブル + Workflows の retry
パターン2: マスタ・トランザクション分離
マスタファイル(参照頻度高、更新頻度低)
CUSTPF(得意先)、ITMPF(商品)、WHSPF(倉庫)
→ Cloud SQL の READ REPLICA で読取負荷分散
トランザクションファイル(更新頻度高)
ORDHDR/ORDDTL(受注)、SHPPF(出荷)、INVTRN(在庫移動)
→ Cloud SQL のプライマリで書込
履歴ファイル(追記のみ、削除なし)
ORDHST(受注履歴)、INVHST(在庫履歴)
→ BigQuery にストリーミングで蓄積 → AI分析の入力データ
パターン3: 世代管理
日次バッチの前後でファイルのバックアップを取る:
CPYF FROMFILE(PRODDATA/INVPF) TOFILE(PRODDATA/INVPF_BK) MBROPT(*REPLACE)
CALL PGM(PRODLIB/INV001R) // 在庫引当バッチ
// 異常発生時 → INVPF_BK から復元
→ モダナイゼーション: Cloud SQL のポイントインタイムリカバリ
関連記事
- COBOL 本番運用 — COBOL の対応する本番運用ガイド
- RPG 文法基礎 — RPG IV の基本文法リファレンス
- RPG モジュール設計 — サブルーチンとモジュール化
- RPG 業務ロジック実装 — 業務システムの設計パターン