「24. CLP で今すぐ作れる CGI」でCLP でも十分、CGI として活用できることがご理解頂けたと思う。
次に SMPRINTCL という名前の印刷結果をHTMLに変換してリダイレクトするCLP-CGIの応用例を紹介しよう。
印刷結果をHTML にして戻す手法は、これまでほとんど解説されていない。
原理としては簡単に思えるがやってみると、やや手こずるのではないだろうか?
処理の手順としては
- ブラウザからの入力値を取得する。
- 印刷プログラムに入力値を渡して印刷出力させる。
- 印刷されたスプールをHTML に変換する。
- HTMLの保管場所をブラウザにリダイレクトする。
という方向となる。
Spoolライター Ver 3.0 のCVTSPLFコマンドによって
「3. 印刷されたスプールをHTML
に変換する。」ことになるが、
Spoolライター Ver 3.0 が無い場合でも
CPYSPLFコマンド
によって印刷スプールを物理ファイルに変換して、
これをHTMLに変換してIFS に出力しておき、
ブラウザには、そのありかをリダイレクトしてやると
ブラウザは直ちに、その場所に移動して結果の
HTMLを表示することになる。
CLPに精通している諸兄であれば、これらの処理は一見、簡単なように思えてしまうが、
「17.FTPで出力したはずのQPRINTはどこへ?」で解説されているように、
TCP/IP経由での
印刷ジョブは別の QPRTJOB という名前のジョブによって処理されてしまうので
Spoolライターの CVTSPLF や CPYSPLF で、それらを実行するJOB名を単純に
指定したのでは印刷スプールを取得することはできない。
それではジョブ名= QPRTJOB, ユーザー= QTMHHTTP1 (Webからのログインは
つねにこのユーザーとなる。)
と良いとしてもジョブ番号はどのように取得すれば良いのであろうか?
現在のところジョブ QPRTJOB のジョブ番号を検索する方法は見つかっていない。
しかし、これまた不思議なことに QPRTJOB のジョブ番号はつねに一定であり、
IPL の後でさえもジョブ番号は変化しない。
筆者の使用しているOS/400 V5R2M0 ではジョブ番号は、つねに 057084 であったので、
これをそのまま採用している。
この詳細が明確になれば追って報告する予定である。
それでは、最初に実際の操作を紹介する。
この リンク をクリックして、画面が表示されたら、そのまま「検索」ボタンを押す。
CGI として CGIBIN/SMPRINTCL が実行される。
SMPRINTCL は商品マスターのRPG印刷プログラム「SMPRINT」を呼び出して実行する。
実行結果の印刷スプールは Spoolライター Ver 3.0 の CVTSPLF コマンドによって
- ホスト変換API (HPT) によって ASCII印刷ストリームに変換
- ASCII印刷ストリームをHTMLに変換
して、IFS に保管する。SMPRINTCL は CVTSPLF が保管した場所をブラウザへ戻す。
ブラウザは直ちにHTML の保管場所に移動して、結果としてHTMLが表示されるという
仕組みである。
以下に SMPRINTCL のソースを紹介する。
0001.00 PGM 0002.00 /*---------------------------------------------------------*/ 0003.00 /* SMPRINTCL : サンプル・データの印刷 */ 0004.00 /* */ 0005.00 /* この CLP は CGI として呼びだされて */ 0006.00 /* RPG : SMPRINT を実行して印刷出力を行います。 */ 0007.00 /* 印刷出力の結果は SPOOL ライターによって */ 0008.00 /* HTML 化されて直ちにブラウザへ戻されます。 */ 0009.00 /* */ 0010.00 /*---------------------------------------------------------*/ 0011.00 DCL VAR(&MSG) TYPE(*CHAR) LEN(80) 0012.00 DCL VAR(&ENBUFF) TYPE(*CHAR) LEN(2048) 0013.00 DCL VAR(&ENBUFFLN) TYPE(*CHAR) LEN(4) 0014.00 DCL VAR(&ENVARNAME) TYPE(*CHAR) LEN(20) + 0015.00 VALUE('QUERY_STRING') 0016.00 DCL VAR(&ENACTLN) TYPE(*CHAR) LEN(4) 0017.00 DCL VAR(&ENVARLN) TYPE(*CHAR) LEN(4) 0018.00 DCL VAR(&APIERR) TYPE(*CHAR) LEN(4) + 0019.00 VALUE(X'00000000') /* 2 進数 */ 0020.00 DCL VAR(&FRMCOD) TYPE(*CHAR) LEN(10) 0021.00 DCL VAR(&DTA001) TYPE(*CHAR) LEN(120) + 0022.00 VALUE('CONTENT-TYPE: TEXT/HTML') 0023.00 DCL VAR(&DTA002) TYPE(*CHAR) LEN(120) VALUE(' ') 0024.00 DCL VAR(&DTA003) TYPE(*CHAR) LEN(120) + 0025.00 VALUE('<HTML><HEAD><TITLE> 印刷 CLP</TITL+ 0026.00 E>') 0027.00 DCL VAR(&DTA004) TYPE(*CHAR) LEN(120) + 0028.00 VALUE('<META HTTP-EQUIV="CONTENT-TYPE" + 0029.00 CONTENT="TEXT/HTML; CHARSET="X-SJIS">') 0030.00 DCL VAR(&DTA005) TYPE(*CHAR) LEN(120) + 0031.00 VALUE('<META HTTP-EQUIV="REFRESH" + 0032.00 CONTENT="0;URL=HTTP://218.44.135.18/AS400-N+ 0033.00 ET.USR/PROJECT/SMPRINT/') 0034.00 DCL VAR(&DTA006) TYPE(*CHAR) LEN(120) + 0035.00 VALUE('</HEAD>') 0036.00 DCL VAR(&DTA007) TYPE(*CHAR) LEN(120) + 0037.00 VALUE('<BODY>') 0038.00 DCL VAR(&DTA008) TYPE(*CHAR) LEN(120) + 0039.00 VALUE('</BODY></HTML>') 0040.00 DCL VAR(&DATA) TYPE(*CHAR) LEN(960) 0041.00 DCL VAR(&HTML) TYPE(*CHAR) LEN(120) 0042.00 DCL VAR(&N) TYPE(*DEC) LEN(4 0) VALUE(1) 0043.00 DCL VAR(&POS) TYPE(*DEC) LEN(4 0) VALUE(1) 0044.00 DCL VAR(&OUTLN) TYPE(*CHAR) LEN(4) 0045.00 DCL VAR(&CRLN) TYPE(*CHAR) LEN(2) VALUE(X'1500') 0046.00 DCL VAR(&OUTPUT) TYPE(*CHAR) LEN(20) 0047.00 DCL VAR(&JOBNBR) TYPE(*CHAR) LEN(6) VALUE('057084') 0048.00 MONMSG MSGID(CPF0000) EXEC(GOTO CMDLBL(ERROR)) 0049.00 0050.00 CHGVAR VAR(&OUTPUT) VALUE('P' *CAT &JOBNBR *TCAT + 0051.00 '.HTM') 0052.00 ADDLIBLE LIB(SPOOLWTR) 0053.00 MONMSG CPF2100 0054.00 /*( ブラウザからの入力値を取得 )*/ 0055.00 CHGVAR VAR(%BIN(&ENBUFFLN)) VALUE(2048) 0056.00 CHGVAR VAR(%BIN(&ENACTLN)) VALUE(0) 0057.00 CHGVAR VAR(%BIN(&ENVARLN)) VALUE(12) 0058.00 CALLPRC PRC(QtmhGetEnv) PARM(&ENBUFF &ENBUFFLN + 0059.00 &ENACTLN &ENVARNAME &ENVARLN &APIERR) 0060.00 CHGVAR VAR(&FRMCOD) VALUE(%SST(&ENBUFF 8 10)) 0061.00 /*---( 印刷プログラム SMPRINT の実行 )------------------------*/ 0062.00 OVRDBF FILE(SHOHIN) TOFILE(QTRFIL/SHOHIN) + 0063.00 OVRSCOPE(*JOB) 0064.00 OVRPRTF FILE(QPRINT) HOLD(*YES) SECURE(*YES) + 0065.00 OVRSCOPE(*JOB) 0066.00 CALL PGM(R520OBJ/SMPRINT) PARM(&FRMCOD) 0067.00 DLTOVR FILE(SHOHIN) LVL(*JOB) 0068.00 /*( SPOOLWTR/CVTSPLF による HTML 変換 )*/ 0069.00 SPOOLWTR/CVTSPLF SPLF(QPRINT) + 0070.00 JOB(&JOBNBR/QTMHHTP1/QPRTJOB) + 0071.00 SPLNO(*LAST) OUTPUT(*HTML) OPTION(*IFS) + 0072.00 TOSTMF(&OUTPUT) + 0073.00 TODIR('/AS400-NET.USR/PROJECT/SMPRINT') 0074.00 /*( 変換後の保管場所にリダイレクト )*/ 0075.00 CHGVAR VAR(&DATA) VALUE(&DTA001 *CAT &DTA002 *CAT + 0076.00 &DTA003 *CAT &DTA004 *CAT &DTA005 *CAT + 0077.00 &DTA006 *CAT &DTA007 *CAT &DTA008) 0078.00 CHGVAR VAR(%BIN(&OUTLN)) VALUE(120) 0079.00 LOOP: CHGVAR VAR(&HTML) VALUE(%SST(&DATA &POS 120)) 0080.00 IF COND(&N *EQ 5) THEN(DO) 0081.00 CHGVAR VAR(&HTML) VALUE(&HTML *TCAT &OUTPUT *TCAT + 0082.00 '">') 0083.00 ENDDO 0084.00 CHGVAR VAR(&HTML) VALUE(&HTML *TCAT &CRLN) 0085.00 CALLPRC PRC(QtmhWrStout) PARM(&HTML &OUTLN &APIERR) 0086.00 IF COND(&N < 8) THEN(DO) 0087.00 CHGVAR VAR(&N) VALUE(&N + 1) 0088.00 CHGVAR VAR(&POS) VALUE(&POS + 120) 0089.00 GOTO LOOP 0090.00 ENDDO 0091.00 /*( 処理完了すればスプールを削除する。 )*/ 0092.00 DLTSPLF FILE(QPRINT) JOB(&JOBNBR/QTMHHTP1/QPRTJOB) + 0093.00 SPLNBR(*LAST) 0094.00 RETURN 0095.00 0096.00 ERROR: RCVMSG RMV(*NO) MSG(&MSG) 0097.00 SNDMSG: SNDPGMMSG MSG(&MSG) TOMSGQ(*SYSOPR) MSGTYPE(*COMP) 0098.00 DSPJOBLOG OUTPUT(*PRINT) 0099.00 ENDPGM
【 解説 】
詳細については「24. CLP で今すぐ作れる CGI」を参照のこと。
ADDLIBLE LIB(SPOOLWTR) も必須である。
DCL VAR(&JOBNBR) TYPE(*CHAR) LEN(6) VALUE('057084')
によって QPRTJOB のジョブ番号を指定している。
Spoolライター Ver 3.0 を使用しなくても腕に覚えがあれば
「ホスト変換API (HPT)
によって ASCII印刷ストリームに変換」は
LPR コマンドによって変換することができる。
TCP/IP の章の「21.EBCDICのスプールをASCIIに変換するには?」を参照。
「ASCII印刷ストリームをHTMLに変換」についても「HTTPサーバーとWeb開発」の章の
「45.テキスト・ファイルをHTML化するには?」にその方法を解説している。
最後に印刷プログラムであるSMPRINT のソースを紹介する。
注目してほしいのは SMPRINT は ILE-RPGではなく、古典的なOPM-RPG である点である。CGI としての役割は SMPRINTCL が担っているのであるから
SMPRINT は
ILE-RPG である必要はない。
さらにILE-RPG よりは OPM-RPG のほうがパフォーマンス面でも優れている。
フレームHTML にリダイリクトするようにすれば、上記の結果のHTML に「戻る」ボタンを
つけることもできる
このように考えれば照会系のCGI は印刷プログラムによって実現できることがわかるであろう。
するとCGIの開発は非常に楽なものとなり、既存のRPG資産をかなり有効活用できるようにもなる。
「印刷結果をHTMLで戻す」という実現は結構、奥が深く、応用範囲が広い。
【 印刷プログラム SMPRINT 】
0001.00 H Y/ 0002.00 F********** サンプル・データ印刷 ************************* 0003.00 FSHOHIN IF E K DISK 0004.00 FQPRINT O F 132 OF LPRINTER 0005.00 F***************************************************************** 0006.00 F* これは SAMPLEDB を外部入力指定された FRMCOD から 0007.00 F* 最大 20 件のレコードを読み取って印刷する 0008.00 F* SMPRINT という名前のプログラムです。 0009.00 F* SMPRINT は CLP: SMPRINTCL によって呼び出されたときは 0010.00 F* WEB の配信処理として印刷結果は SPOOL ライターによって 0011.00 F* HTML に変更されてブラウザに戻されます。 0012.00 E HDR 1 1 32 見出し 0013.00 LQPRINT 66FL 62OL 0014.00 C*----------------------------------------------------+ 0015.00 C *ENTRY PLIST | 0016.00 C PARM FRMCOD 10 | 0017.00 C*----------------------------------------------------+ 0018.00 C****************************************************** 0019.00 C* 明 細 演 算 0020.00 C****************************************************** 0021.00 C*----------------------------------------------------+ 0022.00 C SETKEY KLIST 0023.00 C KFLD SHCODE 0024.00 C*----------------------------------------------------+ 0025.00 C MOVELFRMCOD SHCODE 0026.00 C* FRMCOD DSPLY ANS 1 0027.00 C SETKEY SETLLSHOHIN 0028.00 C 1 DO 20 N 40 1-20 LOOP 0029.00 C SETOF 50 0030.00 C READ SHOHIN 50 0031.00 C 50 LEAVE 0032.00 C* 0033.00 C*( 明細印刷 ) 0034.00 C*----------------------------------------------------+ 0035.00 C SETON 42 | 0036.00 C EXSR OUTPUT | 明細印刷 0037.00 C*----------------------------------------------------+ 0038.00 C ADD 1 KENSU 70 件数 0039.00 C ADD SHTANK TANKEI 70 単価計 0040.00 C END 1-20 LOOP 0041.00 C*( 小計 ) 0042.00 C* 0043.00 C END TAG 0044.00 C*( T-LR 最終合計 ) 0045.00 C*----------------------------------------------------+ 0046.00 C SETON 49 | 0047.00 C EXSR OUTPUT | 件数印刷 0048.00 C*----------------------------------------------------+ 0049.00 C SETON LR 0050.00 C RETRN 0051.00 C****************************************************** 0052.00 C *INZSR BEGSR 0053.00 C****************************************************** 0054.00 CSR ENDSR 0055.00 C****************************************************** 0056.00 C OUTPUT BEGSR 0057.00 C****************************************************** 0058.00 CSRN40 SETON 4041 0059.00 CSR EXCPT 0060.00 CSR OF SETOF 40OF 0061.00 CSR SETOF 414243 0062.00 CSR SETOF 444546 0063.00 CSR SETOF 474849 0064.00 CSR ENDSR 0065.00 OQPRINT E 206 41 0066.00 O UDATE Y 8 0067.00 O 14 ' 作成 ' 0068.00 O HDR,1 82 0069.00 O 129 'PAGE.' 0070.00 O PAGE Z 132 0071.00 O E 1 41 0072.00 O E 1 41 0073.00 O 24 '------------------------' 0074.00 O 48 '------------------------' 0075.00 O 72 '------------------------' 0076.00 O 96 '------------------------' 0077.00 O 120 '------------------------' 0078.00 O 132 '------------' 0079.00 O E 1 41 0080.00 O 12 ' 商品コード ' 0081.00 O 21 ' 商品名 ' 0082.00 O 62 ' 単価 ' 0083.00 O 75 ' 品種コード ' 0084.00 O E 2 41 0085.00 O 24 '------------------------' 0086.00 O 48 '------------------------' 0087.00 O 72 '------------------------' 0088.00 O 96 '------------------------' 0089.00 O 120 '------------------------' 0090.00 O 132 '------------' 0091.00 O*( 明細行 ) 0092.00 O E 1 42 0093.00 O SHCODE 12 0094.00 O SHNAME 50 0095.00 O SHTANKJ 62 0096.00 O SHSCOD 68 0097.00 O E 1 42 0098.00 O E 1 49 0099.00 O 20 ' 【合計】 ' 0100.00 O TANKEIJ 62 0101.00 O E 1 49 0102.00 O 40 ' 処理件数 ' 0103.00 O 57 '. . . . . . . . .' 0104.00 O KENSU 2 65 0105.00 ** HDR 0106.00 サンプル・データ印刷