DataGridViewの行取得

このQ&Aのポイント
  • DataGridViewの行を取得するためのVB2010のコード
  • DataGridViewのDataSourceに設定されたコレクションのアイテムを指定して行のインデックスを取得する方法を検討
  • DataGridViewに表示されている行をテキストボックスに入力された名前で選択する機能
回答を見る
  • ベストアンサー

DataGridViewの行取得

VB2010です。 DataGridViewのDataSourceにコレクションを設定しており、 このコレクションのアイテムを指定してDataGridViewに表示されている行インデックスを取得したい。 以下、現状のコードです。Form1にDataGridView、ボタン、テキストボックスを貼り付けており、 テキストボックスに名前を入力してボタンをおすとその行を選択状態とします。 行を取得するために行頭から順に調べておりますが、 アイテムを指定して行を参照できるようなプロパティなり なにか良い方法が無いでしょうか? Public Class Form1 Private _persons As Collection Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load _persons = New Collection _persons.Add(New Person With {.Name = "あかい", .Age = 10}, "あかい") _persons.Add(New Person With {.Name = "いまい", .Age = 13}, "いまい") _persons.Add(New Person With {.Name = "うかい", .Age = 43}, "うかい") _persons.Add(New Person With {.Name = "えのき", .Age = 8}, "えのき") _persons.Add(New Person With {.Name = "おかの", .Age = 3}, "おかの") DataGridView1.SelectionMode = DataGridViewSelectionMode.FullRowSelect DataGridView1.DataSource = _persons Dim col As New DataGridViewColumn col = New DataGridViewTextBoxColumn col.DataPropertyName = "Name" col.Name = "NameField" DataGridView1.Columns.Add(col) col = New DataGridViewTextBoxColumn col.DataPropertyName = "Age" col.Name = "AgeField" DataGridView1.Columns.Add(col) End Sub Private Class Person Public Property Name As String Public Property Age As Integer End Class Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click Dim name As String = TextBox1.Text If name.Length = 0 Then Return If Not _persons.Contains(name) Then Return Dim person As Person = _persons.Item(name) For i As Integer = 0 To DataGridView1.Rows.Count - 1 Dim rowItem As Person = DataGridView1.Rows(i).DataBoundItem If rowItem.Equals(person) Then DataGridView1.Rows(i).Selected = True End If Next End Sub End Class

質問者が選んだベストアンサー

  • ベストアンサー
回答No.5

もう一ついい感じのものがありました。KeyedCollection クラスです。 Private Class Person を Public Class Person に変更して Public Class Form の外に出さなければなりませんが、 Public Class Form1 Private Class Persons Inherits System.Collections.ObjectModel.KeyedCollection(Of String, Person) Protected Overrides Function GetKeyForItem(ByVal item As Person) As String Return item.Name End Function Public Overloads Function IndexOf(ByVal name As String) As Integer Return MyBase.IndexOf(MyBase.Item(name)) End Function End Class Private _persons As Persons Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load _persons = New Persons _persons.Add(New Person With {.Name = "あかい", .Age = 10}) _persons.Add(New Person With {.Name = "いまい", .Age = 13}) _persons.Add(New Person With {.Name = "うかい", .Age = 43}) _persons.Add(New Person With {.Name = "えのき", .Age = 8}) _persons.Add(New Person With {.Name = "おかの", .Age = 3}) DataGridView1.SelectionMode = DataGridViewSelectionMode.FullRowSelect DataGridView1.DataSource = _persons Dim col As New DataGridViewColumn col = New DataGridViewTextBoxColumn col.DataPropertyName = "Name" col.Name = "NameField" DataGridView1.Columns.Add(col) col = New DataGridViewTextBoxColumn col.DataPropertyName = "Age" col.Name = "AgeField" DataGridView1.Columns.Add(col) End Sub Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click Dim name As String = TextBox1.Text Me.DataGridView1.Rows(_persons.IndexOf(name)).Selected = True End Sub End Class という感じでできます。

参考URL:
http://msdn.microsoft.com/ja-jp/library/ms132438(v=vs.80).aspx
msx68000
質問者

お礼

回答ありがとうございます。 indexを勝手に振ってくれるわけですね。これは良さげです。

その他の回答 (4)

回答No.4

Person に Index プロパティーを追加してやれば Private Sub AddPerson(ByRef p As Person, ByVal key As String) p.Index = _persons.Count _persons.Add(p, key) End Sub でコレクションに追加して Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click Dim p As Person = _persons.Item(Me.TextBox1.Text) Me.DataGridView1.Rows(p.Index).Selected = True End Sub とできます。 Person に Index プロパティーを追加するというのが設計思想に反するかもしれませんが…。

msx68000
質問者

お礼

回答ありがとうございます。 参考になります。 こういった機能が組み込まれていればいいんですけどね。

  • tissue001
  • ベストアンサー率21% (28/132)
回答No.3

すいません答えじゃないですが... 簡単なのは、CellFormattingイベントを使う。 ボタンを押した時に、それぞれセルのvalueにテキストボックスに入力されている値が 含まれているかInstr関数で判定。 含まれていれば、 .DefaultCellStyle.BackColorや .DefaultCellStyle.ForeColorを変更するとか... ただ、行番号(インデックス)のみを取得したいのであれば、 やはり、全行を確認するしかないのではないでしょうか...

msx68000
質問者

お礼

回答ありがとうございます。 データが多くなると全行確認したくないですが 仕方ないですね。

  • tissue001
  • ベストアンサー率21% (28/132)
回答No.2

No.1です。 ごめんなさい求めている答えじゃなかったですね^^;

msx68000
質問者

補足

回答ありがとうございます。 (もしあればですが・・・) Forを使わない方法をご教授いただきたく。

  • tissue001
  • ベストアンサー率21% (28/132)
回答No.1

datagridviewに主キーとなる列があるのなら... もしくは、テキストボックスに入力する値が、他にはない場合... '全行を比較 For Earc v As DatagridviewRow In Me.Datagridview.Rows   'テキストと列("名前")の値が同じならその行を選択状態にし、カレント行とする。   If Me.テキストボックス.Text = v.Cells("名前").Value Then     Me.datagridview.CurrentCell = v.Cells("名前")     v.Selected = True     Exit For   End If Next ただし、MultiSelectがTrueの場合は一旦datagridviewのカレント行を以下のように無くす必要があります。 Me.datagridview.CurrentCell = Nothing

関連するQ&A

  • DataGridViewのコンボボックスについて

    開発環境:Visual Basic 2005 DataGridViewのDataGridViewTextBoxColumnの1行目をコンボボックスにして、 そのコンボボックスのドロップダウン幅を100に設定しようとしていますが、うまくいきません。 DataGridViewをフォームに貼り付け、以下のプログラムを実行すると、幅が120くらいになってしまいます。 Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load DataGridView1.Columns.Clear() DataGridView1.AllowUserToAddRows = False Dim TextColumn As New DataGridViewTextBoxColumn TextColumn.Name = "Name" TextColumn.Width = 100 Dim ComboColumn As New DataGridViewComboBoxColumn ComboColumn.Name = "Type" Dim List() As String = {"Type A", "Type B", "Type O"} ComboColumn.DataSource = List ComboColumn.DropDownWidth = 100 DataGridView1.Columns.Add(TextColumn) DataGridView1.Columns.Add(ComboColumn) For i As Integer = 1 To 5 DataGridView1.Rows.Add() Next Dim ComboCell As New DataGridViewComboBoxCell Dim NameList() As String = {"Name A", "Name B", "Name C"} ComboCell.DataSource = NameList ComboCell.DropDownWidth = 100 DataGridView1.Rows(0).Cells(0) = ComboCell End Sub どこが問題なのかどなたかご教授いただけると助かります。どうぞよろしくお願い致します。

  • DataGridViewから値取得

    DataGridViewにボタンと項目2つが配置されています。 DataGridView1 DataGridView1.Columns("btn").HeaderText = "ボタン" DataGridView1.Columns("item1").HeaderText = "アイテム1" DataGridView1.Columns("item2").HeaderText = "アイテム2" ボタンを押すと、押した行のレコードを取得したいです。 ボタンのところを押下すると、 イベントハンドラで何行目か分かるサンプルをネットで見つけました。 惜しいですが、やりたいのと少し違いました。 'CellContentClickイベントハンドラ Private Sub DataGridView1_CellContentClick(ByVal sender As Object, ByVal e As DataGridViewCellEventArgs) Handles DataGridView1.CellContentClick Dim dgv As DataGridView = CType(sender, DataGridView) Dim test_item1 As String Dim test_item2 As String ' "btn"列ならば、ボタンがクリックされた If dgv.Columns(e.ColumnIndex).Name = "btn" Then MessageBox.Show((e.RowIndex.ToString() + "行のボタンがクリックされました。")) End If ' ここに押された行のitem1の値をセット ' test_item1 = (A) ' ここに押された行のitem2の値をセット ' test_item2 = (B) End Sub (A)、(B)に何を記述すれば値を取得できますか?

  • VB2005 DataGridViewにチェックボックスを追加する方法

    タイトル通りなのですが VB2005でDataGridViewにチェックボックスを追加したいです。 ############################################################### Public Class Form1 Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load Dim chColumn As New DataGridViewCheckboxColmun DataGridView1.ColumnCount = 5 DataGridView1.Columns(0).HeaderText = "1" DataGridView1.Columns(1).HeaderText = "2" DataGridView1.Columns(2).HeaderText = "3" DataGridView1.Columns.Insert(4, chColumn) End Sub End Class ############################################################## Dim chColumn As New DataGridViewCheckboxColmun ↑で'型'DataGridViewCheckboxColmunが定義されていません となってしまいます。 どうすればよいでしょうか。。。。 プログラム初めて1週間の初心者なのでお手柔らかに よろしくお願いします。

  • コンボボックスのマウスホイールを無効にしたい

    DataGridView内にコンボボックスを設定しております。 マウスのホイールボタンは、DataGridViewの縦スクロールに 使いたいのですが、DataGridView内のコンボボックスに カーソルがある場合、コンボボックス内のデータが変わってしまいます。 ユーザー側と打ち合わせた結果、コンボボックスにカーソルが ある時に、マウスのホイールボタンを無効に出来ないかと 言われております。 色々調べてみましたが、私では分からず、教えて下さい。 (サンプルソース) Dim column1 As New DataGridViewComboBoxColumn() With DataGridView1 .Columns.Clear() .Columns.Add("Col01", "列1") With column1 .Items.AddRange(New String() {"Item01", "Item02", "Item03"}) .Name = "Col02" .HeaderText = "列2" End With .Columns.Add(column1) For i As Integer = 0 To 100 .Rows.Add() Next i End With

  • VB2005 Datagridview の仮想モードでメモリリーク

    VB2005にてDatagridviewの仮想モードを実装しています。 DataGridviewを全件ループ処理する場合にメモリが増加します。完了してもそのままメモリが減りません。これを回避する方法がありますか?CellValueNeededはメモリを消費し続けるものなのでしょうか。 実際のプログラムでは件数が多い場合にメモリの消費が止まらずメモリ不足に陥ります。 以下は単純なコードにしたサンプルです。これでもデバッグモードで動かすと起動時20Mくらいのメモリ消費がループ処理時に100Mくらいにに増えます。 ※実際の処理でバインドしているデータ(datatable等)の方をループさせるという代替案がありますが、今回はdatagridviewから行った結果のメモリ不足についてご教授いただければと思います。 Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load With Me.DataGridView1 .Columns.Add("Column1", "列1") .Columns.Add("Column2", "列2") .Columns.Add("Column3", "列4") .Columns.Add("Column4", "列4") .Columns.Add("Column5", "列5") .Columns.Add("Column6", "列6") .Columns.Add("Column7", "列7") .VirtualMode = True .RowCount = 100000 End With End Sub Private Sub DataGridView1_CellValueNeeded(ByVal sender As Object, _ ByVal e As System.Windows.Forms.DataGridViewCellValueEventArgs) _ Handles DataGridView1.CellValueNeeded e.Value = e.RowIndex.ToString & "," & e.ColumnIndex.ToString End Sub Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click For i As Integer = 0 To DataGridView1.Rows.Count - 1 DataGridView1.Rows(i).Cells(1).Value = DataGridView1.Rows(i).Cells(2).Value Next MsgBox("終了") End Sub

  • VB2005 CSVファイルをテーブルへインポート

    こんばんは。 VB2005にてCSVファイルをテーブルへ、インポートする処理を作成しています。ネットで調べたコードを試しています。デバックは通るのですが、処理結果がテーブルへ出力されません。 (TESTdataset内にTable1を作成しています。) 何か解決案がありましたらご教示をお願いいたします。 また、 ※1の'DataGridView1の文なのですが、コメントを外すと 宣言がされていない旨のメッセージが出てきてしまいます。 もし此方も解決案が御座いましたらご教示をお願いいたします。 -------------------------------------------------------------- 以下コードです -------------------------------------------------------------- Imports System.Data Imports System.Data.OleDb Public Class Form1 Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click Const csvPath As String = "c:\DB\" Const csvFile As String = "TEST.csv" Dim sConnectionString As String = "Provider=Microsoft.Jet.OLEDB.4.0;" _ & "Data Source=" & csvPath _ & ";" & "Extended Properties='text;FMT=Delimited'" Dim objConn As New OleDbConnection(sConnectionString) objConn.Open() Dim objCmdSelect As New OleDbCommand("SELECT * FROM " & csvFile, objConn) Dim objAdapter1 As New OleDbDataAdapter() objAdapter1.SelectCommand = objCmdSelect Dim objDataset1 As New DataSet() Dim objTable As DataTable Dim Col As DataColumn objDataset1 = New DataSet("TEST") objTable = New DataTable("Table1") Col = New DataColumn("No") Col.DataType = Type.GetType("System.Int16") objTable.Columns.Add(Col) Col = New DataColumn("Name") Col.DataType = Type.GetType("System.String") objTable.Columns.Add(Col) Col = New DataColumn("出身") Col.DataType = Type.GetType("System.String") objTable.Columns.Add(Col) objDataset1.Tables.Add(objTable) objAdapter1.Fill(objDataset1.Tables(0)) ※1'DataGridView1.DataSource = objDataset1.Tables(0).DefaultView objConn.Close() End Sub End Class --------------------------------------------------------- ※お礼が遅れる場合がありますが、必ずしますので、その時は少々お待ちください。

  • DataGridViewからDBの更新

    DataGridViewの内容を変更してボタンを押したらDBを更新する ということをしたいのですが とあるサンプルコードには Public Class Form1 Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load Dim dAdp As OleDb.OleDbDataAdapter Dim dSet As DataSet = New DataSet("t_商品") Dim cn As OleDb.OleDbConnection = New OleDb.OleDbConnection( _ "Provider=Microsoft.ACE.OLEDB.12.0;" _ & "Data Source=C:\VB2008\SampleDB.accdb;") 'データセットに取得してデータを表示する dAdp = New OleDb.OleDbDataAdapter("SELECT * FROM 商品", cn) dAdp.Fill(dSet, "t_商品") Me.DataGridView1.DataSource = dSet.Tables("t_商品") End Sub Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click Dim dTbl As DataTable Dim dRow As DataRow Dim i As Integer 'DataGridからデータソースを取得する dTbl = Me.DataGridView1.DataSource '編集された行をコミットする For Each dRow In dTbl.Rows If dRow.RowState <> DataRowState.Unchanged Then dRow.AcceptChanges() End If Next End Sub End Class となっているのですがこのまま使用しても更新されません 全くの他力本願な質問ですがよろしくおねがいします イミデイトにはグリッド内容をnchange」になっています?

  • DataGridViewで1行全てを選択状態にするには

    VB.NETのDataGridViewについての質問です。 DataGridViewでセルを選択した時に、そのセルの行を全て選択したいのですが、その方法がわからず困っています。 単純な方法を試してみたのですが Private Sub DataGridView_CellClick(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellEventArgs) Handles DataGridView.CellClick DataGridView.CurrentCell = DataGridView.Rows(e.RowIndex).Cells(-1) End Sub この方法ですと、Cells(-1)の所で境界外となって上手くいかないようです。 何か良い方法がありましたら、ご教授願います

  • DataGridViewで行選択して、対応するDataTableの行を得るには?

    いつもお世話になっております。VB2005環境です。 DataGridViewの行を選択したときに、そのソースであるDataTableの同じ行のデータを参照するには、どうしたらいいでしょうか。DataTableのデータをまるごとDataGridViewに表示しているわけではないので、必要に応じて直接DataTableから取得したいです。とても初歩的な質問だと思うのですが・・・。 DataGridView1.DataSource = DataTable  ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ Dim r As Integer = DataGridView1.CurrentCell.RowIndex Dim str As String str = DataTable.Rows(r)("項目名") MsgBox(str)  ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ このように行インデックスを取得してやってみたのですが、これだとDataGridView上でソートすると行番号が変わってしまい、DataTable側の対応する行のデータが得られません。 もう少し詳しく現状を書くと、まずCSVファイルからデータをロードして、DataTableに渡しています。そして、その内容をDataGridViewに表示しているのですが、表示する内容はデータテーブル通りの構造ではなく、表示する必要がある項目だけを選んで、1つずつカラムを追加してバインドいます。  ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ’自動で列を追加しないようにする DataGridView1.AutoGenerateColumns = False ’データソースを指定する DataGridView1.DataSource = DataTable ’1つ1つ順番などを変えながら列を追加していく Dim column1 As New DataGridViewTextBoxColumn() DataGridView1.Columns.Add(column1) column1.Name = "Date" column1.HeaderText = "日付" column1.DataPropertyName = "F4" Dim column2 As New DataGridViewTextBoxColumn() DataGridView1.Columns.Add(column1) column1.Name = "Locatoin" column1.HeaderText = "場所" column2.DataPropertyName = "F1" ・ ・ ・  ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ こんな感じでなので、表示されていない列のデータについては、必要に応じて直接DataTableから取得したいと思います。アドバイスよろしくお願いいたします<(_ _)>

  • datagridviewからエクセルへ出力する際のエラーについて

    datagridviewからエクセルへ出力する際のエラーについて いつもお世話になります。 datagridviewに表示されたデータをエクセルへ出力したく以下のコードを書きました。 Imports System.IO Imports System.Data Imports System.Data.SqlClient Imports Microsoft.Office.Interop Public Class form1 Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click Dim cn As OleDb.OleDbConnection _ = New OleDb.OleDbConnection( _ "Provider=Microsoft.Jet.OLEDB.4.0;" _ & "Data Source=C:\VB2008\コピー ~ 社会保険計算.mdb;") End Sub Private Sub Button7_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button7.Click Dim xlapp As Excel.Application Dim xlBook As Excel.Workbook Dim xlSheet As Excel.Worksheet 'Excelを開く xlapp = CreateObject("Excel.Application") xlapp.Visible = True xlapp.Workbooks.Add() xlBook = xlapp.ActiveWorkbook xlSheet = xlBook.ActiveSheet 'シートの編集 ☆ xlSheet.Cells(1, 1).Value = DataGridView1(1, 1).Value.ToString  xlSheet.Cells(2, 1).Value = DataGridView1(2, 1).Value.ToString xlBook.Close() xlapp.Quit() xlBook = Nothing xlapp = Nothing End Sub ☆マークで止まってしまいます。 argumentoutofrangeexceptionがハンドルされませんでした。 インデックスが範囲を超えています。負でない値でコレクションのサイズよりも小さくなければなりません。 パラメータ名:index と表示されます。 環境は、VB.NET2008     XP(SP3)     Excel2007 になります。 上記のエラーで止まり、エクセルも立ち上がりぱなしです。 お忙しい所お手数をお掛けしますが、ご教授下さい。

専門家に質問してみよう