回答箱 No.147-4: 町内会夜警カレンダーを作りたい
        ◆ 質問箱 No.147 質問者: 西村 重幸  2004年05月 268号 P.14
            ◆ 質問箱 目次へ
No.147-4   町内会夜警カレンダーを作りたい 回答者
  高橋 周助
2004年09月
272号 P.18
 質問箱No.147を題材に、ひとりブレーンストーミングをした成果の、第4弾をお届けします。コマンド等の使い方について、同じ題材でも、これだけ多彩な考え方が出来る、という例示に挑戦してみたかったためです。

□■□ 第四回答例の特徴
 コマンドの使用を最低限に抑えて、ほとんどをLET文にしました。結果は、スピードが格段に速いように思います。見ているととても快適です。しかし私は、どちらかというと、あまりこういうBASIC的な使い方をしたいという気がしません。PIPSのオートは本来的に、BASICそのものだということの再認識のために、作ってみました。
 私がやってきた仕事は、1秒・2秒を争うような場面にはないと思ってきました。だから、スピードにそれほどの価値を与えていません。何が大事かといえば、運用開始後の保守だと思っています。プログラム完成後何ヶ月も経ってしまったら、もう内容の詳細など頭からなくなっていることがほとんどです。まして、他人様が保守する時のことを考えたら、理解しやすく、修正しやすいこと、バグが発生しにくい構造であることの方がずっと重要で、スピードやカッコ良さなどにこだわってはならないと思ってきました。BASICがもともと得意だった人々にとっては、BASIC的な作り方が最適な選択でしょうが、私にとっては、コマンド最優先が最適です。一概には言えませんが、コマンドの方が解りやすいことが多いと思います。原作者がいちいち解説しなければならないようなプログラムは、できるだけ避けたいと思っています。
 何年も前のことになりますが、「ソフトウェア工学」の書籍紹介の記事を書いたことがあります。その中で、ソフトウェアのコストは一般的に、保守のコストが全体の6割に達するという事実を知りました。私の頭の中での実感は、もっと高い比率です。
 PIPSは開発費が安く出来るメリットがある、というのがPIPSユーザーの間で定説になっています。私はむしろ、手間を掛け無さすぎることが多いと考えています。開発時に2倍・3倍の手間を付け加えてでも、解りやすい・保守し易いプログラムにしておくべきと考えています。
 前記の書籍でも、「品質の良いソフトとは、解りやすいソフトのことだ」とさえ言い切っています。そのための方法論について説いています。
 ただし、このことは、あくまでも長期使用のプログラムを作るとしたら・・・の話です。もともとPIPSはノンプログラム主義から出発したのですから、オートなど作らないで済むなら、作らないに越したことはない、という基本をまず忘れないようにしています。
 私がプログラム事例を発表している意図は、プログラムという手段を使って、コマンドを組み合わせた使用例を紹介しよう、ということの方に重点を置いています。

□■□ 使い方
  1.  実行すると、Select文の窓が開くので、カレンダーを作りたい年を選択してください。
  2.  最終結果は、「WK2」バインダーの1〜12ページに登録されます。
  3.  2個のバインダー「WK1」・「WK2」を使います。同名のバインダーが存在していても、いなくてもかまいませんが、上書きしてしまうので、大切なデータであれば、退避してから実行してください。
□■□ プログラム
<夜警班番号_4>
        STEP OFF;  CLOSE;                   /*前歴の影響を消しておく*/
/****** A.条件設定 **************************************************/
    /*====== A-1. カレンダーを作りたい年============================*/
        SELECT [10,10],"対象年",X5,"2004","2005","2006","2007","2008";
          LET Z15=DCML(X5)+2003;                    /*対象年(西暦)*/
          LET Z16=Z15*10000+101;                        /*元日の日付*/
    /*====== A-2.スタートの条件 ====================================*/
        LET Z11=2004;                               /*夜警スタート年*/
        LET Z12=5;                                  /*夜警スタート月*/
        LET Z13=30;                                 /*夜警スタート日*/
    /*====== A-3.条件の妥当性検査 ==================================*/
$検査:  LET Z14=DATE(Z11*10000+Z12*100+Z13,1,0);  /*スタート日の日付*/
          IF ERR(0)=0 THEN GOTO $B;
        DISP OPEN,[10,10],"スタート日は存在しません。";
        INPUT [10,12],"了解したらリターンキーを押して下さい。",V1;
        GOTO $終;                                           /*出口へ*/
/****** B.七曜表の空表を作成 ****************************************/
$B:     SET;S;M;1;256;;Y;                        /*横桁数256桁に設定*/
        O;夜警七曜表(空);4*14;;日;;月;;火;;水;;木;;金;;土;ESC;
        CS;M;C1=C1;;A;WK1/D;               /*バインダー「WK1」を作成*/
        IR;S;H;12;                                /*空行を12行挿入*/
        DRL/C;R;6/8/10/12/14;                         /*横罫線を引く*/
              C;1/3/5/7/9/11/13;  C;N;  ESC;          /*縦罫線を引く*/
        ATR;P;L;A;                            /*全列に左詰属性を設定*/
        P;WK1/1;ESC;                           /*「WK1」の1頁に保存*/
/******* C.最終結果保存用バインダー12頁分を確保月別処理 *************/
        IF NAME(3,"WK2")=0 THEN GOTO $頁確保;  BIND;D;WK2;Y;
$頁確保:CLM;ダミー;Y;  MB;WK2;;  MP;WK2;11;;
/******* D.月毎の処理12ヵ月分を繰り返す *****************************/
        FOR X1=1 TO 12;
          IF Z15=Z11 AND DCML(X1)<Z12 THEN CONTINUE;
                                          /*スタート月以前はスキップ*/
    /*=== D-1.当月の条件を計算 =====================================*/
          LET Z22=Z15*10000+DCML(X1)*100+1;       /*当該月1日の日付*/
          LET Z23=DATENUM(Z22);               /*当該月1日の日付連番*/
          LET Z24=Z23 MOD 7;  LET X24=INTG(Z24);  /*当該月1日の曜日*/
          LET Z25=MDATE(Z22,0,99);                /*当該月末日の日付*/
          LET Z26=DATE(Z22,Z25)+1;                    /*当該月の日数*/
    /*=== D-2.七曜表へ書き込み =====================================*/
          G;WK1/1;                          /*七曜表の空表を読み込む*/
          CT;%Z15年%X1月_夜警カレンダー;            /*タイトルを変更*/
          LET X6=H;                    /*1日の日付書き込み先 行番号*/
          FOR X4=1 TO %Z26;         /*当該月1日から末日まで繰り返す*/
       /*--- D-2-a.暦日記入 ----------------------------------------*/
            LET X5=(X24+X4-1) MOD 7;                  /*対象日付の曜*/
            LET X7=X5*3+2;             /*対象日付の書き込み先 列番号*/
            LET [X6,X7]=NUM$(X4);                       /*暦日を記入*/
       /*--- D-2-b.班番号記入 --------------------------------------*/
            LET Z1=Z15*10000+DCML(X1)*100+DCML(X4);           /*日付*/
              IF Z1<Z14 THEN GOTO $書込行変更;   /*スタート日以前はスキップ*/
            LET X8=X6+1;                 /*班番号の書き込み先 行番号*/
            LET X9=X7+1;                 /*班番号の書き込み先 列番号*/
            LET Z2=DATE(Z14,Z1);    /*スタート日から対象日までの経過日数*/
            LET Z3=(ROUND(Z2/7,-1,0)+Z2) MOD 7+1;           /*班番号*/
            LET [X8,X9]=NUM$(Z3)+"班";                  /*班番号記入*/
$書込行変更:IF X5=6 THEN LET X6=X6+3;
          NEXT;
       /*--- D-2-c.当該ページへ登録 --------------------------------*/
          P;WK2/%X1;ESC;                 /*「WK4」の当該ページに登録*/
        NEXT;
/******* Z.終 *******************************************************/
$終:    STEP OFF;  CLOSE;  STOP;          /*前歴の影響を消して、終了*/
回答箱のプログラムがプログラム集に収録されています。


このページのTOPへ戻る