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上で利用可能な様にアドレスまでくれてしまうという太っ腹。

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