tagCANDY CGI VBレスキュー(花ちゃん) の Visual Basic 2010 用 掲示板(VB.NET 掲示板)
VBレスキュー(花ちゃん) の Visual Basic 2010 用 掲示板(VB.NET 掲示板)
[ツリー表示へ]  [ワード検索]  [Home]

タイトル 謝罪 と その後判明した事
投稿日: 2008/06/24(Tue) 14:59
投稿者ひぃ
何より先にまずお詫びさせて頂ければと思います。
賛否両論はあるようですが、URLを記述しなかった点や、
こちらでの決まりに違反していた事を謝罪致します。


さて、今回、書き込みさせて頂きましたのには理由があります。
前回書き込んだ「一先ず解決しました」ではまだ解決出来ていなかったからです。
(自分としては解決出来たつもりでいましたが、テストを実施していたら不具合が見つかりました)
完全解決ではありませんが、逃げ道を見つけましたのでご報告させて頂きます。
(少々長くなりますのでご興味がある方のみお読み頂くか、LINQ開発する時の参考にして頂ければ幸いです)


前回書き込みさせて頂いたソースでは、DataPropertyNameを設定すれば可能
というような感じになっていましたが、それだけでは実現出来ませんでした。
DataPropertyNameを正しく設定すれば、その行に値は入るのですが、
当初の問題であった、「SELECT順の通りに並ばない」が実現出来ていませんでした。
(フィールド数が多かったので、少し確認して「出来た」と思い違いしていました)
当初質問させて頂いていた状態での結果と、
DataPropertyNameを設定してからの結果では並び順は少し変わっていましたが、
やはりこちらが指定した通りのSELECT順にはなっていませんでした。

例えば、以下のような2つのテーブルがあったとします。
テーブル名:Siten_Table AS Siten
フィールド名:A_SitenCD,B_SitenMei,C_SitenChoCD,D_SitenChoMei
テーブル名:Ka_Table AS Ka
フィールド名:A_SitenCD_Ka,B_KaCD,C_KaMei,D_KaChoCD,E_KaChoMei
(並び順がどうなるか分かりやすいように頭をABCにしています)

このテーブルをLINQの結合で取得したとします。
当初の状態(DataPropertyNameに設定なし)で実行すると、
実際にDataGridViewに表示される順は、
Siten.A_SitenCD, Ka.A_SitenCD_Ka, Ka.B_KaCD, Siten.B_SitenMei,
Ka.C_KaMei, Siten.C_SitenChoCD, Ka.D_KaChoCD, Siten.D_SitenChoMei, Ka.E_KaChoMei
というように、完全にABC順に並んでしまいます。
(実際にこういうテーブルを用意して試したわけではありませんが、
 私が使っているテーブルでは完全ABC順となりました)

では、DataPropertyNameに設定有で実行すると、
実際にDataGridViewに表示される順は、
Siten.A_SitenCD, Siten.B_SitenMei, Siten.C_SitenChoCD, Siten.D_SitenChoMei,
Ka.A_SitenCD_Ka,Ka.B_KaCD,C_KaMei,Ka.D_KaChoCD,Ka.E_KaChoMei
というように、テーブル単位でABC順に並んでいました。
恐らく、結合順序によりこの逆の状態にもなるのではないかと思います。

原因を調べる為にステップ実行でいろんなプロパティを見ていたのですが、
データソース=LINQ結果が行われた瞬間に変更される値を見つけました。
DataGridViewが所有する「DisplayIndex」というプロパティでした。
「一先ず解決しました」で記述しましたソース

dim strColNM() As String = { "支店名", "支店コード", "課名", "課コード"}

For intCnt = 0 to (strColNM.Count - 1)
     Me.DataGridView.Colmuns.Add( strColNM(intCnt), strColNM(intCnt))
     Me.DataGridView.Colmuns(intCnt).DataPropertyName = strColNM(intCnt)
Next

Dim dtc As New dcTestCheck

Dim var = From SitenMei In dtc.SitenTbl, KaMei In dtc.KaTbl _
           Where SitenMei.SitenCD = KaMei.SitenCD _
           Order By SitenMei.SitenCD , KaMei.KaCD_
           Select 支店名 = SitenMei.SitenName _
                , 支店コード = SitenMei.SitenCD _
                , 課名 = KaMei.KaName _
                , 課コード = KaMei.KaCD

Me.DataGridView.DataSource = var

↑の「Me.DataGridView.DataSource = var」が実行されるまでの
「DisplayIndex」はColmuns.Addした順になっているのですが、
「Me.DataGridView.DataSource = var」が実行されると、
「DisplayIndex」の中身が変更される。という現象が起きます。

おそらくLINQの仕様なのではないかと思いますが、
LINQの結合で取得した結果(データベース クエリという名前らしいです)
の中身が既にABC順となっていました。
それをDataGridViewのデータソースに入れると、順番がバラバラとなり、
DataPropertyNameを設定していない場合は完全ABC順
DataPropertyNameを設定した場合でもテーブル単位でABC順
に並び変わってしまうようです。

これを回避するには、「DisplayIndex」を当てなおすしかありません。
(もしくはLINQのクラスに必要なフィールドを順番通りに抜き出したクエリ用のClassを作成して、
 それをデータソースとしてDataGridとして表示させる。でしょうか?
 試していないので出来るかどうかはわかりませんが)
私は、お客様の依頼により、
「デザイナで全部出来るならデザイナでやって欲しいが、
 それが無理ならば、逆にデザイナはあまり使わず、
 ソースでここだけ直せば大丈夫。という状態にして欲しい」
という事でしたので、DisplayIndexを当て直す事にしました。

以下のようなソースになります。

dim strColNM(,) As String = {{0,"支店名"}, {1,"支店コード"}, {2,"課名"}, {3,"課コード"}}

For intCnt = 0 to strColNM.GetUpperBound(0)
     Me.DataGridView.Colmuns.Add( strColNM(intCnt,1), strColNM(intCnt,1))
     Me.DataGridView.Colmuns(intCnt).DataPropertyName = strColNM(intCnt,1)
Next

Dim dtc As New dcTestCheck

Dim var = From SitenMei In dtc.SitenTbl, KaMei In dtc.KaTbl _
           Where SitenMei.SitenCD = KaMei.SitenCD _
           Order By SitenMei.SitenCD , KaMei.KaCD_
           Select 支店名 = SitenMei.SitenName _
                , 支店コード = SitenMei.SitenCD _
                , 課名 = KaMei.KaName _
                , 課コード = KaMei.KaCD

Me.DataGridView.DataSource = var

'データソースに入れた後、DisplayIndexを当て直す(LINQ仕様回避)
For intX = 0 to (Me.DataGridView.ColmunCount - 1)
    For intY = 0 to strColNM.GetUpperBound(0)
        If Me.DataGridView.Colmuns(intX).Name = strColNM(intY,1) Then
            Me.DataGridView.Colmuns(intX).DisplayIndex = strConNM(intY,0)
        End IF
    Next intY
Next intX


かなり逃げなソースですが、
配列に指定した数値通りの順に行を並べる事が出来ました。

長々と書き込み申し訳ありませんでした。
どなたかの参考になれば幸いです。

- 関連一覧ツリー をクリックするとツリー全体を一括表示します)

古いスレッドにレスはつけられません。