99Basicインタプリタ(手引き書) その他いろいろ


◇可能サイズの超拡大(プログラム領域と変数)

◇変数内に記憶できるサイズの上限について
 N88-dosベーシックでは、変数内に記憶できるサイズか254バイト?という制限がありました。
例えば、Q$="??? ???"で、あるいは INPUT Q$で、
 ここでQ$が254b?という上限を超えると、エラーになったはずです。これが99Basicでは1,240bていどまでは、格納できます。
透明スペーサー
 ちなみに、それ以上で1,600bくらいまでは、「入力した文字数が大きすぎる」エラーです。(このときに実行中のプログラムは、「他のアプリが使用中のため」保存できないし、あるいはエディターなどで読み込むと「編集不可で読み込みます」という状態になります。)
 さらに1,600bていど以上に大きくすると、99Basicは「ファイル形式が違っている」エラーです。(変数サイズとしてここまで巨大なミスは想定外だったので、誤ったエラーに変わったのでしょう)
透明スペーサー
◇プログラムのサイズの上限について
 組めるプログラムの最大サイズは、DOS-N88BASICでは60kb弱のハズだったが、両方とも67kbを超えてもまだOK(99Basicでは70kb超OKを確認)。これは大変に助かります。
 ある人の99Basic報告によれば、
 114KB(2552行)で実行時に、「39 Program text accident   プログラムが破壊されている」のエラーが発生します。110KBまで削減したら動作します。
 とあります。プログラムの自由度も上がり、有り難いことです。
透明スペーサー
◇おまけ.1 プログラム領域 300kb を確保する方法
  • 99Basic公式サイト Q&A(【リンク切れ】2013.10.28) 相原スグルさん回答より

一つ 余分な手間が入りますが、それで解決します。
まず、実際に動作させたいプログラムの名前が"execute.b99" であるとします。
しかし、そのファイルをすぐには開かずに、そのプログラムを開くためのプログラムを作ります。
透明スペーサー
10 rem "pre-execute"
11 rem
12 clear 300,200,200:rem プログラム領域 300kb / 変数領域 200kb / 文字列領域 200kb
13 load "execute",r:rem "execute.b99"を loadして 即 実行する。
透明スペーサー
この場合、"execute.b99"をloadした時点で、 "pre-execute.b99"は破棄されます。
これにより、プログラム領域 300kb が確保された上で"execute.b99"を読み込んで実行することになるので、"execute.b99"の容量が 299kb まで読み込んで実行する事が出来ます。
※ 上の12行の clear命令を使う際には、プログラム領域・変数領域・文字列領域 の合計が770kb 未満でなければなりません。
◇おまけ.2
 OPEN #数
 同時に開けるファイルの最大数は4。
 しかし、最大20まで拡張出来るそうです。
 ちなみにDOS-N88BASICは11かそれ以上のハズ。

Top  99Menu


◇ 環境設定

99Basic画面  これは99Basic実行画面の左上にある99の数字をクリックすると現れます。
 その中で、とくに「マウスでカーソル位置を変更する」に設定すると、ダイレクトモード(=画面上で命令する)でデバッグなどをするときに、大変に便利になります。お勧めです。
 「エラーを日本語で表示する」に設定すると、英語よりも日本語のほうが強い人に役立ちます。
 「命令/関数のヘルプを使う」に設定すると、これも便利です。わざわざ手動で、ヘルプファイルを開いておく必要が無くなります。設定したキーを押すだけで、「命令/関数のヘルプ」が開かれます。
透明スペーサー
◇おまけ
 この「設定を常に使う」に設定しても、次に環境設定を開くとこのマークが消えています。他の設定マークは残っているので不安になりますが、そのままOKで閉じても、以降も他の設定マークは残っています。ですから、一度「設定を常に使う」でOKで閉じれば、変更がない限り毎回、「設定を常に使う」を設定してOKで閉じる必要は無いように思います。
透明スペーサー
 この環境設定では、印刷開始時間をコントロールすることも出来ます。詳しくは、

Top  99Menu


 

◇ INPUTのバグ?1.


 2行にまたがるような画面表示に続く INPUT では、その行の画面表示まで読み込んでしまうことがあります。
 再現性ですが、以下のプログラムで何度もテストした結果、99Basicを立ち上げて最初の実行では問題ありません。2度目、または3度目の RUN させた以降から狂います。
透明スペーサー
100 A$="AAAAAAAAAAAAAAAAAAなら(1)、BBBBBBBBBBBBBBBBBBなら(2)、CCCCCCCCCCCCCCCCCCなら(3) 1〜3を選んでください。"
110 PRINT A$ ; : INPUT B$: C=VAL(B$)
120 PRINT "120行 B$=";B$ ; " C=";C
200 A$="AAA"
210 PRINT A$ ; : INPUT B$: C=VAL(B$)
220 PRINT "220行 B$=";B$ ; " C=";C
300 A$="AAAAAAAAAAAAAAAAAAなら(1)、BBBBBBBBBBBBBBBBBBなら(2)、CCCCCCCCCCCCCCCCCCなら(3) 1〜3を選んでください。"
310 PRINT A$ ; : INPUT D
320 PRINT "320行 D=";D
 上記プログラムで、全て 1 の数値を入力したとします。
 120行では、
B$="AAAAAAAAAAAAAAAAAAなら(1)、BBBBBBBBBBBBBBBBBBなら(2)、CCCCCCCCCCCCCCCCCCなら(3) 1〜3を選んでください。 1" : C=0
 と、おかしな結果になることがあります。B$=" 1" : C=1が本来の正しいもので、原因は冒頭に書いたようなバグによるものです。
 220行では、
B$=" 1" : C=1
 必ず正しい結果が得られます。
 320行では、
 Redo from start(スタートからやり直し) のエラーになることがあります。100行代と同じ理由で、INPUT Dに対して数字ではなく、文字列(A$の中身 + " 1")が入力されたと誤判断されてしまうのです。

◇解決策
 原因は不明ですが、メモリーの何かの影響のように思われます。
 いずれにしろその可能性があるのですから、2行にまたがらないように INPUT 文を組むべきでしょう。
 もっとも簡単な直しなら、色気もありませんが ; を削除するだけで解決します。
110 PRINT A$ ; : INPUT B$: C=VAL(B$)
 あるいは、さらに次のように直します。
100 A$="AAAAAAAAAAAAAAAAAAなら(1)、BBBBBBBBBBBBBBBBBBなら(2)、CCCCCCCCCCCCCCCCCCなら(3)"
110 PRINT A$ : INPUT "  1〜3を選んでください。"; B$: C=VAL(B$)

Top  99Menu


 

◇ INPUTのバグ?2.

670     INPUT "        以 上です  *同じ仕事( )  *もう一度 画面(y)  *終る(999) を";XY$
680     COLOR 7: IF XY$="999" THEN 300
 999を入力すれば、XY$="999"となって、THEN 300でGOTOするはずですが、何故かそうなりません。
 試しにダイレクト・コマンドで、
PRINT XY$ を実行してみると、 XY$ は次のように化けています。
        以 上です  *同じ仕事( )  *もう一度 画面(y)  *終る(999) を999

 但し何度か、いろいろテストしてみたところ、正しく「999」になっていることもあります。
 しかし化ける時とそうでない時の規則性や原因は分かりません。

◇解決策
 化ける時の規則性が発見できなかったので、次のように2行に分割することで、回避しました。

670     PRINT "        以 上です  *同じ仕事( )  *もう一度 画面(y)  *終る(999) を "
675 INPUT XY$

Top  99Menu

◇ INPUTのバグ?3.

600 LOCATE 44,10 : PRINT "コメント AAAAAAAAA"
610 LOCATE 44,12 : PRINT "コメント BBBBBBBBB"
680 LOCATE 4 ,12 : INPUT "  仕事は何ですか ";JOB
 最初に画面右側に、コメントなどを書いておき、その後で「 LOCATE 4,12」などで画面上部にカーソルを移動して、「INPUT "  仕事は何ですか ";JOB」を実行。というよくあるプログラムの一部です。
 次は、上記を実行した画面の感じです。
                 コメント AAAAAAAAA
  仕事は何ですか ?    コメント BBBBBBBBB
透明スペーサー
 JOBに文字列を入力するか、無入力(ENTERのみ)した場合は、Redo from start(スタートからやり直し) のエラーになり、ブレークはしません。このケースは正常です。
 ところがJOBに数値を入力すると、「データーの型が一致していない」のエラーが出て、ブレークして終了になります。
 これはDOS-N88BASICなどでは、数値変数に対して文字変数が入力され場合のエラーです。
    しかし99Basicでは少し異なります。
    単純に「INPUT A」と画面に直入力して実行し、文字列を入力した場合は、Redo from start(スタートからやり直し) のエラーになり、ブレークはしません。
 JOBに数字だけを入力しても、たまたまその行の後に、「コメント BBBBBBBBB」が表示されていたので、文字を入力されたとみなしてしまう訳です。その証拠に、入力をJOB$に変えて 1 を入力すると、JOB$=" 1    コメント BBBBBBBBB"となっています。

◇解決策
 対策としては、すでにテキスト画面上に文字列などが表示されている行には、INPUT "#  仕事は何ですか ";JOB などを続く表示をさせないことです。
 LOCATE などを利用して、行ずらすことで解決出来ます。

Top  99Menu


◇ 上記「INPUTのバグ?3.」の活用

 上記「INPUTのバグ?2.」に記してあるように、変数の入力行の後に、文字列が書かれているとそのゴミも拾ってしまう、というバグ?があることが分かりました。
「コメント BBBBBBBBB」が表示されていたので、文字を入力されたとみなしてしまう訳です。その証拠に、入力をJOB$に変えて 1 を入力すると、JOB$=" 1    コメント BBBBBBBBB"となっています。
 ということは、既にテキスト画面に描かれている文字列や数字を、新たな入力として利用出来るということなのです。この特性を利用しない手はありません。
 ちなみにDOS-N88BASICでも同様でしたが、N88互換BASICでは原則出来ません。
透明スペーサー
2000 PRINT E$
2010 INPUT Q$
2020 IF Q$<>"" THEN E$=Q$
 もしQ$がヌルなら(=データー入力が無ければ)、 E$はそのままで、
 もしQ$としてデーター入力があれば、そのQ$が新 E$になります。というプログラムです。
 例えば上記のようなプログラムで、データー E$の一部を訂正するケースでは、
  誤って入力した E$ の内容 → "〒969-3102 福島県耶麻郡猪苗代町字葉山"
      ↓↓
      ↓↓ 上記では番地7105が抜けていたので、以下のように追加したいとします。
      ↓↓
  正しく入力したい E$ の内容 → "〒969-3102 福島県耶麻郡猪苗代町字葉山7105"
透明スペーサー
 99BasicではDOS-BASICと同様に、カーソルを一行上に上げて、表示されている E$の一部を直すだけで済みます。すなわち、データー E$の最後尾にカーソルを置き、7105のみを入力して、リターン(=Enter)で済みます。
 たいへんに便利になります。
透明スペーサー
◇ ちなみに.1
 テキスト画面を持たないN88互換BASICでは、グラフィック画面に E$を表示するため、同じ方法が出来ません。即ち、一部訂正の場合でも、 E$の新データー全て「〒969-3102 福島県耶麻郡猪苗代町字****」を打ち込む必要があるのです。
 あるいは複雑なサブルーチンを組みむ必要があります(サブルーチンの実例)。
透明スペーサー
◇ ちなみに.2
 99Basicの画面上段・右端にある99をクリックすると、「環境の設定」に入いれます。この中で「マウスでカーソル位置を変更する」を有効に設定しておくと、使い勝手が向上してたいへんに便利になります。  しかし、この INPUT によるキー入力待ちの状態では、「マウスでカーソル位置を変更」は利きません。念のためのお知らせです。

Top  99Menu


◇ DATE

 書式: DATE
7050 FOR I=1 TO J1: READ GG$(I): NEXT
7060 DATA "New DATA 打込み + JR名簿作製" , , 訂正 & 探し出し : ' DATA 1 2 3
 GG$(I)のDATA 3、すなわちGG$(3)は、
 DOS-N88BASICとN88互換BASICでは、GG$(3)="訂正 & 探し出し"となる。
 しかし99Basicでは、GG$(3)="訂正 & 探し出し : " となってしまう。 ' の前の : まで読み込まれてしまう。
透明スペーサー

◇解決策
7060 DATA "New DATA 打込み + JR名簿作製" , , 訂正 & 探し出し ' : ' DATA 1 2 3  ' の後に : を移動するか、削除します。DATE 文で無い場合、普通は関係ありません。

Top  99Menu


◇ DATE$

 書式: DATE$
DATE$ は、現在の日付の文字列が格納されているシステム変数です。代入はできません。得られる文字列は、"yyyy-mm-dd" の形式です。
透明スペーサー
40010 YY$=LEFT$(DATE$,2): YY=VAL(YY$): MM$=MID$(DATE$,4,2): MM=VAL(MM$) ''  WIN互換ベーシック
40010 YY$=MID$(DATE$,3,2): YY=VAL(YY$): MM$=MID$(DATE$,6,2): MM=VAL(MM$) ''  99Basic
 DATE$については、99Basicでは"yyyy-mm-dd" の形式。
 DOS-N88BASICや、WIN互換ベーシックでは"yy-mm-dd" の形式。
 2桁がずれるので、この違いの修正が必要になります。

Top  99Menu


◇ STR$(数値)

数値を10進数の文字列に変換します。
 書式: STR$(数値)
 与えられた数値を、10 進数で、文字列に変換します。
 指数部が必要な数字では、指数表現になります。
 STR$ 関数で作られる数字の文字列は、PRINT 命令で表示されるのと異なり、数字の前後には空白が付加されません。
透明スペーサー
 N88-BASIC(86)とN88互換BASIC では、先頭に半角空白が1つ挿入されているので、移植の際には注意が必要です。
 INPUT Q : Q$=STR$(Q) で、仮に 1を入力すれば、
 Q$="1" が、99Basicでの結果です。
 Q$=" 1"が、DOS-N88BASICや互換BASICでの結果です。
透明スペーサー
2010 IF A1=1 AND SP$="" THEN EE$=STR$(1) → 問題なし
2564 IF A1=1 AND SP$="" THEN EE$=STR$(VAL(EE$)+1) → 問題なし
 上記のように、数値を単純に文字列に変換している場合は問題はありません。そのままで良いです。
40030 IF YY<30 THEN YY=YY+100: YY$=RIGHT$(STR$(YY),3) '  → 問題なし
 上記のように、RIGHT$を使って右から何文字かを記憶する場合も、問題はありません。そのままで良いです。


40340 YY$(I)=RIGHT$(STR$(X),(LEN(STR$(X))-1)): HH$=YY$(I) → 要 修正
 上記のように、RIGHT$を使っても半角空白1文字分をマイナスしている場合は、狂います。

◇解決策
 例えばX=1234の場合、N88互換BASICやDOS-N88BASICでは、YY$(I)="1234"。
 99BasicではYY$(I)="234"となってしまうので、(LEN(STR$(X))-1)の-1を削除し、
YY$(I)=RIGHT$(STR$(X),(LEN(STR$(X))))とするか、YY$(I)=STR$(X)だけでも良いのです。

Top  99Menu


◇ LEFT$、MID$

MID$ (命令・関数)
 文字列の一部を置き換えます(=命令書式)。あるいは、文字列の一部を切り出します。(=関数書式)
 命令書式: MID$(文字列変数,開始位置[,[長さ][,置換方法]])=文字列
 関数書式: MID$(文字列,開始位置[,長さ])
命令書式とは、
 W$="123456789": MID$(W$ ,4 ,2)="AB"  とした場合、W$="123AB6789"に置換されます。
関数書式とは、
 W$="123456789": A$=MID$(W$ ,4 ,2)  とした場合、A$="45"になります。
 W$="123456789": PRINT MID$(W$ ,4 ,2)  とした場合、"45"が画面表示されます。

 LEFT$、MID$そのものはDOS-N88BASICやN88互換BASICとまったく同じですが、STR$と組み合わせた場合は注意が必要です。
 99BasicではSTR$の先頭に半角スペース1文字が入りません。そのためにSTR$と組み合わせた場合は、従来のままだと先頭の数字1文字が消えてしまいます。
100 A=123: A$=STR$(A): W$="----------": MID$(W$,1,5)=A$ '' というプログラムの場合、
   A$=" 123": W$=" 123------"  ←  DOS-N88BASICN88互換BASIC
   A$="123" : W$="123-------"  ←  99Basicでは、
透明スペーサー
200 W$="AAA ---BBBB-------": N#=1234567: N$=STR$(N#): MID$(W$,5-1,8)=N$: N$=MID$(W$,5,7): N#=VAL(N$)
210 PRINT " W$="; W$ ; "N$="; N$; "N#="; N# '' というプログラムの場合、
   W$="AAA 1234567---BBBB-------": N$="1234567": N#=1234567  ←  DOS-N88BASICN88互換BASIC
   W$="AAA1234567 ---BBBB-------": N$="234567 " : N#=234567  ←  99Basicでは、
 プログラム上ではエラーとならなくても、例えば"1234567"が"234567 "に化けてしまうのです。この場合だと100万円単位の1桁が消えるのですから、大変なことになります。金額、電話番号などなどのように数字を扱う場合に注意が必要です。とくにファイル出力の場合は、その段階では画面上にバケが現れないので、より注意します。
5500 ' ------ Sub. OUTPUT #1-8(VV) ---- 730
5510 W$=SPACE$(250): MID$(W$,1,13)=NA$
5555 ' MID$(W$,139,6)=LAST$  : MID$(W$,145,2)=MID$(STR$(VAL(POIN$)+VAL(P1$)),2,2)    '  N88互換BASIC
5560   MID$(W$,139,6)=LAST$  : MID$(W$,145,2)=MID$(STR$(VAL(POIN$)+VAL(P1$)),1,2)    '  99Basic
5577 'MID$(W$,241,1)=DM$    : MID$(W$,242,2)=A1$    '  N88互換BASIC
5580  MID$(W$,241,1)=DM$    : MID$(W$,243,2)=A1$    '  99Basic
5582      W$=W$+SPACE$(100): W$=MID$(W$,1,250)

5590 IF A1>9 THEN A1=0
5592 '' NSA$(I)=RIGHT$(STR$(A1),1)+RIGHT$(STR$(SEX+JR),1)+LEFT$(NA$,3)+MID$(I$,2,3)     ''  N88互換BASIC
5595    NSA$(I)=RIGHT$(STR$(A1),1)+RIGHT$(STR$(SEX+JR),1)+LEFT$(NA$,3)+MID$(I$,1,3)     ''  99Basic

Top  99Menu


◇ KMID$

全角文字を1文字と数える数え方で、文字列中から指定した文字数の文字列を切り出します。
 書式: KMID$(文字列,開始位置[,文字数])


全角文字を1文字と数える数え方で、文字列の、指定された開始位置文字目から始まる文字数を切り出します。KMID$ は MID$ と異なり、命令としての使用方法はありません。
参照: MID$(命令・関数)



 KMID$そのものはDOS-N88BASICやN88互換BASICとまったく同じように思います。
 しかしKMID$はありますが、KLEFT$ KRIGHT$は存在しません。必要な場合は、KMID$を応用します。
100  W$="1234567890"
110  A$=KMID$(W$ , 1 , 3)             ''   存在しない KLEFT$($ ,3)と同じ意味の命令になり、A$="123"になります
120  B$=KMID$(W$ , KLEN(W$-3) , 3)    ''   存在しないKRIGHT$($ ,3)と同じ意味の命令になり、B$="890"になります

 全角文字を扱う場合は、半角との混合であってもMID$ではなく、「KMID$(関数)」を使うのが基本です。
 同じく、全角文字を扱う関数にKLENがあり、こちらも同様です。
参照: KLEN

Top  99Menu


◇ KLEN (とLEN)

全角文字を1文字と数える数え方で、文字列の長さを調べます。
 書式: KLEN(文字列)
LEN 関数では全角文字を 2 文字として数え、すなわち文字列の「バイト数」を返しましたが、KLEN 関数では、全角文字を1文字として数えた「文字数」を返します。
例:
PRINT LEN("123全角文字") →  11
PRINT KLEN("123全角文字") →  7

100 A$="1234567890"
200 B$= MID$(A$ , 5, 4): BL=LEN(B$): BKL=KLEN(B$)
300 C$=KMID$(A$ , 5, 4): CL=LEN(C$): CKL=KLEN(C$)
 これを実行するとB$="45?"  、BL=4 、 BKL=3
 これを実行するとC$="5678"、CL=7 、 CKL=4
 注:B$="45?"の左端の?は、全角数字(=2バイト)を強引に半切した化け文字で、見た目は半角の空白に見えます。


 全角文字を扱う場合は、半角との混合であってもLENではなく、「KLEN(関数)」を使うのが基本です。
 同じく、全角文字を扱う関数にKMID$があり、こちらも同様です。


参照: KMID$(関数)

Top  99Menu


◇ +.9などの省略形(小数点の数字の表記)

8040 COLOR 4: N=N-1: T1=INT(N/5+.9)
3170 K#(14,I)=(T_K*10000)*(R_RITU*(365/365))*.8 ' 社債受取利息
 +.9 *.8などの省略形は「必要なパラメーターの指定がない」のエラー。
 +0.9 *0.8などと正しく書くこと。
透明スペーサー
 ちなみにDOS-N88BASICでは、T1=INT(N/5+0.9)と書いておいても読み込まれたプログラムLISTを見ると、自動的にT1=INT(N/5+.9)に書き改められてしまう。

Top  99Menu


◇ FOR〜NEXT

 FOR〜NEXT ループがふつうに使われている場合は変更無しで動きます。
 しかしFOR 命令の初期値が、終了値よりも大きいことによって、FOR〜NEXT ループ内の部分の実行をスキップすることを期待するプログラムは改造の必要があります。99 BASIC の FOR〜NEXT ループは、初期値が終了値より大きい場合でも、1回はループを実行します。ですから、その様な部分では、FOR 命令の直前で、IF 命令を使い、初期値と終了値をチェックして、正しい場所に GOTO してやる必要があります。
透明スペーサー
 このように難しいことが書かれていますが、私の場合はほとんど修正の必要無しで動きました。
 テストして分かったのは、以下の点は異なるようです。
100 FOR N=1 TO X: PRINT N: NEXT
 DOS-N88BASICとN88互換BASICでは、X=0の場合にはこの行は実行されません。従って、PRINT Nは表示されません。それを利用して、Xが1かそれ以上の場合のときだけ、NEXTまでの命令を実行せよ=そうでなければ、この行は無視せよ、という簡略な書き方なのです。
 しかし99Basicでは、「-STEP 1」などが無くても1回だけ実行され、「(X=)1」表示されます。

◇解決策
 もしXが0ならこの行は無視しせよ、という命令なら次のように書く必要があります。
100 IF X=>1 THEN FOR N=1 TO X: PRINT N: NEXT
 または、
90 IF X=0 THEN GOTO 110
100 FOR N=1 TO X: PRINT N: NEXT

Top  99Menu

◇ FOR〜NEXT その2.

100 FOR N=1 TO 9
150     IF *** = /// THEN  500
200 NEXT
300 PRINT " N= "; N
350   N=N-1
 私の不確かな記憶では、DOS-N88BASICやN88互換BASIC for Windows95の場合は、このケースなら N = 9 が表示されたように思います。ところが99Basicでは、Nは +1 されて、10になってしまいます。
 FOR〜NEXT がただの循環ならこのままで良いのですが、、。

◇解決策
 150行でのIF の該当が無く最後までループを繰り返した後で、Nが意味を持っている場合は 350行のようなフォローが必要です。
 たったこれだけのことです。
 でも本日(2007/ 6/23)、たまたま私は自作の源泉徴収納税のプログラムの結果で、各月の人数が一人多いことに気がつきました。今までの数年はこれを知らずに、書類に転記をしていました。
 たったこれだけのことでも、FOR〜NEXTのこういうケースでの違いを知らなかったために、原因究明までに半日以上を費やしたのです。
 基本的には20年近く前に組んだプログラムで設計をあまり理解できず、しかも約1,034行という大きなサイズのものだったので、かなかなの苦戦でした。

Top  99Menu


◇ LOCATE

 書式: LOCATE [@画面番号,]X,Y[,カーソル]
   画面番号........0〜3 の数値
   X、Y..........0〜画面サイズより小さい数値
   カーソル........0 か 1。
 文字を表示する位置を指定します。あるいはカーソル表示を有無を設定します。
 PRINT 命令や PRINT USING 命令、WRITE 命令などで文字を表示する位置を指定します。
 これらの命令で文字が表示できるのは、テキスト画面だけではありません。キャラクタ画面、グラフィック画面にも PRINT 命令や PRINT USING 命令、WRITE 命令(注:)などで文字が表示できます。
注:
 WRITE 命令とは、「画面やシーケンシャルファイルに数字や文字を表示します」となっています。
 このLOCATE が有効なのは、WRITE 命令の画面表示だけであって、シーケンシャルファイル出力では無効ではないかと想像します。但しテストはしていません。

 なおXは桁位置を、Yは行位置を指示します。
LOCATE 10, 5 の場合は、6行目の10桁目にカーソルを置け、という命令です。(行については、画面最上端を0行と数えるので、Y=5 とすれば+1の6行目になります)
* X、Yを()で囲った場合、
LOCATE ( X )     桁位置Xだけを囲うことはOK
LOCATE ( X, Y )   桁位置X、行位置Yの両方を囲うとエラー
 99Basicではエラーになりますが、DOS-N88BASICとN88互換BASICでは、どうだったかは不明です。
透明スペーサー

100 PRINT TAB(8); "資 産"; TAB(28); "負 債"; TAB(48); "収 入"; TAB(68); "支 出"
 99BasicではTAB( )は用意されていないので、単なる配列と判断し、配列宣言( DIM )をしていなければ、TAB(10)以上では「配列外」エラーになります。仮に配列宣言をしても、10を越しても配列変数TAB( )がエラーにならないだけで、本来の文字列の表示位置を指定するという働きはしません。

◇解決策
 そこで、
100 LOCATE (8): PRINT "資 産";: LOCATE (28): PRINT "負 債";: LOCATE (48): PRINT "収 入";: LOCATE (68) :PRINT "支 出"
 正しい使い方かどうかは不明ですが、上記のように書き換えると今までと同様に表示されます。即ち、TAB( )の完全な代理を果たしてくれます。
 詳しくは

Top  99Menu


◇ CLS

850 CLS 2
 CLS 2は、グラフィック画面の消去。CLS は、テキスト画面の消去。
 99BasicはDOS-N88BASICとまったく同じ機能。
 N88互換BASICではテキスト画面を持たないが、CLS でも、CLS 2でもエラーにならずは画面の消去をしてくれたハズ?

Top  99Menu


◇ 「シェアリング」違反

6010 OPEN DR$+"カイケイ."+YY$ AS #2
Sharing violation シェアリング違反
 この「DR$+"カイケイ."+YY$」ファイルが既にエディタなどで開かれているとき、「シェアリング」違反、ということである。
 エディターなどにデーター(やプログラム)を読み込んでおき、同時進行が出来るので、これはN88互換BASICでは許されて便利です。DOS-N88BASICではどうだったか覚えていません。
 しかし但し一般論としては、違反とするソフトのほうが多いのではないでしょうか。MBASICでも違反になったハズです。

Top  99Menu


◇ SOUND$

9330 SOUND$=INKEY$: IF SOUND$="" THEN 9330
 99BasicではSOUNDという関数が用意されているので、SOUND$という変数は使えません。
 DOS-N88BASICでは、確か「予約語」とか何とか呼んだように思いますが、関数やコマンドと重なる文字列を変数などに使用出来ません。N88互換BASICでも同じです。

Top  99Menu


◇ BEEP

4020 FOR N=1 TO 30: FOR I=1 TO 25: BEEP 1: NEXT: BEEP 0: NEXT
 上記は、99BasicではBEEPにオプションは無いので、文法エラーになります。
4020 FOR N=1 TO 3: BEEP: NEXT
 上記のようにオプションを外した上に、繰り返し回数もかなり減らしておきます。
透明スペーサー
 ちなみにDOS-N88BASICではBEEP 0は、BEEP音を消す役目。BEEP 1と繰り返すことで短く軽い音に変え、注意を促すBEEP音を長い秒数鳴らしても、騒音ではなくなるプログラムだったように記憶しています?
 今チェックしたところN88互換BASICでは、エラーにはならないが、BEEP音も出していませんでした。

Top  99Menu


◇ VAL(関数)

 文字列表記の数値の値を実際の数値に変換します
   書式: VAL(文字列)
 文字列で指定した数値の書かれた文字列を、数値型に変換します。文字列は、プログラムに書く様な書式の数値が書かれている文字列ならば何でも構いません。文字列長 0 の文字列を指定するとエラーになります。
 返される数値の型は、文字列の中で指定された型になります。
透明スペーサー
A=VAL("97 11 13")
 99BasicではA=97、不確かですがDOS-N88BASICではA=971113。
A=VAL("9711 13")
 99BasicではA=9711、不確かですがDOS-N88BASICではA=971113。
A=VAL("971113")
 99BasicでもDOS-N88BASICでも、A=971113と同一になります。
注意:  従って99Basicでは、VAL("00 11 13")、VAL("00 00 13")などは =0 になってしまいます。

Top  99Menu


◇ CHILD

 DOS-N88BASICでは、CHILD または CHILD,M によって一時的にコマンドライン(MS-DOSモード)に入り、EXIT 命令によってDOS-N88BASICに戻ってきたはずです。
50070 IF Q$="" THEN CHILD " COPY "+DR$+"*.8* " +RAM$ ,1,0
50080 IF Q$<>"" THEN YY$=Q$: CHILD " COPY "+DR$+"*."+YY$+" "+RAM$ ,1,0
50090 CLOSE :RUN "資金繰.BAS"
 例えばCHILD では、上記のようにコマンドラインで何らかの仕事を処理した後、自動的にBASICに戻ってきて、50090行の実行に入ります。
 CHILD,M の場合は、EXIT 命令によってDOS-N88BASICに戻ってきたはずです。
透明スペーサー
 99BasicではCHILDは命令、関数として用意されていますが、全く別物です。ですから、
CHILD
CHILD,M
 どちらも「文法どおりに記述されていない」のエラーになります。
透明スペーサー
 N88互換BASICでは、
機能:指定したWindows 実行可能プログラムを起動します。
文例:CHILD "WINBAS95 P090.BAS",5
 となっていてます。やはり、
CHILD
CHILD,M
 どちらも「文法エラーです。」になります。

Top  99Menu


◇ DEFFN(命令)/ FN(関数)

◇ DEFFN (命令)
 ユーザ定義関数を定義します。
 書式: DEFFN英文字[(仮引数[,仮引数,...])]=式
     英文字.....A〜Z の1文字     仮引数.....変数名
 ユーザ定義関数は、26 個定義出来ます。A〜Z の英文字で識別される 26 個です。定義する関数は、数値を返すものでも文字列を返すものでも構いません。
 ユーザ定義関数は、仮引数の値を使った式で定義されます。式は、ユーザ定義関数の演算内容を記述する式で、1行で記述できるものでなければなりません。仮引数は、プログラムの他の部分で使っている変数名であっても、それとは関係なく、この式の中だけで有効です。もちろん式の中には仮引数ではない変数も使えます。
 ここで定義したユーザ関数は、プログラムの各所で、FN 関数として使用できます。
 FN で実際に関数が使われる時、FN に引数として与えられた値が、仮引数に代入されて式の演算で出た値を FN 関数の値として返します。仮引数と一般の変数が同じであった場合でも、一般の変数の方の値が変化してしまうことはありません。
 仮引数は無くても構いません。
 DEFFN 命令は、ダイレクトモードでは実行できません。
参照:FN(関数) 
透明スペーサー
 このDEFFN(命令)/ FN(関数)についてのコメントは、次のFN(関数)の後にまとめて書いてあります。

◇ FN (関数)
 EFFN 命令で定義したユーザ定義関数を使う関数です。
 書式: FN英文字[(引数[,引数,...)]
 ユーザ定義関数は英文字 A-Z で識別される 26 個が使えます。
 書式は、上記の様に書かれていますが、実際には DEFFN 命令で定義した仮引数の形の書式通りでなければいけません。
 仮引数と実際の引数の個数が異なったり、仮引数が文字列型なのに数値を引数にしたりすると、エラーになります。戻り値も、DEFFN 命令で定義した型になります。
 以下の様に、FN 関数の中で、他の FN 関数を使用することもできます。
10 DEFFNA(X)=X*10
20 DEFFNB(X,Y)=FNA(X)+FNA(Y)
30 PRINT FNB(10,20)
透明スペーサー
 しかし、以下の様に1つの FN 関数が再帰的に呼び出されるような構造になっている場合には、エラーとなります。
10 DEFFNA(X)=FNB(10,X)
20 DEFFNB(X,Y)=FNA(X)+FNA(Y)
30 PRINT FNB(10,20)
参照:DEFFN(命令) 

◇ DEFFN(命令)/ FN(関数)についてのコメント
 説明を読んでも私にはまっくた理解も出来ず、イメージも湧きませんでした。私がTAB( )の変更で悩んだときに、

Top  99Menu


◇ RENUM

      注:DOS-N88BASICでは省略の REN でも良かったような気がしますが、99Basicではエラーになります。
 行番号をきれいにふり直します。
 書式: RENUM [先頭行番号][,[<開始行番号‖*ラベル>][,増分]]
透明スペーサー
 プログラミングを続けていくと、次第に行番号の並びが不揃いになって、行番号の間隔が狭くなり、プログラムの挿入ができなくて困ったりします。
 この様なとき、RENUM 命令を実行すると、プログラムの行番号が、等間隔にきれいに付け直されます。もちろん行頭にある行番号だけでなく、GOTO 命令で指定される行番号の方も、矛盾無く付け直されます。
透明スペーサー
 先頭行番号は、新しく付ける最初の行番号で、省略すると 10 になります。
 開始行番号は、行番号のふり直しを始める行番号で、現在プログラムに付けられている行番号のどこかを指定します。省略すると、プログラムの全体が RENUM の対象になります。
 増分は、新しくつけ直す行番号が、いくつずつ増える行番号であるか指定します。省略した場合は 10 です。
透明スペーサー
 GOTO 命令などで存在しない行番号が指定されている部分が、プログラム中に存在すると、RENUM 命令を実行した時に Undefined line number エラーとなります。その行番号は、ふり直しされずに、古い行番号の状態が、そのまま残ります。
透明スペーサー
例:
   15 FOR I=0 TO 10
   30 PRINT I;
   40 NEXT
   60 GOTO 15
 上記の様なプログラムに対して、RENUM 100,,5 を実行すると以下の様になります。
   100 FOR I=0 TO 10
   105 PRINT I;
   110 NEXT
   115 GOTO 100
透明スペーサー
 以上は、ヘルプファイルに書かれているとおりです。
 これについては、99Basicも、DOS-N88BASICも、N88互換BASICも同じです。
透明スペーサー

◇実際の使い方
1.基本的な使い方。
1−1 プログラムの読み込みは、通常と同じです。LOAD "****.**"
 プログラムとして中味が正しければ、***.、***.BAS、***.PRO、***.TXT、***.DATなどなど、ファイル名は何でも構いません。
1−2 RENUM などを画面に入力後、Enterキーを押します。
1−3 LIST で、行番号を書き換えたプログラムを画面で見ることが出来ます。これは必ずしも必要な訳ではありません。
1−4 SAVE "***.***",Aで保存して、完了。
 ,Aは不可欠のものではありませんが、これを省くとバイナリー・ファイルで保存されてしまい、後でエディターなどでの編集が出来なくなってしまいます。
透明スペーサー
2.実際上のポイント
 上記のような単純な使い方では、行番号は等間隔に10番ずつ大きくなるだけです。
 ところが大きなプログラムでは、
1000番台は行う仕事の選択メニュー、
2000番台は対象年度、使用ドライブやフォルダー、プリント実行の有無の確認、
3000番台はファイルの読み込み、
4000番台は計算、
5000番台は結果.1の表示、
 などなどのように、整理しているはずです。これが狂っては、今後の手入れが行いにくくなります。
透明スペーサー
 そのために、LIST 、LIST -500、LIST 1000-1200、などなどを使いながら、書き換え後のリストを確認します。
 そして、もし1000行にしたい行が、580行になっていたとします。この場合は、
RENUM 1000 , 580 を実行します。
もし、
透明スペーサー
 以降も同様に行い、2000番台、3000番台と整理していきます。
 そして全てが終わったら
 SAVE "***.***",Aで保存して、完了です。
透明スペーサー
3.実際上のポイント.2
 ところがRENUM を行うと、どこが本来の2000番台、3000番台か分からなくなってきます。その防止策として、
8000 ' ------------ PartB-3 ------------ 2340 損益計算書
 上記が本来のプログラムであるとすれば、次のように追加をしておきます。
8000 ' 8000------------ PartB-3 ------------ 2340 損益計算書
 このようにしておけば、この行番号が代わっても、「' 8000」は不変です。その結果、この行は最終的に8000 番にしなければいけないことが分かります。
 RENUM の途中で、
4620 ' 8000------------ PartB-3 ------------ 2340 損益計算書
 と代わっていれば、
RENUM 8000 , 4620 を実行すれば良いのです。
透明スペーサー
4.実際上のポイント.3
 ひじょうに大きなプログラムでは全体を一緒にRENUM すると、とうぜん全体の行番号が代わり、LIST確認などが大変です。
 それを防ぐには、1000番台、2000番台、3000番台と分割して、それぞれをRENUM していくと楽です。
透明スペーサー
 仮に2000番台の手入れを例にして、説明をします。
 残りの2000番台以外の行が、2000番の行だけにGOSUB している場合はOKですが、それ以外の2000番台にGOSUB している場合はエラーの原因になります。(必ずしもエラーとしてメッセージが出るとは限らず、多くは誤った結果が出るだけの実質的なエラーです)
 その対策はありますが、面倒なのでお勧めできません。
720 GOSUB 2000 '''  この場合はOK。
860 GOSUB 2400 '''  この場合はダメ。この2400行はRENUM 実行で、違う行番号に変わっています。
   対策としては、
2400 ' 2400------------ PartB-3 ------------ 損益計算書
 あらかじめ、上記のように ' 2400を入れておけば、RENUM 実行後これを探し、860 GOSUB を手動で訂正すれば良いのです。

Top  99Menu


◇ ON **** GOSUB XXXX

 **** をした時は、サブルーチン XXXXへ GOSUBし、そこでの処理をして戻ってらっしゃいという便利な命令です。飛び先のXXXXには、行番号、または*Raberuなどのラベルが使えます。
 いろいろな種類がありますが、その一部だけを紹介します。
ON 数値 GOSUB
2130 INPUT " 訂正があれば、名前(1)、住所(2)、電話(3)、年齢(4) 番号の入力を";Q
2140    IF Q<>0 THEN  ON Q GOSUB 2900,3000,3300,3500
 このように数値には Q などの変数が使え、もしQ=1ならGOSUB 2900、もしQ=2ならGOSUB 3000、
 もしQ=3ならGOSUB 3300、もしQ=4ならGOSUB 3500をします。

ON ERROR
290 ON ERROR GOTO  *ONERROR
 もしエラーが発生したら、ラベル*ONERRORに GOTO しなさい、というプログラムです。 私の場合、DOS-N88BASICを使っていた時代には、飛び先では主に次の2つの処理をしていました。
1.
 DOS-N88BASICのエラーメッセージが英文だったので、日本語で詳しく自作しておいたものを、表示する。
2.
 作りかけのデーターがムダにならないように、別名で強制保存する。
 または、データーを壊す恐れがある時は、ファイルの書き換えなどをさせずに強制保存する。

ON KEY GOSUB ,,, : KEY () ON
80 ON KEY GOSUB ,,,,,, 16000,15000
90 KEY (7) ON: KEY (8) ON
 ファンクション・キー( Fキー)が押された時に、キー番号に応じてGOSUB せよ、という命令です。
 サンプルのプログラムでは、80行ではもしF-7キーならGOSUB 16000、F-8キーならGOSUB 15000
 そして90行では、この命令を有効にせよ、となっています。

ON MOUSE
100 ON MOUSE GOSUB 2000
110 MOUSE ON
 100行で、マウスが何かをしたら GOSUB 2000をせよ、110行でこの命令を有効にせよ、と設定しています。
* ON MOUSEと GET MOUSE の詳しい説明とサンプルのプログラムは、別ページにあります。
◇ ON MOUSE GOSUB や ON KEY GOSUB命令を有効にする
 プログラムで、割込ルーチンを指定しただけでは割込が開始されません。その後で、割込を MOUSE ON や KEY (7) ONなどを書いておく必要があります。99Basic、DOS-N88BASIC、N88互換BASICの全て同じです。
100 ON MOUSE GOSUB *ON_MOUSE : GOSUB ON
280 ON KEY GOSUB ,,,,,, 16000,15000 : KEY (7) ON: KEY (8) ON
 このように同一行に書くこともOKです。

◇INPUT Q$ では割り込まず、 INKEY$では割り込みます。
 何故かINPUT Q$ の最中にはマウスを動かしても、99Basic、N88互換BASICでは割り込みが発生しません。( GOSUB *ON_MOUSE、 GOSUB 2000などが実行されないという意味です。)INPUT Q$ が終わった瞬間に、割り込みが発生します。(但し、N88互換BASICではテストをしていないので不明です。)
 DOS-N88BASICでは、実行出来ていたはずです。
 いろいろテストの結果、INPUT Q$ を辞めて INKEY$に代えたところ、割り込みが発生すること分かりました。
1000 INPUT Q$
 この状態では、割り込みを発生しない、という意味です。
1000 Q$=INKEY$ : IF Q$="" THEN GOTO 1000
 この状態では、割り込みが有効になります。

Top  99Menu