[PR]今日のニュースは
「Infoseek モバイル」

INPUT_NO  2001/12/24 V1.00完成

 

 どうも皆さん。楽しくオートプログラム作ってますか?私はマイツールを使い始めて5年になりますが、ずっとオートプログラムの自分の作ったプログラムの中で、単独指定だけでなく、PAGE命令のように連続指定や複数指定、混合指定(指定方法については命令辞典P488参照)などが使えたら便利だなぁと思っていました。

 

 それを実現するプログラムモジュールを作ってみましたのでここで紹介してみます。興味を持った方は是非使ってみて、感想、批評、苦情、エラー報告などお待ちしています。プログラムの中でプログラムを実行するのを繰り返すので、実行速度は速くないかもしれませんが、結構使えると思います。

※このINPUT_NOで指定できるのは数値による単独、連続、複数、混合の指定法のみです。H,T,A,C,L等の指定やグループ指定、他はできません。やるとしたらサブルーチンの方でV変数でつなげてやる手もあります。

 

INPUT_NOとは?

 

 単独、連続、複数、混合指定の数値を解析するプログラムモジュールです。使う変数はZ41〜Z48,Z54,Z55とV49,V50です。

 まずV50とV49ですが、まず上位プログラムで、V50に指定数値(ex. 10,20-35,40-48,59 )を入力し、V49にはその数値に対して、実行するプログラム名を入力しておいてからINPUT_NOを実行します。するとINPUT_NOはV50を解析して、Z46に一つずつ数値を入れて、INPUT_NOの内部で、V49に書かれているプログラムを実行します。(解析する時入力エラー(※1)を発見した場合、Z48=1にして上位プログラムに戻ります。メッセージはプログラムによって違うこともありますので上位プログラムで表示するようにします。)実行されたV49はZ46の数値を元に処理をして、INPUT_NOに戻ります。INPUT_NOは次の数値をZ46に代入して、V49のプログラムを実行します。最後までこれを繰り返して終了です。

 

テストプログラム「MAIN」によるINPUT_NOの流れ

 

 これだけの説明は使い方がイマイチよくわからないという方もいるかと思いましたので、簡単なサンプルプログラムで具体的な使用例を挙げてみます。まず3つのファイル「INPUT_NO.MYX」,「MAIN.MYX」,「SUB.MYX」をMYFILEXフォルダに保存してFILEXでオートプログラムに登録しておきます。多分保存するだけで登録する必要はないと思います。登録されてなかった場合FILEX命令で登録してください。

 INPUT_NOを使うには最低2個のプログラムが必要になります。一つはメインとなるプログラム(ここでは[MAIN]とします。)で、ACCPなどで、V50に指定数値(ex. 10,20-35,40-48,59 )を入力します。V49にその数値(Z46)を受け取って実行するプログラム名(ここでは[SUB]とします。)を書いておきます。SUBはここでは入力された数値の行に"選択"または""(空白)を入力するプログラムです。

 

まず「仕事は=」の状態から

 

RUN[Enter]MAIN[Enter] 

 

としてください。MAINが起動します。

 

 まずMAINは表題が[TEST]の1列7000行の表を作成し、サブルーチンである"SUB"をV49に格納します。

[ 入力‥[Enter],削除‥1,終了‥ESC ]: で動作を選択します。

 

「入力」を選択した時は"選択"、削除を選んだ場合は""が指定した行のセルに入るようになります。

ここでは入力する為に[Enter]を押します。

 

 

次に指定する行を入力します。

 

ここでは 

8-12,19,24-26,20[Enter]

と指定します。入力された数値はV50に代入します。

 

ここでINPUT NOを起動させ、V50を解析して、もし数値入力にエラー(※1)があった場合、Z48=1にしてINPUT NOは終了します。Z48=1を受け取ったMAINプログラムはエラーメッセージ(ページ指定に誤りがあります、入力が範囲外です、等)を表示します。

 正しい入力だった場合、数値を一つずつZ46に入れてV49のSUBを実行するのを繰り返します。

 指定した行に"選択"の文字列が入力されます。色々削除したり、入力したりができるのを確かめてみて下さい。

 このプログラムは無限ループになっているので、エスケープキーを押すまで、同じことを繰り返します。適当なところで終わらせてください。

 

...というような流れです。わかりますでしょうか?なにぶんこのような場で説明するのは初めてなので、わかりにくいところはご了承ください。

 まだできたばかりですのでエラーなど、動作に異常があるかもしれません。もし使っていただいて、異常な動作があったというような方は、までメールでお知らせください。

 

※1 下記のような入力があった場合はエラーになります。

・(カンマ、ハイフン、数値)以外の入力が一つでもある場合、スペースもだめです。

・1バイト目が0-9の数値以外の時。

・最終バイトにハイフンが入力された時。カンマはOK。

・,,  ,-  -,  --など区切り文字の後に続けて区切り文字が入力された時。

・○−○の連続指定の時に、左側の数値が右側の数値よりも大きい時。

・ ,- がエラーになるのでマイナスの数値は扱えません。あまり必要になるとも思われませんでした。

 

下記のファイルをお使いのマイツールのMYFILEXフォルダに保存してください。

 INPUT_NO.MYXはなるべくカプセル化を心がけたつもりです。改善点があったらお教えください。

全て、使う方自身の責任に置いて行って下さい。
リコー社、私、ともに、如何なる保証も出来ません。特にまだできたばかりなので注意してください。

INPUT_NO.MYX(33KB)

 

MAIN.MYX(8KB)

 

SUB.MYX(2KB)

 

コード

[INPUT_NO] 

*このプログラムはオ―トプログラム内において、単独、連続、複数、混合指定をする為のモジュ―

*るです。

*V49  実行するプログラム名(このプログラムがZ46を受け取る)

*V50  カンマ,ハイフン区切り数値範囲

 

*Z41  数値の最初のバイト

*Z42  数字の最後のバイト

*Z43  数字のバイトの長さ

*Z44  V50のバイト数

*Z45  直前は"数値"  "-"  "," のどれだったか?

*     "数値(48-57)"=0,"-(45)"=1, ",(44)"=2      ()内はASCIIコ―ド

*Z46  V49で実行されるモジュ―ルへの引数

*Z47  Z42+1  ハイフン又はカンマの次のバイトは数値かどうかのチェックの為

*Z48  エラ―?  Y=1,N=0

 

*Z54  "-"でつながっていた場合の前半の数値

*Z55  "-"でつながっていた場合の後半の数値 & ","で区切られた直前の数値

 

  WSIZE:2:::::                     *Z40で行数を得るため

  IF V50="" THEN:GOTO *END:ENDIF:

  IF V49="" THEN:

    COLOR:7:4:2:

     LOC:Z40-3:6:PRINT: 実行するプログラム名が :

    LOC:Z40-2:6:PRINT:" V49に入っていません。  ":

     LOC:Z40-1:6:PRINT:                        :

    ACCP:"[ 魔押してください。]:":?:

    GOTO *ERROR:

  ENDIF:

  Z48=0:

  TOASCII:V50:"V50":

  LEN:V50:Z44=Z0:                   *Z44  V50のバイト数

*~~~~~~~~~~~~~~~~~~エラ―検出部START~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

  V0="":

  Z41=1:                            *Z41  数値の最初のバイト

  Z45=0:                            *Z45  直前は"数値"  "-"  "," のどれだったか?

  IF V50[1]<48 OR 57<V50[1] THEN:   *先頭のバイトは数字以外の時は

    GOTO *ERROR:

  ENDIF:

  IF (V50[Z44]<48 OR 57<V50[Z44]) AND V50[Z44]<>44 THEN:

    GOTO *ERROR:                    *最後のバイトが数値でなく、カンマでもない時は

  ENDIF:

  FOR Z42=1 TO Z44-1:

    V0="":

    Z47=Z42+1:

    IF V50[Z42]=45 OR V50[Z42]=44 OR (48<=V50[Z42] AND V50[Z42]<=57) THEN:

                                          *Z42バイト目が"数値"  ","  "-" のどれかならば

      IF V50[Z42]<48 OR 57<V50[Z42] THEN:     *Z42バイト目が数値以外の時は

 

        IF V50[Z42]=44 THEN:                    *Z42バイト目が","の時は

          IF V50[Z47]<48 OR 57<V50[Z47] THEN:     *Z42+1バイト目が数値以外の時は

            GOTO *ERROR:

          ENDIF:

          GOSUB *HANTEI_-:                      *ハイフン区切りのエラ―チェック

          Z41=Z42+1:                            *次の為に数値の最初のバイト数をセット

          Z45=2:                                *Z42バイト目は","でした

        ELSE:

          IF V50[Z42]=45 THEN:                  *Z42バイト目が"-"の時は

            IF Z45=1 THEN:                      *2連続ハイフンの時は

              GOTO *ERROR:

            ENDIF:

 

            Z43=Z42-Z41:        *数値のバイトの長さ

            STRCPY:V50:V0:Z41:1:Z43:"V0":

                                *V50を:V0に:V50のZ41BYTE目から:V0の1BYTE目から:Z43BYTE分:

            Z54=V0:             *"-"でつながっていた場合の前半の数値

            Z41=Z42+1:          *次の為に数値の最初のバイト数をセット

 

            IF V50[Z47]<48 OR 57<V50[Z47] THEN:   *Z42+1バイト目が数値以外の時は

              GOTO *ERROR:

            ENDIF:

            Z45=1:                              *Z42バイト目は"-"でした

          ENDIF:                                *Z42バイト目が"-"の時は

        ENDIF:                                  *Z42バイト目が","の時は

 

      ENDIF:                                  *Z42バイト目が数値以外の時は

    ELSE:

      GOTO *ERROR:

    ENDIF:                                 *Z42バイト目が"数値"  ","  "-" のどれかならば

  NEXT:

  Z42=Z42+2:

  GOSUB *HANTEI_-:

*~~~~~~~~~~~~~~~~~~エラ―検出部END~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

 

  Z41=1:                  *Z41  数値の最初のバイト

  Z45=0:                  *Z45  直前は"-"の処理だったか?  Y=1,N=0

  FOR Z42=1 TO Z44+1:

    V0="":

    IF V50[Z42]=45 THEN:  *Z42バイト目が"-"だったら      "-"はASCIIコ―ドで45です

      Z43=Z42-Z41:        *数値のバイトの長さ

      STRCPY:V50:V0:Z41:1:Z43:"V0":

                          *V50を:V0に:V50のZ41BYTE目から:V0の1BYTE目から:Z43BYTE分:

      Z54=V0:             *"-"でつながっていた場合の前半の数値

      Z41=Z42+1:          *次の為に数値の最初のバイト数をセット

      Z45=1:              *直前は何? "数値"(48-57)=0,"-"(45)=1, ","(44)=2

    ELSE:

 

      IF V50[Z42]=44 OR Z42=Z44+1 THEN:     *","か 最後まできたら

        IF V50[Z44]=44 AND Z42=Z44+1 THEN:

          GOTO *END:                   *最後のバイトが","で終わってる時はここで終わり

        ENDIF:

        Z43=Z42-Z41:       *数値のバイトの長さ

        STRCPY:V50:V0:Z41:1:Z43:"V0":

                           *V50を:V0に:V50のZ41BYTE目から:V0の1BYTE目から:Z43BYTE分:

        Z55=V0:            *"-"でつながっていた場合の後半の数値&","で区切られた直前の数値

        Z41=Z42+1:         *数値の最初のバイト

        IF Z45=1 THEN:     *前の区切りは"-"のだったらば

          FOR Z46=Z54 TO Z55:

             GOSUB *SUB:

          NEXT:

          Z45=0:           *直前は何? "数値"(48-57)=0,"-"(45)=1, ","(44)=2

        ELSE:

          Z46=Z55:

          GOSUB *SUB:

        ENDIF:

      ENDIF:

    ENDIF:                 *V50のZ42バイト目が"-"だったら      "-"はASCIIコ―ドで45です

  NEXT:

 

*END

  STOP:

 

*SUB

  RUN:V49:RETURN:         *Z46が引数

 

*ERROR

  Z48=1:

  STOP:

 

*HANTEI_-

  IF Z45=1 THEN:       *前の区切りがハイフンならば

    Z43=Z42-Z41:       *数値のバイトの長さ

    STRCPY:V50:V0:Z41:1:Z43:"V0":

                       *V50を:V0に:V50のZ41BYTE目から:V0の1BYTE目から:Z43BYTE分:

    Z55=V0:            *"-"でつながっていた場合の後半の数値&","で区切られた直前の数値

    IF Z55<Z54 THEN:   *○―○指定の時左側の数値の方が右側の数値よりも大きい時は

      GOTO *ERROR:

    ENDIF:

  ENDIF:

  RETURN:

 

*エラ―があったらZ48=1にして終了。エラ―メッセ―ジは上位プログラムでやってもらう。

*考えられるエラ―類

*  [0-9の数字,(カンマ)-(ハイフン)]以外の入力が一つでもあったらエラ―

*  1バイト目に数値以外の入力があった時

*  最終バイトにハイフンが入力された時

*  ,,  ,- -,  --   など区切り文字の後にまた区切り文字が入力された時

*  ○―○連続指定の時に左側の数値が右側の数値よりも大きい時

 

* * このプログラムの使い方* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *

*

*1.まず上位のプログラムで実行する範囲をV50に、その範囲に対して、実行させるプログラム名

*    をV49に格納する。

*2.INPUT_NO開始

*    V50を解析してZ46に番号を渡す。

*    (ここで入力エラ―があった場合、Z48=1 にしてSTOPする。

*    Z48=1を受け取った上位プログラムはエラ―メッセ―ジを表示する。)

*

*3.Z46を受け取ったV49のプログラムはZ46を使ってさまざまな処理をする。(行番号やペ―ジ番号

*    等に)

 

 

*UPDATE

*2001/12/24 V1.00完成

 

 

 

[MAIN]                                    02.01.01        L=11401 C=0090

 

  Z48=0:                           *Z48  エラ―?  Y=1,N=0

  WSIZE:2:::::                     *Z40で行数を得るため

  V49="SUB":              *INPUT_NOに渡す  実行するプログラム名

  F:TEST:5::ESC:                   *実験用の表

  ILS:6:7000:

 

  FOR Z3=1 TO 1000:

    Z0=0:ACCPNUM:"[ 入力‥磨C削除‥1,終了‥ESC ]:":1:1:2:?:

    GOSUB *Z:

    Z1=Z0:

    FOR Z2=1 TO 1000:

      Z48=0:

      V0="ESC":

      ACCP:"指定する行は?(連続,複数,混合指定OK):":?:

      DPON:

      IF V0="ESC" THEN:GOTO *END:ENDIF:

      V50=V0:                      *INPUT_NOに渡す

      DPOFF:

      RUN:INPUT_NO:

      DPON:

      IF Z48=1 THEN:               *入力エラ―があった場合INPUT_NOからZ48=1が返って来・

        COLOR:0:2:2:

        LOC:Z40-3:6:PRINT:  入力が範囲外です。  :

        LOC:Z40-2:6:PRINT:  正しい行番号を入力  :

        LOC:Z40-1:6:PRINT:  してください。      :

      ELSE:

        BREAK:

      ENDIF:

      Z2=Z2-1:                     *永久ル―プ

    NEXT:

    Z3=Z3-1:                       *永久ル―プ

  NEXT:

 

*END

  STOP:

 

*Z

  IF Z0=0 THEN:GOTO *END:ENDIF:RETURN:

 

[SUB]                                     02.01.01        L=11401 C=0090

  *Z46を受け取って処理するサンプルプログラムです。

  *Z46行目に"選択"の文字列を入れます。

  IF Z1=2 THEN:

    "選択"=MZ46,1:

  ELSE:

    IF Z1=1 THEN:

      ""=MZ46,1:

    ENDIF:

  ENDIF:

  STOP:

このプログラム作成の経緯

 いやーやっとできました。マイツールを使い始めて2年ぐらい(今から3年前ぐらい)の時からずーっとこのようなものがあればいいなぁと思っていました。最初はACCPNUMを二回使って最初と最後のページ番号を聞いたりしてました。だんだんめんどくさくなって次に、○ー○の連続指定のモジュールだけは変数を27個(!?)も使ってなんとかできていましたが、発表するにはちょっとなぁと思っていました。実はこのINPUT_NOでZ54,Z55が何故離れ小島みたいに使われているかというとそのプログラムでZ54,Z55を使っていたからです。違う変数を使いたい方は御自分で修正をお願い致します。ここでのサブルーチンSUB.MYXは選択した行に、文字列を入れるプログラムになっていますが、私は主にページ指定をしたくて作りました。ここでのSUB.MYXはただのサンプルです。あとは皆さんの工夫次第です。

 このプログラムモジュールは最近学校でアルゴリズムの授業を受けるようになってピーン!ときまして、作ることができました。アルゴリズムって重要なんですね。

 もし使っていただけましたら、感想、改善案等お待ちしています。