コード

例えば、”様”とか”殿”とか”御中”とかの敬称を幾つかのForm(あるいはクラス)で使うとします。データベースの中の顧客テーブルでこれをどのように表現するかという問題です。

最初の案は、顧客テーブル敬称列に”様”、”殿”、”御中”をそのまま記入します。敬称がたくさん使われていないのであればそれでもいいかもしれませんが、沢山ありしかも列の値(”様”、”殿”、”御中”等)が長い場合、あるいは今後変更が予想される場合は、データベースでは列の値そのままではなくコードを使う方が有利です。

最初に考えるのは、すべてのコードをたとえば2ケタの整数で表現する方法です
(勿論数字でなく、アルファベットでも日本語でもここでの議論では本質的に同じです)。最初の桁はコード分類:たとえば性別は1、敬称は2とします。2桁目は項目の内容:たとえば”様”は”1″、”殿”は”2”、”御中”は”3”
とします。

するとたとえば”12”は敬称の”殿”を表現しています。

この方法の長所は単純だということですが、欠点は後の変更に対応しにくいことです。たとえば分類区分が1桁で足りなくなったとき、あるいはあとで考えるとコードを入れ替えた方がいい等メンテナンス上の弱点があります。

次の案はコード区分項目名コード等の列を持つコードテーブルを作る案です。下のようになっています。

敬称、様、0
敬称、殿、1
敬称、御中、2

顧客テーブル敬称列にはコードテーブルコードを記入します。Formで顧客の敬称を表示するには、顧客テーブルコードテーブルJoinを使って項目名を取得し表示します。画面の[敬称]データを保存するときは、逆に敬称項目名から同じくSQLを使ってコードを算出し、顧客テーブルにこのコードを保存します。

ただしこの方法では顧客のコードを算出するのに、そのたびにデータベースへのアクセスをしますのでいかにも非効率です。

当然データの量とIOアクセスのトレードオフを勘案しなければなりませんが、このテーブルデータをメモリ上に保存することを考えます。

私は長年ある意味原始的なDictionaryを使った方法を使っています。多少工夫をしていますが、ベストと思っている訳ではありません。参考までにご紹介します。

今例として性別敬称の処理を取り上げます。

まず、BICollectionというクラスを定義します(勿論名前は何でもいいです)。
中身は項目名からコードを検索するDictionaryと、逆にコードから項目名を検索するDictionaryからなります。

Public Class BICollection
    Private m_dist項目名2CD As Dictionary(Of String, Integer)
    Private m_distCD2項目名 As Dictionary(Of Integer, String)

	・・・・

     Public Function GetCD(ByVal prm項目名 As String) As Integer
        Return m_dist項目名2CD(prm項目名)
    End Function

    Public Function GetName(ByVal prmCd As Integer) As String
        Return m_distCD2項目名(prmCd)
    End Function
End Class

これに対して、列挙子とオブジェクトを定義します。

    Public Enum CODE
      性別
        敬称
	・・・・
        LAST = 999
    End Enum

    Public BIC性別 As BICollection
    Public BIC敬称 As BICollection

さらに、列挙子をキーにBICollectionオブジェクトをValueにしたDictionaryを定義し、CODE列挙子と項目名からコードを算出するメソッドと、逆にCODE列挙子とコードから項目名を算出するグローバル・メソッドを定義します。

     Public Dct区分2BIC As New Dictionary(Of Integer, BICollection)

    Public Function GetCd(ByVal prmPF As Integer, ByVal prm表示名 As String) As Integer
        Return CType(Dct区分2BIC(prmPF), BICollection).GetCD(prm表示名)
    End Function

    Public Function GetName(ByVal prmPF As Integer, ByVal prmDbCode As Integer) As String
        Return CType(Dct区分2BIC(prmPF), BICollection).GetName(prmDbCode)
    End Function

敬称の”様”からそのコード(今その値は0とします)を計算するには、
GetCd(CODE.敬称, “様”)で、逆に性別の”0″の項目名は、 etName(CODE.敬称, 0)で算出します。

実際にはBICollectionにはもう少し情報が付加されていて、性別や敬称の項目名とそのコードをもっていますので、ComboBoxItem設定の仕組みも持っています。

すなわち、項目名をDisplayMemberにコードをValueMemberに設定しますと、ComboBoxで表示されたTextはDisplayMemberに、ValueMemberコードを示します。

しかし、LINQが使えるようになった今は、メモリ上でSQLを作成できますので特別厳密に処理速度を求めるのでなければ、LINQの方が数段すぐれているように思います。

error: コピーできません !!