SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

ComponentZine(InputMan)

Accessデータをリスト化する-リスト内の検索機能を使う

InputMan for Windows Forms 5.0JのGcListBoxコンポーネントを使った、カラフルリストボックスの作成

  • このエントリーをはてなブックマークに追加

使用するデータベース

 使用するAccessのデータベースは、ノートPCの一覧という簡単なデータベースで、1つのテーブルに「ID」「メーカー」「機種」「発売日」の4つのフィールドがあります。実際に使用するのは「ID」を除くフィールドで、それぞれ「テキスト型」で入力されており、発売日は「yyyy/mm/dd」という形式で保存されています。

使用するAccessのデータベース
使用するAccessのデータベース

選択されたリスト項目の取得

 最初に、リストを選択したときにその項目を取得して、GcListBoxコンポーネントのステータスバーに表示する処理を作成します。ユーザーがリストをクリックすると、GcListBoxコンポーネントにはSelectedIndexChangedイベントが発生しますので、ここで処理を行います。

 現在選択されている項目は、GcListBoxクラスの「SelectedItem」プロパティを使って取得できます。このプロパティは、選択されている項目をListItemオブジェクトで返してきます。プログラムでは、単一の項目しか選択できないように設定していますが、GcListBoxコンポーネントは複数選択も可能で、その場合選択項目はすべてListItemオブジェクトとして返されます。

 後は、このListItemオブジェクトのSubItemsプロパティで、参照したいフィールドをインデックス番号で指定して取り出します。

Visual Basic
Dim li As ListItem = GcListBox1.SelectedItem
Me.GcListBox1.StatusBar.Text = li.SubItems(0).Value
C#
ListItem li = gcListBox1.SelectedItem;
gcListBox1.StatusBar.Text = li.SubItems[0].Value

 後は、必要な列の値をSubItemsプロパティをつなげていけば、選択した行のデータを取得できます。

 ただし、このSelectedIndexChangedイベントがハンドルされている時にフォームを閉じると、以下のプロパティ値でイベントハンドラが呼び出されるようになっています。

プロパティ
SelectedIndexプロパティ -1
SelectedItemプロパティ Nothing

 このままだと、NothingとなっているSelectedItemプロパティに対してSubItemsプロパティを参照することになってしまい、フォームを閉じる際に「オブジェクトが参照されていない」というエラーメッセージが出てしまいます。

 この問題を回避するために、SelectedIndexプロパティを参照しこの値が0以上だった場合のみSubItemsプロパティを参照するようにします。

Visual Basic
Private Sub GcListBox1_SelectedIndexChanged( _
   ByVal sender As System.Object, ByVal e As System.EventArgs) _
      Handles GcListBox1.SelectedIndexChanged
    If (GcListBox1.SelectedIndex < 0) Then
        Return
    End If

    Dim li As ListItem = GcListBox1.SelectedItem
    Me.GcListBox1.StatusBar.Text = li.SubItems(0).Value & _
                                   " : " & li.SubItems(1).Value & _
                                   " : " & li.SubItems(2).Value
    End Sub
C#
private void gcListBox1_SelectedIndexChanged(object sender, 
                                             EventArgs e)
{
    if(gcListBox1.SelectedIndex < 0){
        return;
    }

    ListItem li = gcListBox1.SelectedItem;

    gcListBox1.StatusBar.Text = li.SubItems[0].Value +
                                   " : " + li.SubItems[1].Value +
                                   " : " + li.SubItems[2].Value;
    }
}

リスト内を検索する処理

 冒頭でも述べましたが、GcListBoxコンポーネントはリスト内を検索して、データを取り出す機能を持っています。

 そこで、この機能を使い日付でリスト内のデータを検索し、一致するデータをもう1つのGcListBoxコンポーネントで表示する機能を組み込んでみます。

FindStringメソッドとMatchedListItemCollection

 検索を行うには、FindStringメソッドを使用します。検索用のメソッドは3つありますが、FindStringメソッドは文字列を検索条件に設定できます。このプログラムでは、日付を文字列で入力していますから、FindStringメソッドで検索をします。

 引数は2つで、最初の引数に検索条件となる文字列を、2番目の引数に検索を行う列番号を指定します。ここでは、GcDateコンポーネントで入力された日付を元に、リストの3番目の列を対象に検索を行います。GcDateコンポーネントのTextプロパティを参照すると、選択された日付を文字列で取得することができますので、これをFindStringメソッドの第1引数に設定します。

 一致するデータが見つかると、FindStringメソッドはそのデータをMatchedListItemCollectionオブジェクトで返してきます。複数のデータが見つかれば、次々とこのMatchedListItemCollectionオブジェクトに追加されていくことになります。

Visual Basic
Private Sub Button1_Click(ByVal sender As System.Object, _
                  ByVal e As System.EventArgs) Handles Button1.Click
    Dim matchedItem As MatchedListItemCollection
    Dim item As ListItem
    Dim additem As ListItem

    'FindObjectメソッドを使って検索
    ' 検索結果はMatchedListItemCollectionに格納される
    matchedItem = GcListBox1.FindString(Me.GcDate1.Text, 2)
C#
private void button1_Click(object sender, EventArgs e)
{
    MatchedListItemCollection matchedItem; 
    ListItem additem; 

    //FindObjectメソッドを使って検索
    // 検索結果はMatchedListItemCollectionに格納される
    matchedItem = gcListBox1.FindString(gcDate1.Text, 2);

検索結果のリスト化

 このMatchedListItemCollectionのCountプロパティを調べることで、検索結果があるかどうかを知ることができますので、検索結果がある場合のみ、もう1つのGcListBoxコンポーネントにリストとして組み込みます。

 まず、すでにリストがある場合はこれを削除します。GcListBoxクラスのItemsコレクションのClearメソッドを使用すると、GcListBoxコンポーネントに組み込まれているリストをすべて削除します。

 次に、For Eachステートメントで、MatchedListItemCollection内のオブジェクトにアクセスし、検索結果1レコード分のフィールド1つ1つをSubItemオブジェクトとして作成し、これをまとめてListItemオブジェクトにします。そして、できあがったListItemオブジェクトをGcListBoxコンポーネントに組み込みます。

 この処理を、MatchedListItemCollection内のすべてのオブジェクト(すべてのレコード)に対して行い、検索結果のデータを全部リスト化していきます。

Visual Basic
    '検索結果があるかどうかを判別
    If matchedItem.Count = 0 Then
        MessageBox.Show("一致するデータはありません", _
        "検索結果", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
    Else
        'すでにリストがある場合は一度削除する
        Me.GcListBox2.Items.Clear()
        
        For Each item In matchedItem
            'データ1件の各列データをそれぞれSubItemオブジェクトにする
            Dim sbitem1 As New SubItem(item.SubItems(0).Value.ToString)
            Dim sbitem2 As New SubItem(item.SubItems(1).Value.ToString)
            Dim sbitem3 As New SubItem(item.SubItems(2).Value.ToString)

            'SubItemオブジェクトをまとめてListItemオブジェクトにする
            additem = New ListItem(sbitem1, sbitem2, sbitem3)

            'できあがったListItemオブジェクトを
            'GcListBoxコンポーネントに組み込む
            GcListBox2.Items.Add(additem)

            '検索されたデータの数だけListItemオブジェクトが作られ
            'GcListBoxコンポーネントに組み込まれる
        Next
    End If
End Sub
C#
    //検索結果があるかどうかを判別
    if(matchedItem.Count == 0){
        MessageBox.Show("一致するデータはありません", 
                        "検索結果", 
                        MessageBoxButtons.OK, 
                        MessageBoxIcon.Exclamation);
    }else{
        //すでにリストがある場合は一度削除する
        gcListBox2.Items.Clear();
        
        foreach(ListItem item in matchedItem){
            //データ1件の各列データをそれぞれSubItemオブジェクトにする
            SubItem sbitem1 = new SubItem(item.SubItems[0].Value);
            SubItem sbitem2 = new SubItem(item.SubItems[1].Value);
            SubItem sbitem3 = new SubItem(item.SubItems[2].Value);

            //SubItemオブジェクトをまとめてListItemオブジェクトにする
            additem = new ListItem(sbitem1, sbitem2, sbitem3);

            //できあがったListItemオブジェクトを
            //GcListBoxコンポーネントに組み込む
            gcListBox2.Items.Add(additem);

            //検索されたデータの数だけListItemオブジェクトが作られ
            //GcListBoxコンポーネントに組み込まれる
        }
    }
}

まとめ

 ベースとなるリストから別のリストを作成することはよくあることですが、データベースからクエリで取得したデータに対してリスト上で検索・抽出ができるとなると、改めてデータベースに対してクエリを実行する必要がありませんから、処理速度も上がりサーバに対する負荷も少なくなります。

 このような点を考えると、このGcListBoxコンポーネントはかなり使い勝手がよいコンポーネントだと思います。

 

この記事は参考になりましたか?

  • このエントリーをはてなブックマークに追加
ComponentZine(InputMan)連載記事一覧

もっと読む

この記事の著者

瀬戸 遥(セト ハルカ)

8ビットコンピュータの時代からBASICを使い、C言語を独習で学びWindows 3.1のフリーソフトを作成、NiftyServeのフォーラムなどで配布。Excel VBAとVisual Basic関連の解説書を中心に現在まで40冊以上の書籍を出版。近著に、「ExcelユーザーのためのAccess再...

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/2527 2009/03/17 12:06

おすすめ

アクセスランキング

アクセスランキング

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング