2014年10月11日土曜日

更新滞っています。

仕事で追い詰められていて、更新が滞っています。
契約条件を無視した○○に責められて、6月から無休でダウン寸前です。
問題の案件が終わる12月末まで、ツールの更新は難しい状態です。

お知らせまで

2014年9月11日木曜日

データの並び順で生じる誤差

細かな端数が生じる変数を順番に足しあげていくとき、並び順が違うと小さな差異が生じることがあります。リスク計算の処理の中で、PROC SQLで書いた部分で生じて、お客様への説明に苦慮しました。SQLで書くと変数の並びと集計関数でシンプルに書けることがありますが、予期せぬ並び順になってうことがあります。当然ソートキーは指定していますが、それ以外の並びは保証されていません。

結合テストのエビデンスつくりで苦戦中です。

2014年8月10日日曜日

SASで文字列を書くときに、ダブルクォーツかシングルクォーツを使うか?

メモです。
今まで、SASのコーディングでシングルクォーツを使うかダブルクォーツを使うか基準があいまいでした。が、10年目にして基準を設けて使い分けることにします。これまでは、マクロ変数を展開するときはダブルクォーツぐらいでした。

  • コード値はシングルクォーツを使う
  • メッセージ、タイトル、マクロ変数を展開するような場合はダブルクォーツを使う

特定のコード値を探すときに、なんだか不便だと思ったら書き方が統一されていないことに気がつきました。後から保守することを考えると、コード値はシングルクォーツという決まりがあった方が良いです。

2014年6月1日日曜日

台湾/中国茶のお店

お茶の覚書です。
楽庵をついかしました。
更新日: 2014年6月1日

楽庵
http://www.kiyosumi-01.com/
東京都江東区清澄3-3-23
TEL 03-5621-4777
営業時間 [月・木~土] 11:00~18:00 [水・日・祝] 11:00~17:00 定休日は火曜日
次に訪れたいお店です。

http://www.blue-t.jp/
東京都渋谷区笹塚1-61-8 ホテルブーゲンビリア1F
TEL 03-3375-1474
営業時間 不定休 12時~21時頃(仕込み等にて早終いすることもあります。)
次に訪れたいお店です。

春水堂 代官山
http://www.chunshuitang.jp/
東京都港区六本木1-4-5 アークヒルズサウスタワー 1F
TEL 03-6277-8622
営業時間 11:00~21:00(定休日なし)
スターバックス風のお店

春水堂 六本木
http://www.chunshuitang.jp/
東京都渋谷区代官山町20-9 アクシス209代官山1F
TEL 03-6809-0234
営業時間 平日:8:00~21:00
土日祝:9:00~20:00(不定休)
スターバックス風のお店

薫風
http://ameblo.jp/wagashikunpu/
東京都文京区千駄木2-24-5
TEL 03-3824-3131
営業時間 「薫風カフェ」13:30~19:00(Close) 水曜定休 土日不定休
「薫風倶楽部」19:00~21:30 イベントスケジュールによる
他にない和菓子と、中国茶の組み合わせが楽しめます。お酒もあり。

cafe紅(もみ)
http://www.momicafe.com/
東京都中央区日本橋小伝馬町8-5
TEL 03-3664-3908
営業時間 火曜日~木曜日 11:30~20:00 (LO.19:30) 金曜日 11:30~21:00 (LO.20:30)
土曜日、日曜日 12:00~18:00 (LO.17:30)
次に訪れたいお店です。

今古茶藉(ここんちゃせき)
http://www.kokonchaseki.com/top.html
東京都渋谷区富ヶ谷2-21-11 西建ビル 1F
TEL 03-5478-1428
営業時間 平日・土 12:00~21:00 日・祝日 14:00~19:00
次に訪れたいお店です。

銀座 三徳堂
http://www.santokudo.jp/
東京都中央区銀座7-8-19喜多ビル1F・2F
TEL.03-5568-6882
営業時間 平日・土  12:00~21:00 日・祝日  14:00~19:00
年中無休
カキ氷でちょっと有名なお店です。

小梅茶荘
http://teachina.exblog.jp/
東京都中央区日本橋人形町2丁目32−13
TEL 03-6206-2217
営業時間 ?
定休日 ?
他のお店にない種類のお茶があります。試飲ができます。

千年茶館
http://dorarosso.com/
東京都港区白金台5-13-14
TEL 03-5447-1200
営業時間12:00~15:00(L.O. 14:30) 18:00~24:00(食事L.O. 22:00)[土曜日]12:00~22:00(L.O. 21:30)[日曜日]12:00~18:00(L.O. 17:00)
イタリアンのお店でありながら、中国茶が飲めます。ランチにはプーアル茶がついてきます。功夫式で入れてくれる時間は、お店に確認してください。

春風秋月
http://www.e-moon.co.jp/
東京都港区高輪3丁目13−1新高輪プリンスホテル内
TEL 03-3473-5638
営業時間 11:00~19:00
定休日 水曜
物販のみのお店に見えますが試飲できて、メニューもあります。グレードの違う蜜蘭香の飲み比べできて良かったです。鳳凰単叢の蜜蘭香は格別の香りです。

掌 TEAROOM
http://www.tanagokoro-tearoom.com/
東京都中央区銀座1-8-15 シーサⅨ 3F
TEL 03-3567-8455
営業時間 11:00~20:00
銀座でのんびりとお茶を楽しめます。

FUKOROKOJI Cafe
http://fukurokojicafe.blog78.fc2.com/
練馬区南大泉4-34-11
TEL 03-3922-6344
営業時間 11:30~18:00
定休日 金曜、平日は営業日を要確認、都内唯一のインコカフェ

喫茶去 一芯二葉 (きっさこ いっしんによう)
http://issin-niyo.forestarium.com/
東京都杉並区西荻北3-31-13
TEL 03-6913-8582
営業時間 12:00~21:00
定休日 火曜

月和茶ゆえふうちゃ 吉祥寺店
http://yuehecha.blog.shinobi.jp/
武蔵野市吉祥寺本町2-14-28 大住ビル2F
TEL 0422-77-0554
営業時間
平日、日)11:30-22:00
・土、祝)11:30-23:00
火曜定休(祝日の火曜は営業


日本華泰茶荘(ファータイチャソウ)
http://www.chinatea.co.jp/
東京都渋谷区道玄坂1-18-6
TEL 03-5728-2551
営業時間 1F・2F 10:30-19:30 3F茶館 11:00-19:00L.O(ランチ11:30~)
定休日なし


悟空茶荘
http://goku-teahouse.com/index.php?page=shop02
横浜市中区山下町130番地
TEL 045-681-7776
営業時間 
平日 1F/11:00~20:00  2F/11:30~20:00(LO.19:15)
土曜 1F/11:00~20:00  2F/11:30~21:00(LO.20:15)
日曜 1F/10:30~20:00  2F/11:00~20:00(LO.19:15)
(季節により変動あり)
定休日/第3火曜日

チャイナティーサロン 茶語 新宿高島屋店 (Cha Yu)
http://www.chayu.net/shinjuku.html
東京都渋谷区千駄ヶ谷5-24-2 新宿タカシマヤ 6F
TEL 03-5361-1380
営業時間
[月~日] 10:00~20:00(L.O. food 19:30 drink 19:30)
定休日 不定休(高島屋に準ずる)

岩茶房(ガンチャボウ)
http://www.gancha-bou.co.jp/
東京都目黒区上目黒3-15-5 1F
TEL 03-3714-7425
営業時間
11:00~19:00(L.O.18:30)
ランチ営業
定休日
日曜(祝日の場合は営業)・月曜


梅舎茶館 (メイシャチャカン)
http://meishachakan.com/
東京都豊島区南池袋2-18-9 2F
TEL 03-3971-2256
営業時間 12:00~18:00
定休日 (日・月)

2014年5月7日水曜日

SRX - SAS Regular Expression Utility

SRXを新しいDelphi XE6でリビルドしました。他の人にも使ってもらうために、メニューを日本語化しています。それと、32bit版、64bit版の2種類をビルドして、EG4.xとEG6.xにも対応しました。

これで、SAS9.4への移行作業でもれなくチェックして、エビデンスを残したり、書き直す前のチェックに時間的な余裕が生まれます。
似たようなツールは他にもありますが、エビデンスとなるものが出力されないのが弱点です。




2014年5月3日土曜日

Delphi XE6 + Excel2013のタイプライブラリ

Delphi XE6とExcel2013の組み合わせで開発していますが、Excelのタイプライブラリが取り込めません。以前は、この「EXCEL2010を操作してみる」の解説どおりできていたのですが、バージョンがあがったためか, いつのころからか、登録済みのタイプライブラリに含まれなくなっていました。


事情は良くわからぬものの、"C:\Program Files (x86)\Embarcadero\Studio\14.0\OCX\Servers\Excel2010.pas" をプロジェクトに追加して騙しだましでビルドしています。

SAS Option Report 1.3.0.6

SAS 9.4のバージョンアップ作業に備えて、SAS Option Reportを更新しました。
微妙に字句が変わっているので、以前のバージョンではうまく設定値を拾うことが出来ませんでした。字句定義を変えて、Delphi XE6でリビルドしています。


次もまた仕事で使うツール手直ししないといけません。
埃をかぶっているSRXはまた出番がありそうです。

2014年5月1日木曜日

Delphi XE6でバージョン情報を取得, GetFileVersionInfo

Delphi XE2に乗り換えてから、既存のコードでバージョン情報が取れなくなりました。気合を入れなおして、サンプルコードを探し出して修正しました。XE6でも動作確認取れました。

  1. unit version;  
  2.   
  3. interface  
  4.   
  5. type  
  6.   TEXEVersionData = record  
  7.     CompanyName,  
  8.     FileDescription,  
  9.     FileVersion,  
  10.     InternalName,  
  11.     LegalCopyright,  
  12.     LegalTrademarks,  
  13.     OriginalFileName,  
  14.     ProductName,  
  15.     ProductVersion,  
  16.     Comments,  
  17.     PrivateBuild,  
  18.     SpecialBuild: string;  
  19.   end;  
  20.   
  21. var  
  22.   theVersion: TEXEVersionData;  
  23.   
  24. implementation  
  25.   
  26. uses Windows, SysUtils, Forms;  
  27.   
  28. procedure LoadVersionInfo;  
  29. type  
  30.   PLandCodepage = ^TLandCodepage;  
  31.   TLandCodepage = record  
  32.     wLanguage,  
  33.     wCodePage: word;  
  34.   end;  
  35. var  
  36.   dummy,  
  37.   len: cardinal;  
  38.   buf, pntr: pointer;  
  39.   lang, key: string;  
  40. begin  
  41.   len := GetFileVersionInfoSize(PChar(Application.ExeName), dummy);  
  42.   if len = 0 then  
  43.     RaiseLastOSError;  
  44.   GetMem(buf, len);  
  45.   try  
  46.     if not GetFileVersionInfo(PChar(Application.ExeName), 0, len, buf) then  
  47.       RaiseLastOSError;  
  48.   
  49.     if not VerQueryValue(buf, '\VarFileInfo\Translation\', pntr, len) then  
  50.       RaiseLastOSError;  
  51.   
  52.     lang := Format('%.4x%.4x', [PLandCodepage(pntr)^.wLanguage, PLandCodepage(pntr)^.wCodePage]);  
  53.   
  54.     key := '\StringFileInfo\' + lang + '\CompanyName';  
  55.     if VerQueryValue(buf, PChar(Key), pntr, len) then  
  56.       theVersion.CompanyName := PChar(pntr);  
  57.     key := '\StringFileInfo\' + lang + '\FileDescription';  
  58.     if VerQueryValue(buf, PChar(key), pntr, len) then  
  59.       theVersion.FileDescription := PChar(pntr);  
  60.     key := '\StringFileInfo\' + lang + '\FileVersion';  
  61.     if VerQueryValue(buf, PChar(key), pntr, len) then  
  62.       theVersion.FileVersion := PChar(pntr);  
  63.     key := '\StringFileInfo\' + lang + '\InternalName';  
  64.     if VerQueryValue(buf, PChar(key), pntr, len) then  
  65.       theVersion.InternalName := PChar(pntr);  
  66.     key := '\StringFileInfo\' + lang + '\LegalCopyright';  
  67.     if VerQueryValue(buf, PChar(key), pntr, len) then  
  68.       theVersion.LegalCopyright := PChar(pntr);  
  69.     key := '\StringFileInfo\' + lang + '\LegalTrademarks';  
  70.     if VerQueryValue(buf, PChar(key), pntr, len) then  
  71.       theVersion.LegalTrademarks := PChar(pntr);  
  72.     key := '\StringFileInfo\' + lang + '\OriginalFileName';  
  73.     if VerQueryValue(buf, PChar(key), pntr, len) then  
  74.       theVersion.OriginalFileName := PChar(pntr);  
  75.     key := '\StringFileInfo\' + lang + '\ProductName';  
  76.     if VerQueryValue(buf, PChar(key), pntr, len) then  
  77.       theVersion.ProductName := PChar(pntr);  
  78.     key := '\StringFileInfo\' + lang + '\ProductVersion';  
  79.     if VerQueryValue(buf, PChar(key), pntr, len) then  
  80.       theVersion.ProductVersion := PChar(pntr);  
  81.     key := '\StringFileInfo\' + lang + '\Comments';  
  82.     if VerQueryValue(buf, PChar(key), pntr, len) then  
  83.       theVersion.Comments := PChar(pntr);  
  84.     key := '\StringFileInfo\' + lang + '\PrivateBuild';  
  85.     if VerQueryValue(buf, PChar(key), pntr, len) then  
  86.       theVersion.PrivateBuild := PChar(pntr);  
  87.     key := '\StringFileInfo\' + lang + '\SpecialBuild';  
  88.     if VerQueryValue(buf, PChar(key), pntr, len) then  
  89.       theVersion.SpecialBuild := PChar(pntr);  
  90.   finally  
  91.     FreeMem(buf);  
  92.   end;  
  93. end;  
  94.   
  95. initialization  
  96.   LoadVersionInfo;  
  97.   
  98. end.  

Delphi XE6 + TMS Component Pack

開発環境を更新しました。
バージョン情報の取得や、Enterprise GuideのOLE Automationなど確認するものがいくつかあります。
Delphi XE6 Professional

TMS Component Pack


2014年4月22日火曜日

Enterprise Guide 6.1 とVBAの組み合わせでエラー

EG6.1とVBAの連携でエラーが出て調査中です。
SAS Enterprise Guide 6.1をEXCEL VBAから使おうとしていますが、何故かエラーが出ます。EG4.3だと問題なくオブジェクトを生成できます。同じことをDelphi XE2から実行しても class not registeredのエラーが出ます。

2014年3月9日日曜日

分析の本番環境

意外とアクセス数があったので、記事を加筆、修正します。

分析とかリスク計算に携わるお客様からよく相談されるのがテスト環境、本番環境のことです。システム部門からすると、本番環境だけしかないのは信じがたく、分析者から見るとなんで本番環境を構えるかわからないことがままあります。


そのギャップを理解しないまま、システム統制に従うと色々苦労が絶えません。設計書ありません、テストケースありませんというのは、アドホックな分析を生業としている人には普通のことです。未知なる数値、ロジックを追い求めるときに設計書作ってレビューなんてしません。

大概、システム統制をかけようとしてユーザから情報システム部へ引き渡すときに問題が生じます。プログラムやデータ資産の範囲が不明確、計算のパラメータはテストすることなく都度修正、計算結果は回してみないと業務で使えるかどうかわからない、テストケースが無い等々、情報システム部にとっては腹の立つことばかりです。


システムとして統制効かせたり、定型化して業務とリンクさせるときには、環境を分けて実装しなおすのが良いです。この設計を起こして、実装をやり直すというのが、あまり理解されていないと感じます。分析環境で書かれたドキュメントのないコードを、そのまま本番環境に放り込んでというのは、最初の1年ぐらいは持つかもしれません。

数年たって立ち往生しそうなシステムの手当てを、SAS Log Utilityを使って何回か引受けています。

2014年3月1日土曜日

マクロ %varlist

変数の値をカンマでつないだリストを作りマクロ変数にセットします。よく使う割りに忘れます。変数が数値でも文字型でも動くように修正しました。

  1. /*  
  2. *++  
  3. * データセット(dsn)の変数(keep)をリストにして、マクロ変数(macvar)にセット  
  4. *--  
  5. */  
  6. %macro varlist(dsn=, keep=, macvar=);  
  7.  %global &macvar;  
  8.  %local i dsid n type rc;  
  9.  %let i=;  
  10.  %let dsid=%sysfunc(open(&dsn,i));  
  11.  %let n=%sysfunc(varnum(&dsid,&keep));  
  12.  %let type=%sysfunc(vartype(&dsid,&n));  
  13.  %let rc=%sysfunc(close(&dsid));  
  14.  %let &macvar=;  
  15.   
  16.  %if &type=C %then  
  17.   %do;  
  18.    /* 変数が文字型 */  
  19.    data _null_;  
  20.     set &dsn(keep=&keep) end=eod;  
  21.     length list $1024;  
  22.     retain list;  
  23.   
  24.     if _n_ eq 1 then  
  25.      do;  
  26.       list = '"' || compress(&keep) || '"';  
  27.      end;  
  28.     else  
  29.      do;  
  30.       list = trim(list) || ',"' || compress(&keep) || '"';  
  31.      end;  
  32.   
  33.     if eod eq 1 then  
  34.      do;  
  35.       call symput("&macvar", compress(list));  
  36.      end;  
  37.    run;  
  38.   
  39.   %end;  
  40.  %else  
  41.   %do;  
  42.    /* 変数が数値型 */  
  43.    data _null_;  
  44.     set &dsn(keep=&keep) end=eod;  
  45.     length list $1024;  
  46.     retain list;  
  47.   
  48.     if _n_ eq 1 then  
  49.      do;  
  50.       list = put(&keep, best.);  
  51.      end;  
  52.     else  
  53.      do;  
  54.       list = trim(list) || ',' || put(&keep, best.);  
  55.      end;  
  56.   
  57.     if eod eq 1 then  
  58.      do;  
  59.       call symput("&macvar", compress(list));  
  60.      end;  
  61.    run;  
  62.   
  63.   %end;  
  64. %mend;  
  65.   
  66. %varlist(dsn=sashelp.class, keep=name, macvar=test);  
  67. %put test=&test;  

マクロ %nobs

データステップを使わないで、OBS数を得るマクロです。よく使う割りに忘れます。

  1. /*  
  2. *++  
  3. * データセットのOBS数を返す  
  4. *--  
  5. */  
  6.   
  7. %macro nobs(ds);  
  8.  %local dsid rc;  
  9.  %let dsid=%sysfunc(open(&ds));  
  10.  %if &dsid %then %do;  
  11.   %sysfunc(attrn(&dsid,NOBS));  
  12.   %let rc=%sysfunc(close(&dsid));  
  13.  %end;  
  14.  %else %do;  
  15.   -1  
  16.  %end;  
  17. %mend nobs;  
  18.   
  19. %put nobs=%nobs(sashelp.class);