2012年5月29日火曜日

年代の書式定義(2)

昨日書いたコードは難しく考えすぎました。素直に数十年先まで定義するのがシンプルです。

  1. options mprint source;  
  2.   
  3. proc format;  
  4.  value $DATE8_F  
  5.   "19900401" - "19910331" = "19900401 - 19910331"  
  6.   "19910401" - "19920331" = "19910401 - 19920331"  
  7.   "19920401" - "19930331" = "19920401 - 19930331"  
  8.   "19930401" - "19940331" = "19930401 - 19940331"  
  9.   "19940401" - "19950331" = "19940401 - 19950331"  
  10.   "19950401" - "19960331" = "19950401 - 19960331"   
  11.   "19960401" - "19970331" = "19960401 - 19970331"  
  12.   "19970401" - "19980331" = "19970401 - 19980331"  
  13.   "19980401" - "19990331" = "19980401 - 19990331"  
  14.   "19990401" - "20000331" = "19990401 - 20000331"   
  15.   "20000401" - "20010331" = "20000401 - 20010331"  
  16.   "20010401" - "20020331" = "20010401 - 20020331"  
  17.   "20020401" - "20030331" = "20020401 - 20030331"  
  18.   "20030401" - "20040331" = "20030401 - 20040331"  
  19.   "20040401" - "20050331" = "20040401 - 20050331"  
  20.   "20050401" - "20060331" = "20050401 - 20060331"  
  21.   "20060401" - "20070331" = "20060401 - 20070331"   
  22.   "20070401" - "20080331" = "20070401 - 20080331"  
  23.   "20080401" - "20090331" = "20080401 - 20090331"  
  24.   "20090401" - "20100331" = "20090401 - 20100331"  
  25.   "20100401" - "20110331" = "20100401 - 20110331"  
  26.   "20110401" - "20120331" = "20110401 - 20120331"  
  27.   "20120401" - "20130331" = "20120401 - 20130331"   
  28.   "20130401" - "20140331" = "20130401 - 20140331"  
  29.   "20140401" - "20150331" = "20140401 - 20150331"  
  30.   "20150401" - "20160331" = "20150401 - 20160331"  
  31.   "20160401" - "20170331" = "20160401 - 20170331"  
  32.   "20170401" - "20180331" = "20170401 - 20180331"  
  33.   "20180401" - "20190331" = "20180401 - 20190331"  
  34.   "20190401" - "20200331" = "20190401 - 20200331"   
  35.   "20200401" - "20210331" = "20200401 - 20210331"   
  36.   "20210401" - "20220331" = "20210401 - 20220331"   
  37.   "20220401" - "20230331" = "20220401 - 20230331"  
  38.   "20230401" - "20240331" = "20230401 - 20240331"  
  39.   "20240401" - "20250331" = "20240401 - 20250331"   
  40.   "20250401" - "20260331" = "20250401 - 20260331"  
  41.   "20260401" - "20270331" = "20260401 - 20270331"  
  42.   "20270401" - "20280331" = "20270401 - 20280331"  
  43.   "20280401" - "20290331" = "20280401 - 20290331"  
  44.   "20290401" - "20300331" = "20290401 - 20300331"  
  45.  ;  
  46. run;  

2012年5月28日月曜日

年代の書式定義

仕事用のメモです。4月始まりで年代を分けるための書式定義です。

  1. options mprint source;  
  2.   
  3. %macro date_fmt(from=, to=, fmt=, fmtnam=);  
  4.         %local i tcount;  
  5.   
  6.         data _null_;  
  7.                 format from to end yymmddn8.;  
  8.   
  9.                 from = &from;  
  10.                 end = &to;  
  11.                 tcount = 0;  
  12.   
  13.                 do while (from < end);  
  14.                         to = intnx('MONTH', from, +11, 'END');  
  15.                         tcount = tcount + 1;  
  16.   
  17.                         /* マクロ変数を定義 */  
  18.                         value = put(from, &fmt);  
  19.                         macvar = compress("FROM" || put(tcount, BEST.));  
  20.                         call symput(macvar, compress(value));  
  21.   
  22.                         value = put(to, &fmt);  
  23.                         macvar = compress("TO" || put(tcount, BEST.));  
  24.                         call symput(macvar, compress(value));  
  25.   
  26.                         call symput("TCOUNT", compress(put(tcount, BEST.)));  
  27.   
  28.                         /* 次の年を設定 */  
  29.                         from = intnx('MONTH', from, +12);  
  30.                 end;  
  31.         run;  
  32.   
  33.         /* 書式を設定 */  
  34.         proc format;  
  35.                 value &fmtnam  
  36.                         %do i=1 %to &tcount;  
  37.                                 "&&from&i" - "&&to&i" = "&&from&i - &&to&i"  
  38.                         %end;  
  39.                 ;  
  40.         run;  
  41. %mend;  
  42.   
  43. %date_fmt(from='1-Apr-1990'd, to=today(), fmt=YYMMN6., fmtnam=$DATE6_F);  
  44. %date_fmt(from='1-Apr-1990'd, to=today(), fmt=YYMMDDN8., fmtnam=$DATE8_F);  
  45.   
  46. data _null_;  
  47.         x = put(today(), yymmddn.);  
  48.         y = put(x, $DATE8_F.);  
  49.         z = put(x, $DATE6_F.);  
  50.         put _all_;  
  51. run;  

2012年5月24日木曜日

SRX, 仕事で使ってみた。良かった!

Microsoft風に現せば、自らドッグフードを喰らうとでも言うのでしょうか。SRXを仕事で使ってみたが、なかなか良かった。いくつもあるSASコードから、同じような問題箇所を洗い出し、報告用の資料を作りました。

Windows環境だと、拡張子.SASのコードの中身を検索できないことがあります。社内ではUNIX上でgrep(1)を使うのですが、エビデンスのファイルを作るのが面倒でした。今回は、SRXを使ってSASプログラム一覧を作成し、抽出パターンとマッチングした結果をExcelファイルに保存しました。30分程度で、まとまったExcelファイルになって、素早さが好評でした。

改善したいと思ったのは、Excelファイルにエクスポートしたときに、ヘッダ、フッタの設定です。これも機能化すれば、10分程度でエビデンスを抽出して精査の時間をゆったり取れます。あ、Windows7未対応でした。

2012年5月15日火曜日

SASログの字句解析を作り直す。

SAS Log Utilityで120MB程度のSASログを解析したら、えらく時間が掛かった。Elapsed, CRUDの字句解析を個別に行っていましたが、処理効率が悪いので1つにまとめることを検討します。それと、画面の更新も足を引っ張っているので、BeginUpdate、EndUpdateで表示周りも調整します。

SASとVBScriptの連携

仕事柄VBScriptとSAS.EXEを連携することが多くあります。 サンプルコードを貼って、LanguageService Objectの資料をリンクしておきます。

  1. '---  
  2. '    SASワークスペース・オブジェクトの生成  
  3. '---  
  4.   
  5. Set oWrkSp = WScript.CreateObject("SAS.Workspace")  
  6.   
  7. '---  
  8. '    ランゲージ・サービスの取得  
  9. '---  
  10. Set oLngSp = oWrkSp.LanguageService  
  11.   
  12. '---  
  13. '    プログラムの実行  
  14. '---  
  15.   
  16. oLngSp.Submit "data class; set sashelp.class; run; proc print; run;"  
  17.   
  18. '---  
  19. '    ログの表示  
  20. '---  
  21. MsgBox oLngSp.FlushLog(100000)  
  22.   
  23. '---  
  24. '    アウトプットの表示  
  25. '---  
  26.   
  27. MsgBox oLngSp.FlushList(100000)  
  28.   
  29. '---  
  30. '    ワークスペースを閉じる  
  31. '---  
  32.   
  33. oWrkSp.Close  
  34. Set oWrkSp = Nothing  
  35.   
  36. WScript.Quit(0)