2008年12月16日火曜日

SqlServer2005 SP3

出ちゃったw
開発はじめのころはまだベータ版だったというのに。

2008年12月2日火曜日

@ITでコラムブログ

地方からの戯言

つーことで週刊ペースでやっております。
暇な人はたまにでも見てやってください。

2008年11月10日月曜日

編集コントロールの使いまわし

DataGridViewはレスポンス上の問題があると思われているので、元々編集コントロール(EditingControl)は原則使いまわすようになっているんだよね。で、基本これは問題ないんだけど・・・。

このサイトで色々やってきたように、基本セルは同一のクラスとし、プロパティとして実際に利用する編集コントロールを設定させるタイプの場合この使い回しと思い切りぶつかるんだよねぇ。まぁ、編集クラスは同一だから同じセルと判断されるのは致し方ないのは承知w

色々調べたんだけどDataGridViewの中で隠蔽している部分らしく、外からどうこうできることはなかったんだよね。

ただそれだとあまりにもなので、OnCellEnterあたりのメソッドで

強制的にEditingPanel内のコントロールを削除」。

一応なんとかなっているけど、ものすごく危険な手段なので別の方法がないかなぁ、と模索中。

2008年11月1日土曜日

MCA MASTER・・・プラス?

ようやく残していたMCAアプリケーションに合格して晴れてMCAマスターに。 あとで証明書やら届くらしいのでちと楽しみ~。

そして地味にもう一つ楽しみなのが。

現在MCAプラットフォーム(Windows2008Serever対応版の)を所有している人限定の追加資格(?)。
Hyper-Vアドバイザーにも一応合格してみたんだけど・・・

提供されるロゴは緑色の通常タイプのみで、MCAマスター向けロゴがまだ見当たらないw
むぅ、問い合わせてみるか・・・。

でも考えてみると、今のMCAマスターのロゴは、「MCAマスター」「プラス セキュリティ」と、追加でセキュリティも増えてますよー的なロゴなんだよね。そこにHyper-Vが増えるとなると・・・。なんというか縦に大きくなってくるなぁ。

今回は「名刺に入れたい」がためにやってみたんで、やっぱり問い合わせてみよう。

2008年10月21日火曜日

ReportBuilder2.0

SqlServer用BIツールの一環として先日リリースされたツール。

具体的にはSqlServerのReportViewerとかReportingServiceとかで利用しているテクノロジに対しての、帳票作成ツール。.Netで開発している人にとっては標準のレポートと言えば通じるかな。

個人的にはこのツールのリリースは大歓迎。なにせ今までSqlServerを購入しないと利用できなかった帳票作成環境が、無償で手に入ってしかもSqlServerに限定しないときているからねぇ。
AccessやOracle、極端に言えばODBC接続したCSV相手に帳票作ることだった可能なワケだ。

業務系で仕事していると「~表」といった類は大量に用意「してしまう」傾向にあるんだけど、こういったツールをユーザーに渡すことによって、ユーザー自身が自前で必要な帳票を作るというのも、あながち夢じゃなくなってきたねぇ。

2008年10月2日木曜日

SQLのTOPクエリ

あるイベントでの説明資料をダウンロードして眺めていると面白いことが書いてあった。

「TOPクエリはUPDATEやDELETEにも適用可能です」

なにぬ?
言葉通りに取ると、更新・削除する件数を限定できそうな・・・。
そのうち試してみるか・・・。

2008年9月22日月曜日

ここまできたんだねぇ

DBアプリをコーディングレスで構築する「ASP.NET Dynamic Data」 - @IT

ライブラリ屋としては、というか開発環境を考える人間としてはある種の最終到達地点とも言える「ノンコーディングでのアプリケーション構築」。
リンク先のサンプルを見てもらうとわかるだろうけど、今の時代はここまできたんだねぇ。

ノンコーディングでブラウザ上からデータメンテナンスが行えるほどにまで。
WindowsフォームであればVB6あたりでも近いものはあったんだけど、2008になってからのこいつはメタデータモデルやらの汎用的開発モデルを利用しているだけあって、Windowsフォームへの移行も単純。というかGUI以外同じロジック、同じクラスでいける。

こういうものをもっともっと見てくれる人が増えてくれば、社内での開発環境、というのにも興味をもってくれるもんだろうか・・・?
個人的には「純粋に仕事として」なら、ノンコーディングでの構築はアリ、と思ってるクチ。

ただ技術者としてはナシだね。これで作り続けた日には全くといって良いほど技術は育たないだろうからねぇ。

2008年8月27日水曜日

GUIのデザイン作業

設計上どうしてもやることの一つがコレ。
そして今回はものすごくこのジャンルで苦しんでいるわけですがw
ネックになるのが「VisualStudioでデザインするのが一番楽」と思えてしまうこと。
個人的にはVisualStudioでデザインするってのは、どちらかというと最後の手段というか時間的都合でというか、とにかくそういう面が大きいと思っているんだよね。
要は「誰でも楽に使えるデザインツールがない」というところ。
そんなことを思っている時に見つかったのがコレ、FireFoxのアドインPencil。

ぱっとみは何かのツールに見えるんだけど、実はこいつがFireFox3のアドオンだというww
「Pencil」というプラグインなので使ってみたい人は、FireFox3をインストールしてこのプラグインもインストールするといいかも。

2008年8月22日金曜日

統合アーカイバプロジェクトって

自分にとってはものすごく有名なところだったんだけど、意外と同業者の間でも知られてないんだねぇ・・・。UNLHA32とかUNZIPとかその他圧縮解凍系のアーカイバDLL群ってそんなに使わないものだったのかw
まぁ業務でUNLHA32.dll使う場合ちょっと注意してね、という点があるんだけどねw
(フリーソフトだけど勝手に使っていいものとはちょっと違うんだよねぇ)

でそういった人のために用意されているのが統合アーカイバのダウンロードツール「Caldix」。
とりあえずPCでアーカイバDLL使う人は使ってみるといいと思う。
これを実行すれば最新のアーカイバDLLワンセット入手してくれるから。

2008年8月13日水曜日

VS2008 ExpressEditionのSP1

Visual Studio 2008 Service Pack 1 および .NET Framework 3.5 SP1

上のリンク先はマイクロソフトのSP1に対するダウンロード情報のサイト。
ここになかなか「なんてこったい」な記述があったもんで。

※注意 Visual Studio 2008 Express Edition の Service Pack 1 は単体で提供しておりません。Visual Studio 2008 Express Edition with Service Pack 1 をインストールするためには、Visual Studio 2008 Express Edition を一度アンインストールしたのち、Visual Studio 2008 Express Edition with Service Pack 1 を新規でインストールする必要があります。

えー?!VS2005の時は同じようにSP1もMicrosoftUpdate経由で適用できたってのに、何故に今回はナシなの?

WebインストールかDVDイメージ落としてそっからのインストールしかないのね・・・不便だ・・・。

2008年7月29日火曜日

フリーのER図作成ツール

仕事でデータベースやら色々触る身分なので、どうしてもER図というのは書く場面が多々あるんだけど、
有償製品ならともかくとして無償となるとなかなかよいツールがないのもこの分野なんだよね。

現在はDBDesigner4をメインで利用しているんだけど、さすがに開発が止まっている現状(有志がDBDesingerForkとして引き継いではいるけど)なので、使いやすいツールがないものかと探してはいるんだよね。今のところ候補に挙がっているのは次のものくらいかな?

MySql Workbench
A5:SqlMk2

まーEclipse+ClayプラグインとかAmaterasERDとかそっち方面もいろいろあるんだけどねー。
見た目がね・・・w(同じ理由でA5:SqlMk2もねぇ)

いやね、見た目よりも内容が重要なのはわかってるんですよ。でも最初に出会ったのがDBDesigner4だったもんで、それなりに見た目も欲しいんですよ。ということで現在の期待はMySqlWorkbench。こいつはDBDesignerの開発メンバーが作成しているし、.Netアプリだしと、DBDesignerのファイル取り込めるし、見栄えもいいしといいことずくめ(w)なので、そのうちこれを使うようにしてみようかなぁ。

そのうち、というのには理由があって。

日本語周りで色々と不具合が多く、今のバージョン(5.0.23)ではデメリットの方が大きいから。

んー、一番の解決策は自前で作ることなんだけど、時間と腕がないからなぁ・・・。

2008年7月15日火曜日

クマー

今日、警察のメルマガで流れてきたんだけど、市内でクマが目撃されているそうだw
メルマガのタイトルも「熊出没注意!!」だったしw

こういうのを聞くと「北海道だよなぁー」って思う。

2008年7月10日木曜日

.Net Framework4.0とVisualStudio2010

どうやら来月あたり行われるTechED2008ではこのあたりのネタも話されるみたいで。ちくしょう、横浜じゃなかったら是非行きたいってんだけどねぇ。
まだまだ詳しい話は全然流れてこないんだけど一つ流れてきたのはAsp.Net系の話。

T2-402:ASP.NET MVC Framework 概説 ~ .NET Web アプリケーション開発のパラレル ワールド!? ~

Asp.NetではFramework4.0でMVCモデルのフレームワークが追加されるんだってねぇ。
んー、個人的にはアプリケーションのアーキテクチャとかそっち系の話題としてMVCモデルを捕らえているんで、ベースとなる.NetFrameworkに搭載されるってのはなんというか微妙なところ。
実際には設計モデルによっては「実装しにくい」とかはあるからいいことだとは思うけどね。
来月あたりから色々話が流れてくるだろうから要チェックかな。

2008年7月8日火曜日

SqlServer2005ExpressEditionからStandardEditionなどへのアップグレードで

色々あって(?)開発環境のDBを今までのExpressEditionからStandardEditionへアップグレードすることに。
ところがちょっとそこで調査しないといけない問題が出たのでメモとして・・・。

基本。アップグレードするときには、コマンドプロンプトよりservers/setup.exeを SKUUPGRADE=1 とオプションつけて起動してあげる必要があるのはいいとして。

今利用している環境はSqlSever2005 ExpressEdition With AdvancedServiceというReportingServiceやら色々できるようにしてくれているものなんだけど、問題となるのはこの中のReportingService

こいつは単純にはStandardEditionにアップグレードできないらしく。セットアップ中にアップグレード対象からはずしてあげないといけない(GUI上でできるから作業的には楽)
でも原因ははっきりしないんだよねぇ。WSS3.0を入れているからか?とか色々考えてはみたんだけどまだわからない。
今のところ対応するとしたら、先にWithAdvancedServiceのSqlServerをアンインストールして・・・くらいなのかな?

ちと調査が必要だねぇ。

2008年6月11日水曜日

CollapsedPanel




コントロールパネルで利用しているコントロールがほしいなぁ、と思って色々探していたら見つかったコントロール。
CodeProjectで.Net1.x時代から存在していたみたい・・・w



ソースを元に.Net2.0ベースに切り替えていってるんだけど、もうちょっと微調整するとなかなか使い出がでてきそう。
Panelに追加されている他のコントロールの位置調整ができれば、十分利用できそうだなぁ。

2008年6月4日水曜日

TabControlでタブを左右に表示させるとき

むー。

TabControlでAlignmentプロパティをLeftやRightに設定して縦にタブを表示しようとしてもそのままじゃできないのね。自力でオーナードローしてあげないといけないとは・・・。

できないなら最初からそんなプロパティ用意しないでくれってのw

2008年6月3日火曜日

「さぁできることから」札幌セミナー

マウスが当たった人です(謎

今日はWeb&データアクセスを題材にしたセミナーだったので、マイクロソフト札幌支社までいってセミナー受けてきましたわ。
内容はなかなか面白いところが多くて(特にLINQ周りは実例つきだったのでわかりやすかった)、大分自分なりにLINQの使いどころも見えてきた感じになってきたんだよね。ASP.NETについては内容というよりも、プレゼンの方法を見に行った節があったりするので、LINQとは違うところで大分参考になったなぁ。

ただ。

参加者の中に変なツッコミをする人がいたのがなんとも。
「どうでもいいんじゃね?」というトコロにいちいちつっこまなくてもなぁ・・・。

2008年5月26日月曜日

SqlServer Management Studio ExpressではSqlServerログが見られない?

MSDNで検索してもManagementStudioで、ログの表示が行えます、とあるのに・・・。

Express版ではダメですか、そうですか。

いやぁ・・・今まで気づかなかったw

SqlServer2008の新機能

ちょろちょろっとPASSJ(SqlServerのコミュニティ)がINETAJ Day 2008というイベントでプレゼンした内容のスライドを見ているんだけど、なかなか2008になって追加されている面白い機能ってのがあるねぇ。まだまだ見ている途中なんだけど、次の2点は今すぐにでも欲しい!

・複数行INSERT
INSERT INTO T1 VALUES (1, 'A'),(2,'B'),(3,'C');
なんて書き方が可能に!大量データ生成の際はレスポンスを一気にあげれるかも。

・MERGEステートメント
詳しい書き方やレスポンスがわからないんだけど、「データが存在する際はUPDATE、存在しない際はINSERT」というのをやってくれるそうで。今まではロジック判断だったのが、SQLステートメントでできるってのは楽だねぇ。

・変更追跡
簡単に言うとレコードレベルの変更を追跡できる仕組み。今までだったらトリガとか使って履歴情報作っていたようなことが、SqlServerの機能として提供されるとな。

これだけでも結構嬉しい機能強化かも・・・。実際には暗号化の話やデジタル証明書の話とかもっとあるみたいなんだけどね。自分たちの仕事にもろ影響がでそうなのは、まずこのあたりかな?

2008年5月22日木曜日

画面デザインの重要性

ERPはフロントシステムから見直せ!- @IT情報マネジメント
元ネタはERPの話として言われているんだけど、ものすごく重要なことだったので。

『アマゾン・ドットコムやアップルのiTunes Storeの使い方を、皆さんは誰から教えてもらいましたか。研修を受けて使えるようになったのでしょうか。そんなわけはありませんね。こうしたシステムは初めから誰にでも使えるように、直感的で分かりやすい操作性を兼ね備えているのです。これからの業務システムもこうしたシステムと同様に、直感的で操作性に優れているべきです。操作が複雑で研修が長時間必要になるシステムは、すでに時代遅れになりつつあります』

これはSalesForce.comという企業のCTOな人が講演で話した内容。
個人的にはまさしくその通り!というところで、業務システムだから教育しないといけないとかそういうのは思い込みであって、本当なら少数の時間教育するくらいで使えるようになっていないといけないだよねぇ。

ただこれを踏まえたデザインというのは、ものすごく難度が高く専門性も高いんだよなぁ・・・。だからデザインだけで一分野築けるくらいなんだし、専門の本とか雑誌とか色々売っているくらいだもんね。たまーに読むけど、元々センスがない人間なのでなかなか身につかないw

継続して努力せんといけませんなぁ・・・。

2008年5月21日水曜日

MultiRow Ver5.0

今日付けのプレスリリースで発表された、「MultiRow for WindowsForm」。

えーと、Ver4を利用しようとして断念した経緯を持つこちらとしては「なんだとこのやろう」的な感じですがw

内容を見てみるとさすがに、Ver4と互換性はありません!と普通に言って来るほどだから、内部的にがっつりと構造から何から何まで変更したんだなぁ・・・というのがよくわかる。
ExpressEditionに厳しくなったのも仕方ないんだ、とはわかる。デザイン用アプリ用意していないからExpressEditionの時は、自前でロジック組めよ、というのもわかる。
しかしなんというか微妙な気持ちだ・・・。

GrapeCityはVer4のMultiRowは黒歴史として封印でもしようとしてるのかねぇw

2008年5月19日月曜日

リーチ!

この間MCA Databaseに合格してMasterになるためにはあとApplicationを残すのみとなりました。

合格したらこのサイトでもMasterのロゴ貼り付けますw
ええ、もちろん自己満足のためですw

自分は根っからの技術者なんだけど、なぜかMCA制覇目指しているんですよねぇ。
それはもう変わり者というのを自覚してますからw

2008年5月13日火曜日

SilverlightでWinForm

GOA - System.Windows.Forms for Microsoft Silverlight and Adobe Flash

なんというか今日はこういう見てくれの話題に驚きっぱなし。
SilverlightやFlashでWinFormを再現しようということを、この会社(?)が実現しちゃったんだよなぁ。
正直なところ、これをみるとAsp.Netでふつーに作った画面がさみしくてしょーがないくらい。マシンパワーが潤沢になっている今、冗談抜きでこういうUIを要求されるのが多くなるだろうなぁ。

今までは「ブラウザだから・・・」といって回避できたことが、それも通用しなくなるんだろうね。

だって、できてしまっているんだから。

OPENROWSET関数を利用するの必要な権限・・・

絶対現地展開するときに忘れるだろうからメモ。

OPENROWSET関数を利用するにあたって必要となるのが、BULK系のコマンドを利用できる権限(+そのほかフォルダとかアドホックに対する権限は必要であれば・・・)。

暫定的にBulkAdminロールにDomainUsersを加入させることによって動作するようになったけど、雰囲気としてデンジャラスな気がする・・・w
まー、細かいロールやら権限やらの調整は後だな。

Health COMMON USER INTERFACE -MS CUI-

元ネタ:Microsoft Health Common User Interface - Home

CodePlexにて始まっているUIのデザインインターフェースに関してのプロジェクトで、Silverlight2を利用してこんなこともできる、というデモサイトが作られていたんだよね。

ざっと眺めてみて・・・発想力の違いに驚かされる。
めちゃくちゃなほどの大量の情報をうまいこと視覚的にまとめているんだよねぇ・・・。
こういうセンスが今ものすごくほしいんだけどw
Silverlight2は1.0と違って.Net系言語から操作することが可能だからなぁ・・・。
できるようにはなっておくべきだねぇ。

2008年5月1日木曜日

HitTest?

以前のエントリでHitTestを利用して、セルをクリックした際のフォーカス制御を直感的にしたい、というのを書き始めていたけど、見事にすっかり忘れていたので改めて追記~。

目的から考えると必要になるのは、クリックした際のマウス座標なんだよね。で、これを扱うのがHitTestと呼ばれるクラス。例えば次のようなロジックにすると、クリックした座標が取得できたりする。

Dim grdhitTest As HitTestInfo = Me.HitTest(e.X, e.Y)


引数で渡しているものとかで、なんとなく想像がつくとおり基本的にはマウス系のイベントで利用するのが多いかな?

その手のイベントではイベント引数でマウス座標が渡ってくるので、それを用いてHitTestを取得することになるんだよね。



で、この情報をDataGridViewでホストしているユーザーコントロール、今までの話でいったらMultiLayoutControlへと渡してあげるってのが第一段階だと思う。

あとは渡されたコントロール側で、その座標の直下に存在するコントロールを洗い出し、そのコントロールへフォーカスを設定してあげれば当初の目標は達成できるかな。


洗い出すためのやりかたは、渡された座標がコントロールの領域に含まれるか、という判断になるね。



''' <summary>指定した座標の下に存在するコントロールを取得します</summary>

Private Function GetChildControlInContainer(ByVal owner As System.Windows.Forms.Control, ByVal pt As System.Drawing.Point) As System.Windows.Forms.Control
  For Each child As System.Windows.Forms.Control In owner.Controls

    If child.HasChildren Then

      Dim result As System.Windows.Forms.Control = Me.GetChildControlInContainer(child, pt)

      If result IsNot Nothing Then Return result

    End If

    If Not Me._focusControl.IsEditableControlType(child) Then Continue For
#160;   Dim childRect As System.Drawing.Rectangle = _

      New System.Drawing.Rectangle(child.Left, child.Top, child.Width, child.Height)

    If childRect.Contains(pt.X, pt.Y) Then Return child

  Next 
  Return Nothing
End Function



こんな感じでやってあげれば、あとは見つかったコントロールにフォーカスを移動してあげればOK。

ちょっと記憶が薄いんだけど、FrameWorkで用意されているメソッドを利用するやり方もあるんだけど、そのコントロール自体が表示されている状態でなければうまいこといかないってのがあったんで、自前でこういった処理を用意した・・・ハズw

2008年4月30日水曜日

オブジェクト指向への壁

なにかにつけて「3年はかかる」と言っている、オブジェクト指向へ考え方を変えるということ。これは冗談でも誇大広告でもなくて、実際の体験談として言っているんだよね。

「仕事上の経験とかがあればもう少し短くなるんじゃないか?」と思われそうだけど、ここに限ってはまったくもって逆。経験があればあるだけ障害が多く時間がかかるんだよねぇ。

最初の1~2年は暗中模索というか「何がメリットなのかわからない」という状態が続くんだけど、それを超えたあたりで、急に「あー、こういうことか」とひらめいてしまうんだよなぁ。ここをクリアしているかどうかは、クラスを使った設計ができるかどうかで見分けられると思う。

実際自分の場合、VB4(古い・・・)時代に一度クラスに取り組んだんだけどまったくくもって意味もメリットもわからなかったのでそこで一度断念してるんだよね。その後、ちょっとした縁で関わったとある案件で、大分叩き込まれたんだけどその時ですらメリットはわからなかった。
でもその案件から離れて、全然違う業種のところへ出向していた時に。
何故か閃いたんだよねぇw
確かにこれは考えやすい、って。

システムを考えるときに「データ」をベースにした考え方でいる限り、オブジェクト指向には中々たどり着けないと思う。事実データをベースにする考え方はデータ指向ということで、開発工学上も分けているしね。相性が悪いんだ、データ指向とオブジェクト指向は。

自分はデータベースの設計においてはデータ指向で、システムを設計する時はオブジェクト指向でと切り替えて使うように心がけているんだけど、まだまだうまいこといってないってのが本音かな。
プログラムというところでは、ちゃんと考えないとクラス指向というちょっと違った道にいってしまいやすいので気をつけないとねぇ

2008年4月29日火曜日

ER図作成ツールで

A5:SQL Mk-2 - フリーのSQL開発ツール/ER図ツール

A5SQL

フリーのER図作成ツールは常に色々探していて、このあいだ日経ソフトウェアで紹介されていたので試してみた。
ツールとしての機能はかなり豊富だねぇ。ER図作成ツールというよりも、データベースに関連する作業を一通りできるツールスイートってところかな?
トランザクションをコマンドでなくツールボタンで開始終了できるってのは何気に便利。Oracleだと普通がそういう感覚(コマンドでCOMMIT切らないと適用されない)んだけど、SqlServerは暗黙的トランザクション(指定しない場合はコマンドの開始終了でトランザクションをCOMMITさせる)だからたくさんの処理をやるときにはちょっと疲れるんだよね。

自分が今回の案件で利用しているDbDesignerだと論理名が入力できないので、他人に見せるときに結構文句がでるんだけど、こいつはそのあたりもカバーしてくれてる。

ただちょっとだけまだ使いづらいのがあって、テーブル数がそれほどない小規模な開発だといいんだけど、ある程度以上を超えるとこのソフトで扱えるER図領域ではちょっと手狭なんだよね。それと見てくれはやっぱりDbDesignerの方がキレイ。

しかしこういったツールってDelphi製が結構多いねぇ・・・。やっぱりHack的な人はそっちが多いんだろうなぁ。

2008年4月28日月曜日

長音と全角ハイフン

VB6での作業中。
伝票明細のケース数を印字しようと思ったので、コントロール名に「ケース数」と入れてみると。

「プロパティの値が不正です」

・・・忘れてたんだよなぁ。コントロール名としては使えない文字があることを。全角だろうと半角だろうと、〒とか&とかー(ハイフンも含む)は使えないんだったよなぁ・・・。

&はショートカットの設定に使うから、というのは覚えているんだけど、なんで長音とかハイフンってダメだったんだっけかな?

2008年4月22日火曜日

まずい

最近はとんとソースコードに触れていない。

なんというかメンバーの調整だとか、プロジェクトの進行把握とかマネージメントなことばかり・・・。

いやぁ、そろそろ普通にコード触りたいんだけどなぁ。
構想だけねって、コードに起こしていないネタが色々あるんだよなぁ。

AOPとかはできるだけ取り込みたいってのに・・・。

2008年4月17日木曜日

データが「ある」ということ

データベース屋さんとしては正規化を行って適切な粒度で細分化されたテーブル構造を正とするのが、嫌な言葉だけど「一般的」なんだよね。
もちろんここにはちゃんとした理由もある。

一つは「異常データを排除する」というため。もう一つは「レスポンス向上」のため。

データの排除についてはそれほど異論はないと思うんだけど、恐らくはもう一つの「レスポンス向上」についてが、変に思うところだと思う。
SqlServerも含めて殆どのRDB系DBMSはインデックスの構築の仕方がレスポンスに直結してくるんだよね。インデックスを利用できないような抽出条件(部分一致検索とか、値がNullという条件とか)をなくすことが、そのままレスポンス向上につながるので、システムの動作速度の大半は実はここで決まってしまうんだよね。

そしてインデックスというのは、参照するのは早いけど更新するのは遅い、という性質を持っているんだ。簡単に言うとSELECTするのは早いけどINSERTやUPDATEは遅い、というところで。

ここで最初の話に戻るけど、なぜ正規化したほうがレスポンスの向上が見込めるかと言うとこの条件指定に関連してくるわけだ。
WHEREが適切に動くようなインデックスを構築する場合だと、参照はそれで済んだとしても更新の際には主キー+インデックスの更新も必要になる。でも正規化して「データが存在すること」が条件になるようにできていれば、殆どはクラスタインデックス(主キー)の更新だけで済むようになるということなんだよね。以前に1つのテーブルに10以上のインデックスを構築したテーブルに対しての更新処理を行ったことがあるんだけど、それはもうなんじゃこりゃ的なトロさだったね(w
インデックスはずして更新するとエライ速度が変わるという。
なのでインデックスでどうこうするのではなく、テーブルにデータが存在することで条件指定を兼ねるよう正規化して設計することが後々で重要なんですなぁ。

2008年4月14日月曜日

Microsoft Visual Studio International Pack 1.0

4/11付けで正式版がリリースされていた模様。

時間があれば色々いじくって仕事で利用できる部分にはぜひ使いたいんだけどねぇ・・・。
何分本当に時間がないorz

ダウンロードのページから引用してるだけでも、ほしい機能が多いというのにっ!

  • East Asia Numeric Formatting Library - 数値データを日本語、繁体字中国語、簡体字中国語および韓国語における漢数字の文字列に変換します。
  • Japanese Kana Conversion Library - ひらがな、カタカナ、半角カタカナの相互変換、およびローマ字の変換をします。
  • Japanese Text Alignment Library - 日本語固有の均等割付を用いて文字列を描画します。
  • Japanese Yomi Auto-Completion Library - 日本語IME における読みの入力に対応したオートコンプリート機能を提供するライブラリとサンプルのTextBox コントロールを提供します。
  • Korean Auto Complete TextBox Control - 韓国語入力に対応したオートコンプリート機能を持つTextBox コントロールを提供します。
  • Simplified Chinese Pin-Yin Conversion Library - 簡体字中国語で一般的に用いられるPolyphone、Homophone、Pinyin や画数などの文字のプロパティを取得します。
  • Traditional Chinese to Simplified Chinese Conversion Library and Add-In Tool - 繁体字中国語と簡体字中国語の間の双方向変換を容易にするクラスライブラリを提供します。このコンポーネントには、簡体字中国のリソースファイルを繁体字中国語に変換するための、Visual Studio 統合開発環境用アドインツールが含まれます。
  • うーむ・・・どうにかして使いたい・・・。

    MicroSoft Conference2008

    ちくしょう、今年は今のところ札幌で開催する予定がないでやんの。
    今年はぜひとも行きたいんだよなぁ、本当は。東京であろうと行きたいところなんだけどなぁ。

    ・・・理由がちょっとあって。

    ちょっと登録したあとで来場すると、景品として「VisualStudio2008Standard」がもらえるから(w
    2005の時なんて乾電池だったってのに、なんだこの差は!(w

    まー、冗談はさておきこういうところで地方というのが不便でしょうがない。
    大分取り残されていくんだよねー、こういうのが積もり積もると。

    2008年3月27日木曜日

    DataRepeaterコントロール

    DataRepeater

    ちと今回は別の話題として。

    VisualBasicPowerPack3.0として最近アップデートリリースされた追加コントロールライブラリ。ShapeとかLineとかVB6までの開発者を対象としたコントロールが含まれているだよね。その中に要望が結構高めだったDataRepeaterコントロールが。

    とりあえず入れてみてささっと触ってみると、デザインがドラッグドロップでできる分やっぱり使い勝手いいなぁ(w、などと思えた。まぁ.Net特有の「DataSetありき」というのはいたしかたないところだろうけど。

    ツールバーが強制的に配置されてしまったり(消せるけど)するけどそこらへんは大した問題じゃなさそう。どちらかというとDataGridViewの様に、常に新規行を表示させる設定がない(デザイナ上ではない。プログラムからは行えるハズ・・・未確認)とかそういうところの使い勝手が異なるのが気になるくらいかな。

    このサイトでやっている伝票入力用セルを作るというのも、こいつがもう少し早くに見えていれば実行しなかったかも(w
    あー、でも列ヘッダがないとかそういったところで色々手を加えないといけないから、そんな変わらなかったかな?

    誰が書いても同じ?

    元ネタ
    「誰が書いても同じコード」は大事なことなのか - ひがやすを blog
    誰が書いても同じコード幻想(凪瀬Blog)

    ネタとしては「誰が書いても同じコードというのは大事か?」というハナシなんだけど、ここらへんは労働環境というかその会社の風土、意識が大きくかかわってくると思う。大企業になればなるだけ、画一的なコードを保守性のために求めコーディングを行う人によってコード(アルゴリズムの方が適してるかな?)が異なるなんてことを避けようとするね。
    対して中小規模の企業となるとそうでもないところが増えてくると思う。
    このあたりは色々と意見が分かれるのが当然だとは思うんだよねぇ。
    どちらのリンク先でも、コメントが大体2分されているところを見てもそうだったように。
    自分としての意見は「まず結果(アウトプット)の要件を満たすこと」が一番大事であり、「アルゴリズムが仕様通り」というのはそれ以下の扱いでいいと思っているんだよなぁ。
    極論的に言うと「アルゴリズムはどうでもいい(w」。そこは実際のコーディングを行う人間の裁量範囲だと考えているんだよね。まぁ詳細仕様として一例となるアルゴリズムを記載する必要はあるかな?と思うところはあるけど。それを使わないといけないなんて事はないよなぁ・・・。

    重要なのは。
    コーディングを行う人と仕様を起こす人との間でちゃんとコミュニケーションが取れるという事だと。コーディングを行う人が「このようなアルゴリズムでやろうと思う」という意思を、仕様を起こす人へ伝えて、そこでちゃんと意見・意思のやりとりができていること。

    ここに尽きると思う。
    仕様を起こす人は機能の目的を定義し、コーディングをする人はその目的を達成する方法を定義する。今のところ自分としてはそういう役割分担が適していると思っているし、悲観的な見方としては「そうせざるを得ない」というのもあるんだけどね(w

    ついでに読んでおくと面白いところへのリンク。
    The Joel on Software Translation Projectというサイトより。
    やさしい機能仕様 パート1: なぜわざわざ書く必要があるのか?
    やさしい機能仕様 パート2: 仕様書とはどんなものか?
    やさしい機能仕様 パート3: だけど・・・どうやって書くの?
    やさしい機能仕様 パート4: ヒント

    2008年3月26日水曜日

    ひぃっ

    3月ももう終わろうとしてるじゃないかw

    ただいま技術講習と仕様作成、打合せなどてんこもりな毎日。
    時間なさすぎ。やること多すぎ。問題多数です。本当にどうにかなるのかなぁ・・・?

    2008年3月25日火曜日

    OOとAO

    これだけしか書いていないと、なにがなんだか(w
    OO(Object Oriented)はオブジェクト指向で、AO(Aspect Oriented)はアスペクト指向の略。

    今現在のフレームワークのようにオブジェクト指向(的な)で設計・開発を行っていると、どうしても面倒なというか、あまりスッキリしない部分というのが色々とでてくるんだよね。

    それは「どこでもやるような共通的な処理」。

    オブジェクト指向は名前の通りオブジェクト(=物)を基本とした考え方なので、売上伝票とか契約書とか、そういった実際の物をベースとした設計になるんだよね。今回もデータクラスのまとめ方はこの発想になっている・・・つもり(w
    でもそのオブジェクトの中では、ログへの出力とかトランザクションの制御とか、どこでも必ずやるような共通的な処理というのも出てくるわけで、こいつが思想の上ではなかなかに相性が悪かったりするわけだ。というのもそういった共通的な処理というのは、そのオブジェクトが本来するべき振る舞いとは異なるから、なんだよね。

    そこでそういった本来の振る舞いは本来のクラスで、それ以外の処理は別のクラスで分けて管理したほうがスッキリとして扱いやすくなるんじゃないのか?、というのがアスペクト指向。

    .NetFrameWorkとしてはそういった思想は持っていないので、言語レベルやフレームワークとしてのサポートはないけれど、属性を利用してそれとほぼ変わらないことは実現できるんだよね。そのあたりをもうちょっと手を入れて使いやすくしたのが、Spring.NetとかS2Container.Net(Seaser2)とか、そういった有志の手によって製作されているフレームワークだったりするわけだ。

    AO自体はDI(Dependency Injection:依存性の注入)と一緒に語られることが多いね。DI自体は今回の手法だと、DataComponentクラスとか定義ファイルからのデシリアライズとかで行っているのよ。あとはコレをうまいこと扱えれば・・・。

    自前でそういったことをやろうとすると、でてくる壁はカスタム属性とかにたどり着くんだよね。んー、あると確実に楽なのはわかっているから何年かかけてとりこむべきだなぁ・・・。

    2008年3月24日月曜日

    DataGridViewのHitTest

    MultiLayoutなる伝票入力用のセルや編集コントロールを用意するところまでは、これまでの記事にて色々書いてきたのである程度のイメージはついていると思う。

    ここまでやってくると次に出てくる問題は、
    セルをクリックした際にその直下のコントロールへとフォーカスしてほしい
    というところにきてしまうんだよねぇ。使ってみると当然そう思うんだけど。

    というのもDataGridViewの仕組み上、セルにフォーカスが移るけどその中のフォーカス制御なんてものは当然やるわけがないからなんだよね。いや、もともとここまでの使い方しようなんて酔狂は少ないから当然なんだけどねw
    ここまでやる前にサードパーティ製品を探すからw
    でもそこは、あえてDataGridViewでがんばってしまうのがこのサイト。
    け、決して貧乏だからとかじゃないんだからね!
    某社の製品購入したはいいけど遅かったからやめた、なんてこともないんだからね!

    くだらないやりとりはおいといて、この問題を解決するにはHitTesと呼ばれるものを利用する必要がある。
    まー、DragDropとかでも利用しているんでたいした話じゃーないけどね。
    要は、セルがクリックされた際の座標を編集コントロールにも伝えてあげればいい、というだけだから。

    ということで具体的なことは次からの記事で書いていきます。

    2008年3月21日金曜日

    Excelでの小技

    どこかのサイトで見た内容で、右クリックメニューにセルの結合・解除を追加するというのがあってやってみた。まぁマクロとして組み込んでおけ、というハナシなんだけどね。これが非常に便利だったりする。

    Sub auto_open()  
    'auto_open に既に他のマクロが記述されている場合には、  
    'この1行だけを追加する  
        Add_RightClickMenu_2 1  
    EndSub  

    Sub Add_RightClickMenu_2(num%)'標準メニューの下に追加  
      Dim iAsLong  
      Dim cstBarAs CommandBar 
      Dim wcbAs CommandBar 

      i = 0 
      For Each wcb In CommandBars 
        i = i + 1 
        SelectCase wcb.Name 
          Case "cell","Cell","column","Column","row","Row" 
               Application.CommandBars(i).Reset 
               Set cstBar = CommandBars(i) 
               cstBar_sub_2 cstBar 
        EndSelect 
      Next 
    EndSub 
    Sub cstBar_sub_2(cstBarAs CommandBar) 
      Dim i% 
      i = cstBar.Controls.Count + 1 

      With cstBar 
          .Controls.Add Type:=msoControlButton 
          .Controls(i).Caption ="セルの結合(&B)" 
          .Controls(i).OnAction ="CellMerge" 
          .Controls(i).FaceId = 798 
          .Controls(i).BeginGroup =True 
      EndWith 

      i = i + 1 
      With cstBar 
          .Controls.Add Type:=msoControlButton 
          .Controls(i).Caption ="セルの結合解除(&R)" 
          .Controls(i).OnAction ="CellDivide" 
          .Controls(i).FaceId = 800 
      EndWith 
    End Sub


    これを個人用マクロとして組み込んでおけば、常に右クリックしたときにセルの結合とセルの結合解除が出てきます。
    個人的にはこれはもう必須(w
    ないとやってけないくらい。

    ライブラリ屋さんとして

    元ネタ:ディベロッパー製品開発統括部 Blog : 開発者共通の悩み?Yomi-Autocompletion の動作に関して

    いやぁ、よくわかるわこの悩みが・・・。
    案件に依存したものしか作っていない場合には、絶対にたどり着かないこの悩み(w

    汎用性と専門性とのバランスというのは、常に悩みどころなんだよね。
    極端な話、案件依存したヤツは社内で統一的に使うライブラリにはなるわけがないし(w

    いや、声を大にして言えないけど。

    2008年3月11日火曜日

    DataGridViewのTabStop対応(4) Process~系のメソッド

    DataGridViewでキー制御をカスタマイズする際に利用するProcess~系統のメソッド。
    ちょっとだけ困ったことがあって、Process系のメソッドのうち一部はOverridableになってないんだよね。
    まぁそのあたりも含めてまずは使う必要が多いメソッドについて。

    • ProcessDataGridViewKeyメソッド
    • ProcessDialogKeyメソッド
    • ProcessRightKeyメソッド、ProcessLeftKeyメソッド(Overridableでない)

    主にオーバーライドを行うのはこのあたり。場合によってはRight、LeftだけではなくUp、DownなどのProcess~メソッドもオーバーライドする必要が出てくるね。Right、LeftはOverridableでないので、Shadowで書き換えてしまいましょう。
    なので、DataGridViewとしてキャストした場合は書き換えたロジックが走らないので注意がいりますな。

    基本的なところはMSDN2でも見てもらうとして、実際に呼ばれるのはProcessDataGridViewKeyメソッドとProcessDialogKeyメソッドの二つ。ここがキー制御の大本だと思っていいと思う。
    若干呼び出されるケースが異なるくらいだけど、どちらもやる内容としては似たようなもんです(w

    極端に言えば、Enterキーを押したら右のセルに移れ!という場合、ProcessDialogKeyメソッドとProcessDataGridViewKeyメソッドにて、Enterキーをキャッチした時にProcessRightKeyメソッドを呼ぶとか直接セルを移動させるとかしてあげればいいんだよね。

    前回までに書いていたTabFocus関連の話は、ProcessRightKeyメソッドとかProcessLeftKeyメソッドの中で利用してあげるのが、結構スマートかな、なんて思います。
    ・・・当然もっともっとスマートな方法はあると思うけど。

    2008年3月7日金曜日

    オブジェクト初期化子

    VB9から利用できるようになったというオブジェクト初期化子。
    こいつを使うとクラスをNewする際にプロパティを指定して初期化できるってヤツで。

    Dim cust As Customer = New Customer() With { .Name ="libaty" }

    これ、今からでも欲しい!コイツが使えると、引数つきコンストラクタ作らないで済む!
    ライブラリ屋としては今すぐにでも欲しい機能だ!

    2008年2月25日月曜日

    DataGridViewのTabStop対応(3)

    前回の続きでTabStop制御について。
    前回で「何をもってフォーカス可能と判断するか」というのを決めたので、次にやることへ。

    • 次にフォーカス可能なセルはどこか、を調査する

    というのが次に行う処理。具体的には2方向に分かれることになる。

    • 現在のカレントセルより後ろに存在するセルでフォーカス可能か
    • 現在のカレントセルより前に存在するセルでフォーカス可能か

    まぁこれは当たり前なところで、実際には「前か後ろか」の違いがあるだけ。やることは同じ。
    そしてここで注意するのは「次ってどっち?」というところ。
    画面の仕様にも関連するけれども、次というのが、「右方向」な場合と「下方向」な場合があるよね。
    まぁこれはとりあえず右方向用メソッドと、下方向用メソッドで切り分けておいていいと思う。
    後々リファクタリングの段階で、くっつけたりまぜたり分解したりしてしまえばいいかな、と。

    ''' <summary>同じ行の中で次にフォーカス可能なセルを取得する</summary>
    Private Function GetAfterCellCanFocusInRow() As System.Windows.Forms.DataGridViewCell

      If Me.CurrentCell Is Nothing Then Return Nothing

      Dim checkResult As System.Windows.Forms.DataGridViewCell = Nothing
      Dim owningCellIndex As Integer = Me.CurrentRow.Cells.IndexOf(Me.CurrentCell)
      For Each gridCell As System.Windows.Forms.DataGridViewCell In Me.CurrentRow.Cells
        If Not Me.CheckFocusCell(gridCell) Then Continue For

        Dim targetCellIndex As Integer = Me.CurrentRow.Cells.IndexOf(gridCell)
        If owningCellIndex >= targetCellIndex Then Continue For
        checkResult = gridCell
        Exit For
      Next
      Return checkResult

    End Function

    やろうとするとこんな感じかな?これはサンプルとして「右方向」に走査するメソッドなので、コレを元にして下方向や左方向を操作するメソッドを用意してあげればいいと思う。そこまでできれば、後はProcess系メソッドのオーバーライドへといけるね。

    2008年2月22日金曜日

    DataGridViewのTabStop対応 (2)

    まずTabStop対応を行うに当たって、決めておかないといけないのが。

    • 何を持ってフォーカス可能と判断するか

    という点。簡単に言えば「入力可能か?」ということに落ち着きそうなんだけど、それを色々なプロパティを元に判断してあげる必要があるんだよね。今回は(手軽にw)こういう条件で。

    1. ReadOnly=False:読み取り専用でない
    2. Visible=True:表示されている

    それだけの判断で対応したいと思う。実際に業務とかで利用するには、もう少し条件がいるとは思うけどね。
    読み取り専用であってもフォーカスさせたいとか、そういうケースはあるだろうから。
    まぁ、そのあたりの制御をプロパティなりを通して設定できるように設計するのがベターだと。

    なのでまずは、あるセルがこの条件を満たすか、というメソッドを用意してあげよう。

    ''' <summary>セルがフォーカス可能かをチェックする</summary>
    ''' <param name="targetCell">対象となるセル</param>
    ''' <returns>フォーカス可能な際はTrue</returns>
    Protected Overridable Overloads Function CheckFocusCell( _
      ByVal targetCell As System.Windows.Forms.DataGridViewCell) As Boolean

      If (Not targetCell.ReadOnly) AndAlso (targetCell.Visible) Then Return True
      Return False

    End Function

    ざっくり用意するとこんな感じ。これでまずは「フォーカス可能なセルか」という判断ができるようになった。
    あとは、次にフォーカス可能なセル、というのを検索する際にこのメソッドをバシバシ利用してあげればいいというハナシ。
    その際にどういう処理になるか、ってのは次の記事で。

    Office Live SmallBusiness

    5ユーザーまでなら無償で利用可能なOfficeLiveスイート。
    中身は簡単に言えばSharePointで、LiveIDさえあれば無料で利用することが可能。

    簡単なCMSやグループウェア、プロジェクト管理などができてしまううえに、メールアドレスも新規に取得できて、なおかつweb上で利用可能な様にアドレスまでくれてしまうという太っ腹。

    マジメにこういうのが無償ででまわってくると、商売の仕方や仕事の仕方ってのは考え直さないといけない気がする・・・。

    2008年2月20日水曜日

    DataGridViewでのTabStop対応

    これもけっこうみかけるサンプルとして、セルを拡張してTabStopを有効化しよう、というのがあるよね。
    でも個人的にはこの方針はあまり好きじゃなかったりする。

    というのも、セルを拡張して対応するとそのセル以外では利用できなくなるからなんだよね。
    普通にDataGridViewTextCellとか利用しても、TabStopが有効にならないから。

    なので個人的には、セル拡張もアリだけどDataGridView本体の拡張も行うべきだと思ってる。
    実際の対応内容は次回以降だけど、基本方針だけを。

    • ProcessDialogKey関連のメソッドオーバーライドにて対応
    • TabStop=Falseとなる条件を決めておきそれによって判断
    • ただし、あらかじめ拡張したセルを使う前提ならばそれを優先する

    こんなところかな。次回から少しずつこのネタで引っ張る予定w

    MS08-008:OLEオートメーションの脆弱性

    マイクロソフト セキュリティ情報 MS08-008 - 緊急 : OLE オートメーションの脆弱性により、リモートでコードが実行される (947890)

    まぁ今回に限らずよくあることなんだけど。基本的にセキュリティパッチは「それを配布したヤツが責任もって再配布しろ」が基本スタンスですわね。

    さて。

    このアドバイザリにて対象となっているのはOLEAUT32.dll。そしてVisualBasic6にて開発されたもの、という限定つきだ(Ver6世代の言語で唯一影響を受ける)。つまるところ、VBの場合AP配布の際に上書きして旧バージョン使いやがることが多いから責任持つのはAP製作者側だぞ、ということ。

    確かデストリビューションウィザード使うと、再配布可能なものは強制的に再配布してしまってたんじゃなかったけかな?なので対応としては、oleaut32.dllを利用するAPを再コンパイルしてインストーラの再構築ですなぁ。VisualInterDevでWindowsInstallerを利用したときは、まだ判断してくれていたと思うけどどうだったかな?

    こういったところにどれだけの人が注意しているんだかねぇ。

    2008年2月18日月曜日

    コンソールセッションへのリモートデスクトップ

    今まで(~Vista)だと、mstsc.exeのオプションで、/consoleをつけてあげるかrdpファイルの中身にコンソールセッションを表す記述をしてあげればOKだったのが。

    VistaSP1およびWindows2008Server
    から変更になります。2008Serverはアナウンスがあったようだけど、VistaSP1については何も聞いていなかったのでメモメモ。

    mstsc.exe /admin

    これでコンソールセッションに接続するそうだ。
    ただコンソールセッションといっても、いままでみたいにセッション0ではないのは周知の通り・・・。

    2008年2月9日土曜日

    VS2005とVS2008の間でのプロジェクトファイル・・・

    色々なところで
    一度アップグレードしたprojファイルは、旧バージョンでは使えなくなるよー
    と聞いていたんだけど。

    試しにライブラリ用のプロジェクトをコンバートしてみて、そのちょろっと変更したあとで保存。その後VS2005で読み直してみたんだけど。

    ・・・読めちゃった
    エラーも出てません。アルェー?

    一応双方のprojファイルでdiffとってみると、変更があったところはほとんどなかったのよね。
    プロダクトバージョンとか、ターゲットFrameWorkとかが増えて、あとは発行回りがprojファイルに保存されているなぁ、ってのが見えたくらい。

    ひょっとして会社には内緒で、自分ひとりだけVS2008環境にしてやっていてもイケる?w

    VirusBuster2008が・・・

    ウィルスバスター2008が反応します - MSDN フォーラム

    どうやらオートコンプリートを利用しているTextBoxがあると、バスター2008が誤って反応してしまうそうで。
    ・・・今のところバスターだけっぽいのが救いだw

    というか、最近のトレンドマイクロは一時期に迫る勢いで色々問題でてきているような気がするなぁ。

    2008年2月8日金曜日

    まぁ、そうだわな

    マイクロソフト製品 & テクノロジのここが聞きたい ~人気講師がお答えします~

    Visual Studio 2005 で開発するか、2008 で開発をするか迷っています。Visual Studio 2008 で開発する際のメリットはなんでしょうか? またデメリットはありませんか?

    と言う質問に対して、NECグループにいるMVPforVBな人が答えているんだけど。

    最後にデメリットですが、基本的にありません。ひとつだけあるとすると、2008 による開発があまりに快適なので、2 度と 2005 には戻ることができないということくらいでしょうか。

    ・・・今からでも2008に切り替えたいんですがどうでしょうかw

    2008年2月5日火曜日

    .Net Frameworkのソース・・・

    以前にも書いたことのある話題で、.NetFrameWorkのソースを公開するってんがあったんだよね。いくらリバースできるとはいえ、ちゃんとしたソースの形で提供されるほうがうれしいので結構心待ちにしていたんだけど・・・。

    VisualStudio2008(Std以上)でないとできませぬ。
    (´・ω・`)

    どうやらソースを参照する機能として「外部サーバー」を設定できるようになっているのがStd以上だということで、Expではダメだそうです。

    まぁ普通に考えると、仕事で使うんだから最低でもStdだろJK・・・というところなんだろうけど。Expは軽いから好きなんだけどなぁ。

    2008年2月4日月曜日

    ロジックからCellの値を設定しても画面に反映しない?

    たぶんDataGridViewを触りはじめでよくひっかかるであろう話題がコレ。
    プログラムからは、DataGridView.Rows(Y).Cells(X).Value = "なにがし"とかやっているのに、
    画面上では全く反映されていない、というヤツ。

    これもわかってしまうと簡単で・・・。
    今現在アクティブなのが編集コントロールだから
    なんだよね。

    つまるところ、セルの値は変更されているんだけど編集コントロール側の値が変更されていないので、画面上ではなにも変更されていないように見えるわけで。
    んじゃあどうするか、と言われると・・・セルの値が変更された際は編集コントロールの値も変更させればOKなわけで。

    If (Me.IsCurrentCellInEditMode) AndAlso _
       (e.RowIndex = Me.CurrentCell.RowIndex) AndAlso _
       (e.ColumnIndex = Me.CurrentCell.ColumnIndex) Then
        If Me.EditingControl IsNot Nothing Then
            With DirectCast(Me.EditingControl, System.Windows.Forms.IDataGridViewEditingControl)
                If Me.CurrentCell.Value IsNot Nothing Then
                    .EditingControlFormattedValue = Me.CurrentCell.Value
                End If
            End With
        End If
    End If

    CellValueChangedイベントとか、OnCellValueChangedメソッドでこんな風にしてあると、どこかからCellの値を操作したタイミングで編集コントロール側の値(EditingControlFormattedValueプロパティ)を書き換えます。ただし、上のサンプルはまだまだ考慮しないといけない点が抜けているので、そのあたりは手を加える必要がありますねぇ。
    Null(Nothing)だったらどうするか、とかそういった点は、あえて実装していないということで言い張っていますw

    DataGridViewの行番号描写

    これも色々とサンプルが見当たるものなので、ちょっと注意点を。

    RowPostPaintイベントを利用して番号をAPIで直接描写、というのが一番ベターな方法になるのは間違いないところで。
    というのも、これと似たような方法として、「RowHeaderCell.Valueに行番号となる値を設定する」方法もあるんだけど、これの場合は「最描写」を意識しないといけないため、ちょっと手間が増えるんだよね。

    そしてもうひとつやってはいけないタイミングが存在していて。

    RowPostPaintイベントやRowPrePaintイベントにてRowHeaderCell.Valueの値を操作すると、DataGridViewの動作が不安定になります。

    というのがあるので、サンプル通り、RowPostPaintイベント(またはOnRowPostPaintメソッド)にてAPIにて番号描写、というのが一番ベターだったりします。

    なんで不安定になるか、というところまでは調査していないですけどね。大体は描写しようとしているイベントの中で、その元ネタを操作するからだとは思います・・・。

    2008年2月1日金曜日

    DataGridViewTextBoxEditingControl系統でオートコンプリート

    よくあるネタとして、なんだけどひとつだけ注意点があったので書いておこうかと。

    オートコンプリート系のプロパティを開放するようにCell、Columnを継承して拡張するというのは、簡単にできると思う。
    ネット上でもIMEModeが設定できるように~とか、その類とやることは同じ。なのでAutoCompleteMode、AutoCompleteSource、AutoCompleteCustomSourceプロパティをそれぞれ開放してあげるだけで、下ごしらえとしてはOKだね。

    注意しないといけないのは、そのプロパティをセットするタイミングで。

    Enterイベント系(今回はOnEnterメソッド内)でこれらのプロパティをいじくると。
    Win32Exceptionが発生します。

    MSDNとか調べたんだけど、このあたりについてはどうも記述がのっていなかったんだよねぇ・・・。
    まぁ理由はわからずともそうなってしまうので(w)、メソッドの本来の目的通りCellクラスのInitializeEditingControlメソッドで設定してあげるのが一番いいんじゃないかな?

    2008年1月29日火曜日

    今まで紹介した伝票入力用セルな手法を使うと・・・

    以前までで色々書いてきたMultiLayoutと呼んでいるやり方を使うとこんなこともできたり。

    Multi4_1

    こんな状態の表示が・・・

    Multi4_2

    こんな風に切り替えられます。しかも特にロジックは必要なく。
    方法としてはwebブラウザで利用するCSSを切り替える、みたいなやり方なので楽にできるんだよねぇ。

    MCA Platform M11-201

    今日、勤務先に合格通知が届きました。

    これでMCAは2つもってることに・・・。しかもどちらもベータ試験で受けていたりするw
    あとデータベースとアプリケーションをどうにかすれば、MCA Masterだけど・・・。

    うむむ。どうすんべか。

    ダイアログっぽくDataGridViewの編集を行う際の表示位置

    前回ダイアログを表示するときにはちょっとロジックがいる、というのを書いた。

    簡単に言うとこういったことをやる必要があるってとこで。

    • 編集するセルにあわせて表示
    • ただし表示するダイアログが親コンテナをはみ出す際にはずらして表示

    言葉で書くと2行なんだけどねw
    実際にはこんな感じで表示座標を算出しないといけないのよ


    Dim editCell As SubEditorDialogCell = TryCast(Me._parentDataGridView.CurrentCell, SubEditorDialogCell)
    If (editCell Is Nothing) OrElse (editCell.EditorInstanceType Is Nothing) Then Return

    subEditorInstance = TryCast(System.Activator.CreateInstance(editCell.EditorInstanceType), SubEditorDialog)
    If subEditorInstance Is Nothing Then Return

    '位置の割り出し
    Dim cellRectangle As System.Drawing.Rectangle = editCell.DataGridView.GetCellDisplayRectangle(editCell.ColumnIndex, editCell.RowIndex, True)
    Dim cellPoint As System.Drawing.Point = Me._parentDataGridView.PointToScreen(New System.Drawing.Point(cellRectangle.Left, cellRectangle.Top))

    '表示位置調整
    Dim editorSize As System.Drawing.Size = subEditorInstance.Size
    Dim owner As System.Windows.Forms.ContainerControl = DirectCast(Me._parentDataGridView.TopLevelControl, System.Windows.Forms.ContainerControl)
    Dim ownerSize As System.Drawing.Size = owner.ClientRectangle.Size
    If (owner.Left + ownerSize.Width) < (cellPoint.X + editorSize.Width) Then cellPoint.X = owner.Left + ownerSize.Width - editorSize.Width
    If (owner.Top + ownerSize.Height) < (cellPoint.Y + editorSize.Height) Then cellPoint.Y = owner.Top + ownerSize.Height - editorSize.Height
    Dim afterCellPoint As System.Drawing.Point = Me._parentDataGridView.TopLevelControl.PointToClient(cellPoint)


    ポイントとなるのは「親コンテナのクライアント領域」。これをコンテナのSizeとかからやると、コンテナにスクロールバーがでたり一部未表示になったりするか注意が必要。



    まあこんな感じで表示位置を求めてあげれば、あとはLocationプロパティとかにつっこむことによってちゃんと表示されるって寸法です。

    Control.GetChildAtPointメソッド

    マウスの座標から、その下にあるコントロールを取得するメソッドなんだけど・・・。
    これ、対象となるコントロールのVisibleがTrueじゃないと動かないっぽい。
    今回の作業中に直接フォーカス移動させるときにぶつかったんだけど、とりあえず自前で同じような動きするメソッドを用意してみた。

    PublicFunction GetChildControl(ByVal pt As System.Drawing.Point) As System.Windows.Forms.Control  
      For Each child As System.Windows.Forms.Control In Me.Controls  
        Dim childRectAs System.Drawing.Rectangle = New System.Drawing.Rectangle(child.Left, child.Top, child.Width, child.Height)  
        If childRect.Contains(pt.X, pt.Y)Then Return child  
      Next  
      Return Nothing  
    EndFunction

    マウスの座標って、フォームとかのイベントで取得しているのはクライアント座標なので処理的にはたいしたことなかったかな。
    まぁこれがスクリーン座標だったとしても、親Formで一度変換かましてあげればいいだけなんだけどね。
    とりあえずの動きとしてはこれでいいので、後は除外されるコントロールを指定できるようにしておかないと・・・。

    2008年1月28日月曜日

    ダイアログっぽくDataGridViewセルの編集を行うために

    伝票レイアウトセル(2) 編集コントロール その5で触っている、編集開始時の処理。
    このときはDataGridViewのEditingPanelに対して直接コントロールを追加することによって、UserControlを継承した編集コントロールを利用するようにしていたんだけど。

    ダイアログで行う場合は、当然この方法だとマズイ場面が。

    ・・・それはダイアログのサイズ

    ダイアログで、となるとケースによっては元のセルよりも大きいものを利用する場面というのが当然でてくるわけで。
    もっといってしまうと、親元のDataGridViewよりも大きいケースというのがありえるわけで。USのMSDNフォーラムにあるサンプルは「セルをダイアログの大きさに拡張する」という手法を使っているけど、それだとちとまずい。
    (本当につきつめると親Formよりも・・・というのがあるんだよねぇ)

    まぁそういうところがあるのでちょっと工夫する必要があるんだけど、今回は「親Formよりは小さいけどDataGridViewよりは大きいかも知れない」というケースまで対応する場合にどうするか、でいこうと思う。

    んで、実は答えはすこぶる簡単。

    Me.EditingControlDataGridView.TopLevelControl.Controls.Add(subEditorInstance)


    これだけ。前はEditingPanelにAddしていたのを、「親DataGridViewの所属するTopLevelControl」に変更してあげればほとんどいける。実際は「表示する位置」の問題があるので、もう少しロジックはいるけどね。それは次回以降で。



    ちなみにこの場合、AddするコントロールはTopLevel=FalseにしておかないとAddできないので注意。

    伝票入力をDataGridViewで行うためのもうひとつの方法

    今までに色々やってきた方法は、DataGridViewの中に伝票を埋め込んでしまおうという見た目にわかりいい方法だったんだけど、単純に入力だけできればいい場合には別の方法もあるよねぇ。

    それはダイアログ形式でエディタを表示するという方法。

    セルの編集状態が開始した際に同じ場所にダイアログを表示して入力させるというやりかたなんだけど、この方法を利用した場合の問題点は何個かあるんだよね。

    1. セルの大きさよりも大きいダイアログを利用する場合
    2. 単純に行うとモーダルダイアログとなる

    ちょっと今回から何回か続けてこのやり方の対応を書いていこうと思う。
    今までのMultiLayoutとよばれるやり方に比べると、わかりやすいから需要があるしね。それにMultiLayoutをちょっと変更してあげれば対応できてしまうんで、実はそれほど難しい話題じゃないしw

    せいぜい気をつけないといけないポイントが何箇所かあるくらいかな?

    2008年1月25日金曜日

    DataGridViewのヘッダー・・・

    なんというかMSDNフォーラムの方で引き合いに出していただけて嬉しいやら恥ずかしいやら。
    ただ自分ができているのは「セルの拡張」だけなので、「ヘッダの拡張」というのはちゃんとできてないんだよねぇ。

    というのも純粋にヘッダーを表示するまでならセルの拡張と話は同じなので、どうにでもできるんだけど。

    デザインのさせ方

    こればっかりがまったくアイデアも何もない。セルと同様にUserControlを継承したクラスで・・・とすれば確かに表示まではどうにかなります。

    でもそれだとデザインがえらいやりにくいんですよね。
    ヘッダをデザインするときは、普通ディティール部のデザインとあわせてやることが多いだろうし。
    そうじゃないと几帳面なところではつっかえされてしまいまするよ。

    ExpressEdition以外であれば、デザイナ自体を作成して・・・という方向にいけるんだろうけど、何しろ間違った方向へと突き進むこのサイトは、原則ExpressEditionが対象w
    ExpressEditionでできないことはやらない、という"( ゚,_ゝ゚)バカジャネーノ"、という意気込みなんですね。

    そうなると考え付く対応ってのもかなり限られてしまい。

    1. プロパティとして直接数値入力させてデザインを調整させる
    2. 完全に外部APとしてデザイナを用意する

    ぐらいなんだよなぁ・・・。手間の量からいくと「1」がまだマシ。使いやすさという点で「2」がベター。
    どちらにしろ手間はかかりますね。このあたりまでくると、どうしても市販コンポーネントを採用する方へと流れてしまいます。

    2008年1月21日月曜日

    ファイルをVarBinary(MAX)列にINSERT、UPDATEする

    これもフルテキストに関連するし、今回使う予定なのでメモ。

    ファイルイメージをそのままDBに落とすためには、項目の型がVARBINARY(MAX)かIMAGEになっている必要がある。VARBINARYやIMAGE列には単純にINSERT(UPDATE)は行えず、OPENROWSET関数を利用しなければならない。OPENROWSET関数は「ローカルファイルをインポート」するような動き(実際にはローカルファイルをOleDbとして扱う、だけど)のでOPENROWSET関数を含んだSQL文を実行する際にはデータベースサーバ上に対象となるファイルが存在していなければならない。インポートの際にはOPENROWSET関数をBULKオプション、SINGLE_BLOBオプション付で実行する。

    ちゅうことで、データベースサーバ上の一時領域をどこかで保持しないといけないね。んでデータクラスでSQLを実行する直前までにファイルをアップロードしておく、と。

    んー、単純にデータクラス内部にアップロードのロジックを用意するってのもやだねぇ。やっぱり、アップロードの部分は別クラスに切り出しておかないと、後々どうにも具合が悪そう。

    メイリオで印刷

    不思議な現象が・・・。
    XP上でメイリオを利用して紙に印刷をかけてみると、一部アルファベットが化けて出力されてきた。(今回はU→r、I→f、D→aとなっていた。要はUID→rfaとなってきたということで)

    「?」と思ってPDFに出力してみると・・・問題ない。
    プレビュー画面で見ても問題ない。
    なんだこれ?

    2008年1月18日金曜日

    OUTPUT句を利用するのが難しい・・・

    SqlServer2005の新機能で非常に便利な機能なOUTPUT句による更新結果の取得と返却。

    現在進行中で困っているんだけども、何となくこういった理由でVisualStudioはOUTPUT句を使った更新後データの取得を行っていないんじゃないかな、ってのが。

    それはトリガの存在。

    トリガが存在するテーブルに対してOUTPUT句を利用する場合、必ずINTOも付与して結果を収納する変数を指定する必要があるんだよね。
    (例外として、トランザクションでなければ大丈夫、というのはある・・・らしいけどManagementStudioでダイレクトに実行してもダメだったからMSDNの記載が違っているような気もする。読み違いの可能性は非常に高いけどw)

    それで厄介なのはINTOで結果を変数に収納するということは、一つのINSERTなりUPDATEを実行するために、こんな感じのSQLにならないといけなくなるってことで。

     BEGIN
    DECLARE @Result TABLE (@id INT NOT NULL, @fieldvalue NVARCHAR(10) NULL);
    INSERT INTO TESTTABLE (FIELDVALUE) OUTPUT INSERTED.* INTO @Result VALUES ('テストな値');
    END


    テストも何もさせていないコードなので間違っているかも知れないけど、おおむねこんな感じ。

    INTOを指定しないOUTPUT句だと「全てのテーブルには使えない」からVisualStudioでは生成しないんだろうなぁ・・・。なので全てのテーブルで利用できるSCOPE_IDENTITY関数による取得と返却をやっているんだと思う。



    つか、本当にどうしようか困っています・・・。

    今の仕事だとトリガはほぼ全てに必須なんでねぇ。何か解決策はないものかなぁ。

    UI Testふたたび

    昔はVisualTest。ちょっと前だとNUnitForms。
    そんなツールを使ってやっていたUIの自動テストに新しいものが。
    といってもWPF用なんだけどな。

    テストの実行: Microsoft UI オートメーション ライブラリ -- MSDN Magazine, February 2008

    対象や方法は違ってもやってることは皆同じ。
    まぁこういった類は、何かしらのアシスト系ツールが出てはじめて利用者が増大するフシがあるからねぇ。まだしばらくは様子見でいいかも。

    2008年1月17日木曜日

    IT Pro道場 アプリケーションプラットフォーム編

    行って来ましたIT Pro道場。

    今回はWebアプリケーション系とはいえ、アプリケーションプラットフォームという食指を非常にそそる内容だったので、自分の仕事が大変な状況の中(w)行って来ました。

    全体的にあまり細部まで下って話そうというスタンスではなかった・・・ハズだったけど、時々熱が入ったのか中々込み入った話やら、(・∀・)ニヤニヤしてしまうセリフもこぼれてきたりと、色々楽しめたなぁ。
    特に松崎さんの方がいろいろと言ってくれているのは面白かったw

    ところで、最後の抽選でチョロQ当たったんだけど、「チョロQでごめんなさい」と言われるとちょっとヘコみますw

    O/Rマッピングツール

    【VB.NET開発コンポーネント・O/Rマッピングツール】ObjectService

    リレーショナルデータベースの設計をキッチリやった場合には、多かれ少なかれクラスとの間で存在理由とか色々な点で違いが発生する(インピーダンスミスマッチ)ので、設計上でマッピングを行って関連付けをする工程が必要になるんだよね。

    これはそもそもの設計手法としての問題(データ指向なRDBとオブジェクト指向との差異)なので解決するには、データベースをooDB(cacheとか)へ変更しオブジェクトをそのままデータベースに永続化できるようにしてしまうか、「何かを行って相互間で橋渡しをする」しかないんだよね。

    でもって自分はooDBはあまりわかっていない(w)ので、マッピングを行う方向でしか設計できないわけなんだけど、その際の負荷を減らしてくれそうな製品がこれ。
    Javaとかだと既にHibernateとかiBatisとか色々とフレームワークが整っているんだけど、.Netではまだまだ少ないのが実態。NHibernateとかS2Da0.NetとかiBatis.NetとかJavaで利用されているフレームワークの移植版が殆どかな。

    そんな中で見つけたのがコイツだったんだけど、こいつはVisualStudioの環境にマージしてくれるので他のツールに比べると使いやすさはかなりいいね。後は実際の実行速度とかがどんなもんかとか、今回みたいな複雑なテーブル設計した際にどうなるかとかだけど、さすがに今はそこまで試せない・・・。

    ただ今後はこういったツールは絶対必要だと思っているんだよね。
    そのための布石というかなんというか、社内用ライブラリのDataComponentクラスはそれ自体を永続化する機能というのは持たせているし、定義を外部から取得するインターフェースも用意している。このあたりは、もう少しS2DaoとかSpringとか研究して、同等機能は持たせたいんだよねぇ・・・。
    ただ「自分以外に使うか?」と言われると・・・w

    2008年1月11日金曜日

    SQLCLRで外部プログラムの起動

    何点か悩んだところが多かったのでちょっと記録もこめて。

    • アセンブリの権限は「無制限」な必要がある
    • データベースのTRUSTWORHYプロパティはONにしておく必要がある
    • データベースの所有者欄が表示されている状態でないといけない

    最高に悩んだのは3つめ。SqlServerのインスタンスにおけるセキュリティ関係で、明確にログインアカウントを作成しておきデータベースのセキュリティでも明確にそのアカウントを作成しておかないと、所有者のところに表示がかかる状態になってくれないんだよね。

    そしてそうなってないと、無制限に設定できないわけだ。

    そこさえクリアすれば、肝心のSQLCLRとして作成するロジック自体はフツーに作ってOK。

    2008年1月10日木曜日

    MeCabによるフルテキスト検索対応

    いろいろ悩みつつもなんとかテストできた。結構トラブルがあったので忘れないようにメモ。

    1:SQLCLRでのアセンブリ権限
    今回のように外部プログラムを実行する場合、権限は「無制限」でないと実行できない。そのためにはデータベースのプロパティの設定、またはログイン周りでの権限設定が必要。今回はデータベースのプロパティ設定にて対応した。

    -- TRUSTWORTHYプロパティの設定
    ALTERDATABASE KEIWASET TRUSTWORTHY ON

    そして今回は実際にログインするアカウントには管理者権限を与えていないので、SQLCLRビルド時は権限を「安全」にして配置を行う。

    2:データベースの所有者
    今までは気にしていなかったけど、「SqlServerのセキュリティにはWindowsグループで登録されていて、そこに属するユーザーでデータベースを構築した」際には、データベースの所有者欄に何も表示されていない状態になる。このままだとアセンブリの権限設定を行うことができないので、明示的に所有者を再設定する必要がある。
    権限設定に必要な条件として、「SqlServerのセキュリティに登録されているログイン(≠グループ)」であり、その「ログインがデータベースの所有者となっている」必要があるみたい。
    SqlServerのセキュリティに明示的にアカウントを追加し、その後ManagementStudioなどからデータベースのプロパティを開き、ファイルのページにある所有者を明示的に設定する。

    SQLCLRの中身としては、今までの開発とほぼ同じなので楽々。気にしないといけないのは、デフォルトで参照設定できるアセンブリは限られているってところくらい。
    そこを除けばT-SQLでゴリゴリ書くよりも大分楽だし、できることがたくさん増えるのですばらしいですわ。
    T-SQLで外部プログラムを実行するためには、悪名高いXP_CMDSHELLを使う必要が高い(もう一つはOLEを利用するのでかなり限定されてしまう)し、しかも標準入出力を使うことができないからどうしても面倒が多いんだよね。ということで実際のSQLCLRで作成したMeCabを起動するためのロジックを。

    Imports System  
    Imports System.Data  
    Imports System.Data.SqlClient  
    Imports System.Data.SqlTypes  
    Imports Microsoft.SqlServer.Server  
    Imports System.Runtime.InteropServices  

    Partial Public Class UserDefinedFunctions   

      Private Const _mecab_InstallPathAsString ="D:\Tool\MeCab\Bin\" 
      Private Const _mecab_FilenameAsString ="MeCab.Exe" 
      Private Const _mecab_WakatiOptionAsString ="-O wakati"  

      <Microsoft.SqlServer.Server.SqlFunction()> _ 
      PublicSharedFunction UP_CLR_DevideStrings(ByVal targetStrings As SqlString) As SqlString 
        ' コードをここに追加してください 
        If targetStrings.ToString.Trim.Equals("")Then Return Nothing 

        Dim resultStringAsString 
        Using mecabProcessAsNew System.Diagnostics.Process 
          With mecabProcess 
            With .StartInfo 
              .RedirectStandardOutput =True 
              .RedirectStandardInput =True 
              .CreateNoWindow =True 
              .UseShellExecute =False 
              .WorkingDirectory = _mecab_InstallPath 
              .FileName = _mecab_InstallPath + _mecab_Filename 
              .Arguments = _mecab_WakatiOption 
            EndWith 
            .Start() 
            .StandardInput.WriteLine(targetStrings) 
            resultString = .StandardOutput.ReadLine 
          EndWith 
        End Using 
        ReturnNew SqlString(resultString) 
      EndFunction 
    EndClass

    現地環境のときにもきっと同じ事で悩みそうだから忘れないようにしないとね。

    2008年1月8日火曜日

    DataGridViewでセル間のドラッグドロップ

    よくある質問としては「DataGridViewで行の並び替えをマウスで行いたい」というのがあるんだけど、
    意外と少ないのは「同じDataGridViewの中でセルの値をドラッグドロップしたい」というやつ。

    どうしても業務AP作っている時間が長ければ長いほど、キーボードメインになってしまうので
    こういった発想自体出てこないというか、やったらいけないと思い込んでしまうんだよね。
    完全にオペレータ向けのGUIならともかく、一般的な社員も使うなら問題ない、むしろ歓迎されるんだけどw

    ということでセル間のドラッグドロップだけど、その前に注意点が。

    編集モードはEditOnEnter禁止

    当たり前だけど編集状態=編集コントロールがアクティブだからセルを操作することができないんで。
    くだらなさそうだけど、実際にひっかかってしまった人がここにいますw

    処理としてはDataGridViewのDrag~系イベントのみの記述で事足りるね。
    DragOverイベントで引数として渡ってくるdrgeventのEffectプロパティに対して適切なエフェクトを設定してあげて、DragDropイベントで元セルから先セルへ値をコピーなり移してあげればOK。

    ただ一点面倒なことがあって、ドラッグ元セルの値の種類を判断してうんぬんしようとすると大変なことになるのよ。
    というのもデフォルトで用意されている各種Cellクラスでは保持する値のTypeがどれもこれもObjectでありやがるからで、
    ここでは割り切ってセルの値を移動(またはコピー)としてしまった方がいいね。

    それであれば、(先セル).Value = (元セル).Valueと書くだけでいけるから。アクションが移動なら、その後に(元セル).Value = Nothingとかそんな類の処理をいれてあげれば大丈夫。

    2008年1月7日月曜日

    SqlServerでのフルテキスト検索

    ちょっと今回は違う話題で。

    SqlServerは結構前からフルテキスト検索という、感覚的にはネットで検索するようなイメージで検索できる仕組みが用意されているんだよね。
    ただそういった機能が用意されているにも関わらず実際に使ったことは殆どなかったわけで。

    色々試してみると中々面白いんだな、コレ。

    やりようにもよるけど、データ量が多くなればなるだけLIKEを使った検索よりも速度は速い。
    (LIKEでレスポンスをあげるには後方一致用のインデックスを用意する必要がある)
    そしてもってxlsファイルやdocファイル、pptファイルも検索対象にできてしまうのでやりようによってはかなり面白いことができるねぇ。

    ついでにいうと、わかち書きとかを自分でカスタマイズできるらしいので、気力と根性があれば・・・!

    VS2008いれてみた

    ということで年末年始の間に、自宅PCにインストールしてみました。

    ExpressEditionでどこまでサポートされているか、ってところをメインに確認してみたんだけど、WPFはちゃんとサポートされていたなぁ。WFはサポートしていないみたいだけど。

    それでもってインストールするとついでにメイリオフォントもインストールされるので、VSでの表示がWPFの時だけ面白い表示に。
    普通の場合は今までと同じ見た目なんだけど、WPF触るときだけダイアログのあたりがメイリオの表示になるので、ちょっとだけ違和感がw
    しかし無償で用意できる環境でここまでできてしまうってのがスゲェなぁ。