□■□ 第三回答例の特徴
- カレンダーを作る対象年の入力に、Select文を使いました。あらかじめオートに書き込んである年の中からしか選択できないので、正当性検査が一つ不要になりました。
-
班番号の決定ルールを考えてみると、スタート日から数えて7日間が1班から始まり、次の7日間は2班から始まり、・・・、最後の7日間は7班から始まるので、全体で7×7=49日で一巡します。その後はまた元に戻るので、この49通りの順序をあらかじめ1回だけ表に作っておいて、この表から各日付に該当する班番号を読み取るようにしました。
これの良い点は、班番号を算出する計算式が分からない場合とか、全くランダムな順序の場合でも応用が利いて、手入力でこの表を作っておきさえすれば良い、ということです。
この表は、手作業で作って構わないのですが、プログラムを動かす都合上、一桁でも/一文字でも狂うと、エラーになる恐れがあるので、オートの中に組み込みました。原理が解れば、どのように変更してもかまいません。 - 今回は、質問箱 No.148への回答(来月投稿予定)への布石にもなっています。ひとつは、派遣要員順序の指定方法に、上記(2)の方法を使う予定です。もう一つは、七曜表に派遣要員名を書き込めるように、各週とも1行余計に空行を設けました。また列幅も、8桁の名前が書き込めるように、広く取りました。結果として、全体の七曜表が縦横とも、一回り大きくなりました。
- 七曜表への記入時に、書き込み先の行番号・列番号を、計算によって算出しました。
□■□ 使い方
- 実行すると、Select文の窓が開くので、カレンダーを作りたい年を選択してください。
- 最終結果は、「WK4」バインダーの1〜12ページに登録されます。
- 4個のバインダー「WK1」・「WK2」・「WK3」・「WK4」を使います。同名のバインダーが存在していても、いなくてもかまいませんが、上書きしてしまうので、大切なデータであれば、退避してから実行してください。
<夜警班番号_3> 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; CF;2/4/6/8/10/12/14;8; CS;M;C1=C1;;A;WK1/D; /*バインダー「WK1」を作成*/ IR;S;H;18; /*空行を18行挿入*/ DRL/C;R;7/10/13/16/19; /*横罫線を引く*/ C;1/3/5/7/9/11/13; C;N; ESC; /*縦罫線を引く*/ ATR;P;L;A; /*全列に左詰属性を設定*/ P;WK1/1;ESC; /*「WK1」の1頁に保存*/ /******* C.班番号順序表作成 *****************************************/ SET;S;M;1;36;;Y; /*横桁数36桁に設定*/ O;班番号順序;4;順序;6;班番号;ESC; IR;S;H;7; /*7行の空行を挿入*/ NUM;M;C;@班番号 ;H;1;1;ESC; /*1班から始まる班順列を記入*/ CPA;M;Y; /*サブバッファにもコピー*/ FOR X5=2 TO 7; /*2〜7班から始まる班順列を記入*/ ROLL;@班番号 ;A;+1; /*上方向に1行ロール*/ S; CPR;SA;T+1; S; /*サブバッファにコピー*/ NEXT; S; NUM;M;C;@順序 ;H;0;1; /*順序列列に順序を記入*/ CS;M;C1=C1;;A;WK2/D; /*WK2バインダーの有無に関係なく保存可能*/ /******* D.班番号決定 ***********************************************/ /*====== D-1.年間データ書き込み用空表を作成 ====================*/ SET;S;M;1;38;;Y; /*横桁数38桁に設定*/ O;夜警班番号;6;No.;15;年月日;2;曜;6;班番号;5;年;3;月;;ESC; ATR;N;D;@年月日 ; /*年月日列に日付属性を設定*/ IR;S;H;370; /*370行の空行を挿入*/ /*====== D-2.各列を完成 ========================================*/ NUM;M;C;@年月日 ;H;%Z16;1; /*年月日列に日付連番を記入*/ CAL;@年月日 MOD 7=@曜 ; /*曜列に曜日連番を記入*/ LET Z1=DATE(Z14,Z16); /*スタート日から元日までの経過日数*/ NUM;M;C;@No. ;H;%Z1;1; /*No.列に番号を記入*/ CAL/C;DF0;@No. MOD 49=@No. ; /*No.列に順序番号を算出*/ ROUND(DATE(@年月日 )/10000,-1,0)=@年 ; /*年列に年を記入*/ ROUND((DATE(@年月日 ) MOD 10000)/100,-1,0)=@月 ;ESC; /*月列に月を記入*/ CAM;M;WK2;@No. ;;@順序 ; @No. ;@年月日 ;@曜 ;S@班番号 ;@年 ;@月 ;;WK3/D; /*「WK2」から班番号を読み取って「WK3」に保存*/ /******* E.月別処理 *************************************************/ /*===== E-1.最終結果保存用バインダー12頁分を確保 ===============*/ IF NAME(3,"WK4")=0 THEN GOTO $頁確保; BIND;D;WK4;Y; $頁確保:CLM;ダミー;Y; MB;WK4;; MP;WK4;11;; /*===== E-2.月毎の処理12ヵ月分を繰り返す =======================*/ FOR X1=1 TO 12; IF Z15=Z11 AND DCML(X1)<Z12 THEN CONTINUE; /*スタート月以前はスキップ*/ /*--- E-2-a.当月の条件を計算 --------------------------------*/ LET Z22=Z15*10000+DCML(X1)*100+1; /*当該月1日の日付*/ LET Z23=DATENUM(Z22); /*当該月1日の日付連番*/ LET Z24=Z23 MOD 7; /*当該月1日の曜日*/ /*--- E-2-b.当該月のデータのみ抽出して加工 ------------------*/ CS;WK3;@年 =%Z15;@月 =%X1;;A;; /*当該月のデータのみ抽出*/ INFO;S;256; /*横桁数256桁に変更*/ IC;S;N;3;日; /*日列を追加*/ NUM;M;C;@日 ;H;1;1; /*日列に暦の日付を記入*/ IF Z24=0 THEN GOTO $第何週; /*当該月1日が日曜ならスキップ*/ IR;S;H;%Z24;/*始めの行が日曜日に相当するようにダミー行挿入*/ $第何週: NUM;M;C;@No. ;H;0;1; /*No.列に連番を記入*/ CAL;DF0;@No. /7+1=@No. ; /*第何週かを記入*/ IF Z24=0 THEN GOTO $E-2-c;/*行挿入していなかったらスキップ*/ DR;H,H+%Z24-1;Y; /*挿入したダミー行を削除*/ /*--- E-2-c.七曜表へ書き込み --------------------------------*/ $E-2-c: S; /*当該月データをサブバッファへ*/ G;WK1/1; /*七曜表の空表を読み込む*/ CT;%Z15年%X1月_夜警カレンダー; /*タイトルを変更*/ FOR X2={H} TO {T}; LET X5=IVAL({X2,@No. })*4; /*日付の書き込み先行番号*/ LET X6=IVAL({X2,@曜 })*3+2; /*日付の書き込み先列番号*/ LET [X5,X6]={X2,@日 }; /*日付を記入*/ IF DATE(DATEVAL({X2,@年月日 }))<Z14 THEN CONTINUE; /*スタート日以前はスキップ*/ LET X5=X5+1; /*班番号の書き込み先行番号*/ LET X6=X6+1; /*班番号の書き込み先列番号*/ LET [X5,X6]={X2,@班番号 }+"班"; /*班番号記入*/ NEXT; /*--- E-2-d.当該ページへ登録 --------------------------------*/ P;WK4/%X1;ESC; /*「WK4」の当該ページに登録*/ NEXT; /******* Z.終 *******************************************************/ $終: STEP OFF; CLOSE; STOP; /*前歴の影響を消して、終了*/
回答箱のプログラムがプログラム集に収録されています。 |
□