Tools

49. IBM i から VBスクリプトを実行するには?

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 は実用上の様々な工夫がソースに配慮されているが
ここでは学習用としてそれらの機能は割愛されている。

【RUNVBS : コマンド・ソース】
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として定義されている。

【RUNVBSCL : CLPソース】
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 認証のダイアログが表示される。

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 のオープン化が
必要になってくる。