第5回の記事「サンプルプログラムの流れ(CSVファイルの作成)」はこちら
EXCELファイルへの変換はPASE環境のPythonで行います。そのため、データをPASE環境(IFS)に転送する必要があります。
もし、IBM iのCCSIDが5026環境の場合は注意が必要です。PASE環境は英小文字を使用しますので、5035か1399で実行する必要があります。
CCSID
CCSID=5026で運用している場合、英小文字を使用するとPASE環境では文字化けします。ただし、CCSIDを5026から5035もしくは1399に変更するのは、労力がかかる割に得られる効果が少ないと思います。
(※新しい非漢字を使えるメリットはありますが、プリンターを考慮するとリスクが高くなると思います。)
前述した通り、今回はCCSID=5026環境で動作させます。使用環境のCCSIDが5035もしくは1399の場合は無視してください。
まず、現状のCCSIDの確認をしてください。弊社では下記(DSPJOB)となっています。
上記ではCCSID=65535(無変換)であり、省略時のCCSID=5026です。この環境の場合、最終的に5026が採用されます。
通常のCCSID=5026では英小文字を使用できませんが、5250エミュレータのホストコードページ=930(拡張カタカナ)にすると英小文字が入力可能となります。ただし、5035の英小文字のコードとは異なりますので、PASE環境では文字化けします。
また、「SQLDAにアクセスする」および「QSYS2/SYSCOLUMNSからデータを取得する」場合、上記環境ではコード変換エラーになります。
(※ CHGJOB CCSID(5026) を実行しCCSIDを設定すると問題なく動作します。省略時のCCSID=5026は有効になっていないようです。)
(コラム)ソースコード上の英小文字について
今回のサンプルプログラム作成時、PASE環境のシェルを起動やファイルを操作する時には英小文字が必須でした。
5250画面の1つのエミュレータコードページを1399に変更し英小文字でソースコードを入力していましたが、誤ってエミュレータコードページ=930で変更してしまい、何度も実行エラーを発生させてしまいました。このため、英小文字を必要とする情報はパラメータファイルに格納するように工夫しています。ファイルはCRTPF時にCCSIDが確定しますので、ファイルからデータを出力する時に実行時のCCSIDに自動変換してくれます。取得時のCCSIDに従って変換されますので、取得後変数に格納されたデータは途中でCCSIDを更しても元の値のままです。編集する場合、格納されたデータは再取得するかコード変換が必要です。
パラメータファイルはUPDDTAコマンドで保守できます。フィールド属性がAであれば、UPDDTAコマンドで英小文字も入力できます。
ただし、フィールド属性が「O:オープンフィールド」の場合は、英小文字入力はできません。
(※エミュレータのホストコードページで930拡張カタカナは必須)
1.1 CCSID(5026<->5035)の補足
5026と5035のコード表をよく見ると、異なるのは英小文字とカタカナ関係だけです。5026環境と1399環境でSEUを実行して、5035のテーブルのソースコードを表示すると下記になります。
A.CCSID=5026でSEUを実行しソースコードを表示
5035のテーブルは5026環境では別の文字が表示されます。幸いなことに、5035の英小文字及びカタカナは5026環境でも文字がマップされています。このため、16進表記を使用せずにSEUで表示できます。
なお、SEUでCtrl+F3を押すと5026環境でも5035の文字が確認できます。(下記画面を参照)
①テーブル1(5035)で文字化けしていた文字が、正常に表示されます。逆に、②テーブル2(5026)が文字化けします。
※↑上記画面の最後の2行はコメントアウトされていますが、記号関係は5026及び5035に関係なく正常に表示されています。この結果から、記号関係は、想定通り5026と5035では同じコード点になっている事が証明できます。
(補足)5035のテーブルは5250エミュレータのホストコードページ=1399かつJOBのCCSID=1399の環境でSEUを実行入力したものです。
B.CCSID=1399でSEUを実行して、ソースコードを表示
CCSID=1399では①テーブル1(5035)が正常に表示されます。②テーブル2(5026)が文字化けします。
(コラム)CCSID=5026について(あくまでも私見です。)
私の記憶ですが、USで開発されたIBMのコンピュータを日本に持ちこむ際に、日本ではカタカナが不可欠との判断から、IBMのコンピュータで使用しているコード体系(EBCDIC:拡張BCD)に無理矢理カタカナを組込もうとしたはずです。
逆に、日本では英小文字は不要と思われたようで、英小文字のエリアにカタカナ文字を割り当てたと聞きました。コード表には文字を割り当てていないコードもあったのですが、プリンタブル文字を差替えたほうが楽ですので、このような結果になったのではと思います。
なお、当時は現在のような漢字を実装するにはコンピュータのリソースとスペックが不足していました。
IBMi(当時はAS/400)及びその前身であるSystem/38ではEBCDICでカタカナを使えるようにしたものでした(EBCDICカタカナと呼称。一部の人はEBCDIKと呼んでいた人もいました。:最後のCをKにしカタカナを意味する)
その後、UNIXのプログラムをOS/400上で稼働させる必要性が生じますが、その場合は、英小文字を当然使用します。(日本で使用していたカタカナと重複しました。このため、USの英小文字を使うために5035が登場しました。
その後、日本でも英小文字を使用するニーズが出てきたため、既存5026の文字が割り振られていないコードに英小文字がマップされました。当初はハードウェアで文字を描画していましたが、ソフトウェアで文字の描画を実現できるようになったことで実施できたのだと思っています。
1.2 コード変換プログラム(5026<->5035)
このプログラムは、5026<->5035間の英小文字とカタカナ(小文字含む)を変換するものです。
コード変換関連は非常に手間がかかったため、逃げ道と想定したプログラムであり、コード変換で機能するかの確認が当初の目的でした(実際に使用しました)。
コード変換プログラムは上記の様に、ファイルからデータ取得後にCCSIDを変更した場合などに使用します。また、5026環境で英語小文字を使用するプログラム(フリーソフトのメール送信ソフトでパスワードに英小文字を使用する場合など)でも使用できます。
パラメータ取得プログラム(UTLGETPRM)からもCALLされますが、直接CLでCALLする場合は以下となります。
下記の例では、変数&CNV_TOにコード変換結果が格納されます。
2. PASE環境へのデータ転送
PythonはPASE環境(AIX)で動作しますので、ここまでに作成したDEF(CSVTXT)及びCSV(CXSVTXT2)をIFSに転送する必要があります。
PASE環境を操作する場合は、実行しているJOBのCCSIDを5035か1399にする必要があります。サンプルではILECLPでCHGJOB CCSID(1399)を実行しています。英小文字は前述したようにSEUで入力するとケアレスミスが多い為、パラメータファイルに値をセットしたものを取得し使用するようにしています。(※この手法を採用してからは、英小文字の問題で悩まされる事はなくなりました。)
2.1 ユーザーホームディレクトリー名文字列の生成
ユーザーホームディレクトリーにファイルを作成します。このために、ユーザーホームディレクトリーの文字列を事前に生成します。
パラメータファイルからパラメータを取得し、ユーザーホームディレクトリーの文字列を生成します。
2.2 ユーザーホームディレクトリーのチェックと作成
PASE(UNIX)環境では、ユーザーごとのデータは、/home/ユーザーIDのディレクトリーを使用することが推奨されます。
PASE環境の場合、IBM iのユーザーIDでは、/home下にユーザー用のディレクトリーは自動で作成されません。
(※UNIXでは、ユーザーを作成すると/homeディレクトリーにユーザー用のディレクトリーが作成されます。)
サンプルプログラムでは、IFSにデータ転送する前に/home下のユーザーIDディレクトリーをチェックします。ユーザーIDディレクトリーが存在しなければ、作成します。
PASE環境で実行する簡単なシェルスクリプトを、CLから実行しています。
PASE環境でユーザーホームディレクトリーをチェックするシェルスクリプト(chk_home_dir.sh)
シェルでディレクトリーが存在するかをチェックし、存在しなければMKDIRで単純に作成しているだけです。
2.3 IFSへのテータ転送
PASE環境へのデータ転送は、IFSファイルへの転送と同じ意味です。IBMi環境のデータからIFSファイルに転送する必要があります。
ここからの処理はIFSを使用しますので、英小文字が必要になります。ILECLPの中で CHGJOB CCSID(1399)を実行してからFTP転送します。
尚、パラメータファイルはCCSID=5026のデータですが、JOBがCCSID=1399ですので、パラメータ取得時に英小文字は1399に自動変換されます。
IFSへのデータ転送はFTPを使用する方法とCPYTOIMPFコマンドを使用する方法があります。推奨はFTPになります。
いずれも、半角EBCDIC->JIS, IBM漢字->シフトJIS漢字 (0E及び0Fは除去されます)の変換を自動で行ってくれます。 (※当初は、PASE環境でデータ転送後にiconvコマンドでコード変換が必要かなと考えましたが、実際には不要でした。)
PASE環境は、AIX(UNIX)互換環境です。基本的にディレクトリー名・ファイル名に英小文字を使用します。また、環境によりディレクトリー階層が異なる事もあります。サンプルでは、ディレクトリー階層が変更されても対応できるように、パラメータファイルからディレクトリー階層を組み立てる様にしています。下記のILECLPでは、3階層までを想定しています。PRM4が未使用ですので、最大4階層まで対応できます。
PASE環境のファイルは、フルパスを長くするとCPYTOIMPFやFTPで文字列が切れる事があるので注意してください。
「パラメータファイル ID=HOME」
サンプルでは、パラメータファイルの設定値(ID:CSVEXPORTの第1パラメータ)によって転送方法が変わります。
・設定値=FTPの時
前述したXSNDFTPでDEFファイル(CSVTXT)とCSVファイル(CSVTXT2)をFTP転送します。FTP転送にてコード変換が実行されます。
FTP転送時にエラーが発生した場合は、エスケープメッセージを送信し処理を異常終了させます。
IBM i環境には、UNIXの様に1行でFTP送信できるコマンドは標準で存在しません。今回は、色々なサンプルをWEB上から集めて作成しました。高機能は目指さなかったので、1回の実行で1ファイルしか転送できませんが、機能的には十分でした。
なお、FTPでファイルを転送する際は、ディレクトリー名及びファイル名に漢字は使用しないでください。(※文字化けします)
・設定値≠FTPの時
CPYTOIMPFで転送します。コード変換はCPYTOIMPFのパラメータで指定しています。(※FROMCCSID、STMFCCSIDで指定)
前述した通り、CPYTOIMPFでIFSにデータ転送したファイルには、行の右端の余分な空白も出力されるのでファイルサイズが大きくなります。
※1:下記のCPYTOIMPFの例ではRCDDLM(*CRLF)としています。通常UNIX環境では*LFです。CR(0x0d)が存在するとkshは実行時エラーとなります。PythonではCSV及びDEFファイルを読込む場合は問題が発生しません。サンプルではWindows環境でもエディタで開けるように*CRLFにしています。
※2:CSVTXT, CSVTXT2,CSVTXT3のレコード長が長いため)CPYTOIMPFコマンドはこのような使用方法を想定していないようです。
2.3.1 FTP転送プログラム(XSNDFTP関連)
XSNDFTPプログラムは、コマンド化しています。(※コマンド化したほうが便利だったため)
実際のFTOは、STRTCPFTPで転送しています。STRTCPFTP実行の終了後、出力されたOUTPUTファイルを読込み、成功または失敗の判定をしています。
FTPが失敗している場合は、SNDPGMMSGでエスケープメッセージを送信し、プログラムを異常終了させます。
一回の実行で1ファイルのみ送受信します。
ILECLPでXSNDFTPを実行している箇所。FTPで必要なパラメータはパラメータ取得で入手しています。
なお、 ILECLP は、&DEF変数設定済の状態から始まっています。
3. PASE環境のプログラム実行
IBMi環境からPASE環境のプログラムを実行するには、QSHもしくはqp2shellを使用する方法があります。
サンプルではqp2shellを使用しています。Qp2shellでは、各パラメータの文字列はヌル文字(0x00)で終了する必要があります。
シェルスクリプト(run_csvExcel2.sh)
Kshのオプション
-v:シェル入力行を読取りながら、標準出力(コンソール)に出力します。
-x:実行されたコマンドとその引数を、標準出力(コンソール)に出力します。
シェルスクリプト (run_csvExcel.sh)
4 PASE環境のプログラム実行確認
PASE環境で実行したプログラムの正常終了・異常終了判定には、工夫が必要です。
PASE環境で実行したプログラムのリターンコードは、ILERPGから直接Qp2CallPase2をcallしないと取得できません。
サンプルプログラムでは、リターンコードが出力されたIFSファイルを読込み、CL変数にセットします。
下記の例では、&P_RTNCODEにセットし後続のCLで成・否の判定をしています。
5. PASE環境の実行済みデータファイル削除
正常にPythonプログラムが実行されていた場合、DEF、CSV, BND, LOG, STSを削除します。
&BASEFIL変数の文字列は以前に作成していますので、この文字列から削除ファイル名を生成します。
(※拡張子だけが異なるファイルで生成していますので、削除するファイル名は拡張子を*にしています。)
CLコマンドのRMVLNKでIFS上のファイルを削除します。












日本アイ・ビー・エム株式会社が毎月開催しているIBM Powerユーザーのための自由な語り場「IBM Power Salon」(月1回、第二水曜日の朝9時から開催)をご存じでしょうか?
IBM Power Salonのページはこちら
2023年1月11日に開催された第14回の、株式会社 電業様による「惜しみなく共有しちゃいます、根っからのエンジニアが語る、IBM i 内製化のリアル。」では、既存IBM i環境を見事に活用し、自作でIBM i と自動倉庫をつなげDXを実現された素晴らしい事例が披露されました。
https://video.ibm.com/recorded/132452956
とはいえ、1時間の講演時間では語りきれなかった詳細は、きっと他のIBM i ユーザーの方にも参考になるはず!ということで、株式会社電業 総務部 竹本伸明様に“内製DX”について具体的にご説明いただきます。読めばきっと、「IBM i でここまでできるんだ!」と目から鱗が落ちるはずです!