2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

IBM (i) Bob RPGⅢプログラムをモダナイズしてみる ②5250対話型PGM→バッチ型変換

2
Last updated at Posted at 2026-02-28

1.バッチ型変換した後のプログラム概要

①5250対話型RPGⅢ→FFRPG変換で変換したFree-form RPGをさらにバッチ型プログラムに変換してみます。

image.png

5250対話型プログラムをバッチ型プログラムに変換する理由

5250画面は5250エミュレーター専用のU/Iです。これまでの社内ユース前提であれば課題は少ないのですが、
昨今のニーズとして
・さまざまなU/I・デバイス(スマフォ、タブレット、PCブラウザー、メッセージング、SNS、etc.)から同じ業務ロジックを利用したい
・サービス(REST APIなど)で同じ業務ロジックを利用したい

要望は多く聞かれます。
この際、一からプログラムを開発するよりも既存の5250対話型プログラムを利用したほうが効率が良い、というケースは多いと思います。

当記事のTips

・Bob(恐らくは他のAIでも)と相性がいい(エラーが少ない)のはFree-form RPG(固定長ソースは現状いろいろ手がかかる)
・超シンプルケース(DB参照のみ)だが対話型→バッチ型のロジック変換はほぼ問題無くできた。
・呼出しパラメーターの桁長のミス、FF RPGのMainプロシージャー宣言が生成されなかった、という変換ミス?があって修正した

変換元のソースは何を選択すべきか?

前記事ではRPGⅢソースコードをFF RPGソースコードに変換しました。別な方法としては固定ILE RPGソースコードに変換することも出来ると思います。

image.png

現時点でさほど多くの検証はしていませんが、個人的な推奨としては、IBM Bob(やその他の生成AI)と相性がいいのは(誤変換などなく運用できるのは)FF RPGである、 と思います。固定フォームのRPG(RPGⅢ、固定フォームIEL RPG)はFF RPG変換では問題とならない、桁位置固定であるがゆえの変換エラーがいつくか見られるようです。

なので今回は①の記事で変換したFF RPGをバッチ型に変換してみます。

1.5250対話型FF RPGのソースコード確認

前記事で生成したソースをそのまま利用します。

**FREE

// IPH110 * 得意先照会 (Customer Inquiry)
// Converted from RPG III to Free-form RPG

Ctl-Opt DftActGrp(*No) ActGrp(*New) Option(*SrcStmt:*NoDebugIO);

// File Declarations
Dcl-F IPH110S WorkStn IndDs(Indicators);
Dcl-F TOKMSL01 Keyed Usage(*Input) ExtDesc('TOKMSL01');

// Indicator Data Structure
Dcl-Ds Indicators;
  Exit Ind Pos(3);
  NotFound Ind Pos(30);
End-Ds;

// Main Processing Loop
Dow '1' = '1';  // Equivalent to DO *HIVAL
  
  // PANEL01の表示 (Display PANEL01)
  ExFmt PANEL01;
  
  If Exit;
    *InLR = *On;
    Return;
  EndIf;
  
  // 得意先マスターの読み取り (Read Customer Master)
  Chain S1TOKB TOKMSL01;
  NotFound = Not %Found(TOKMSL01);
  
  If Not NotFound;
    // 画面フィールドセット (Set screen fields)
    S2NAKJ = %TrimR(TKNAKJ);
    S2ADR1 = %TrimR(TKADR1);
    S2ADR2 = %TrimR(TKADR2);
    S2TIKU = %TrimR(TKTIKU);
    S2POST = %TrimR(TKPOST);
    S2GEND = TKGEND;
    S2UZAN = TKUZAN;
    
    // 差額計算 (Calculate difference)
    S2GAKU = TKGEND - TKUZAN;
    
    // PANEL02の表示 (Display PANEL02)
    NotFound = *Off;
    Write PANEL01;
    ExFmt PANEL02;
    
    If Exit;
      *InLR = *On;
      Return;
    EndIf;
    
  EndIf;
  
EndDo;

2.Bobにバッチ型RPG変換を指示したプロンプト

指示したプロンプトはこちら。
※注 Bobに不慣れなのでなるべく一意に具体的な指示を心がけたつもりです(^^;

Read D:\DEMO\PGM_SOURCE\ILERPG\IPH110FF.txt
and convert it as follows:
1. Do not use the Workstn file IPH110S.
2. Delete input/output commands for the Workstn file.
3. Use the input/output parameters defined in PANEL01 of IPH110S as input parameters when calling the program.
4. Return the input/output parameters defined in PANEL02 of IPH110S to the called program.
Save the results of the above steps in
D:\DEMO\PGM_SOURCE\ILERPG\IPH110BCH.txt

日本語だとこんなでしょうか?(日本語は試してません)

Free-form RPGソースコード
D:\DEMO\PGM_SOURCE\ILERPG\IPH110FF.txt
を以下のように変換してください。
1.Workstnファイル IPH110Sを使用しない
2.Workstnファイルに対する入出力命令は削除する
3.IPH110SのPANEL01に定義されている入出力パラメーターをプログラム呼出し時のインプットパラメーターとして使用
4.IPH110SのPANEL02に定義されている入出力パラメーターを呼び出したプログラムにリターンする
以上を実行した結果を
D:\DEMO\PGM_SOURCE\ILERPG\IPH110BCH.txt
に保管してください。

3.Bobがバッチ変換した結果のソースコード

こちらです。

**FREE

// IPH110BCH * 得意先照会バッチ処理 (Customer Inquiry Batch Processing)
// Converted from interactive to batch program with parameters

Ctl-Opt DftActGrp(*No) ActGrp(*New) Option(*SrcStmt:*NoDebugIO);
Ctl-Opt NoMain;

// File Declarations
Dcl-F TOKMSL01 Keyed Usage(*Input) ExtDesc('TOKMSL01');

// Procedure Interface - Main Entry Point
Dcl-Proc IPH110BCH Export;
  
  // Input Parameters (from PANEL01)
  Dcl-Pi *N;
    pS1TOKB Char(10) Const;  // 得意先コード (Customer Code)
    pS2NAKJ Char(40);        // 得意先名 (Customer Name)
    pS2ADR1 Char(40);        // 住所1 (Address 1)
    pS2ADR2 Char(40);        // 住所2 (Address 2)
    pS2TIKU Char(20);        // 地区 (District)
    pS2POST Char(8);         // 郵便番号 (Postal Code)
    pS2GEND Packed(15:2);    // 限度額 (Credit Limit)
    pS2UZAN Packed(15:2);    // 売掛残高 (Accounts Receivable Balance)
    pS2GAKU Packed(15:2);    // 差額 (Difference)
    pNotFound Ind;           // レコード未検出フラグ (Record Not Found Flag)
  End-Pi;
  
  // 得意先マスターの読み取り (Read Customer Master)
  Chain pS1TOKB TOKMSL01;
  pNotFound = Not %Found(TOKMSL01);
  
  If Not pNotFound;
    // 画面フィールドセット (Set output fields)
    pS2NAKJ = %TrimR(TKNAKJ);
    pS2ADR1 = %TrimR(TKADR1);
    pS2ADR2 = %TrimR(TKADR2);
    pS2TIKU = %TrimR(TKTIKU);
    pS2POST = %TrimR(TKPOST);
    pS2GEND = TKGEND;
    pS2UZAN = TKUZAN;
    
    // 差額計算 (Calculate difference)
    pS2GAKU = TKGEND - TKUZAN;

  Else;
    // レコードが見つからない場合、出力パラメータをクリア
    // Clear output parameters if record not found
    pS2NAKJ = *Blanks;
    pS2ADR1 = *Blanks;
    pS2ADR2 = *Blanks;
    pS2TIKU = *Blanks;
    pS2POST = *Blanks;
    pS2GEND = 0;
    pS2UZAN = 0;
    pS2GAKU = 0;
  EndIf;
  
  Return;
  
End-Proc;

このままではエラーがありコンパイルは通りませんでした。

4.生成されたバッチ型ソースコードを修正する

主な修正点は、
・呼出しパラメーターの桁数が正しくない (Char 20桁がChar 40桁、などで生成された)
・mainプロシージャーの宣言が無かった

上記の他に少し修正しましたがこれはテスト目的のための修正なのでノーカウントです。(47行目のdsply命令など)
修正したコードはこちら

**FREE

// IPH110BCH * 得意先照会バッチ処理 (Customer Inquiry Batch Processing)
// Converted from interactive to batch program with parameters

// Ctl-Opt DftActGrp(*No) ActGrp(*New) Option(*SrcStmt:*NoDebugIO);
// Ctl-Opt NoMain;

Ctl-Opt Main(IPH110BCH) ;

// File Declarations
Dcl-F TOKMSL01 Keyed Usage(*Input) ExtDesc('TOKMSL01');

// Procedure Interface - Main Entry Point
Dcl-Proc IPH110BCH;
  
  // Input Parameters (from PANEL01)
  Dcl-Pi *N;
    pS1TOKB Char(5) Const;  // 得意先コード (Customer Code)
    pS2NAKJ Char(20);        // 得意先名 (Customer Name)
    pS2ADR1 Char(20);        // 住所1 (Address 1)
    pS2ADR2 Char(20);        // 住所2 (Address 2)
    pS2TIKU Char(2);        // 地区 (District)
    pS2POST Char(6);         // 郵便番号 (Postal Code)
    pS2GEND Packed(9:0);    // 限度額 (Credit Limit)
    pS2UZAN Packed(9:0);    // 売掛残高 (Accounts Receivable Balance)
    pS2GAKU Packed(9:0);    // 差額 (Difference)
    pNotFound Ind;           // レコード未検出フラグ (Record Not Found Flag)
  End-Pi;
  
  // 得意先マスターの読み取り (Read Customer Master)
  Chain pS1TOKB TOKMSL01;
  pNotFound = Not %Found(TOKMSL01);
  
  If Not pNotFound;
    // 画面フィールドセット (Set output fields)
    pS2NAKJ = %TrimR(TKNAKJ);
    pS2ADR1 = %TrimR(TKADR1);
    pS2ADR2 = %TrimR(TKADR2);
    pS2TIKU = %TrimR(TKTIKU);
    pS2POST = %TrimR(TKPOST);
    pS2GEND = TKGEND;
    pS2UZAN = TKUZAN;
    
    // 差額計算 (Calculate difference)
    pS2GAKU = TKGEND - TKUZAN;
    dsply ('tokuisaki name is ' + %char(pS1TOKB) +' ' + %char(pS2TIKU) +
      ' ' + %char(pS2GAKU) );

  Else;
    // レコードが見つからない場合、出力パラメータをクリア
    // Clear output parameters if record not found
    pS2NAKJ = *Blanks;
    pS2ADR1 = *Blanks;
    pS2ADR2 = *Blanks;
    pS2TIKU = *Blanks;
    pS2POST = *Blanks;
    pS2GEND = 0;
    pS2UZAN = 0;
    pS2GAKU = 0;
  EndIf;
  
  
  Return;
  
End-Proc;

この状態でコンパイルは通りました。

5.バッチ型に変換したRPGを実行してみる。

変換以前は5250画面から得意先番号 '01010' 等を入力して該当レコードと計算フィールドを画面表示していましたが、バッチ型だと呼出し元のプログラムやジョブに同じ値を返します。

今回は5250画面からCALLしてみました。

CALL PGM(DEMOLIB_G/IPH110BCH) PARM(('01020' (*CHAR 5)) ('' (*CHAR 20)) (' 
' (*CHAR 20)) ('' (*CHAR 20)) ('' (*CHAR 2)) ('' (*CHAR 6)) (0 (*DEC 9 0) 
) (0 (*DEC 9 0)) (0 (*DEC 9 0)) (0 (*DEC 9 0)) ('' (*CHAR 1)))            

image.png

上記スクショの最終行、DSPLY の行に 呼出し時のキー(01020)、地区コード(02:Db2 for iから取得)、計算フィールド(480000)が表示されており、ロジックは正常に変換されたことが確認できました。

次はこのバッチプログラムをREST APIコールしてみます。続き③はこちらです。

2
0
3

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?