VB.NET DataGrid カレント行の値を全て取得するには?

解決


入門者さん  2003-03-11 00:01:29  No: 106265

こんにちわ。
VB.NETのDataGridを勉強しているものです。
先日、こちらの掲示板でDataGridのカレントセルの場所を特定することができました。

今度はDataGridに表示されたデータで、クリックしてカレントにした行の値全部を取得したいと思っているのですが、どうすればいいのかわかりません。

DataGridにはボタン形式で10個の項目があり、うち8個は非表示にしています。
住所録みたいな感じのものを作っているのですが、DataGridに実際に表示されるのは名前と番号だけです。
で、その名前と番号だけの行をクリックしたらダイアログメッセージに「住所」や「電話番号」などの詳細な部分も表示できるようにしたいのですが・・・。

DataGridのMoucuDownイベントにて作成しているのですが、いろいろ考えてるうちに混乱してしまい、何からすればいいのかわかりません;;
どなたかご教授いただけませんか?


入門者さん  2003-03-11 03:51:17  No: 106266

こんにちわ。
自分で調べた結果、以下の方法でカレント行をクリックした場合に取得した値をテキストボックスに放り込む処理ができました。
=====================================================================
    Private Sub DataGrid1_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles DataGrid1.MouseDown
        Dim myGrid As DataGrid = CType(sender, DataGrid)
        Dim hti As System.Windows.Forms.DataGrid.HitTestInfo = myGrid.HitTest(e.X, e.Y)
        Dim TID As String = "-1"

        Select Case hti.Type
            Case System.Windows.Forms.DataGrid.HitTestType.Cell

                TID = myGrid.Item(hti.Row, 0)
                myGrid.Select(hti.Row)

            Case System.Windows.Forms.DataGrid.HitTestType.RowHeader
                TID = myGrid.Item(hti.Row, 0)
        End Select

        If Not TID = "-1" Then
            DataView1.RowFilter = "Num='" & TID & "'"
            TextBox1.Text = DataView1(0)("Num")
        End If
    End Sub
=====================================================================
以上のコードでレコードの一番左の列の値は引き出せるのですが、それ以外の列を引き出そうとするとエラーが返ってきます。
エラー内容は「インデックス 0 は負の値です。また、行カウントの合計よりも小さい値です。」というものです。
現在上記のコードでは「Num」という一番左の列を取得しています。
このコードでは問題ありませんでした。
「Num」の右隣に並ぶ列「Name」取得するにはどこを修正・追加すればいいのでしょうか?


Y2  2003-03-11 06:28:22  No: 106267

DataRowオブジェクトを使うっていう方法はだめでしょうか?
DataRowクラスはDataTableの各行を管理するためのクラスなんですけど、指定した行のDataRowオブジェクトを獲得すれば、その行の値全部を取得できると思います。

DataRowの獲得方法は↓のような感じで
Dim DataRow1 As DataRow = DataTable.Rows("行のインデックス")

ちなみに、DataRowとかDataGridとかの関連を表すと、

DataGrid ← DataSet ← DataTable(複数可) ← DataRow(各行)

という感じです。


入門者さん  2003-03-12 18:59:30  No: 106268

毎度の返信ありがとうございます。
DataRowを使う場合、行の値を全て取得できるとのことですが、異なるテキストボックスにそれぞれの値を表示するには各々の値を取得したほうがわかりやすいかな?と思って最初の方法でやってみました。

Y2さんの方法でやるには
DataRowで行全て取得>そこから各々に必要なものを摘出。
ということになるのでしょうか?


Y2  2003-03-13 04:46:25  No: 106269

その通りなんですけど、
DataTableの各々の値はDataRowとして行単位で保存されているので、各々の値を獲得するにはDataRow(行)を獲得しなければならないということでした。

DataViewを知らないのでヘルプで少し読んだんですけど、入門者さんの書いたプログラムも基本的に同じことをやっていると思います。
>TextBox1.Text = DataView1(0)("Num")
↑0行目のDataRowView(行)を獲得してから、"Num"列の値を獲得

DataViewの概要は
「並べ替え、フィルタ処理、検索、編集、および移動を実行できる、データ連結可能な、カスタマイズされた DataTable のビューを表します。」
と書いてある通り、DataViewはDataTableを便利にするためのものですが、

入門者さんがやりたい動作は、セルの座標が分かっていてその値を獲得したいということなので、DataViewを使わなくてもできる動作だと思います。

入門者さんのプログラムの動作は、HitTestで調べた行番号を元にフィルタをかけて、DataViewに表示される行(DataRowView)を一つ?に絞り、その絞った行達の中の0番目の行の"Num"列の値を獲得してるようですけど、
おそらく、エラー内容を考えると、その絞られた行達が一つも無かったのではないでしょうか?
絞られた行が一つでも存在していれば、0行目として利用できると思います。
なので、RowFilterの設定が間違えていると思われます。


入門者さん  2003-03-13 05:06:57  No: 106270

なるほど・・・。
貴重な意見を頂き大変ありがとうございます。
もう一度よく確かめてみます。


Y2  2003-03-13 05:41:45  No: 106271

すみません、間違ったことを書いてしまいました。"入門さんのプログラムの動作は"から後を無しにしてください。

RowFilterの使い方は
.RowFilter="AAA = 'BBB'"
とした場合、AAA列の値が'BBB'にマッチする行(DataRowView)を検索するものだったみたいですね。間違って認識していました。

ということで、RowFilterは行を検索するものなので、入門さんが求めるものではないかもしれません。
やっぱり、行単位以外で値を獲得する方法は、無いような気がします。(Tableの保存方法に反していて効率が悪いですし(´Д`)/~)


入門者さん  2003-03-14 01:42:33  No: 106272

Y2さん、どうもありがとうございます。
非常に申し訳ないんですが、すっごくオバカな間違いを犯していますた。
実は、RowFilterで抽出しなくても、その前のSelectCaseの部分でクリックされたデータ行は取得しているので、回りくどくする必要はなかったみたいです。

現状ではRowFilterにより抽出したレコードを別のものに格納し、そこのインデックスが0の値をひっぱってきているのですが、インデックス値に取得した行の情報を入れてやることで解決しました。
つまりRowFilterの部分は使用しません。

以下コード
=====================================================================
    Private Sub DataGrid1_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles DataGrid1.MouseDown
        Dim myGrid As DataGrid = CType(sender, DataGrid)
        Dim hti As System.Windows.Forms.DataGrid.HitTestInfo = myGrid.HitTest(e.X, e.Y)
        Dim TID As String = "-1"

        Select Case hti.Type
            Case System.Windows.Forms.DataGrid.HitTestType.Cell

                TID = myGrid.Item(hti.Row, 0)
                myGrid.Select(hti.Row)

            Case System.Windows.Forms.DataGrid.HitTestType.RowHeader
                TID = myGrid.Item(hti.Row, 0)
        End Select

        If Not TID = "-1" Then
            TextBox1.Text = DataView1(hti.Row)("Num")
        End If
    End Sub
=====================================================================

説明下手ですいませんでした;;
ちなみに、RowFilter使う場合なんですが、どうやらこれも自分でものすごい失敗をしていて・・・

            DataView1.RowFilter = "Num='" & TID & "'"
            TextBox1.Text = DataView1(0)("Num")

の部分でNumというのをほかのデータにすればそれが引き出せる。とまではよかったのですが、わけもわからずFilter部の"Num"まで変えてしまったがためにデータを抽出できずにエラーとなっていました。

お恥ずかしい限りです^^;
Y2さんのご教授くださった方法も試してみようと思います。
ありがとうございました。


Y2  2003-03-14 07:02:49  No: 106273

恥ずかしいことではないと思いますが、悩んだ分だけスキルアップして良かったですね。
ところで、解決のチェックが入ってないみたいですけど、解決の際はチェックを入れたほうが良いですよ。


入門者さん  2003-03-14 18:15:50  No: 106274

あ、すいません。
うっかり忘れていました^^;
Y2さん、ありがとうございました^^


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加