月別アーカイブ: 2010年01月

4 posts

LINQ to DataSet

[LINQ to DataSet]については、VS2008のドキュメントにかなり詳しく書かれています。

話は変わりますが(突然)、あることについて初めて勉強するときに、コンピュータ画面は不向きだと思います。
ちょっとしたことを調べる、あるいは大体は知っていることについて確認する場合は、画面の方がいいかも知れません。
コンピュータの新しい技術を勉強するとき、一度流して読んだだけでは理解しがたいときが間々あります。
この場合以前読んだ部分を何度も読み返しことになりますが、この読み返す操作では画面は大変カッタルク、書籍がはるかに勝ります。

そんな訳で[LINQ to DataSet]のVS2008のヘルプは、初めての勉強には不向きです。


以前紹介した[murach’s ADO.NET 3.5 LINAQ and the Entity Framework with VB2008]が入門としては最適(私の持ち合わせの中では)だと思います。ここでは[LINQ to DataSet]に一章を割いていて、概要を知るには最適だと思います。

さて、最初VS2008のドキュメントで手探りでVB6のバージョンアップのコードを書いていたのですが、murach’sを読んで大きく間違ってはいなかったと確認しました。

VB6プロジェクトのアップグレード

「VB6+ADO」のプロジェクトがあります。

Vistaではうまく表示できない部分があると報告がありました。
「Windows 7」でうまくいけばそれでもいいのですが、どちらにしても書き換えの時期がきたようです。

悪いことに(?)このプロジェクトはAccessを使っています。
このプロジェクトは「Access+.NET」ではどのようになるか検討を始めました。

まず、VBのアップグレードウィザードを使ってみましたが、エラーがいっぱい出てきて、それをを修正していくのが大変そうなので早々にこのウィザードを使うのを断念しました。

ところで私は「LINQ」を気に入っています。
なぜ「LINQ」がいいのかまだ十分分かっていませんが、理由は多分データのセットに対してSQLが使えることだと思います。

例えばList(Of T)に対して従来の技術のみである種の演算をしようとするとそれなりの工夫が必要です。
「ソート」やある条件のデータの合計を計算する等それなりのコードが必要です。

ところがこれらは「Linq」のSQL構文を使えば簡単に処理できます。

さて、「Linq to Entity」は「Access」をサポートしません。
将来の不安もあるのですが、「Linq to Dataset」を検討しています。
私は、「ADO.NET」は使ってきたのですが、数年前に発表された「TableAdapter」は将来性を見てからにしようと考え、使わないできました。

「データソース」作成ウィザードをつかうと、簡単にデータソース(データセット?)を作ることができますし、ここでつかわれている技術は(多分)「TableAdapter」だと思います。

ウィザードで生成された「TableAdapter」を使ってデータソース(データセット?)にDBデータを読み込みますが、このデータはLinq構文を使ってクラスのリスト-List(Of T)-に変換でき(そもそも読み込まれたデータはクラスの集合かもしれません)、したがってこのListに対してSQL演算が可能です。

まだ、十分の調査ではありませんが、「多分使える」、「なかなかいい」という印象を持っています。

編集モードとアイドルモード 2

コレクションを使って、モードを切り替えることは簡単です。

例えば9月18日の[CtrlBindingCollection]クラスに次のメソッドを追加します。

    Sub モード設定(ByVal blnEdit As Boolean)
        For i As Integer = 0 To m_lst.Count - 1
            m_lst(i).モード設定(blnEdit)
        Next
    End Sub

m_lst(i).モード設定(blnEdit)という怪しげなコードがありますが、要は[編集モード]にしたいときはそのコントロールがButtonなら[Enable = False]、TextBoxなら[Readonly = False]にするだけです。

すこし厄介なのは、画面上のコントロールに触ったとき、直ちに[編集モード]([修正]作業)に切り替える仕組みです。

やりたいことは、当該のコントロールが[TextBox(Base)]のときは[TextChanged]イベント、[ListBox]のときは[SelectIndexChanged]イベントが発生したとき、コントロールの入力データが編集されたとみなし、[編集]作業用ルーティンをコールすることです。

ここで、引数のない[Sinki]、[Shusei]、[Sakujo]等のメソッドを用意し、[新規]、[修正]、[削除]等のボタンのクリックイベントでこれらのメソッドをコールするようにします(無理に引数のないメソッドにすつこともないのですが、説明も楽ですので…)。
すなわち、れぞれのボタンをクリックすれば、それぞれのメソッドを起動し[新規]、[修正]、[削除]等の作業に入ります。

さて、TextBox等が[編集]されればこの[修正]メソッドをコールするようにしたいのです。

次にこれを処理するクラスをご紹介します。
本当はもっと複雑ですが、本質部分はこのようなものです。

Public Class Set2Changed

    Private m_dlg修正メソッド As System.Action

    Sub New(ByRef 修正 As System.Action, ByRef ctrls() As Control)
        Me.m_dlg修正メソッド = 修正

        For Each ctrl As Control In ctrls
            SetChangedHandler(ctrl)
        Next
    End Sub

    Private Sub SetChangedHandler(ByRef ctrl As Control)
        If TypeOf (ctrl) Is TextBoxBase Then
            AddHandler ctrl.TextChanged, AddressOf MyTextChanged
        ElseIf TypeOf (ctrl) Is ListControl Then
            AddHandler CType(ctrl, ListControl).SelectedIndexChanged, AddressOf MySelectedIndexChanged
        ElseIf TypeOf (ctrl) Is ButtonBase Then
            AddHandler CType(ctrl, ButtonBase).CheckedChanged, AddressOf MyCheckedChanged
        End If
    End Sub

    Private Sub MyTextChanged(ByVal sender As Object, ByVal e As System.EventArgs)
        m_dlg修正メソッド.Invoke()
    End Sub

    '    その他、[MySelectedIndexChanged][MyCheckedChanged]等も準備します
End Class

Formからこのクラスのインスタンスを作成しますが、このときそのFormの[修正]メソッドと、監視するコントロールの集合(実際にはコレクション)を渡します。
メソッド[SetChangedHandler]では、これらのコントロールのデータが修正されると、修正デリゲートが起動するイベントハンドラを各コントロールに付加しています。

これだけで、画面の各コントロールの修正にかかると、[修正]作業に入り、[モード設定]をコールすることにより[編集モード]になります。

編集モードとアイドルモード

David Sceppa[プログラミング ADO.NET]の13章の例に倣って(Sceppaでなくてもよくあることですが)、現在私はデータ入力画面では[編集モード]と[アイドルモード]の区別を徹底しています。そうしないと、メモリ上のデータの管理が難しくなるからです。

画面で何か編集すると編集モードに移行し、必ずそのデータを保存するか作業をキャンセルするか(すなわちアイドルモードに移行)しないと、他の画面への遷移ができないようにしています。

もっと正しくいうと、画面上で[新規]、[修正]、[削除]の何れかのボタンを押すと編集モードに移行します。編集モードでは[登録]あるいは[キャンセル]ボタンを押さない限り、[その]操作すなわち[新規]作業、[修正]作業あるいは[削除]作業から抜け出すことはできません。

[新規]作業中は新規データを作成する以外の作業は許されません。[修正]作業でも修正作業以外の作業はできませんし、[削除]でも同様です。

ただし[削除]はワンクリックの操作しかなく、あとは[登録]するか[キャンセル]するかです。

また、画面であるデータを読み出して修正しようとするとき、その都度[修正]ボタンを押すのは「カッタルイ」ので、画面を修正した途端に自動的に[修正]作業に移行するようにしています。

同じ編集モードでも[新規]、[修正]あるいは[削除]作業から最終的にデータベースにデータを保存するとき、処理が異なってきますので、Form変数でその時の作業状態を保存しています。

編集の途中で他の画面に移行したり、[削除]に続いて[新規]作業しデータベースへの保存を試みると[同時実行違反]の原因になります。
ですからプログラムでそれらの操作をさせないようにする必要があります。
[編集モード]になったら、まず[編集]用ボタン[新規]、[修正]および[削除]ボタンはEnabel = Flaseにしなければいけませんし、これだけでなく触らせたくない画面上のコントロールはすべてEnable = Falseにしなければいけません。

そして、[アイドルモード]に移るとこれらのコントロールを開放してやらなければなりません。

たくさんのコントロールの状態制御に以前(昨2009年9月)ご紹介しましたCollectionを使っています。