DOBON.NETプログラミング道掲示板

■34464 / 親記事)  DataGridViewの行番号
  
□投稿者/ 社畜からの開放 一般人(7回)-(2020/05/13(Wed) 00:30:34)
  • アイコン環境/言語:[VB.NET、Win10 64bit] 
    分類:[.NET] 

    mdbファイルのテーブルの内容をJETを用いてDataGridViewに反映したり、その逆を行うアプリケーションを作成しております。

    ただ、DataGridView(1,1).valueを読み取ったときフォームを開くたびに行番号に対応する行が変わってしまう仕様に困惑しております。

    例えば
    id namae busho
    100 田中太郎 営業部
    101 鈴木次郎 人事部
    というmdbファイルがあるとしてmdb⇒DataGridViewの反映は毎回うまくいきます。

    その状態で
    Debug.Print (DataGridView(1,0).Value)を行うと"田中太郎"が表示されることを想定しておりますが、うまくいく場合もあれば営業部が表示される場合もあります。(フォームを開きなおす(コンパイルする?)たびに行番号が変わっている感じです。

    調べてみると内部で処理される行番号と表示される順番は固定されていないため、そのことそのものは不具合ではないようです。(多分)

    しかし、そうなると
    select id,namae,busho from user where id = datagridview(0,0).value
    という処理を行おうとしてもうまくid列を参照できません。

    一般的にどのように行番号と対応させるのでしょうか。
    ヘッダーテキストと照合を毎回行わないといけないのでしょうか。

マルチポストを報告
違反を報告
引用返信 削除キー/
■34465 / ResNo.1)  Re[1]: DataGridViewの行番号
□投稿者/ 魔界の仮面弁士 大御所(1280回)-(2020/05/13(Wed) 10:14:29)
  • アイコンNo34464に返信(社畜からの開放さんの記事)
    > id namae busho
    > 100 田中太郎 営業部
    > 101 鈴木次郎 人事部
    > というmdbファイルがあるとしてmdb⇒DataGridViewの反映は毎回うまくいきます。
    >
    > その状態で
    > Debug.Print (DataGridView(1,0).Value)を行うと"田中太郎"が表示されることを想定しておりますが、
    > うまくいく場合もあれば営業部が表示される場合もあります。


    う〜ん……。DataGridView のインデクサは、
      DataGridView1(列名, 行番号)
    もしくは
      DataGridView1(列番号, 行番号)
    のいずれかですよね。
    DataGridView1(1, 0).Value であるならば、
    columnIndex := 1 なので、常に namae 列の "田中太郎" が得られるはず…?

    たとえば 4 列構成の 1 列目が非表示になっているような場合、
    columnIndex := 2 を指定した時に、namae 列が得られてしまうことはありますが、
    columnIndex := 1 が指定されているのに、busho の列が得られるケースは思い当たらないです。


    強いて言えば、DataGridView の AllowUserToOrderColumns が True にしておいて、
    id, busho, namae 順でバインドしておいてから、表示される列順をドラッグで
    入れ替えれば、columnIndex := 1 で busho の列が得られるケースが、一応ありえます。

    DataGridview1.Columns(何某).Index が「本来の列番号」
    DataGridview1.Columns(何某).DisplayIndex が「表示順の列番号」

    でも、列順を入れ替えたり、DisplayIndex の変更なんて行っていませんよね…。



    >(フォームを開きなおす(コンパイルする?)たびに行番号が変わっている感じです。

    質問内容をもう一度確認しておきたいのですが:

    【行番号】が変化したのなら、「田中太郎」→「鈴木次郎」になるはずではないでしょうか。
    「田中太郎」→「営業部」に変化したのなら、【列番号】の変化だと思うのですが…。


    既定の設定では、DataGridView の列ヘッダーをクリックすると、データがソートされますので、
    表示されている順番と、データソースの行順は必ずしも合致しません。

    でも、今回問題視しているのは、DataGridView のインデクサの話なのですよね。


    > 一般的にどのように行番号と対応させるのでしょうか。
    列番号ならさておき、行番号を使うことはそもそも稀です。


    行列挙なら For Each を使いますし、データソースにバインドしているなら、
    DataGridView 上の入力値を直接扱うのではなく、データソースの値を
    直接読み取れば済むからです。

    ちなみに DataGridViewRow から BoundItem プロパティにアクセスすれば、
    DataRowView オブジェクトの Row プロパティから、バインド元の DataRow オブジェクトを得られます。

    Dim viewRow = DirectCast(DataGridView1.Rows(0).BoundItem, DataRowView)
    Dim row As DataRow = viewRow.Row
違反を報告
引用返信 削除キー/
■34466 / ResNo.2)  Re[2]: DataGridViewの行番号
□投稿者/ 社畜からの開放 一般人(8回)-(2020/05/13(Wed) 16:32:53)
  • アイコン> 強いて言えば、DataGridView の AllowUserToOrderColumns が True にしておいて
    現状ではAllowUserToOrderColumnsはFalseにしてあります。

    > DataGridview1.Columns(何某).Index が「本来の列番号」
    > DataGridview1.Columns(何某).DisplayIndex が「表示順の列番号」
    > でも、列順を入れ替えたり、DisplayIndex の変更なんて行っていませんよね…。

    列順の入れ替えを行ったつもりはありません。

    > 質問内容をもう一度確認しておきたいのですが:
    >
    > 【行番号】が変化したのなら、「田中太郎」→「鈴木次郎」になるはずではないでしょうか。
    > 「田中太郎」→「営業部」に変化したのなら、【列番号】の変化だと思うのですが…。
    書き間違いが多く混乱を招いて申し訳ございません。
    今回の問題はすべて列番号の話です。(タイトルさえ間違っています。)
    安定してid列を取得したいのになぜかnamae列を取得してしまったりbusho列を取得してしまったりして結果的にinsertやupdateの処理に支障が出ている状態です。
違反を報告
引用返信 削除キー/
■34467 / ResNo.3)  Re[3]: DataGridViewの行番号
□投稿者/ 魔界の仮面弁士 大御所(1281回)-(2020/05/13(Wed) 16:54:49)
  • アイコンNo34466に返信(社畜からの開放さんの記事)
    > 今回の問題はすべて列番号の話です。(タイトルさえ間違っています。)

    DataGridView の列は、どうやって定義していますか?

    (1) デザイン時に型付 DataSet をバインドしている

    (2) デザイン時に非バインド列を追加してから、列編集で DataPropertyName を設定している

    (3) DataGridView1.AutoGenerateColumns = True の状態で、
     実行時に DataSource を割り当てている

    (4) 列は自動生成させずに、DataSource を割り当てた後で、
     コードから列の追加と DataPropertyName の設定を行っている



    > 安定してid列を取得したいのになぜかnamae列を取得してしまったりbusho列を取得してしまったりして結果的にinsertやupdateの処理に支障が出ている状態です。

    その DataGridView を TabControl (というか TabPage) 上に配置していませんか?
    また、違った値が取得されてしまう場合と正しく取得されてしまう時とで

    For c = 0 To DataGridView1.Columns.Count - 1
     Debug.WriteLine(String.Format("{0}, {1}", c, DataGridView1(c, 0).Value))
    Next

    を実行した場合、どういう差異が現れますか?
違反を報告
引用返信 削除キー/
■34468 / ResNo.4)  Re[4]: DataGridViewの行番号
□投稿者/ 社畜からの開放 一般人(9回)-(2020/05/14(Thu) 23:12:22)
  • アイコンDataGridView の列は、どうやって定義していますか?
    (2) デザイン時に非バインド列を追加してから、列編集で DataPropertyName を設定している
    だと思います。
    あらかじめデザインビューから列を追加⇒列名やらプロパティネームやらを手動で(処理実行前に)追加しております。
    型付データセット・・・があまりよくわかりませんが、多分(2)です。
    少なくとも(3)、(4)ではないと思います。

    >その DataGridView を TabControl (というか TabPage) 上に配置していませんか?
    フォームに直接置いております。
    タブコントロールは使っておりません。
    ※タブコントロールって使ったことはありませんが、プリンターの設定とかであるようなタブを切り替えて複数のフォームが1つに集約されている感じのものですよね?

    > また、違った値が取得されてしまう場合と正しく取得されてしまう時とで
    For i = 0 to DataGridView_User.RowCount-1
    For j = 0 to DataGridView_User.ColumnCount-1
    Debug.Print(i & "," & j & "," & DataGridView_User(j,i))
    Next
    Next
    を走らせたとき
    0,0,0000
    0,1,田中太郎
    ...
    と表示されるのに次に試すと
    0,0,田中太郎
    0,1,0000
    のような感じになっておりました。
    ※ボタンで処理する限りは何回やっても変わりませんが、一度フォームを閉じた後にもう一度試すと並び順が変わっている感じです。
    ※実際の実行結果はイミディエイトウィンドウに表示されていて残っていないため今回の例は記憶から作っています。
    正しい値が取得できる・・・というより何列目がidかわからないから運が良ければ正しい値を取得できることもある感じです。
違反を報告
引用返信 削除キー/
■34469 / ResNo.5)  Re[5]: DataGridViewの行番号
□投稿者/ 魔界の仮面弁士 大御所(1282回)-(2020/05/15(Fri) 11:05:51)
  • アイコンNo34468に返信(社畜からの開放さんの記事)
    > 少なくとも(3)、(4)ではないと思います。

    AutoGenerateColumns プロパティは、既定で True のはず。

    (3) でも (4) でもない…という事はつまり、
    DataSource プロパティは使っていない(Nothing のまま)ということですね?


    > タブを切り替えて複数のフォームが1つに集約されている感じのものですよね?
    多分それかな。こんな感じのものです。今回は使っていないとのことで了解です。
    http://codepanic.itigo.jp/cs/tabcontrol.html


    >> また、違った値が取得されてしまう場合と正しく取得されてしまう時とで
    > For i = 0 to DataGridView_User.RowCount-1
    >  For j = 0 to DataGridView_User.ColumnCount-1
    >   Debug.Print(i & "," & j & "," & DataGridView_User(j,i))
    >  Next
    > Next
    DataGridView_User(j,i) が返すのは DataGridViewCell 型ですよね。
    この型には & 演算子が実装されていないので、Option Strict Off だとしてもエラーになるハズ…?


    > 0,0,0000
    > 0,1,田中太郎
    > ...
    > と表示されるのに次に試すと
    > 0,0,田中太郎
    > 0,1,0000
    > のような感じになっておりました。

    前者が「正しく取得される時」で、後者が「違った値が取得されてしまう場合」でしょうか?
    行は変わっていますが(それは別に重要ではない)、列は変わっていませんね(こっちが重要)。

    いずれにしても、 No34464 にあるように、
    >>> Debug.Print (DataGridView(1,0).Value)を行うと"田中太郎"が表示される
    には至らないはずです。

    元質問の DataGridView を DataGridView_User と読み替えたとしても、"田中太郎" が表示されるためには
     DataGridView_User(2, 0).Value
     DataGridView_User(2, 1).Value
    のいずれかであったはずであり、インデクサの指定が (1, 0) だった場合には、
    この場合には「0」が返されるはずです。


    実際に実験しているコードと、掲示板に書かれている質問内容がちぐはぐに思えるので、
    もう一度、ひとつひとつ正確に確認しなおしてみてください。


    > ※実際の実行結果はイミディエイトウィンドウに表示されていて残っていないため今回の例は記憶から作っています。
    それでは、実験用に新規プロジェクトを作成し、現象を再現できる最低限のコードを含めた状態で、
    ソリューションフォルダーをまるごと zip ファイルにして、アップロードしていただけませんか?
    (ソースだけで十分なので、bin や obj フォルダーは含めないでください)
違反を報告
引用返信 削除キー/
■34470 / ResNo.6)  Re[6]: DataGridViewの行番号
□投稿者/ 社畜からの開放 一般人(10回)-(2020/05/18(Mon) 21:54:04)
  • アイコンNo34469に返信(魔界の仮面弁士さんの記事)
    > ■No34468に返信(社畜からの開放さんの記事)
    >>少なくとも(3)、(4)ではないと思います。
    >
    > AutoGenerateColumns プロパティは、既定で True のはず。
    >
    > (3) でも (4) でもない…という事はつまり、
    > DataSource プロパティは使っていない(Nothing のまま)ということですね?
    >
    > DataGridView_User(j,i) が返すのは DataGridViewCell 型ですよね。
    > この型には & 演算子が実装されていないので、Option Strict Off だとしてもエラーになるハズ…?
    DataGridView_User(j,i).valueです。
    申し訳ございません。


    > ソリューションフォルダーをまるごと zip ファイルにして、アップロードしていただけませんか?
    > (ソースだけで十分なので、bin や obj フォルダーは含めないでください)
    質問を行っているのが自宅で、実際に処理を行っているのが職場のため記憶からの再現しか行えない状態で申し訳ございません。
    質問を度々書き間違えているあたり、(j,i)と(i,j)を描き間違えている個所がどこかにあることが原因の気がしてきました。今日は見つけられなかったのですが今一度見直してみます。混乱させて申し訳ございません。
違反を報告
引用返信 削除キー/
■34471 / ResNo.7)  Re[7]: DataGridViewの行番号
□投稿者/ Azulean 大御所(516回)-(2020/05/18(Mon) 22:20:35)
  • アイコン回答ではありませんが…。

    No34470に返信(社畜からの開放さんの記事)
    > 質問を度々書き間違えているあたり、(j,i)と(i,j)を描き間違えている個所がどこかにあることが原因の気がしてきました。

    i と j はタダでさえ似ている文字であることと、i と j 自体に意味がないので、誤りに気づきづらいです。
    (場所によって、i と j の意味が逆になっていることさえあり得るので)

    このため、x/y や row/column といった間違いづらく、かつ意味を表す変数名を使っていった方がミスを軽減できると思います。
    (行や列の方が意味として明確だが、時々、行と列を間違えてしまうこともなくはないので、x/y の方が良いのかな…?)
違反を報告
引用返信 削除キー/



スレッド内ページ移動 / << 0 >>

このスレッドに書きこむ

Mode/  Pass/


- Child Tree -