} I言語VER8システム開発の入門編 6/9 (ファイルからの登録)


(6)ファイルからの登録。

☆テスト用ファイルを作ります,メモ帳で以下の内容のファイル「C:¥市一覧.txt」として作って下さい。 (注意:このホームページはUTF-8で作られているため半角円記号が「\」(バックスラッシュ)になってしまいます, よって全角の「¥」を使っていますが正しくは半角の円記号ですので注意して下さい)
仕様:先頭◎が都道府県で以外は最後に市が有るものが市の名前。 (最後のデータは7文字でエラーとなる予定)
***(C:¥市一覧.txt)***
◎長野県
飯田市
長野市
◎愛知県
名古屋市
1234567市
*******************

◎(6.1)「システム 開発 メニュー」で'21'を入力し「テスト 全 プログラム 更新」に行き。 ジョブに'ZZZZ30'で[Enter]後'←','↓'5個後,'2','ZZZZ','30','01','40','JA'はスキップ,'TEST', 'ZZZY','AA','INPUT'(処理種類,更新のプログラムでは無いですが,「テーブル更新」で作成されたテーブルを更新する場合は ,「INPUT」にする必要があります),'A'(認証,管理者のみ可),'↓'でメニューに行き'ファイルから市 作成処理',[Enter]で作成します。

◎(6.2)'0'で選択しプログラムを更新します。今回のプログラムは検索でも更新でも無いので全てを手動で作ります。
メニュー起動プログラムは最初にPROGRAM=を書きます、今回は検索をしないのでPROGRAM=NOTと書きます。
100 PROGRAM=NOT
PROGRAM=NOTではDATA=で入力させないと、いきなり処理が実行されるので200以下にDATA=を書いて一旦止め、 ’YES'でない場合は終了するようにプログラムを作成します。
200 DATA=YES{3}{YES,NO}
300 =IF{_DATA!='YES'}EXIT{_END};
YESはデータ名です、{3}が桁数です、{YES,NO}でYESかNOを選ぶりストボックスが表示出来ます。
IFで判定し'YES'では無いときはEXIT{_END};でプログラムの終了処理に行きます。
最初にファイルを読み込む必要があるのでこの部分を作ります、 ファイルを読み込むためには少し面倒な作業が必要です。 最初にREAD1_OPENでファイルを開き次にREAD1_NEXTで一件づつデータを読み、 最後にREAD1_CLOSEで閉じる必要があります。この部分を書くのは面倒ですので今回は雛型で作ります。
操作で”A 400 =READ1”と入れ[Enter]で雛型が作成されます。 尚”=READ2"もありI言語では同時に開くことのできるファイルは2個までです。
AはADDの意味で400は開始番号です、命令をうる覚えの場合は=READ1に存在しない物を入れると、 別画面が表示しそこから選ぶことも出来ます。

◎(6.3)出来た雛型を修正します。
"(FILE)”の部分はファイル名ですので"C:¥市一覧.TXT”に変更します。 (注意:I言語は英字は全て大文字です、WINDOWSの場合ファイル名は英小文字と大文字は同じと見なします)
[,UTF-8,SHIFT_JIS]はエンコードです、普通にメモ帳で作った場合はSHIFT_JISです。
W.~~_XXX,W.~~_YYYは読み込むデータの転送先です、今回は1データですのでとりあえずW.DATAとします。
(W.DATAのようにWで始まるデータ名は宣言無しで即使えます)
(尚、2文字目が数値は数字項目(0はINT、以外はDECIMALと想定)、CはCHAR、EはDATETIME、FはFLOAT、以外はNCHARと想定します)
次は少し余分な作業ですが万が一読み込みデータに空白が有った場合でも正しく動くように空白を取ります。 今回はSQLのREPLACE関数を使って取ってみます。
510 =SQL_SET{W.DATA}
520 = {SELECT REPLACE(?_VC&W.DATA?,' ','') ?_FROM_DUAL?};
SQL_SETはSQL_SET{転送先データ名,..}{SQL文};の構成で、SQL文を実行し、転送先データ名に1件のみのデータを受け取る場合の命令です。
REPLACE('?_VC&W.DATA?',' ','')で空白を取ります。 (尚、SQL Serverの場合は全角も半角も区別しないので、全角空白も取ります)
"_VC&W.DATA"のように"_"から始まるシステム提供データ名の途中に"&"が有った場合は"左辺データ名"+"比較"+"データ名または編集した値"と比較用SQLが作られますが、 Cで左辺データ名を取り、比較の設定が無いのでV(VALUE,Nの時はNAMEでデータ名)で編集した値の「N'?W.DATA?'」のみとなります。
?_FROM_DUAL?はテーブルを使用しない場合に書きます、 SQL Serverでは空白になり書かなくても良いですがOracleとDB2ではエラーとなるので書きます。
読み込まれたデータは都道府県と市が混在しているので、プログラムで判定する必要があります。
都道府県は先頭に’◎’が有るものですのでその判定を書きます,"/"が前方一致比較用です。
530 =IF{W.DATA/'◎'}JUMP{都道府県};
600 =都道府県:
(600は3の修正で対応します)
JUMP{都道府県}で一致した時"都道府県:”にジャンプします。
都道府県:と最後に":"を付けるとJUMPまたはBACKの飛び先(名札)を意味します。
都道府県を発見したので都道府県実表を作成してみます。
ここで日本語の問題があるので、事前に対応します。 ZZZYAA_都道府県はテーブルにNCHAR(10)でZZZYAA_市はNCHAR(12)で設定されており、 この文字数までエラーが出ないで登録できます。 一方、I言語はその半分の文字数で有る事を想定しているためこの問題に対処します。 対処方法は定義情報にSET命令で転送する事で5又は6文字以上を送るとエラーとなります。
まずテーブル定義情報を受け取るため2個の項目のある市実表をTABLE=で宣言します。
110 TABLE=&X2,?_MM?_市実表
次にデータを宣言しますがPROGRAM=NOTではSET=は使いませんし、 DATA=では画面上に表示されるので、今回はWORK=で宣言します。
120 WORK=X2.?&X2.DATA&~+_市?
130 WORK=X2.?&X2.DATA&~+_都道府県?
そして実際にSETで転送します。
610 =SET{X2.~+_都道府県=W.DATA[2]}ERROR{};
SETで転送しERROR{}がある事でエラーが発生しても異常終了しないで2行目にエラーメッセージを表示し、 再入力となります。
W.DATA[2]はUNICODE文字で換算し2文字目から最後まで、つまり先頭の"◎"を取った物を意味しています。
やっと本題の作成する部分ですが、命令PROGRAMを使用しますので雛形を”A 620 =PROGRAM"で作成してみます。
620 =PROGRAM{?_M?_XXX_TABLE}
646 = {W.~~_KEY1,W.~~_KEY2}
672 = {W.~~_DATA1,W.~~_DAT2}{[1,2,3][,N,E,P,PE]};
の3行が作成されました。
620の?_M?_XXX_TABLEはテーブル名で?_MM?_都道府県実表にします。
646は更新キーデータですX2.~+_都道府県にします。
672の最初は更新データです、今回は無いので空白となります。
672の{[1,2,3][,N,E,P,PE]}は操作で2が作成でNがすでにデータが有ると何もしないので今回は"2N"とします。
620 =PROGRAM{?_MM?_都道府県実表}
646 = {X2.~+_都道府県}
672 = {}{2N};
となります。これは1行に書けるので620で1行にして。
620 =PROGRAM{?_MM?_都道府県実表}{X2.~+_都道府県}{}{2N};
とします。

◎(6.3)今度は市実表の作成を作ります。
最後が市のデータが市ですので、その判定をします。
"%"は後方一致比較で"!"は否定ですので、最後が’市'でないとNEXTに戻ります。
540 =IF{W.DATA!%'市'}BACK{NEXT};
都道府県同様市の長さも確認の為定義したZZZYAA_市に転送します。
W.DATA[1;W.DATA@COUNT-1]は先頭から1少ない文字数分転送なので、最後の"市"は転送しません。
550 =SET{X2.~+_市=W.DATA[1;W.DATA@COUNT-1]}ERROR{};
市実表を作成します。
560 =PROGRAM{?_MM?_市実表}{X2.~+_市}{X2.~+_都道府県}{2N};
作成後次のデータを読むためNEXTに戻ります。
570 =BACK{NEXT};
全て実行後自動で終わらせるため最後に以下のプログラムを入れて完成です。
900 =EXIT{_END};

◎(6.5)実際に実行してみました。
最後のデータは長いのでエラーとなりましたが、実行結果を見てみます。

◎(6.6)市検索処理で見ると、長野と名古屋が有り成功です。(飯田は無処理でOK)
本来はエラーとなった場合は今までの作業を全て無効にすべきですが、 今回はそれをしていないので、エラー前の物はすでに登録されています。 全てを無効にするためには開始前にSQL{BEGIN TRANSACTION};でトランザクションの開始を宣言し、 正常終了した時点でSQL{COMMIT TRANSACTION};を行うことで可能となります、 エラー発生時はI言語がSQL{ROLLBACK TRANSACTION};を実行するので全て無効となります。 尚、PROGRAM=INPUTの更新処理はSTOP_BEFOREの前にSQL{COMMIT TRANSACTION};が実行され、 STOP_AFTERの後にSQL{COMMIT TRANSACTION};が実行されます。
次へ(7/9,ひらがな項目の追加)
All Rights Reserved, Copyright (C) 2011-2011 Nobumichi Harasawa.