コレクション

考えてみれば私がもっとも重宝しているのは、Collectionかもしれません。最初はCollectionBaseの継承をつかっていましたが、今はList(Of T)をメンバー変数に持つクラスです。

最も基本的な使用法は、画面で使うADO.NETのDataTable一つに対してこのクラスのインスタンスを一つ作ります。メソッドBindでは、画面のコントロールとテーブルの列名と列のデータ型を関連付けています。

Public Class CtrlBindingCollection
    Private m_lst As List(Of Cell)
    Sub New()
        m_lst = New List(Of Cell)
    End Sub

    Public Sub Bind(ByRef ctrl As Control, ByVal colName As String, ByVal DataType As Integer, ByVal blnNext As Boolean)
        m_lst.Add(New Cell(ctrl, colName, DataType, blnNext))
    End Sub

    Public Sub モード設定(ByVal blnEdit As Boolean)
   ' 全Cellのモード設定
    End Sub

    Public Sub テキストクリア()
   ' 全Cellのテキストクリア
    End Sub

    Class Cell
        Private m_Control As Control
        Private m_列名 As String
        Private m_データ型 As Integer

        Sub New(ByRef ctrl As Control, ByVal colName As String, ByVal intDataType As Integer, ByVal blnNext As Boolean)

            Me.m_Control = ctrl
            Me.m_列名 = colName
            Me.m_データ型 = intDataType

            If blnNext Then
                If Me.m_データ型 = DT.Str OrElse Me.m_データ型 = DT.Dte Then
                    SubFuncs.SetEnterKeyHandler(ctrl)
                Else
                    SubFuncs.SetSimpleEnterKeyHandler(ctrl)
                End If
            End If
   End Sub

        Sub モード設定(ByVal blnEdit As Boolean)
     .....
        End Sub

        Sub テキストクリア()
     .....
   End Sub
    End Class
End Class

今たとえば、Form コードの中で、
Private instCtrlBindingCollection As New CtrlBindingCollection

が宣言されているとして、[instCtrlBindingCollection.テキストクリア]でコントロールをすべてクリアすることができますし、[instCtrlBindingCollection.モード設定]では、画面コントロールのEnableの可能/不可能の切り替えができます。

すなわち、このコレクションに登録されたコントロールをいっせいに「どうこう」したいときにこのクラスのメソッドを一回コールすることで事足ります。

次回は実際何をしているかご紹介します。

これから

何人かの方がつたない私のブログを読んでくださっています。

ところが私はLINQと格闘していて、ブログを書く余裕がありません。

LINQについては、もう少し習熟が進んでから私なりに内容のあるお話を書きたいと思います。

VS2002から10年近く、.NETの開発を続け、その過程で様々なプログラムの工夫をしてきました。
ベストというほどの自信家ではありません。
ご批判をいただければ、また多少の参考になればと思い、少しずつ皆様にご披露していきたいと思っています。

LINQ を使う

その後、[LINQ to Entity Framework]を使ってプロジェクトを進めています。

まだ、小学生程度の習熟度ですが、「総じてLINQはいい」というのが感想です(複雑なビジネスロジックの場合はどうなのか分かりません)。

私は、マイクロソフトが用意するデータバインドが気に入りません。
一言で言えば、カスタマイズについての柔軟性に欠けると思います。

具体的にいえば、データベースとコントロールでの表示の間に関数を入れたいのですが、どうすればいいのかよく分からない。たぶんできない(と思います)(もちろん、ストアドプロシージャを使うとかまったく方法がない訳ではありません。データバインドでのカスタマイズができません)。

したがって、データバインドを一切つかわないで、コントロールへの表示と、コントロールデータのデータベースへの格納の部分をすべてコーディングしています。

これを統一的に書くために、ADO.NETではコントロールとデータベースの列名のマップを定義していますが、LINQを使うと厳密に型づけされていますので、列名とEntity Objectとのマップをどう定義すればいいのかわかりません。

やむなくその都度、コントロールへの表示とデータベースへの保存をいちいち書いているというわけです。
ここが一番気にいらないのですが、Entity Frameworkをもっと研究すれば、解決策があるのではないかと思っています。

LINQのいいところは、先にも書きましたが、ADO.NETではデータベースへのコネクションを書き(忘れず終了し)、トランザクションを書き、複数テーブルを保存するときは、Insert、Update、Deleteとテーブルの依存関係を考慮したコードを書かなければいけません。

これらをLINQが全部やってくれるので、LINQのプログラミングはADO.NETに比べずいぶん楽です。

まだまだ研究中ですが、研究する価値が十分あると思います。

セットアッププログラム

5月だったか[ソフトウェアの開発 Etc]で触れましたが、
パッケージソフトであれ受託ソフトであれ、開発が完了したら、
最終的にはそれを顧客のコンピュータにインストールしなければいけません。

そのためには開発とは別にインストールプログラムを作成しなければいけません。
Visual Studio 6では(およそ10年前)、
ディストリビューションプロジェクトというのがあって、これでインストールメディアを作っていましたが、
この仕組みは先にも書きましたように、
必要とする関連ソフトを闇雲にターゲットコンピュータにインストールするので、[Dllの地獄]という状態を作り出していました。

それを解消すべく、マイクロソフトはMicrosoft Installer(MSI)を開発し、あらかじめターゲットコンピュータにこのMSIをインストールしておいて、個別のソフトのインストールはMSIがすべて一元管理するようにしました。今ではMicrosoft InstallerがWindowsでのインストール標準になっています。

Windowsの開発環境であるVisual Studioでは、標準でmsi準拠のセットアッププロジェクトを作成する仕組みが提供されています。ただインストールする条件もいろいろあるため、いわばアドホック(場当たり的)な部分があります。
近年、インストール条件をXMLで記述する技術がオープンソースとしてMicrosoftから発表されました(WIXといいます)。
これによってインストール条件の設定についてはだいぶ透過性がよくなったと思います。がこれも発展途上というところだと思います。

インストールプロジェクト作成ソフトとして日本で最も有名なのは、[Install Sheild]ですが、このソフトは何故か年々高額になって、現在では一本数十万円から100万円を超える価格になっています。

高額なソフトや大量に販売が見込めるソフトのインストールプログラムの作成であれば、[Install Sheild]はベストチョイスでしょうが、そうでなければなかなか手が出ません。

この様な状況の中で、できるだけお金をかけないで、いまセットアッププログラムを作成するのにどのようにすればいいか。私たちのケースをご紹介いたします。

インストール時にユーザにシリアル番号等特に厳密はチェックを必要としない場合は、Visual Studioのセットアッププロジェクトを使うのが便利です。Visual Studio 6で開発したソフト(.NETを使っていない)であれば、Visual Studio 2003のセットアッププロジェクトが使えます。残念なことは、Visual Studioのシリアル番号のチェックは甘いので、厳密なチェックはできません。

あるプロ不ラムをインストールし使うには、別のソフトが必要な場合があります。たとえば.NET Frameworkやクリスタルレポートが必要な場合は、それらのソフトがターゲットコンピュータにすでにインストールされているかどうか調べ、なければこれらをインストールしなければいけません(ランタイムのプレインストール)。

Visual Studioは、このあたりの処理は見事にやってくれます。
Visual Studioの短所は、こまめな処理ができないということです。たとえば、先の例で独自のシリアル番号チェックプログラムを組み込むことができません(少なくとも私たちにはわからなかった)。

 WIXはこのあたりの処理ができます。私はWIXがすきです。WixEditというWIX用IDEツールがあります(Sharp Developも要検討)。なかなかいいのですが、WIXを使いこなすには少し勉強が必要です。
それと、これはWIXの仕様だと思うのですが、ランタイムのプレインストールができないようです。
この部分は、Visual Studioと組み合わせて使うことができるのではないかと考えています。

WIXを時間をかけて勉強する時間がなかったので、私たちはInstall Aware(以下IAといいます)というソフトを使いました。理由は比較的安く、やりたい機能がそろっていたからです。ただし、ドキュメントが悪いし、サポート対応が悪い。それに日本語版(IDEでの日本語表示等)はないのです。
IAにはScriptと称するものがありますが、この言語仕様がない。チュウトリアルもない。手探りで習得するしかない。
Scriptは言語というよりいわばコマンドセットで、ともかくこのコマンドの使い方を習得するのがIA習得の手っ取り早い方法です。
機能や使い方そのものは悪くないのに、このドキュメントの悪さは何なのかと不思議に思います。

LINQ をどうするか 2

いつまでも勉強している訳にもいかないので、我々としてのLINQの評価をしなければいけません。

結論からいえば、LINQの採用は最小限にすることにしました。

理由は、LINQはDBへの問い合わせあるいは更新等(CRUD)については、だいぶ機能がそろっていると思いますが、これらのデータの表示については柔軟性に欠けると判断したからです。

LINQのサンプルとしては読み込んだデータをDataBindでコントロールに表示する例が載っています。しかし私たちはDataBindingを採用していません。ADO.NETの最初期に私たちも一度この採用を検討したのですが、おそらくバグと思われる異常な動きをするため使うのを断念しました。

そのためDBから得た情報をコントロールに表示するとき、すべてFormatし、逆に画面データをDBに書き込むときにはすべてParseしてからDBに書き込んでいます。LINQは遅延読み込みをしているのも一因だとおもいますが、LINQでよみこんだデータを効率よく体系的に(私たちのソフト資産を生かして)FormatなりParseなりをする方法を考えつきませんでした。

また、私たちは米FarPoint社のSpreadを多用していますが、FarPoint社のLINQ DataBindの対応がイマイチなのも理由の一つです。

これらの理由から私たちはLINQを全面的に採用するには時期尚早と結論しました。

便利に使えるところは使いますが、全面的には使わないことにいたしました。