DataGridViewについて勉強しています
投稿者 るきお  (社会人)
投稿日時
2020/9/7 19:42:58
たとえば、次のような感じになります。
DataGridViewは複数の行(DataGridViewRow)から構成されます。それぞれの行は複数のセル(DataGridViewCell)から構成されます。
このような2重構造になっているので、ループで値を検索と二重ループが必要です。
Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click
Dim strText As String = TextBox1.Text
For Each row As DataGridViewRow In DataGridView1.Rows
For Each c As DataGridViewCell In row.Cells
Dim Data As String = c.Value?.ToString
If Data = strText Then
'Visual Basic 2013以前の場合
'MsgBox("列" & c.ColumnIndex + 1 & "と" & "行" & c.RowIndex + 1 & "に存在しています値は" & Data & "です")
'Visual Basic 2015以降ならこう書くほうが楽
MsgBox($"列{c.ColumnIndex + 1}と行{c.RowIndex + 1}に存在しています値は{Data}です")
End If
Next
Next
End Sub
DataGridViewは複数の行(DataGridViewRow)から構成されます。それぞれの行は複数のセル(DataGridViewCell)から構成されます。
このような2重構造になっているので、ループで値を検索と二重ループが必要です。
投稿者 (削除されました)  ()
投稿日時
2020/9/8 12:13:07
(削除されました)
投稿者 のの  (社会人)
投稿日時
2020/9/8 12:14:36
るきお様
返信ありがとうございます
2重ループが必要だったのですね!
初心者なのでコードも書いてくださり大変助かります。mom
参考にしてフォームつくります。
あと、もう一つわからないことがあって、、、教えてほしいのですが、書籍をみてデータセットによるデーターベースプログラムの作成をやっていまして、ある値だけ抜き出して欄に残すことをやりたいのですが
そういう場合はコードに接続文字を新たにセットしてSQLで構文をかいてTableDataGridViewにセットするのでしょうか?
よろしくおねがいします。
返信ありがとうございます
2重ループが必要だったのですね!
初心者なのでコードも書いてくださり大変助かります。mom
参考にしてフォームつくります。
あと、もう一つわからないことがあって、、、教えてほしいのですが、書籍をみてデータセットによるデーターベースプログラムの作成をやっていまして、ある値だけ抜き出して欄に残すことをやりたいのですが
そういう場合はコードに接続文字を新たにセットしてSQLで構文をかいてTableDataGridViewにセットするのでしょうか?
よろしくおねがいします。
投稿者 魔界の仮面弁士  (社会人)
投稿日時
2020/9/8 13:18:27
> 新たにセットしてSQLで構文をかいてTableDataGridViewにセットするのでしょうか?
そういう方法を取ることもできますが、既に DataTable にデータを抽出済みであれば、
そこから絞り込むという手も使えます。
既に DataSet/DataTable に取得済みの内容のうち、一部の行だけを表示させたい場合には、
BindingSource の Filter プロパティ あるいは DataView の RowFilter プロパティを使います。
たとえば、数学または英語が赤点だった生徒を列挙するために
BindingSource1.Filter = "数学<=40 OR 英語<=40"
のように記述することができます。
ソートやフィルター、イベント処理などの制御が必要な場合には、
DataGridView1.DataSource に指定するのは、DataSet や DataTable ではなく、
BindingSource もしくは DataView の方が扱いやすいと思います。
BindingSource はデザイン時に割り当てておくこともできます。
※BindingSource1 の DataSource に DataTable を割り当てておき、
※DataGridView1 の DataSource に、BindingSource1を割り当てるようにする。
Visual Studio のサーバーエクスプローラーからドラッグ & ドロップで
フォームにテーブルを貼った場合も、DataGridView と共に BindingSource が貼られますね。
とはいえ、現在 BindingSource を現在使っておらず、
DataSource に DataSet や DataTable を直接割り当てていたとしても、
必ずしも BindingSource を使わなければいけないわけではありません
ソート処理やフィルター処理のためには、DataTable の DefaultView プロパティが返す
DataView オブジェクトの Sort / RowFilter プロパティを使って同じことができるためです。
なお、DataGridView の DataSource を用いている場合には、
> Data = Me.DataGridView1(c.ColumnIndex, c.RowIndex).Value
のような、行番号・列番号に依存したコードを書くことはお奨めしません。
列ヘッダーをクリックするなどしてソート処理を行うと、DataTable 上の行番号と
DataGridView 上の行番号は一致しなくなるためです。
このため、バインド元の DataRow を通じて読み書きする方が安全ですし、
パフォーマンスも向上します。
また、DataGridView 上で編集中の値は、他の行にカーソル移動するなどして
行データを確定するまでは、DataRow に反映されない事にも注意が必要です。
そういう方法を取ることもできますが、既に DataTable にデータを抽出済みであれば、
そこから絞り込むという手も使えます。
既に DataSet/DataTable に取得済みの内容のうち、一部の行だけを表示させたい場合には、
BindingSource の Filter プロパティ あるいは DataView の RowFilter プロパティを使います。
たとえば、数学または英語が赤点だった生徒を列挙するために
BindingSource1.Filter = "数学<=40 OR 英語<=40"
のように記述することができます。
ソートやフィルター、イベント処理などの制御が必要な場合には、
DataGridView1.DataSource に指定するのは、DataSet や DataTable ではなく、
BindingSource もしくは DataView の方が扱いやすいと思います。
BindingSource はデザイン時に割り当てておくこともできます。
※BindingSource1 の DataSource に DataTable を割り当てておき、
※DataGridView1 の DataSource に、BindingSource1を割り当てるようにする。
Visual Studio のサーバーエクスプローラーからドラッグ & ドロップで
フォームにテーブルを貼った場合も、DataGridView と共に BindingSource が貼られますね。
とはいえ、現在 BindingSource を現在使っておらず、
DataSource に DataSet や DataTable を直接割り当てていたとしても、
必ずしも BindingSource を使わなければいけないわけではありません
ソート処理やフィルター処理のためには、DataTable の DefaultView プロパティが返す
DataView オブジェクトの Sort / RowFilter プロパティを使って同じことができるためです。
なお、DataGridView の DataSource を用いている場合には、
> Data = Me.DataGridView1(c.ColumnIndex, c.RowIndex).Value
のような、行番号・列番号に依存したコードを書くことはお奨めしません。
列ヘッダーをクリックするなどしてソート処理を行うと、DataTable 上の行番号と
DataGridView 上の行番号は一致しなくなるためです。
このため、バインド元の DataRow を通じて読み書きする方が安全ですし、
パフォーマンスも向上します。
For Each gridRow As DataGridViewRow In DataGridView1.Rows
Dim rowView = DirectCast(row.DataBoundItem, DataViewRow)
Dim row As DataRow = rowView.Row '型付DataSetの場合は、型付DataRowで受け取れる
row("氏名") = "のの"
また、DataGridView 上で編集中の値は、他の行にカーソル移動するなどして
行データを確定するまでは、DataRow に反映されない事にも注意が必要です。
投稿者 のの  (社会人)
投稿日時
2020/9/8 15:36:17
魔界の仮面弁士様
ご返信ありがとうございます。
>そういう方法を取ることもできますが、既に DataTable にデータを抽出済みであれば、
そこから絞り込むという手も使えます。
すでにデーターはデーターソースからドラック&ドロップで
TableDataGridViewにはTableBindingSourceが割り当てられています。
>既に DataSet/DataTable に取得済みの内容のうち、一部の行だけを表示させたい場合には、
BindingSource の Filter プロパティ あるいは DataView の RowFilter プロパティを使います。
BindingSourceはTableBindingSourceと一緒なのでしょうか?
なんかアイコンが一緒なので、、なまえが違うだけですか?
自分の割り当てはTableDataGridViewにTableBindingSourceという割り当てがされていて
品番という列に該当する値(テキストボックス入力)があった場合
Private Sub Button3_Click_1(sender As Object, e As EventArgs) Handles Button3.Click
Dim strText As String = TextBox1.Text
TableBindingSource.Filter = strText
みたいな感じでいいのでしょうか?(ハンドルされてない例外が出てきました)
>Visual Studio のサーバーエクスプローラーからドラッグ & ドロップで
フォームにテーブルを貼った場合も、DataGridView と共に BindingSource が貼られますね。
とはいえ、現在 BindingSource を現在使っておらず、
DataSource に DataSet や DataTable を直接割り当てていたとしても、
必ずしも BindingSource を使わなければいけないわけではありません
ソート処理やフィルター処理のためには、DataTable の DefaultView プロパティが返す
DataView オブジェクトの Sort / RowFilter プロパティを使って同じことができるためです。
いろんなやり方があるのですね!
おもったより奥がふかいです。。
なお、DataGridView の DataSource を用いている場合には、
> Data = Me.DataGridView1(c.ColumnIndex, c.RowIndex).Value
のような、行番号・列番号に依存したコードを書くことはお奨めしません。
なるほど、、
はじめてDataGridViewをつかうので気を付けたいとおもいます
コード参考にさせていただきます。
よろしくおねがいします。
ご返信ありがとうございます。
>そういう方法を取ることもできますが、既に DataTable にデータを抽出済みであれば、
そこから絞り込むという手も使えます。
すでにデーターはデーターソースからドラック&ドロップで
TableDataGridViewにはTableBindingSourceが割り当てられています。
>既に DataSet/DataTable に取得済みの内容のうち、一部の行だけを表示させたい場合には、
BindingSource の Filter プロパティ あるいは DataView の RowFilter プロパティを使います。
BindingSourceはTableBindingSourceと一緒なのでしょうか?
なんかアイコンが一緒なので、、なまえが違うだけですか?
自分の割り当てはTableDataGridViewにTableBindingSourceという割り当てがされていて
品番という列に該当する値(テキストボックス入力)があった場合
Private Sub Button3_Click_1(sender As Object, e As EventArgs) Handles Button3.Click
Dim strText As String = TextBox1.Text
TableBindingSource.Filter = strText
みたいな感じでいいのでしょうか?(ハンドルされてない例外が出てきました)
>Visual Studio のサーバーエクスプローラーからドラッグ & ドロップで
フォームにテーブルを貼った場合も、DataGridView と共に BindingSource が貼られますね。
とはいえ、現在 BindingSource を現在使っておらず、
DataSource に DataSet や DataTable を直接割り当てていたとしても、
必ずしも BindingSource を使わなければいけないわけではありません
ソート処理やフィルター処理のためには、DataTable の DefaultView プロパティが返す
DataView オブジェクトの Sort / RowFilter プロパティを使って同じことができるためです。
いろんなやり方があるのですね!
おもったより奥がふかいです。。
なお、DataGridView の DataSource を用いている場合には、
> Data = Me.DataGridView1(c.ColumnIndex, c.RowIndex).Value
のような、行番号・列番号に依存したコードを書くことはお奨めしません。
なるほど、、
はじめてDataGridViewをつかうので気を付けたいとおもいます
コード参考にさせていただきます。
よろしくおねがいします。
投稿者 魔界の仮面弁士  (社会人)
投稿日時
2020/9/8 16:59:33
掲示板の IMAGE タグで https プロトコルをサポートして頂けないでしょうか。 > るきおさん
> BindingSourceはTableBindingSourceと一緒なのでしょうか?
もしかして、【型名】と【フィールド変数名】を混同していませんか?
恐らくは System.Windows.Forms.BindingSource クラスのインスタンスの Name プロパティに
"TableBindingSource" という名前が付けられている状態だと思います。
System.Windows.Forms.TextBox クラスのインスタンスの Name プロパティに
"TextBox1" や "TextBox2" といった名前が付けられるのと同じように。
> TableBindingSource.Filter = strText
> みたいな感じでいいのでしょうか?(ハンドルされてない例外が出てきました)
いいえ。SQL でいうところの WHERE 句に書く問い合わせ式が必要です。
先ほどは "数学<=40 OR 英語<=40" という文字列を例に挙げましたが、この場合、
DataTable 上に "数学" 列と "英語" 列があり、かつそれらが数値型であることを想定しています。
Filter プロパティに設定できる文字列は、DataColumn の Expression プロパティに
指定できる内容に準じます。たとえば LIKE 検索なども可能です。
具体的にな構文については、下記を参考にしてみてください。
(翻訳ミスで構文が崩れている箇所があるので、英語版も併記しておきます)
https://docs.microsoft.com/ja-jp/dotnet/api/system.data.datacolumn.expression?WT.mc_id=DT-MVP-8907&view=netframework-4.8
https://docs.microsoft.com/en-us/dotnet/api/system.data.datacolumn.expression?WT.mc_id=DT-MVP-8907&view=netframework-4.8
あるいは、DataTable の Select メソッドを使って、DataRow の配列を得る方法もあります。
使い方はほぼ同じですが、抽出結果の DataRow 配列を DataGridView 等に表示したいなら、
そのための再割り当て等は、自分で行う必要があります。
このほか、LINQ to DataSet で問い合わせるといった方法があります。
https://docs.microsoft.com/ja-jp/dotnet/framework/data/adonet/creating-a-datatable-from-a-query-linq-to-dataset?WT.mc_id=DT-MVP-8907
> BindingSourceはTableBindingSourceと一緒なのでしょうか?
もしかして、【型名】と【フィールド変数名】を混同していませんか?
恐らくは System.Windows.Forms.BindingSource クラスのインスタンスの Name プロパティに
"TableBindingSource" という名前が付けられている状態だと思います。
System.Windows.Forms.TextBox クラスのインスタンスの Name プロパティに
"TextBox1" や "TextBox2" といった名前が付けられるのと同じように。
> TableBindingSource.Filter = strText
> みたいな感じでいいのでしょうか?(ハンドルされてない例外が出てきました)
いいえ。SQL でいうところの WHERE 句に書く問い合わせ式が必要です。
先ほどは "数学<=40 OR 英語<=40" という文字列を例に挙げましたが、この場合、
DataTable 上に "数学" 列と "英語" 列があり、かつそれらが数値型であることを想定しています。
Filter プロパティに設定できる文字列は、DataColumn の Expression プロパティに
指定できる内容に準じます。たとえば LIKE 検索なども可能です。
具体的にな構文については、下記を参考にしてみてください。
(翻訳ミスで構文が崩れている箇所があるので、英語版も併記しておきます)
https://docs.microsoft.com/ja-jp/dotnet/api/system.data.datacolumn.expression?WT.mc_id=DT-MVP-8907&view=netframework-4.8
https://docs.microsoft.com/en-us/dotnet/api/system.data.datacolumn.expression?WT.mc_id=DT-MVP-8907&view=netframework-4.8
あるいは、DataTable の Select メソッドを使って、DataRow の配列を得る方法もあります。
使い方はほぼ同じですが、抽出結果の DataRow 配列を DataGridView 等に表示したいなら、
そのための再割り当て等は、自分で行う必要があります。
このほか、LINQ to DataSet で問い合わせるといった方法があります。
https://docs.microsoft.com/ja-jp/dotnet/framework/data/adonet/creating-a-datatable-from-a-query-linq-to-dataset?WT.mc_id=DT-MVP-8907
投稿者 のの  (社会人)
投稿日時
2020/9/9 11:59:22
魔界の仮面弁士様
ありがとうございます。
恐らくは System.Windows.Forms.BindingSource クラスのインスタンスの Name プロパティに
"TableBindingSource" という名前が付けられている状態だと思います。
System.Windows.Forms.TextBox クラスのインスタンスの Name プロパティに
"TextBox1" や "TextBox2" といった名前が付けられるのと同じように。
>点と点がつながりました。
自分勘違いしていました。
いいえ。SQL でいうところの WHERE 句に書く問い合わせ式が必要です。
>リンクみました。ありがとうございます。
テキストボックスの値を品番という列で検索してフィルターしたいのですが、(全部str型です)
TableBindingSource.Filter = "品番 = '*name' '*"
の"name" を strText (変数)に置き換えたいのですがどうやるかわかりません。。おしえてください。
宜しくおねがいします。
ありがとうございます。
恐らくは System.Windows.Forms.BindingSource クラスのインスタンスの Name プロパティに
"TableBindingSource" という名前が付けられている状態だと思います。
System.Windows.Forms.TextBox クラスのインスタンスの Name プロパティに
"TextBox1" や "TextBox2" といった名前が付けられるのと同じように。
>点と点がつながりました。
自分勘違いしていました。
いいえ。SQL でいうところの WHERE 句に書く問い合わせ式が必要です。
>リンクみました。ありがとうございます。
テキストボックスの値を品番という列で検索してフィルターしたいのですが、(全部str型です)
TableBindingSource.Filter = "品番 = '*name' '*"
の"name" を strText (変数)に置き換えたいのですがどうやるかわかりません。。おしえてください。
宜しくおねがいします。
投稿者 魔界の仮面弁士  (社会人)
投稿日時
2020/9/9 13:22:18
御自身の発言の直前に全角「>」を挿入するスタイルは、ちょっと読みにくいです。
相手の発言を引用する場合は、行頭に半角の「>」を挿入してください。
この掲示板では、引用文が青文字で表示されるようになっています。
> TableBindingSource.Filter = "品番 = '*name' '*"
> の"name" を strText (変数)に置き換えたいのですがどうやるかわかりません。。
ですね。VB2015 以降をお使いであれば、このようにも書けます。
実際にはインジェクション対策も必要なことに注意しましょう。
(たとえば、strText 内に「'」の文字が含まれていた場合の対策を行う、ということです)
ところで……品番ということは恐らく、主キー項目もしくは外部キー項目だと思います。
もし、外部キーではなく主キーであるなら、"品番" 列を
その DataTable の PrimaryKey プロパティに割り当てておくと良いでしょう。
(型付 DataSet の場合は、品番列の上で右クリックして、「主キーの設定」を行う)
PrimaryKey が "品番" 列だけを指し示している場合、品番検索の結果は
複数行にはならず、特定の行を指し示すことになりますが、この場合は
下記のような処理も行えます。(この方法では、インジェクション対策が不要です)
型付DataSet を使っている場合には、このように書けます。
相手の発言を引用する場合は、行頭に半角の「>」を挿入してください。
この掲示板では、引用文が青文字で表示されるようになっています。
> TableBindingSource.Filter = "品番 = '*name' '*"
> の"name" を strText (変数)に置き換えたいのですがどうやるかわかりません。。
TableBindingSource.Filter = "品番 = '" & strText & "'"
ですね。VB2015 以降をお使いであれば、このようにも書けます。
TableBindingSource.Filter = $"品番 = '{strText}'"
実際にはインジェクション対策も必要なことに注意しましょう。
(たとえば、strText 内に「'」の文字が含まれていた場合の対策を行う、ということです)
ところで……品番ということは恐らく、主キー項目もしくは外部キー項目だと思います。
もし、外部キーではなく主キーであるなら、"品番" 列を
その DataTable の PrimaryKey プロパティに割り当てておくと良いでしょう。
(型付 DataSet の場合は、品番列の上で右クリックして、「主キーの設定」を行う)
PrimaryKey が "品番" 列だけを指し示している場合、品番検索の結果は
複数行にはならず、特定の行を指し示すことになりますが、この場合は
下記のような処理も行えます。(この方法では、インジェクション対策が不要です)
Dim row As DataRow = データテーブル.Rows.Find(strText)
型付DataSet を使っている場合には、このように書けます。
Dim row As データセット名.表名Row = データテーブル.FindBy品番(strText)
投稿者 のの  (社会人)
投稿日時
2020/9/9 15:55:51
>御自身の発言の直前に全角「>」を挿入するスタイルは、ちょっと読みにくいです。
>相手の発言を引用する場合は、行頭に半角の「>」を挿入してください。
>この掲示板では、引用文が青文字で表示されるようになっています。
なんで青くなっているのかとおもったら 「>」 だったのですね
教えて下りありがとうございます つぎから気をつけます
コードをいろいろいじっていたら気づきがたくさんありました。
どうすればいいかこまっていたのでとっても助かりました。
>ところで……品番ということは恐らく、主キー項目もしくは外部キー項目だと思います。
鍵マークのことですよね
初心者なものでそこまで気が付けなくて、、言ってもらえて助かりました。PrimaryKey
に設定しました。
>Dim row As データセット名.表名Row = データテーブル.FindBy品番(strText)
ちなみになのですがデーターセット名や表名 データーテーブル名はどこを見れば確認できますでしょうか?
自分でデータセット作っておきながら右も左もわからなくてすいません。。
宜しくお願いします。
>相手の発言を引用する場合は、行頭に半角の「>」を挿入してください。
>この掲示板では、引用文が青文字で表示されるようになっています。
なんで青くなっているのかとおもったら 「>」 だったのですね
教えて下りありがとうございます つぎから気をつけます
コードをいろいろいじっていたら気づきがたくさんありました。
どうすればいいかこまっていたのでとっても助かりました。
>ところで……品番ということは恐らく、主キー項目もしくは外部キー項目だと思います。
鍵マークのことですよね
初心者なものでそこまで気が付けなくて、、言ってもらえて助かりました。PrimaryKey
に設定しました。
>Dim row As データセット名.表名Row = データテーブル.FindBy品番(strText)
ちなみになのですがデーターセット名や表名 データーテーブル名はどこを見れば確認できますでしょうか?
自分でデータセット作っておきながら右も左もわからなくてすいません。。
宜しくお願いします。
DataGridViewについて勉強しています。
テキストボックスに値を入れてボタンを押したら、テーブル内にその値があるか
確認したい場合、どうしたらいいのでしょうか?
その値があったらメッセージボックスで列と行と値がみたいです。
Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click
Dim Data As String
Dim strText As String = TextBox1.Text
For Each c As DataGridViewCell In DataGridView1.SelectedCells★
Data = Me.DataGridView1(c.ColumnIndex, c.RowIndex).Value
MsgBox("列" & c.ColumnIndex + 1 & "と" & "行" & c.RowIndex + 1 & "に存在しています値は" & Data & "です")
Next c
End Sub
End Class