人力検索はてな
モバイル版を表示しています。PC版はこちら
i-mobile

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

●質問者: crashtruck
●カテゴリ:コンピュータ
✍キーワード:ABC 全一 勉強 文字列
○ 状態 :終了
└ 回答数 : 2/2件

▽最新の回答へ

1 ● KirakiraHikaru
●100ポイント ベストアンサー

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

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

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

 'テキスト検索タイプ
 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)

◎質問者からの返答

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


2 ● KirakiraHikaru
●100ポイント

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

最初の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

◎質問者からの返答

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

関連質問


●質問をもっと探す●



0.人力検索はてなトップ
8.このページを友達に紹介
9.このページの先頭へ
対応機種一覧
お問い合わせ
ヘルプ/お知らせ
ログイン
無料ユーザー登録
はてなトップ