解説

実例で学ぶASP.NETプログラミング

第11回 ASP.NETで進化する「検索画面」の構築

小田原 貴樹(うりゅう)
2004/03/20

ユーザーが項目を選択した際のイベント処理を実装する

 「検索画面」が表示された後、ユーザーが実際に各項目を選択した際のイベント処理をコーディングしていこう。RadioButtonListコントロールの項目が選択された場合に発生するイベントは、SelectedIndexChangedイベントになる。まず「お酒の種類」のRadioButtonListコントロールの項目が選択された場合のコードを以下で確認してほしい。

 1: Private Sub SAKE_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles SAKE.SelectedIndexChanged
 2:   Dim OVALUE As Object = SAKE.SelectedItem.Value
 3:   Dim OTEXT As Object = SAKE.SelectedItem.Text
 4:   OWNCLR(SAKE, OVALUE, OTEXT)
 5:   Session("SX(1)") = 1
 6:   Session("PVIEW").RowFilter = Session("BFIL") & "酒種ID = " & OVALUE
 7:   Session("BFIL") = Session("PVIEW").RowFilter
 8:   NCNT.Text = Session("PVIEW").Count
 9:   If Session("SX(2)") = 0 Then NOMICH(Session("PVIEW"), NOMI, Session("BFIL"))
10:   If Session("SX(3)") = 0 Then AMACH(Session("PVIEW"), AMA, Session("BFIL"))
11:  If Session("SX(4)") = 0 Then KAKAKUCH(Session("PVIEW"), KAKAKU, Session("BFIL"))
12:  If Session("SX(5)") = 0 Then SIZECH(Session("PVIEW"), SIZE, Session("BFIL"))
13:
14:   Session("BFIL") = Session("BFIL") & " AND "
15: End Sub
「お酒の種類」RadioButtonListコントロールの項目が選択された場合のイベント処理コード

 ユーザーが任意の項目を選択した場合、期待どおりの動作をさせるためには以下の流れで処理を実装しなければならない。

処理1

項目が選択されたRadioButtonListコントロールの内容を変更し、無効化する。

処理2

フィルタの文字列を変更し、データビューのRowFilterプロパティに割り当て、結果を受け取る

処理3

フィルタの結果を元に、項目が選択されていないRadioButtonListコントロールの内容から、商品情報と一致しない項目を削除する。

 上記の処理の流れを頭に入れて、コードの解説を参照してほしい。

 まず2行目と3行目で、選択された項目の「表示文字列」と「内容文字列」を変数に格納している。格納した内容は後で利用する。

 4行目で、項目が選択されたRadioButtonListコントロールの内容を変更し、無効化している。この処理は何度も行われるので、関数化している。関数の内容はこの後解説する。

 5行目で、セッション変数「SX」の配列のうち、1つ目の内容を「1」に変更している。セッション変数「SX」の5つの配列は、それぞれの5つのRadioButtonListコントロールに対応させており、配列(1)は「お酒の種類」が選択されたかどうかを格納する。後はそれぞれ、配列(2)が「飲み方」・配列(3)が「甘辛」・配列(4)が「価格帯」・配列(5)が「容量」の状態を格納する。ここまでで、上述の「処理1」が実装されている。

 6行目ではセッション変数に格納した商品情報のデータビューのRowFilterプロパティに、このイベントで選択された項目を追加してフィルタ文字列として割り当てている。右辺の先頭にセッション変数「BFIL」を指定しているのは、この変数の中にフィルタ文字列を格納していっているからだ。「お酒の種類」の「内容文字列」は、「酒カテゴリ」の列「ID」なので、フィルタに指定するWHERE条件としては6行目のような形式になる。

 7行目では、セッション変数「BFIL」に、先ほど追加したデータビューのRowFilterプロパティの内容を戻している。これでセッション変数「BFIL」はこのイベントで追加された検索条件を格納していることになる。

 8行目では、このイベントの結果として一致する商品情報が何件になるのかを、あらためてデータビューのCOUNTプロパティを参照し、格納している。これで、全件中一致する情報が何件かという情報がリアルタイムに格納されていくことになる。ここまでで、上述の「処理2」が実装されている。

 9行目〜12行目は上述の「処理3」を行っている。具体的には、項目が選択されていないRadioButtonListコントロールの内容から、商品情報と一致しない項目を削除している。この処理も何度も行われるので、関数化している。関数の内容はこの後解説する。各行の先頭で、条件文を使ってセッション変数「SX」の内容を確認している。もし対応する配列の内容が「1」になっている場合には、そのRadioButtonListコントロールはすでに選択が行われているので、一致しない項目の削除をする必要はない。

 14行目は少し冗長な記述に見えるかもしれないが、セッション変数「BFIL」の末尾に複合検索にするために“ AND ”という文字列を追加している。これでユーザーが項目を選択する度に、検索文字列が追加され「AND」による複合検索が可能な状態になる。

 SelectedIndexChangedイベントのハンドラ・メソッドに記述するコードは以上だ。次は、先ほど解説を飛ばした関数の作成を行おう。

1: Public Sub OWNCLR(ByVal RL As RadioButtonList, ByVal OVALUE As Object, ByVal OTEXT As Object)
2:   RL.Items.Clear()
3:   RL.Items.Add(New ListItem(OTEXT, OVALUE))
4:   RL.Items(0).Selected = True
5:   RL.Enabled = False
6: End Sub
RadioButtonListコントロールの項目内容を変更/無効化する関数

 OWNCLRメソッドは、指定されたRadioButtonListコントロールの内容を、選択された項目だけに変更し、その後の操作が行えないように無効化するための関数だ。処理を行うRadioButtonListコントロール、選択された項目の「表示文字列」と「内容文字列」をパラメータとして利用する。非常に単純なコードなので、ざっくりと説明する。

2行目:
RadioButtonListコントロールの内容をクリアする。
3行目:
パラメータとして渡される選択された項目の「表示文字列」と「内容文字列」を、新しい項目内容として追加する。
4行目:
追加された項目を選択された状態にする。
5行目:
ユーザーがこれ以後操作できないように無効化する。

 単純な関数だが、ユーザーの誤操作を防ぐという意味では、重要な役割を果たしているといえるだろう。

 次に、商品情報と一致しない項目を削除するための関数を解説する。この削除処理は、項目が選択されていないすべてのRadioButtonListコントロールで行う必要がある。上記のサンプル・コードでは、「お酒の種類」の項目が選択されているので、そのほかの選択されていない「飲み方」「甘辛」「価格帯」「容量」で商品情報と一致しない項目の削除処理を行う。この削除処理は、それぞれのコントロールごとでまったく同じなので、関数としてまとめている。「お酒の種類」はSAKECHメソッド、「飲み方」はNOMICHメソッド、「甘辛」はAMACHメソッド、「価格帯」はKAKAKUCHメソッド、「容量」はSIZECHメソッドである。ここではこのうち、SAKECHメソッドを例に削除処理関数の内容を解説することにしよう。

 1: Public Sub SAKECH(ByVal PVIEW As DataView, ByVal RL As RadioButtonList, ByVal BFIL As String)
 2:   Dim I As Integer
 3:   Dim X As Integer = 0
 4:   Dim DELI() As Integer
 5:   For I = 0 To RL.Items.Count - 1
 6:     PVIEW.RowFilter = BFIL & " AND 酒種ID = " & RL.Items(I).Value
 7:     If PVIEW.Count = 0 Then
 8:       ReDim Preserve DELI(X)
 9:       DELI(X) = I
10:       X += 1
11:     End If
12:     PVIEW.RowFilter = BFIL
13:   Next
14:   If Not DELI Is Nothing Then
15:     Dim L As Integer = 0
16:     For I = 0 To DELI.GetUpperBound(0)
17:       RL.Items.RemoveAt(DELI(I) - L)
18:       L += 1
19:     Next
20:   End If
21: End Sub
「お酒の種類」RadioButtonListコントロールでフィルタ条件に一致しない項目を削除する関数(SAKECHメソッド)

 SAKECHメソッドは、「お酒の種類」RadioButtonListコントロールに表示されている各項目のうち、指定されたフィルタ条件に一致しない項目を削除するための関数だ。パラメータとして商品情報が格納されているデータビュー、指定のRadioButtonListコントロール(といっても、「お酒の種類」以外での利用はできない)、現在のフィルタ文字列を指定する。

 作った本人から見ても、冗長で読みにくいコードだと思う。よってここでは、順を追ってコードの内容を解説していこう。

 まず2行目と3行目は、ループ用のカウンタ変数の宣言を行っている。

 次の4行目では、「削除しなければならない項目のインデックス値」を格納するための動的配列を宣言している。

 5行目〜13行目の1回目のループでは、RadioButtonListコントロールの各項目を確認し、削除しなければならない項目の判定を行っている。以下で、もう少し詳細に各行を解説する。

 6行目では、パラメータとして渡された現在のフィルタ文字列にRadioButtonListコントロールの各項目を追加してフィルタ文字列を再作成し、そのフィルタ文字列を商品情報が格納されているデータビューのRowFilterプロパティに設定している。これにより、コントロールの項目が絞られた状態で7行目の条件文の判定が行われるようになる。

 7行目の条件文で、COUNTプロパティを利用してレコードが存在するかどうかを実際に判定している。

 8行目〜10行目で、レコードが存在しなかった場合の処理を行っている。まず8行目で、動的配列「DELI」の内容を保存したまま、Redimステートメントでサイズを変更している。9行目では、「削除しなければならない項目のインデックス値」として一致するレコードが存在しなかった項目のインデックス値を配列に格納している。10行目は次の削除対象となる項目が存在したときのために、カウンタ変数を1つ増加させている。

 12行目では、次の項目を確認する前にRowFilterプロパティを元のフィルタ文字列に戻している。こうしておかないと、前の項目をどんどん引きずってしまうからだ。

 ここまでの処理で、RadioButtonListコントロールに格納された各項目のうち、削除しなければならない項目は判明した。14行目〜20行目の2回目のループでは、実際に項目の削除を行っている。

 15行目は2回目のループで利用するカウンタ変数を宣言している。その上で、16行目から削除しなければならない項目数を、動的配列「DELI」の上限を調べることで確認し、ループを開始している。

 実際の削除処理を行っているのが17行目だ。RadioButtonListコントロールのItemesコレクションのRemoveAtメソッドに、削除しなければならない項目のインデックス値を渡すことで削除が行われる。インデックス値からカウンタ変数を引いているのは、項目が削除されるごとにRadioButtonListコントロール内の項目数が減少し、その分インデックス値もずれていくからだ。この引き算を行わないと思わぬ項目が削除されることになる。


 INDEX
  実例で学ぶASP.NETプログラミング
  第11回 ASP.NETで進化する「検索画面」の構築
    1.Web系システムにおける「検索画面」の必要性と問題点
    2.検索画面のデザインを作成する
    3.RadioButtonListコントロールを初期化するための関数を作成する
  4.ユーザーが項目を選択した際のイベント処理を実装する
    5.ユーザーが選択を解除した際のイベント処理を実装する
    6.検索結果画面の作成と実行結果の確認
 
インデックス・ページヘ  「解説 :実例で学ぶASP.NETプログラミング」


Insider.NET フォーラム 新着記事
  • 第2回 簡潔なコーディングのために (2017/7/26)
     ラムダ式で記述できるメンバの増加、throw式、out変数、タプルなど、C# 7には以前よりもコードを簡潔に記述できるような機能が導入されている
  • 第1回 Visual Studio Codeデバッグの基礎知識 (2017/7/21)
     Node.jsプログラムをデバッグしながら、Visual Studio Codeに統合されているデバッグ機能の基本の「キ」をマスターしよう
  • 第1回 明瞭なコーディングのために (2017/7/19)
     C# 7で追加された新機能の中から、「数値リテラル構文の改善」と「ローカル関数」を紹介する。これらは分かりやすいコードを記述するのに使える
  • Presentation Translator (2017/7/18)
     Presentation TranslatorはPowerPoint用のアドイン。プレゼンテーション時の字幕の付加や、多言語での質疑応答、スライドの翻訳を行える
@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)

注目のテーマ

Insider.NET 記事ランキング

本日 月間