2015年1月5日月曜日

1年分のカレンダーを作るSASプログラム


本年も、どうぞよろしくお願い致します!!


年の始まりということで、以前紹介した「RWIでカレンダーを作ってみる。」を改良して、1年分のカレンダーを作るプログラムを2パターン作りました。
祝日を色分けする処理も加えてます。


(実行する場合は、最後のほうに書いた補足の通り、プログラムを直してください)


(2020/12/26 出力結果のタイトル文字を大きくするなど、プログラムを改良)


まずは、以下の通り、その年の祝日をデータセット化しておきます。
「祝日一覧」とか適当にググると調べられます。

*** 2015年の祝日をデータセット化 ;
data HOLIDAY;
input  i :yymmdd10. HOLIDAY :$30.;
cards;
2015/1/1 元日
2015/1/12 成人の日
2015/2/11 建国記念の日
2015/3/21 春分の日
2015/4/29 昭和の日
2015/5/3 憲法記念日
2015/5/4 みどりの日
2015/5/5 こどもの日
2015/5/6 振替休日
2015/7/20 海の日
2015/9/21 敬老の日
2015/9/22 国民の休日
2015/9/23 秋分の日
2015/10/12 体育の日
2015/11/3 文化の日
2015/11/23 勤労感謝の日
2015/12/23 天皇誕生日
;


カレンダーのパターン①



*** 年を指定 ;
%let YEAR = 2015;


*** 用紙の向きを横に ;
options orientation = landscape;


title height=20pt "SAS Calendar ( &YEAR )";
ods pdf file="出力するパス\calendar1.pdf" notoc;


*** RWIでカレンダーを作る ;
data _NULL_;

  * 祝日一覧をハッシュオブジェクトに格納 ;
  length HOLIDAY $20.;
  dcl hash hs( dataset:"HOLIDAY" );
  hs.definekey( "i" );
  hs.definedata( "HOLIDAY" );
  hs.definedone();


  * 月ごとにループ ;
  do MONTH = 1 to 12;

     * 月の開始日と終了日を取得 ;
     STDT = mdy(MONTH, 1, &YEAR);
     ENDT = intnx("month", STDT, 0, "end");

     * カレンダー作成開始 ;
     dcl odsout ob();
     ob.table_start();

         * 月を出力 ;
         ob.head_start();
         ob.row_start();

              ob.format_cell( data: put(STDT,monname20.), column_span:7,
                                     style_attr: "background=midnightblue  color=white
                                                      fontsize=10  fontweight=bold  just=left");
         ob.row_end();

         * 曜日を出力 ;
         ob.row_start();
              do i = 1 to 7;
                  ob.format_cell( data: char("SMTWTFS",i) ,
                                        style_attr: "background=skyblue color=white fontsize=5") ;
              end;
         ob.row_end();
         ob.head_end();

         * 日付を出力 ;
         ob.row_start();
              do i = STDT to ENDT;

                  * 初日が日曜以外であれば空白を埋める ;
                  if i=STDT then do i2=1 to weekday(STDT)-1;
                      ob.format_cell();
                  end;

                  * 日付を出力 (文字色も設定) ;
                  HOLIDAY="";

                  *--- 平日は黒 ;
                  COLOR="BLACK";

                  *--- 日曜と祝日は赤 ;
                  if weekday( i )=1 or hs.find()=0 then COLOR="RED";

                  *--- 土曜は青 ;
                  else if weekday( i )=7 then COLOR="BLUE";

                  ob.format_cell( data:cats( day( i ), "#", HOLIDAY ) ,split:"#",
                                         style_attr:"height=2.7cm width=3.5cm fontsize=5 color="||COLOR);


                  * 土曜日であれば折り返す ;
                  if weekday( i )=7 and i^=ENDT then do;
                       ob.row_end();
                       ob.row_start();
                  end;

              end;
         ob.row_end();

      ob.table_end();

      * 月ごとに改ページ ;
      if MONTH^=12 then ob.page();

  end;
run;


ods pdf close;




カレンダーのパターン②




*** 年を指定 ;
%let YEAR = 2015;


*** 用紙の向きを縦に ;
options orientation = portrait;


title height=20pt "SAS Calendar ( &YEAR )";
ods pdf file="出力するパス\calendar2.pdf" notoc;


*** RWIでカレンダーを作る ;
data _NULL_;

  * 祝日一覧をハッシュオブジェクトに格納 ;
  length HOLIDAY $20.;
  dcl hash hs( dataset:"HOLIDAY" );
  hs.definekey( "i" );
  hs.definedata( "HOLIDAY" );
  hs.definedone();

  * カレンダー作成開始 ;
  dcl odsout ob();
  ob.layout_gridded(columns:3,rows:4);

  * 月ごとにループ ;
  do MONTH = 1 to 12;

      * 月の開始日と終了日を取得 ;
      STDT = mdy(MONTH, 1, &YEAR);
      ENDT = intnx("month", STDT, 0, "end");

      ob.region();
      ob.table_start();

         * 月を出力 ;
         ob.head_start();
         ob.row_start();

              ob.format_cell( data: put(STDT,monname3.), column_span:7,
                                     style_attr:"background=midnightblue  color=white 
                                                     fontsize=3  fontweight=bold  just=left");
         ob.row_end();

         * 曜日を出力 ;
         ob.row_start();
              do i = 1 to 7;
                  ob.format_cell( data: char("SMTWTFS",i),
                                        style_attr: "background=lightsteelblue color=white");
              end;
         ob.row_end();
         ob.head_end();

         * 日付を出力 ;
         ob.row_start();
              do i = STDT to ENDT;

                  * 初日が日曜以外であれば空白を埋める ;
                  if i=STDT then do i2=1 to weekday(STDT)-1;
                      ob.format_cell();
                  end;


                  * 日付を出力 (文字色も設定) ;
                  HOLIDAY="";

                  *--- 平日は黒 ;
                  COLOR="BLACK";

                  *--- 日曜と祝日は赤 ;
                  if weekday( i )=1 or hs.find()=0 then COLOR="RED";

                  *--- 土曜は青 ;
                  else if weekday( i )=7 then COLOR="BLUE";

                  ob.format_cell( data: day( i ), style_attr:"color="||COLOR );


                  * 土曜日であれば折り返す ;
                  if weekday( i )=7 and i^=ENDT then do;
                       ob.row_end();
                       ob.row_start();
                  end;

             end;
         ob.row_end();
      ob.table_end();

  end;
  ob.layout_end();
run;


ods pdf close;




補足


・SAS9.4より前のバージョンでは、format_cellメソッドの「style_attr」を「overrides」に置き換える。


・プログラムの最初らへんの「ods pdf」部分を、各自保存したいパスに変えてください。
ods pdf file="結果を保存するパス\ファイル名.pdf";


・ 出力する年を変えたい場合は、プログラム先頭の以下の箇所を変えてあげる。

*** 年月を指定 ;
%let YEAR = 2015;

また、その年の祝日にあわせてデータセットHOLIDAYを更新してください。



0 件のコメント:

コメントを投稿