N88互換BASIC for Windows95(手引き書) - DISK / FILE操作


◇OPENの出来るファイル番号数


3130 CLOSE #10: OPEN D.BC$+"SH"+NT$(VV) FOR INPUT AS #10

 「ファイル番号が不正です」のエラー。
 最大番号は9までのようです。
 (または同じケース AS #11では、「定義されていないエラー」)

Top  88Menu


◇シーケンシャルファイル

INPUT #>ファイル番号>,>変数>,----
機能:シーケンシャルファイルからデータを読み込みます。
文例:INPUT #1,SNAME$,AGE,SEX
解説:>ファイル番号>で指定するファイルは、あらかじめINPUTモードでオープンしておきます。
   >変数>が数値変数の場合、ファイル中の空白、コンマ、改行文字がデータの区切りとな
   ります。>変数>が文字型変数の場合、コンマ、改行文字がデータの区切りとなります。

 N88互換BASICでは、1行にデーターを幾つも並べて書く場合、最終行の最初のデーターを最後のものと判断してしまう。1行しかない場合、最初の1データーのみしか読み込まない。

◇シーケンシャルファイル 例1
155 CLOSE: OPEN "ケイリビコウ.DAT" FOR INPUT AS #1 ' 備考メニューDATA1
160 FOR N=1 TO 110: IF EOF(1) OR FA$(N-1)="**" THEN ELSE INPUT #1,FA$(N): NEXT N
ケイリビコウ.DATの内容=
 (この前に60個のデーターが存在し、以下はそれに続く)
61保険料,62治療費,青色申告会費, 源泉所得税, **

 上記の場合、61保険料までしか読み込まれない。=最終行の最初のデーター61保険料までで、残りの62治療費,青色申告会費, 源泉所得税, **は読み込まれない。
◇解決策
61保険料,62治療費,青色申告会費, 源泉所得税(改行)
**
 上記のように、最終データーを最終行に一つだけ置くようにしてOK。または次の「◇シーケンシャルファイル 例2」のように、「データーの最後に改行コードを追加」でも良い。

◇シーケンシャルファイル 例2
140 CLOSE: OPEN "ケイリカモクG.DAT" FOR INPUT AS #1 ' 経費の音別 並べ換え用
145 FOR G=G3+1 TO G4: IF NOT EOF(1) THEN INPUT #1,GF(G): NEXT
"ケイリカモクG.DAT"の内容=
55,33,31,32,39,52,46,42,53,30,29,45,37,41,48,36,43,44,49,40,47,50,51,38,34,35,54

 最初の55のみを読み、EOF(1)と判断してしまう。
透明スペーサー
"ケイリカモクG.DAT"の内容を以下のように変更した場合=
55,
33,
31,
32
,39,52,46,42,53,30,29,45,37,41,48,36,43,44,49,40,47,50,51,38
 最初の 55から32までの4つしか読み込まれない。
◇解決策
 以下のように、改行コードのみで良いから、データーの最後(行末)に1行を追加することで、解決。これがもっとも簡単でベスト。
55,33,31,32,39,52,46,42,53,30,29,45,37,41,48,36,43,44,49,40,47,50,51,38,34,35,54
改行コード
透明スペーサー
 または
 "ケイリカモクG.DAT"の全てを改行していく
 または
145 FOR G=G3+1 TO G4: IF NOT EOF(1) THEN INPUT #1,GF(G): NEXT
 を
145 FOR G=G3+1 TO G4: IF EOF(1)=0 THEN INPUT #1,GF(G): NEXT G
 このようにプログラムを修正する。(注:この最後の方法は、まだ知識レベルの浅い時点でのメモ。本当に正しいかどうか、再チェックをしていないので注意!)

◇シーケンシャルファイル 例3
120 CLOSE: OPEN "ケイリカモク.DAT" FOR INPUT AS #1 ' 科目の読み込み
125 FOR G=1 TO G4: IF NOT EOF(1) THEN INPUT #1,F$(G)
"ケイリカモク.DAT"の内容=
商 品 , 有価証券, 前払費用, 前払金 , 汁器備品 ,
引当金 , 売 上 , 特別売上, 雑収入 , 受取利息 ,

 dosでは、,に改行コードが続く場合、そこに中味の無い(空白)データーが1つあると判断する。データーは、汁器備品 空白データー 引当金 と続くと理解する。
 N88互換BASICでは、これを存在しないと判断する。データーは、汁器備品 引当金 と続いているものと理解する。
◇解決策
 対策としては、以下のように空白データー(=" ")、またはダミーを正式に挿入しておけば解決される。
商 品 , 有価証券, 前払費用, 前払金 , 汁器備品 , " "
引当金 , 売 上 , 特別売上, 雑収入 , 受取利息 , ダミー
 (← 注:この最終行に改行コードを1つ追加しておくこと)
 但し、例2.で記したように最終行は最初のデーター(=引当金)でEOF(1)と判断して、続く「売 上〜受取利息」は読み込まれない。その対処が、上記の改行コードの追加です。

Top  88Menu


◇EOF(ファイル番号)

機能:ファイルの終わりの位置に達したかどうかを調べる関数です。
文例:EOF(1)
解説:ファイル番号で指定したファイルが読み終わりの位置に達したかどうかを調べます。
   終わりに達していれば真(−1)、達していなければ偽(0)を与えます。

 上記◇シーケンシャルファイル 例1. や ◇シーケンシャルファイル 例3.のような狂いが生まれ、実際にデーターが残っているのに、EOF(?)と判断するケースがある。

◇EOF( ) 例2
720 FOR I=1 TO 1000: IF NOT EOF(2) THEN INPUT #2, NSA$(I) : IMAX1=I: NEXT

  NOT EOF(2)は、ファイル#2のデーターが残っていれば THEN という命令だが、N88互換BASICではエラー。
◇解決策
 次のように EOF(2)=0 に置き換ればOK。
720 FOR I=1 TO 1000: IF EOF(2)=0 THEN INPUT #2, NSA$(I) : IMAX1=I: NEXT
 私のウインドーズ95では起きたエラーだが、その後ウインドーズXPでは従来のEOF( ) や NOT EOF( )は正常に機能していた。
 詳しくは、HP管理人では を参照

◇EOF( ) 例3
720    IF SH>>1 THEN OPEN D.BC$+"SH"+NT$(SW)      FOR INPUT AS #2:
                     FOR I=1 TO 1000: IF NOT EOF(2) THEN INPUT #2, NSA$(I) : IMAX1=I: NEXT I
760    IF SH>=1 THEN OPEN D.BC$+"SH"+NT$(SW)+".S" FOR INPUT AS #3:
                     FOR I=1 TO 1000: IF NOT EOF(3) THEN INPUT #3, NSA2$(I): IMAX2=I: NEXT I

 720行のNOT EOF(2) THEN」の次ぎで、エラー。
 しかし何故か別のプログラムでは、ほぼ同一内容の760行のNOT EOF(3)は問題無し。(ということでは、別の要因かも?)
◇解決策
720    IF SH>>1 THEN ELSE 755
740                 OPEN D.BC$+"SH"+NT$(SW)      FOR INPUT AS #2:
                     FOR I=1 TO 1000: IF  EOF(2)=0 THEN INPUT #2, NSA$(I) : IMAX1=I: NEXT I
 上記のように、2行に分割したらOK。
 「エラーを出さない実質エラー」の 原因は重文 1.  原因は重文 2.の参照もお勧め。

◇EOF( ) 例4
3150 FOR D=1 TO UMAX: NSA$(D)="": IF EOF(9) THEN INPUT #9,NSA$(D): NEXT D

 EOF(9)は、DOS-BASICでは正常に機能するが、N88互換BASICでは続く THEN 以降は無視される(=実行されない)。「エラーを出さない実質エラー」である。
◇解決策
3150 FOR D=1 TO UMAX: NSA$(D)="": IF EOF(9)=0 THEN INPUT #9,NSA$(D): NEXT D
 省略は禁物で、 EOF(9)=0 のように正式に書くこと。

Top  88Menu


◇ランダムファイル

LOF(ファイル番号)
機能:ファイルの大きさを与える関数です。
文例:LOF(1)
解説:ファイル番号で指定されたファイルの大きさをバイト単位で与えます。
   RS-232Cファイルの場合、入力バッファ内の文字数を与えます。

320 OPEN DR$+"カイケイ."+YY$ AS #2
325 FIELD #2,51 AS W$
330 I=LOF(2)
 DOS-BASICでは、「ランダムファイルであれば、その最大レコード数を返します。」
 ところが、N88互換BASICでは、ランダムファイルの場合も、大きさをバイト単位で与えます。
◇解決策
330 I=LOF(2): IF DR2$="WIN互換ベーシック" THEN I=LOF(2)/51
 そこで、レコード数を得たければ、上記のように直します。
 この場合は51で割っているのは、325行の「FIELD #2,51 AS W$」で、1データーは51バイトと宣言しているから。

Top  88Menu


#VV ( OPEN FIELD GET CLOSE PUT などで )

OPEN D.BC$+NT$(VV)+".TXT" AS #VV


3510 FOR VV=1 TO VV.END
3520 OPEN D.BC$+NT$(VV)+".TXT" AS #VV
3530 FIELD #VV,250 AS D$(VV),6 AS DUMY$(VV)
3535 I=LOF(VV): IF LOF(VV)>>0 AND DR2$="WIN互換ベーシック" THEN I=LOF(VV)/256
3540 IF LOF(VV)>>0 THEN GET #VV,I
3550 IF EOF(VV)>>0 THEN I=I-1
3560 IF I>=0 THEN I=0
3630 I(VV)=I: IF I(VV)+35>UMAX THEN UMAX=I(VV)+35
3640 NEXT VV
3650 DIM NA$(UMAX), R(UMAX), RI(UMAX)
3660 RETURN
 「型が一致しません」のエラー。
◇解決策
 上記では、3520行 AS #VV、3530行 FIELD #VV、3540行 GET #VV,I
の、#VVが原因でエラーに成ります。変数はだめで、「#1」「#2」「#3」のように実数を入ればOKです。
3510 VV=1: OPEN D.BC$+NT$(VV)+".TXT" AS #1: FIELD #1,250 AS D$(VV),6 AS DUMY$(VV): GOSUB 3700
3515 VV=2: OPEN D.BC$+NT$(VV)+".TXT" AS #2: FIELD #2,250 AS D$(VV),6 AS DUMY$(VV): GOSUB 3700
3520 VV=3: OPEN D.BC$+NT$(VV)+".TXT" AS #3: FIELD #3,250 AS D$(VV),6 AS DUMY$(VV): GOSUB 3700
透明スペーサー
3700 ' *VV
3710 I=LOF(VV): IF LOF(VV)>>0 AND DR2$="WIN互換ベーシック" THEN I=LOF(VV)/256
3720 ' ' '   IF LOF(VV)>>0 THEN GET #VV,I 
3730 IF EOF(VV)=-1 THEN I=I-1 : '終わり=-1、達していなければ=0
3740 IF I>=0 THEN I=0
3750 I(VV)=I: IF I(VV)+35>UMAX THEN UMAX=I(VV)+35
3760 RETURN
  または、
透明スペーサー
3700 ' *VV
3710 I=LOF(VV): IF LOF(VV)>>0 AND DR2$="WIN互換ベーシック" THEN I=LOF(VV)/256
3720 IF LOF(VV)=0 THEN 3730
3722   IF VV=1 THEN GET #1,I ELSE IF VV=2 THEN GET #2,I ELSE IF VV=3 THEN GET #3,I ELSE IF VV=4 THEN GET #4,I
3725   IF VV=5 THEN GET #5,I ELSE IF VV=6 THEN GET #6,I ELSE IF VV=7 THEN GET #7,I ELSE IF VV=8 THEN GET #8,I
3730 IF EOF(VV)=-1 THEN I=I-1 : '終わり=-1、達していなければ=0
3740 IF I>=0 THEN I=0
3750 I(VV)=I: IF I(VV)+35>UMAX THEN UMAX=I(VV)+35
3760 RETURN

Top  88Menu


◇PUT #VV

5610 PUT #VV,R

 上記では#VVが原因でエラーに成ります。変数はだめで、「#1」「#2」「#3」のように実数を入ればOKです。
5610 IF VV=1 THEN PUT #1,R ELSE IF VV=2 THEN PUT #2,R
5612 IF VV=3 THEN PUT #3,R ELSE IF VV=4 THEN PUT #4,R
5615 IF VV=5 THEN PUT #5,R ELSE IF VV=6 THEN PUT #6,R
5617 IF VV=7 THEN PUT #7,R ELSE IF VV=8 THEN PUT #8,R

Top  88Menu


◇使えない変数

5605 LSET DUMY$=RET$

DUMY$=RET$ は問題ありませんが、 LSET (ランダムファイルの出力用)と組み合わせた
 上記は「文法エラー」になります。
 DUMY$が原因で、次のDUMY$(VV)のように変更すればOKです。
◇解決策
5605 LSET DUMY$(VV)=RET$

Top  88Menu


◇TAB( )位置の狂い

8620 PRINT #4,AB$; TAB(GD-1);: PRINT #4,USING "##,###,###";D#;
8635 PRINT #4,TAB(24);: PRINT #4, USING "###,###,###";N#;: PRINT #4,E$

@ 125給料賃         7,470     37,350 ×田★子1月分源泉所得税
A 125給料賃 7,470 37,350 ×田★子1月分源泉所得税
 本来は、上段@のようになるべきものが、下段Aのようになってしまう。
 原因は TAB( ); 。
 PRINT #? 命令では、間に挟まる空白の長さを決め、 TAB( ) = SPACE$( ) のような働きをしてしまう。画面表示はOKだが、印刷とディスク出力では狂う。
  (もしかしたら、ディスク出力ではOKのケースがあったかも? 不確か)
◇解決策
 対策は、LPRINTでのTAB( ) を参照。

Top  88Menu