この特集のトップページへ
Chapter 7:プレゼンテーション層の構築

7.4.3 顧客の一覧参照
●データの並べ替えをサポートする
 データグリッドに表示されたレコードは,特定の列で並び替えることができると便利である。たとえば,顧客番号順に並べたり,顧客名のよみがな順に並べたりすることができれば,データの可視性が増す。そこで,データの並べ替えをサポートする方法について考えてみよう。

 先に説明したように,データグリッドは結び付けられているADODB.Recordsetオブジェクトに格納されているのと同じ順序で表示される。よって,並び替えて表示するには,結び付けられているADODB.Recordsetオブジェクトに格納されているレコードの順序を変更すればよい。

 「ADODB.Recordsetオブジェクトに格納されているレコードの順序を変更する」というと,SELECT文を実行するときにORDER BY句を付与する方法がまず思い浮かぶ。しかし今回の場合,Business.CustomerコンポーネントのGetCustomersメソッドの戻り値として得たADODB.Recordsetオブジェクトを利用しているから,ORDER BY句を付与するには,Business.CustomerコンポーネントのGetCustomersメソッドの実装を変更しなければならない。

 それ以外に並べ替える方法はないかというと,そんなことはない。ADODB.RecordsetオブジェクトのSortプロパティを使うと,任意の列で並び替えることができる。

 データグリッドに結び付けられているADODB.Recordsetオブジェクトは,グローバル変数g_objRecに保存されている(List 7-12を参照)。よって,たとえば次のようにすると,YOMIGANAの列で並び替えることができる。

g_objRec.Sort = "YOMIGANA"

 また,次のようにフィールド名のうしろに「DESC」を付けると,昇順ではなく,降順で並び替えることができる。

g_objRec.Sort = "YOMIGANA DESC"

One Point!DESCは,「降順」を示す特別な意味で使われる。そのため,ADODB.Recordsetオブジェクトが保持するレコードにDESCという名前のフィールドがある場合には誤動作する。またASCは,「昇順」を示す特別な意味で使われる(フィールド名の後ろに何も表記しなかった場合には,ASCが省略されているものとみなされるというのが正しい)。よって,ASCという名前のフィールドがある場合にも誤動作する。

 さらに,Sortプロパティには,複数のフィールド名を空白で区切って指定することもできる。たとえば,次の設定はIDフィールドで並び替えたあとYOMIGANAフィールドで並び替えるという意味になる。

g_objRec.Sort = "ID YOMIGANA"

 さて,このようにSortプロパティの値を指定することで任意の列(フィールド)で並び替えることができるということはわかったわけだが,並び替える項目はどのようにしてユーザーに選択させるのがよいだろうか。

 比較的簡単なのは,ドロップダウンリストボックスなどで,並び替え項目をユーザーに選択できる場所を用意することである。確かにその方法も悪くないが,ここではデータグリッドの列見出しをクリックすると,その列で並び替えることができるようにしてみることにする(Fig.7-30)。

Fig.7-30 列見出しをクリックする方法による並び替え
fig7_30

 ユーザーがデータグリッドの列見出しをクリックしたときには,データグリッドのHeadClickイベントが発生する。HeadClickイベントに対応するプロシージャは,次のような書式となる。

Private Sub データグリッド名_HeadClick(ByVal colIndex As Integer)

 引数colIndexには,ユーザーがクリックした列見出しの列番号が格納される。列番号は,列の左から順に,0,1,……と対応する(ただし,表示されている列の左から順にというわけではなく,非表示になっている列も含まれる)。「●データグリッドとADODB.Recordsetオブジェクトとを結び付ける」で説明したように,データグリッドの各列はColumnオブジェクトとして構成され,データグリッドのColumnsコレクションを使ってアクセスできる。つまり,HeadClickイベントの引数として渡されるcolIndexを利用し,データグリッド名.Columns(colIndex)とすると,ユーザーがクリックした列に対応するColumnオブジェクトを取得することができる(ただし,ユーザーが列以外の部分をクリックしたときには引数colIndexの値が負の値になるので,そのエラーをチェックする必要がある)。

 ColumnオブジェクトのDataFieldプロパティを参照すると,その列に対応するADODB.Recordsetオブジェクトでのフィールド名を取得できる。このフィールド名とは,Fig.7-26に示したデータグリッドのプロパティの[列]ページにおいて,[DataField]の項目に設定した値と同じものである。

 このようにして,フィールド名が得られるから,ここで得られたフィールド名をADODB.RecordsetオブジェクトのSortプロパティに設定すれば,ユーザーがクリックした列見出しに対応する列で並び替えることができる。実際にその処理を実装したものが,List 7-18である。

 List 7-18ではまず,8〜11行目において,引数colIndexの値が負でないことを確認している。負であるときには,列見出しで列以外の場所がクリックされたときなので,何もせずにそのまま戻る。

 13〜19行目では,クリックされた列を示すColumnオブジェクトのDataFieldプロパティを参照し,クリックされた列のフィールド名を取得し,g_Order変数に格納する。そして21行目では,グローバル変数g_objRecが指すADODB.RecordsetオブジェクトのSortプロパティに,g_Order変数に格納した文字列を設定し,並べ替えをしている。

 13行目でbDesc変数を使い,少々わかりにくい処理をしているのには理由がある。この処理により,1度目にクリックされたら昇順,さらにクリックされたら降順,それからさらにクリックされたら昇順,……という具合に,列見出しをクリックするたびに昇順と降順を切り替えることができる。

 bDesc変数がTrueであるときには15行目が実行され,g_Order変数にはクリックされた列のフィールド名のみが格納される。よって,このときは昇順で並べ替えられることになる。そのあと21行目の処理でbDesc変数の内容がTrueからFalseに変更される。次に列見出しがクリックされてDGrid_Customer_HeadClickプロシージャが呼び出されたときには,bDesc変数がFalseになっている。したがって今度は18行目が実行され,g_Order変数には,フィールド名の後ろに“ Desc”が付与された文字列が設定される。この結果,降順で並び替えられることになる。さらにそのあと21行目の処理で,bDesc変数はFalseからTrueに変わる。そのため,次にDGrid_Customer_HeadClickプロシージャが呼び出されたときには,昇順で並び替えられることになる,。このように,クリックのたびに昇順と降順を切り替える処理を実現できる。

 ところで,21行目ではグローバル変数g_objRecが指しているADODB.RecordsetオブジェクトのSortプロパティに並べ替える項目を設定しているわけだが,List 7-12に示したRefreshDataプロシージャを呼び出したときには,Business.CustomerコンポーネントのGetCustomersメソッドを呼び出して取得したADODB.Recordsetオブジェクトがグローバル変数g_objRecに設定されるから,21行目で設定したSortプロパティの内容は消えてしまう。

 そのため,List 7-19に示すように,RefreshDataプロシージャ内でもSortプロパティを設定するように修正する必要がある。修正した箇所は13行目で,Business.CustomerコンポーネントのGetCustomersメソッドの戻り値として取得したADODB.RecordsetオブジェクトのSortプロパティをg_Order変数の内容に置き換えているだけである。g_Order変数はList 7-18の1行目に示したグローバル変数であり,ユーザーが列見出しをクリックすることによって並び替えのフィールド名が設定される。

 しかし,このように変更した場合,ユーザーが列見出しをクリックするまではg_Order変数の内容が不定になるので,並び替え項目も不定になってしまい,好ましくない。そこで,FormCustomerフォームがロードされるときに実行されるForm_Loadプロシージャ(List 7-13)をList 7-20のように変更しておく。変更した箇所は46行目で,g_Order変数の内容を“ID”という文字列に設定するようにしているだけである。この変更により,初期状態ではIDフィールドの内容に従って昇順で並び替えられるようになる。IDフィールドは顧客番号を格納するフィールドであるから,初期状態ではデータグリッドに顧客番号の若いものから順に並び替えられて表示されるということになる。

prevpg.gif Chapter 7 20/65 nextpg.gif