DataTableのあるレコードからDataGridViewのレコードを見つける〜ソートされたDataTable

  • 2017.08.30 Wednesday
  • 12:26

 

ずいぶん大昔に、DataGridViewの選択レコードからDataTableのレコードを見つけるという記事を書いたが、

今回はそれの逆、DataTableのあるレコードからDataGridView上の位置を見つける方法について考えてみる。

 

復習として、DataGridViewからDataTableの位置を見つけるには IndexOf を使えばその位置を取得できる。
 

   1:  Dim Index As Int32 = tbData.Rows.IndexOf(vwData(0).Row)


しかし、その逆はどうやらそう簡単ではなさそうだ。

 

 

というのも、DataGridViewのRowsはDataGridViewRowというクラスで、

これに対してIndexOfするためにはDataTableのDataRowをDataGridViewRowに変換してあげないといけない。

 

ザックリ書いてみると

 

   1:  Dim dgRow As DataGridViewRow = New DataGridViewRow
   2:  Dim intC As Int32
   3:   
   4:  dgRow.CreateCells(dgv)
   5:   
   6:  For intC = 0I To dgv.ColumnCount - 1I
   7:   
   8:      dgRow.Cells(intC).Value = tbData(intR).Item(intC)
   9:   
  10:  Next intC

 

といった感じで変換する方法があるようだ。

 

しかし、変換した DataGridViewRow でいざ IndexOf をしても、

-1、つまり一致しないと返ってくる

 

これは上のようなゴリッと書いたくらいの変換では完全にDataGridViewのRowと一致しないからである。

(どこが違うかはゴリゴリ書いて比較してみれば分かると思うので、省略)

 

ちなみに、適当な DataGridView 上の Rows を dgRow に突っ込んで IndexOf をするとちゃんとその行が取れるので、

上の変換にもうちょっと手を加えて完全に一致するような DataGridViewRow を作ってあげれば

今回の問題はクリアとなる。

 

ただ、IndexOf 自体が For ループで回しているのと同じ動作をしていることを考えると、

変な変換を書くより、単純に上から順に検索しても同じことと言えるので、

 

   1:  rwData = tbData(RowIndex)
   2:   
   3:  For intR = 0I To dgv.RowCount - 1I
   4:   
   5:      mrData = DirectCast(dgv.Rows(intR).DataBoundItem, DataRowView).Row
   6:   
   7:      If mrData.Equals(rwData) = True Then '一致した
   8:          Index = intR '一致した行
   9:          Exit For
  10:      End If
  11:   
  12:  Next intR

 

と DataGridView 上の DataRowView から DataRow を引っ張り出して、

DataTable 上の DataRow と比較して一致する場所を見つける方が単純かもしれない。

 

ちなみに、これなら簡単かなと思った方法、

DataGridViewと同じテーブルになる、DataTable.DefaultView.ToTable を生成して、

それに対して Rows.IndexOfしてみたが、

 

   1:  tbData = DirectCast(Me.DataSource, DataTable) 'テーブルを読み出す
   2:   
   3:  srData = tbData.DefaultView.ToTable 'DataViewからTableを読み出す
   4:   
   5:  Index = srData.Rows.IndexOf(rwData)

 

やはり -1 を返した。

もうひと工夫必要なのかもしれない

 

で、調べていると、DataView.Find というのがあるようで、

 

   1:  Index = tbData.DefaultView.Find(rwData.Item(ConIndex))

 

で 欲しい位置が取得できる。

 

注意として、というか今回の話の前提として、DataView.Sort でデータの並び替えをしていることが前提となる。

なので、Sort が Nullの場合エラーとなる。

 

Findは、並べ替え順序に基づいて行を検索しますが、

並べ替えが指定されていません。

 

ソートされていない場合、DataTable の位置と DataGridViewの位置は同じ(なはず)なので、

場合分けをして取り出すことで今回の問題が解決できる。

 

   1:  Dim tbData As DataTable = DirectCast(Me.DataSource, DataTable) 'テーブルを読み出す
   2:  Dim ojItem As Object
   3:   
   4:  If tbData.DefaultView.Sort <> "" Then 'ソートされている
   5:      ojItem = tbData.Rows(RowIndex).Item(FindIndex)
   6:      Index = tbData.DefaultView.Find(ojItem)
   7:  Else
   8:      Index = RowIndex 'そのまま返す
   9:  End If

 

 

 

 

関連投稿

DataGridViewの選択レコードからDataTableのレコードを見つける

DataViewのデータ(抽出結果)からDataTableの位置を検索

 

 

コメント
コメントする








    
この記事のトラックバックURL
トラックバック

calendar

S M T W T F S
     12
3456789
10111213141516
17181920212223
24252627282930
<< September 2017 >>

search this site.

よく使う、検索される投稿

categories

アマゾン

楽天

selected entries

archives

recent comment

recent trackback

profile


※当ブログはリンクフリーですが、 取材や雑誌等で掲載される場合は、事前にお知らせください

others

mobile

qrcode

powered

無料ブログ作成サービス JUGEM