VisualBasic2005で勉強している者です。表示されているDataGridView1のColumn1に"ABC"という文字列を持つ行があるかどうか(完全一致・部分一致どちらでも結構です)を調べるにはどうすればよいでしょうか?

回答の条件
  • 1人2回まで
  • 登録:2006/09/22 21:58:44
  • 終了:2006/09/24 20:02:08

ベストアンサー

id:KirakiraHikaru No.1

KirakiraHikaru回答回数354ベストアンサー獲得回数682006/09/23 12:49:59

ポイント100pt

下記のようにすると検索できます。

ただ、大量のデータの場合は、

バインディングしているデータの方を検索するほうが速いと思います。

    'テキスト検索タイプ
    Private Enum enumSearchTextType
        Full            '完全一致
        Left            '前方一致
        Right           '後方一致
        Part            '部分一致
    End Enum
    ''' <summary>
    ''' テキスト検索
    ''' </summary>
    ''' <param name="text">検索キーワード</param>
    ''' <param name="type">検索タイプ</param>
    ''' <param name="col">検索対象列</param>
    ''' <param name="dgv">検索対象DataGridView</param>
    ''' <returns>検索結果RowIndexリスト:List(Of Integer)</returns>
    ''' <remarks></remarks>
    Private Function SearchText(ByVal text As String, _
                                ByVal type As enumSearchTextType, _
                                ByVal col As Integer, _
                                ByRef dgv As DataGridView) _
                                As List(Of Integer)
        Dim indexs As List(Of Integer) = New List(Of Integer)

        Try
            For i As Integer = 0 To dgv.RowCount - 1
                Select Case type
                    Case enumSearchTextType.Full
                        If dgv.Rows(i).Cells(col).Value.ToString.Equals(text) Then
                            indexs.Add(i)
                        End If
                    Case enumSearchTextType.Left
                        If dgv.Rows(i).Cells(col).Value.ToString.StartsWith(text) Then
                            indexs.Add(i)
                        End If
                    Case enumSearchTextType.Right
                        If dgv.Rows(i).Cells(col).Value.ToString.EndsWith(text) Then
                            indexs.Add(i)
                        End If
                    Case enumSearchTextType.Part
                        If dgv.Rows(i).Cells(col).Value.ToString.Contains(text) Then
                            indexs.Add(i)
                        End If
                End Select
            Next

        Catch ex As Exception
            Return indexs
        End Try

        Return indexs
    End Function

下記が使い方です。

        Dim indexs As List(Of Integer)
        indexs = SearchText("ABC", enumSearchTextType.Full, 0, DataGridView1)
        Dim dispStr As String = ""
        For i As Integer = 0 To indexs.Count - 1
            dispStr &= indexs(i).ToString & vbCrLf
        Next
        MessageBox.Show(dispStr)

id:crashtruck

ありがとうございます。これは難しいですね。しかし、勉強させていただきます。BindingSourceを用いたらもっと容易にできるのでしょうか。よろしければそちらもお教え願えませんか。

2006/09/23 20:46:35

その他の回答(1件)

id:KirakiraHikaru No.1

KirakiraHikaru回答回数354ベストアンサー獲得回数682006/09/23 12:49:59ここでベストアンサー

ポイント100pt

下記のようにすると検索できます。

ただ、大量のデータの場合は、

バインディングしているデータの方を検索するほうが速いと思います。

    'テキスト検索タイプ
    Private Enum enumSearchTextType
        Full            '完全一致
        Left            '前方一致
        Right           '後方一致
        Part            '部分一致
    End Enum
    ''' <summary>
    ''' テキスト検索
    ''' </summary>
    ''' <param name="text">検索キーワード</param>
    ''' <param name="type">検索タイプ</param>
    ''' <param name="col">検索対象列</param>
    ''' <param name="dgv">検索対象DataGridView</param>
    ''' <returns>検索結果RowIndexリスト:List(Of Integer)</returns>
    ''' <remarks></remarks>
    Private Function SearchText(ByVal text As String, _
                                ByVal type As enumSearchTextType, _
                                ByVal col As Integer, _
                                ByRef dgv As DataGridView) _
                                As List(Of Integer)
        Dim indexs As List(Of Integer) = New List(Of Integer)

        Try
            For i As Integer = 0 To dgv.RowCount - 1
                Select Case type
                    Case enumSearchTextType.Full
                        If dgv.Rows(i).Cells(col).Value.ToString.Equals(text) Then
                            indexs.Add(i)
                        End If
                    Case enumSearchTextType.Left
                        If dgv.Rows(i).Cells(col).Value.ToString.StartsWith(text) Then
                            indexs.Add(i)
                        End If
                    Case enumSearchTextType.Right
                        If dgv.Rows(i).Cells(col).Value.ToString.EndsWith(text) Then
                            indexs.Add(i)
                        End If
                    Case enumSearchTextType.Part
                        If dgv.Rows(i).Cells(col).Value.ToString.Contains(text) Then
                            indexs.Add(i)
                        End If
                End Select
            Next

        Catch ex As Exception
            Return indexs
        End Try

        Return indexs
    End Function

下記が使い方です。

        Dim indexs As List(Of Integer)
        indexs = SearchText("ABC", enumSearchTextType.Full, 0, DataGridView1)
        Dim dispStr As String = ""
        For i As Integer = 0 To indexs.Count - 1
            dispStr &= indexs(i).ToString & vbCrLf
        Next
        MessageBox.Show(dispStr)

id:crashtruck

ありがとうございます。これは難しいですね。しかし、勉強させていただきます。BindingSourceを用いたらもっと容易にできるのでしょうか。よろしければそちらもお教え願えませんか。

2006/09/23 20:46:35
id:KirakiraHikaru No.2

KirakiraHikaru回答回数354ベストアンサー獲得回数682006/09/23 22:57:20

ポイント100pt

ちょっと難しかったですかね。

最初のenumSearchTextTypeは列挙体で、

関数を呼び出す際の検索タイプを明示的に指定できるようにするために定義しています。

(検索タイプをIntegerにしても問題ないのですが、

 Fullで呼び出せば完全一致であると明示的にわかりやすくなりますが、

 0や1だとわかりにくくなるので列挙体を用いています)

SearchText関数は、指定されたDataGridViewの指定列を指定キーワードと種別で検索し、

検索内容に該当した行のIndexをリスト化して返却しています。

List(Of Integer)というのはInteger型のリストオブジェクトです。

Try~Catch文で囲んでいる部分は、

指定列が存在しない場合などエラーが発生した場合には、

その時点で検索を終了するようにしています。

(Return indexsとしていますが、エラーが発生したということで

 Return Nothingとするほうが良いかもしれません)

Forループでは、dgv.RowCountにより指定DataGridViewの行数分繰り返し処理をしています。

Select Case typeは指定された検索タイプによって、

各行の指定列のテキストの検索の仕方を分岐しています。

完全一致はString型のEquals関数、

前方一致はString型のStartsWith関数、

後方一致はString型のEndsWith関数、

部分一致はString型のContains関数

で判定できます。

判定が真(True)の場合は、該当した行のIndexを返却するリストに登録しています。

すべての行の指定列を検索し終えたときに該当した行のIndexリストを返却しています。


BindingSourceを用いても容易になるということではなく、

速いのではないかということです。

実際私自身大量データを扱うことがないので、実験できていないので、

パフォーマンスが気になる場合は、そちらのほうがよいかもしれまえせん。

BindingSourceがDataSetのTableの場合は、

Rowsをループ対象にして、

Rows(i).Item(j).ToString

を先の回答と同じようにチェックすれば一致しているかが検索できます。

大量データの場合はこちらを検索する方が速いようです。

(DataTable.Selectを使ってできるような単純な条件ならこちらの方が速いと思いますが)

また、SQLで問い合わせして問題ないものであればこちらの方が速くなるかもしれません。

DataGridViewはまだまだ理解ができていなくて、

下記のように大量のデータを扱いパフォーマンスも気を使う必要がある場合には、

様々な条件を守りながら使わなければいけないようです。(難しいー)

http://msdn2.microsoft.com/ja-JP/library/ha5xt0d9.aspx

id:crashtruck

詳しいご説明大変ありがとうございます。頂いたコードをそのまま組み込み、動きました。いずれ理解しなければならない時が来ると思いますので、そのときこの情報を参考にさせていただきます。いつもありがとうございます。

2006/09/24 20:01:42

コメントはまだありません

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

絞り込み :
はてなココの「ともだち」を表示します。
回答リクエストを送信したユーザーはいません