回答箱 No.147-2: 町内会夜警カレンダーを作りたい
        ◆ 質問箱 No.147 質問者: 西村 重幸  2004年05月 268号 P.14
            ◆ 質問箱 目次へ
No.147-2   町内会夜警カレンダーを作りたい 回答者
  高橋 周助
2004年07月
270号 P.26
 質問箱No.147は、個人ブレーンストーミングを試みるために最適な題材でした。第二の回答例を、ここに提出します。

□■□ 第一回答例との差
 第一回答例では、年間の班番号を一括して計算しておいて、そこから月毎に必要なデータだけ読み込みました。毎月のデータを処理変形することによって、最終七曜表を作りました。
 今回は、班番号を月ごとに計算するようにしました。
 七曜表は最初に一回だけブランクの表を作っておいて、毎月その表を引っ張り出しては、そこにデータを記入するようにしました。
 七曜表には42個の枠があり、どの日がどの枠に書き込まれるかは、一日(ついたち)の曜日に依存します。一日(ついたち)の枠が決まれば、あとの日の枠は自動的に決まります。そこで、42個の枠の記入先セル番地をあらかじめ表にしておいて、それを読み取って使うようにしました。
 どちらが良いかは分かりません。スピードは今回の方が速いようです。
 PIPS的面白さから言えば、出来るだけ色々なコマンドを使うようにした点で、前回の方が私としては好きです。特に今回は、枠に記入する肝心なところで、LET文に頼っているという点で、PIPS的でなく、後ろめたい気分(?)です。

□■□ 使い方
  1. プログラム中、ブロックA-1の変数Z15に、カレンダーを作りたい年の西暦を書き込んで、実行してください。例えば、2005年のカレンダーを作る場合は、次のように設定します。
            LET Z15=2005;
  2. 最終結果は、「WK3」バインダーの1〜12ページに登録されます。
  3. 三個のバインダー「WK1」・「WK2」・「WK3」を使います。同名のバインダーが存在していても、いなくてもかまいませんが、上書きしてしまうので、大切なデータであれば、退避してから実行してください。
    <夜警班番号_2>
            STEP OFF;  CLOSE;                   /*前歴の影響を消しておく*/
    /****** A.条件設定 **************************************************/
        /*====== A-1. カレンダーを作りたい年============================*/
            LET Z15=2004;                           /*西暦で指定すること*/
              LET Z16=Z15*10000+101;                        /*元日の日付*/
        /*====== A-2.スタートの条件 ====================================*/
            LET Z11=2004;                               /*夜警スタート年*/
            LET Z12=5;                                  /*夜警スタート月*/
            LET Z13=30;                                 /*夜警スタート日*/
        /*====== A-3.条件の正当性検査 ==================================*/
    $検査1: LET Z14=DATE(Z11*10000+Z12*100+Z13,1,0);  /*スタート日の日付*/
              IF ERR(0)=0 THEN GOTO $検査2;
            DISP OPEN,[10,10],"スタート日は存在しません。";
            INPUT [10,12],"了解したらリターンキーを押して下さい。",V1;
            GOTO $終;                                           /*出口へ*/
    $検査2: IF Z15>=Z11 THEN GOTO $B;
            DISP OPEN,[10,10],"スタート日以降の年を指定して下さい。";
            INPUT [10,12],"了解したらリターンキーを押して下さい。",V1;
            GOTO $終;                                           /*出口へ*/
    /******* B.最終結果保存用バインダー12頁分を確保 *********************/
        /*====== B-1.七曜表の空表を作成 ================================*/
    $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;R;6/8/10/12/14;                           /*横罫線を引く*/
            DRL;C;1/3/5/7/9/11/13;                        /*縦罫線を引く*/
            DRL;C;N;                                      /*縦罫線を引く*/
            ATR;P;L;A;                            /*全列に左詰属性を設定*/
            P;WK1/1;ESC;                           /*「WK1」の1頁に保存*/
        /*====== B-2.バインダー「WK3」を作成して、12ページ確保 =========*/
            IF NAME(3,"WK3")=0 THEN GOTO $頁確保;
            BIND;D;WK3;Y;            /*バインダー「WK3」が存在したら削除*/
    $頁確保:G;WK1/1;  MB;WK3;;  MP;WK3;11;;          /*「WK3」に12頁確保*/
    /******* C.記入先のセル番地一覧表を作成 *****************************/
            SET;S;M;1;256;;Y;                        /*横桁数256桁に設定*/
            O;記入先セル番地;8/4/12/12;ESC;ESC;
            IR;S;H;42;                                  /*空行を42行挿入*/
            WR;2;1;第何週;曜;日付記入先;班番号記入先;
    1;0;[04,02];[05,03];1;1;[04,05];[05,06];1;2;[04,08];[05,09];
    1;3;[04,11];[05,12];1;4;[04,14];[05,15];1;5;[04,17];[05,18];
    1;6;[04,20];[05,21];
    2;0;[07,02];[08,03];2;1;[07,05];[08,06];2;2;[07,08];[08,09];
    2;3;[07,11];[08,12];2;4;[07,14];[08,15];2;5;[07,17];[08,18];
    2;6;[07,20];[08,21];
    3;0;[10,02];[11,03];3;1;[10,05];[11,06];3;2;[10,08];[11,09];
    3;3;[10,11];[11,12];3;4;[10,14];[11,15];3;5;[10,17];[11,18];
    3;6;[10,20];[11,21];
    4;0;[13,02];[14,03];4;1;[13,05];[14,06];4;2;[13,08];[14,09];
    4;3;[13,11];[14,12];4;4;[13,14];[14,15];4;5;[13,17];[14,18];
    4;6;[13,20];[14,21];
    5;0;[16,02];[17,03];5;1;[16,05];[17,06];5;2;[16,08];[17,09];
    5;3;[16,11];[17,12];5;4;[16,14];[17,15];5;5;[16,17];[17,18];
    5;6;[16,20];[17,21];
    6;0;[19,02];[20,03];6;1;[19,05];[20,06];6;2;[19,08];[20,09];
    6;3;[19,11];[20,12];6;4;[19,14];[20,15];6;5;[19,17];[20,18];
    6;6;[19,20];[20,21];ESC;
            CS;M;C1=C1;;A;WK2/D;               /*バインダー「WK2」に保存*/
    /******* 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;                      /*当該月1日の曜日*/
              LET Z25=MDATE(Z22,0,99);                /*当該月末日の日付*/
        /*===== D-2.当該月のデータを作成 ===============================*/
           /*--- D-2-a.表作成 ------------------------------------------*/
              SET;S;M;1;256;;Y;                      /*横桁数256桁に設定*/
              O;%Z15年%X1月;
                4;No.;4;日;16;年月日;6;第何週;4;曜;8;班番号;;ESC;
              ATR;N;D;@年月日 ;               /*年月日列に日付属性を設定*/
              LET Z1=DATE(Z22,Z25)+1;  IR;S;H;%Z1;/*当該月の日数分の空行*/
           /*--- D-2-b.年月日、日、曜 ----------------------------------*/
              NUM;M;C;@年月日 ;H;%Z22;1;/*年月日列に当該月の日付連番記入*/
              NUM;M;C;@日 ;H;1;1;                 /*日列に暦の日付を記入*/
              CAL;@年月日 MOD 7=@曜 ;             /*曜列に曜日連番を記入*/
           /*--- D-2-c.第何週 ------------------------------------------*/
    $始空行:  IF Z24=0 THEN GOTO $No.;
              IR;S;H;%Z24;  /*始めの行が日曜日に相当するように、空行挿入*/
    $No.:     NUM;M;C;@No. ;H;0;1;                    /*日列に連番を記入*/
              CAL;DF0;@No. /7+1=@第何週 ;               /*第何週かを計算*/
              CS;M;@年月日 <>"";;A;;                    /*不要な行を削除*/
           /*--- D-2-d.班番号 ------------------------------------------*/
              LET Z1=DATE(Z14,Z22);   /*スタート日から1日までの経過日数*/
              NUM;M;C;@No. ;H;%Z1;1;                 /*No.列に番号を記入*/
              CAL;DF0;@No. /7=@班番号 ;         /*班番号算出の前半計算式*/
              CAL;(@班番号 +@No. ) MOD 7+1=@班番号 ;  /*算出の後半計算式*/
           /*--- D-2-e.記入先を読み込んで、サブバッファへ --------------*/
              CAM;M;記入先セル番地;@第何週 ;@曜 ;;@第何週 ;@曜 ;
                 A;S@日付記入先 ;S@班番号記入先 ;;;       /*記入先を参照*/
              S;                                        /*サブバッファへ*/
        /*===== D-3.七曜表へ記入 =======================================*/
           /*--- D-3-a.空表読み込み ------------------------------------*/
              G;WK1/1;                            /*記入用空表を呼び出す*/
              CT;%Z15年%X1月_夜警カレンダー;            /*タイトルを変更*/
           /*--- D-3-b.日付を記入 --------------------------------------*/
              FOR X2={H} TO {T};
                LET V1={X2,@日 };
                LET V2={X2,@日付記入先 };
                LET V3="LET "+V2+"="+"'"+V1+"'";  %V3;        /*日付記入*/
              NEXT;
           /*--- D-3-c.班番号を記入 ------------------------------------*/
              FOR X2={H} TO {T};
                IF IVAL({X2,@No. })<0 THEN CONTINUE; /*スタート日以前はスキップ*/
                LET V1={X2,@班番号 };
                LET V2={X2,@班番号記入先 };
                LET V3="LET "+V2+"="+"'"+V1+"班'";  %V3;    /*班番号記入*/
              NEXT;
           /*--- D-3-d.当該ページへ登録 --------------------------------*/
              P;WK3/%X1;ESC;                 /*「WK3」の当該ページに登録*/
            NEXT;
    /******* Z.終 *******************************************************/
    $終:    STEP OFF;  CLOSE;  STOP;          /*前歴の影響を消して、終了*/
    
    回答箱のプログラムがプログラム集に収録されています。


このページのTOPへ戻る