IBM i のエンド・ユーザーに VBS (VBスクリプト)を配布して実行させていると
VBS に変更を生じたときには、すべてのクライアントの再配布しなければ
ならない。
このようなときに IBM i に保存してある VBS スクリプトを実行する方法が
あれば変更があったとしても IBM i の VBS を変更するだけで済む。
要はその昔流行った C/S(クライアント・サーバー)モデルの App の弱点を
補うことができる。
また DOS コマンドを IBM i で動作させることは PC オーガナイザーで
実現することができるのは広く知られているが VBS となると
DOS コマンドのように単純には動作しない。
そこで今回の紹介では 最初に IBM i から VB スクリプトを動作させる
RUNVBS というコマンドを紹介する。
元々、VBスクリプトの実行は弊社製品 Spoolライター Ver5.0 の SNDFAX という
印刷スプールを FAX送信するためのコマンドに利用されている。
SNDFAX は C/400で書かれているため RPG/COBOL の開発者には
理解しにくいと思われるので CLP に書き直している。
実際の SNDFAX は実用上の様々な工夫がソースに配慮されているが
ここでは学習用としてそれらの機能は割愛されている。
0001.00 CMD PROMPT('VBS の実行 ') 0002.00 PARM KWD(VBS) TYPE(*PNAME) LEN(128) CASE(*MIXED) + 0003.00 PROMPT('VB スクリプト ')
VBスクリプトは IFS に保存しておいて上記のパラメータ: VBS で、その IFS のパス名を
入力する。
従ってパラメータ: VBS
は TYPE が 128バイト
の *PNAME
として定義されている。
0001.00 PGM PARM(&VBS) 0002.00 /*-------------------------------------------------------------------*/ 0003.00 /* RUNVBS : VB スクリプトの実行 */ 0004.00 /* */ 0005.00 /* 2016/10/25 作成 */ 0006.00 /*-------------------------------------------------------------------*/ 0007.00 DCL VAR(&VBS) TYPE(*CHAR) LEN(128) 0008.00 DCL VAR(&CMD) TYPE(*CHAR) LEN(132) 0009.00 DCL VAR(&SYSNAME) TYPE(*CHAR) LEN(8) 0010.00 DCL VAR(&MSG) TYPE(*CHAR) LEN(132) 0011.00 DCL VAR(&MSGID) TYPE(*CHAR) LEN(7) 0012.00 DCL VAR(&MSGF) TYPE(*CHAR) LEN(10) 0013.00 DCL VAR(&MSGFLIB) TYPE(*CHAR) LEN(10) 0014.00 DCL VAR(&MSGDTA) TYPE(*CHAR) LEN(132) 0015.00 DCL VAR(&TYPE) TYPE(*CHAR) LEN(1) 0016.00 DCL VAR(&TOPGMQ) TYPE(*CHAR) LEN(10) 0017.00 DCL VAR(&MSGTYPE) TYPE(*CHAR) LEN(10) + 0018.00 VALUE('*ESCAPE ') 0019.00 DCL VAR(&APIERR) TYPE(*CHAR) LEN(116) + 0020.00 VALUE(X'000074') /* 2 進数 */ 0021.00 DCL VAR(&NULL4) TYPE(*CHAR) LEN(4) + 0022.00 VALUE(X'00000000') 0023.00 /* VBS のエンコード */ 0024.00 DCL VAR(&PCCMD) TYPE(*CHAR) LEN(128) 0025.00 DCL VAR(&STRLEN) TYPE(*DEC) LEN(3 0) VALUE(128) 0026.00 DCL VAR(&STRPOS) TYPE(*DEC) LEN(3 0) VALUE(1) 0027.00 DCL VAR(&PATLEN) TYPE(*DEC) LEN(3 0) VALUE(1) 0028.00 DCL VAR(&RESULT) TYPE(*DEC) LEN(3 0) 0029.00 DCL VAR(&STR) TYPE(*DEC) LEN(3 0) 0030.00 DCL VAR(&NXT) TYPE(*DEC) LEN(3 0) 0031.00 DCL VAR(&LEN) TYPE(*DEC) LEN(3 0) 0032.00 MONMSG MSGID(CPF0000) EXEC(GOTO CMDLBL(ERROR)) 0033.00 0034.00 /*( 環境の取得 )*/ 0035.00 RTVJOBA TYPE(&TYPE) 0036.00 IF COND(&TYPE *EQ '0') THEN(DO) /* バッチ */ 0037.00 CHGVAR VAR(&TOPGMQ) VALUE('*SYSOPR ') 0038.00 ENDDO /* バッチ */ 0039.00 ELSE CMD(DO) /* 対話式 */ 0040.00 CHGVAR VAR(&TOPGMQ) VALUE('*TOPGMQ ') 0041.00 ENDDO /* 対話式 */ 0042.00 RTVNETA SYSNAME(&SYSNAME) 0043.00 0044.00 /*( URL の文字 # をエンコード )*/ 0045.00 CHGVAR VAR(&PATLEN) VALUE(1) 0046.00 NXT#: CALL PGM(QCLSCAN) PARM(&VBS &STRLEN &STRPOS '#' + 0047.00 &PATLEN ' ' ' ' ' ' &RESULT) 0048.00 IF COND(&RESULT *NE 0) THEN(DO) 0049.00 CHGVAR VAR(&STR) VALUE(&RESULT - 1) 0050.00 CHGVAR VAR(&NXT) VALUE(&RESULT + 1) 0051.00 CHGVAR VAR(&LEN) VALUE(128 - &RESULT) 0052.00 CHGVAR VAR(&PCCMD) VALUE(%SST(&VBS 1 &STR) + 0053.00 *TCAT '%23' *CAT %SST(&VBS &NXT &LEN)) 0054.00 CHGVAR VAR(&VBS) VALUE(&PCCMD) 0055.00 GOTO NXT# 0056.00 ENDDO 0057.00 0058.00 /*( 実行コマンドの作成 )*/ 0059.00 CHGVAR VAR(&CMD) VALUE('\\' *CAT &SYSNAME *TCAT + 0060.00 '\ROOT' *CAT &VBS) 0061.00 /*( VBS の実行 )*/ 0062.00 STRPCO 0063.00 MONMSG MSGID(IWS4010) 0064.00 CHGVAR VAR(&PCCMD) VALUE(&CMD) 0065.00 STRPCCMD PCCMD(&PCCMD) PAUSE(*YES) 0066.00 RETURN 0067.00 0068.00 APIERR: 0069.00 CHGVAR VAR(&MSGID) VALUE(%SST(&APIERR 9 7)) 0070.00 CHGVAR VAR(&MSGDTA) VALUE(%SST(&APIERR 17 100)) 0071.00 CHGVAR VAR(&MSGF) VALUE('QCPFMSG ') 0072.00 CHGVAR VAR(&MSGFLIB) VALUE('QSYS ') 0073.00 GOTO SNDMSG 0074.00 0075.00 ERROR: RCVMSG MSGTYPE(*LAST) RMV(*NO) MSG(&MSG) + 0076.00 MSGDTA(&MSGDTA) MSGID(&MSGID) MSGF(&MSGF) + 0077.00 MSGFLIB(&MSGFLIB) 0078.00 SNDMSG: IF COND(&MSGID *EQ ' ') THEN(DO) 0079.00 SNDPGMMSG MSGID(CPF9897) MSGF(QCPFMSG) MSGDTA(&MSG) + 0080.00 TOMSGQ(&TOPGMQ) MSGTYPE(&MSGTYPE) 0081.00 ENDDO 0082.00 ELSE CMD(DO) 0083.00 SNDPGMMSG MSGID(&MSGID) MSGF(&MSGFLIB/&MSGF) + 0084.00 MSGDTA(&MSGDTA) TOMSGQ(&TOPGMQ) + 0085.00 MSGTYPE(&MSGTYPE) 0086.00 ENDDO 0087.00 ENDPGM
RUNVBS VBS('\TEST\HELLO.VBS')
のようにして /
(バックスラッシュ)ではなく
\
記号を使ってフォルダーを表現すること。
動作原理は 「\\(システム名)\ROOT(VBスクリプト名)」
を
PCオーガナイザーによって起動している。
例えば HELLO.VBS という名前のVBスクリプトを フォルダー /TEST の配下に保存した場合、
\\S652ABCD\ROOT\TEST\HELLO.VBS
という名前のコマンドを実行していることになる。( S652ABCD とはシステム名 )
この原理を理解するには Win エクスプローラの URL 欄に
\\S652ABCD を入力するか、または \\192.168.1.1 ( IBM i のIPアドレス)
を入力して実行すると次のような Basic 認証のダイアログが表示される。
ここで IBM i のユーザー名とパスワードを入力すると Winエクスプローラに
IBM i のパスが表示される。
(一度でもログインしておけば2回目以降の実行ではログインが再び要求されることはない。)
その中で ROOT という名前のフォルダーを展開すると IBM i の IFS の内容が
展開される。
( ROOT=根っこというのはIFSツリー構造の最上位を意味する)
STRPCCMD PCCMD(&PCCMD) PAUSE(*YES)
の PAUSE(*YES)
は
デバッグが終わって正常に実行されることを確認したのであれば
PAUSE(*NO)
にすることが望ましいだろう。
VBスクリプトの実行はほんの簡単な入口であるが、これは IBM i のオープン化の
発端を示している。もしこの IFS に VisualBASIC や VC++, あるいは Java で
書かれた .exe や .class を配置すれば原理的に IBM i に存在している VB や Java を
起動することができることを理解して頂けるのではないかと思う。
ただし IBM i の DB2/400データ・ベースは Visual BASIC や Java からは簡単には
アクセスすることはできない。
もしデータ・ベースも含めてのシームレスな結合ができれば
IBM i を VisualBASIC で普通に開発することができるようになるのかもしれない。
近年、RPG の開発者が減っている傾向に対しては 開発も含めて IBM i のオープン化が
必要になってくる。