複数のDataGridにそれぞれ別のデータを表示するには?

解決


通りすがり  2004-07-26 00:04:07  No: 115022  IP: [192.*.*.*]

分類コード(フィールド名:CD)が文字列で「01」から「10」まであり、この中でどのコードが格納されているかはその時々で違います。ただ1〜3種類は格納されています。そこでどのコードが格納されているかわからないのでFor文を使用し、すべてのコードをあるかないか判断。あった場合をDataGrid1に表示、なかった場合は飛ばし、さらに次にあった場合はDataGrid2へ表示…としていきたいのですがどのようなコーディングがいいのでしょうか?
すいません。説明がわかりづらくて(環境:VB.NET)
当然↓ではダメです。

For i = 1 To 10
 CD = Format(i, "00")

 'SQLを発行しデータ抽出
 sql = "select * from HEAD where CD="""
 sql = sql & CD & """"

 oleDa = New OleDb.OleDbDataAdapter(sql, oleCn)
 oleDa.Fill(dtSet, "HEAD")

 dtTbl = dtSet.Tables("HEAD")

 dtView1 = New DataView(dtSet.Tables("HEAD"), "CD=" & CD, "", DataViewRowState.CurrentRows.CurrentRows)
 LabelA.Text = dtView1.Count
 DataGrid1.DataSource = dtView1

 dtView2 = New DataView(dtSet.Tables("HEAD"), "CD=" & CD, "", DataViewRowState.CurrentRows.CurrentRows)
 LabelB.Text = dtView2.Count()
 DataGrid2.DataSource = dtView2

 dtView3 = New DataView(dtSet.Tables("HEAD"), "CD=" & CD, "", DataViewRowState.CurrentRows.CurrentRows)
 LabelC.Text = dtView3.Count()
 DataGrid3.DataSource = dtView3

 oleCn.Close()
 MsgBox("読込が終了しました。")

Next

編集 削除
特攻隊長まるるう  2004-07-26 11:24:18  No: 115023  IP: [192.*.*.*]

DataSet の中には複数の DataTable を格納できるし、
1つの DataGrid で複数の DataTable を表示できますよ?。
(最初にツリー状にテーブル名の一覧が出て、そこからテーブルを
選択して表示する形となります)

まぁ…それはいいとして…上のコードをなるべく修正せずに
実現するなら CD で表示対象を Select 文の処理に分けて
やればいいんじゃないですか?変数とか共通化できるけど
…ま、修正が少ない方向で回答しておきます。
[VB.NET]
        Select Case CD
            Case 1
                dtView1 = New DataView(dtSet.Tables("HEAD"), "CD=" & CD, "", DataViewRowState.CurrentRows.CurrentRows)
                LabelA.Text = dtView1.Count
                DataGrid1.DataSource = dtView1
            Case 2
                dtView2 = New DataView(dtSet.Tables("HEAD"), "CD=" & CD, "", DataViewRowState.CurrentRows.CurrentRows)
                LabelB.Text = dtView2.Count()
                DataGrid2.DataSource = dtView2
            Case 3
                dtView3 = New DataView(dtSet.Tables("HEAD"), "CD=" & CD, "", DataViewRowState.CurrentRows.CurrentRows)
                LabelC.Text = dtView3.Count()
                DataGrid3.DataSource = dtView3

        End Select

編集 削除
通りすがり  2004-07-26 12:20:28  No: 115024  IP: [192.*.*.*]

まるるうさん、回答ありがとうございます。そこでもうちょっと聞かせてください。このCDですが問題がありまして、「01」で始まるとはかぎらず例えばデータベースには「02」、「04」、「10」と格納されている時や次に読込時にはテーブルクリアし別ファイルを見に行くため「01」、「03」、「08」と格納されていたりします。ちょっとなんでこんな風に格納されるかは長くなりますので割愛させてください。
どんなCDが格納されていても別CDの場合には別DataGridに表示したいというわけなのです。
なにかよい方法はありますでしょうか?
よろしくお願いします。

編集 削除
特攻隊長まるるう  2004-07-26 13:17:25  No: 115025  IP: [192.*.*.*]

>「01」で始まるとはかぎらず  …
それは関係ないデショ?(._゜)?

> sql = "select * from HEAD where CD="""
> sql = sql & CD & """"
の時点で検索対象としている CD を持ってるレコードのみ
検索してるんですから、順番がなぜ問題になるか理解できません。
対象となる CD を持つレコードがデータベース上に存在しない
場合は、データテーブルを取得できない場合はあるかもしれません。
その場合は Fill の時点で DataTable が作成されないでしょうから、
その辺で処理を条件分けすればいいだけですし…。

上のコードを見る限り、CD の順番は関係ないはずです。
質問の問題点が見つかりません。実際に実行してみて都合の悪い
部分をできるだけ正確に質問して下さい。

編集 削除
通りすがり  2004-07-26 13:48:47  No: 115026  IP: [192.*.*.*]

わかりづらく申し訳ありません。そこで実現したいことを記述いたします。
アドバイスいただけますでしょうか。
初回読込をした場合、DBにはCD「02」、「04」、「10」が格納されて
います。実際にはCDになにが格納されているかわかりませんので
select文で狙い撃ちはできません。
検索対象である「02」をDataGrid1へ表示、「04」をDataGrid2へ表示、
「10」をDataGrid3へ表示。
次回読込をした場合、DBにはCD「01」、「03」、「08」が格納されて
います。こちらも実際にはCDになにが格納されているかわかりません。
検索対象である「01」をDataGrid1へ表示、「03」をDataGrid2へ表示、
「08」をDataGrid3へ表示。

っという具合に検索対象で見つかったCDのレコードをDataGrid1へ、次にDataGrid1に表示したCDとは別のCDが検索対象で見つかった場合は
DataGrid2へ、DataGrid2、DataGrid3とは別のCDがさらに見つかった
場合はDataGrid3へ表示したいというわけです。

ちなみにCDは最大でも3種類しかDBには格納されていません。
質問の意図はわかっていただけましたでしょうか?
申し訳ございませんがわからない部分がありましたらまたレスをください。
よろしくお願いします。

編集 削除
特攻隊長まるるう  2004-07-26 14:55:43  No: 115027  IP: [192.*.*.*]

ああ、DataGrid って3個しか無いんですね?(^^;)

>初回読込をした場合、DBにはCD「02」、「04」、「10」が格納されて
>います。実際にはCDになにが格納されているかわかりませんので
>select文で狙い撃ちはできません。
>検索対象である「02」をDataGrid1へ表示、「04」をDataGrid2へ表示、
>「10」をDataGrid3へ表示。
>次回読込をした場合、DBにはCD「01」、「03」、「08」が格納されて
>います。こちらも実際にはCDになにが格納されているかわかりません。
>検索対象である「01」をDataGrid1へ表示、「03」をDataGrid2へ表示、
>「08」をDataGrid3へ表示。
データベースの運用上、文句を言いたい部分はありますがw

とりあえず色々と変更しちゃったのでソース載せます。動作確認は
SQLサーバーでやってますので、動かない部分があれば修正して下さい。
確認用に DataGrid4 を貼り付けておいて下さい。必要無くなったら
コードでは
        Me.DataGrid4.DataSource = wDS
だけ削除すれば動くと思います。

[VB.NET]
    ' 複数テーブル検索
    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Dim wDS As New DataSet()
        Dim wDT As DataTable
        Dim i As Integer

        Dim wCnStr As String = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=ファイル.mdb"
        Dim wSqlStr As String = "SELECT * FROM HEAD WHERE CD="""
        Dim wCD As String

        Me.DataGrid4.DataSource = wDS

        For i = 1 To 10
            wCD = Format(i, "00")
            Try
                wDT = (Me.GetDataTableFromDataServer(wCnStr, wSqlStr & wCD & """", 15))
            Catch ex As Exception
                MsgBox("データベース検索処理に失敗しました。")
                Debug.WriteLine(ex.Message)
                Exit Sub
            End Try
            If Not (wDT Is Nothing) Then
                With wDT
                    If .Rows.Count = 0 Then
                        ' 対象レコード無し
                    Else
                        .TableName = "CD" & wCD
                        wDS.Tables.Add(.Copy) ' 検索時に DataSet に属してるため、データのみコピーしないとエラー
                    End If
                End With
            End If

            ' MSDN サンプル
            'Dim tablesCol As DataTableCollection
            '' Get the DataTableCollection of a DataGrid control's DataSet.
            'tablesCol = CType(DataGrid1.DataSource, DataSet).Tables
            '' Create a new DataTable.
            'Dim myTable As DataTable = New DataTable()
            '' Code to add columns and rows not shown here.
            '' Add the table to the DataTableCollection.
            'tablesCol.Add(wDataTable.Copy)
        Next

        With wDS.Tables 'CType(Me.DataGrid4.DataSource, DataSet).Tables
            For i = 1 To .Count
                Select Case i
                    Case 1
                        Me.LabelA.Text = .Item(i - 1).Rows.Count
                        Me.DataGrid1.DataSource = .Item(i - 1)
                    Case 2
                        Me.LabelB.Text = .Item(i - 1).Rows.Count
                        Me.DataGrid2.DataSource = .Item(i - 1)
                    Case 3
                        Me.LabelC.Text = .Item(i - 1).Rows.Count
                        Me.DataGrid3.DataSource = .Item(i - 1)
                    Case Else
                        MsgBox("4件以上検索されてますよ?")
                        Exit Sub
                End Select
            Next
        End With

    End Sub

    Private Function GetDataTableFromDataServer( _
        ByVal CnStr As String, _
        ByVal SQLx As String, _
        ByVal TimeoutVal As Integer _
        ) _
        As DataTable

        Dim DA As IDbDataAdapter
        Dim Cn As IDbConnection
        Dim Cmd As IDbCommand
        Dim Prm As IDataParameter
        Dim DS As New DataSet()
        Dim DT As New DataTable()

        Dim i As Integer

        'Select Case ServerKind
        '    Case ServerKindInfo.SQLServer
        'Cn = New SqlClient.SqlConnection()
        'Cmd = New SqlClient.SqlCommand()
        'DA = New SqlClient.SqlDataAdapter()
        '    Case ServerKindInfo.Oracle
        '        Cn = New OracleClient.OracleConnection()
        '        Cmd = New OracleClient.OracleCommand()
        '        DA = New OracleClient.OracleDataAdapter()
        'End Select
        Cn = New OleDb.OleDbConnection()
        Cmd = New OleDb.OleDbCommand()
        DA = New OleDb.OleDbDataAdapter()

        Cn.ConnectionString = CnStr
        With Cmd
            .CommandText = SQLx
            Debug.WriteLine(SQLx)

            .Connection = Cn
            .CommandTimeout = TimeoutVal
        End With

        With DA
            .SelectCommand = Cmd

            .Fill(DS)
        End With

        Cn = Nothing
        Cmd = Nothing
        DA = Nothing

        If DS.Tables.Count = 0 Then
            Return Nothing
        Else
            Return DS.Tables(0)
        End If
    End Function

編集 削除
特攻隊長まるるう  2004-07-26 15:23:32  No: 115028  IP: [192.*.*.*]

上の方法はデータベースの中に CD が1種でも4種でも
対応できると思います。ただし、データベース検索回数は
つねに10回、すべての CD を検索してます。
CD が3種しかないなら、先に CD のみ全て検索して
検索に引っかかった CD でデータベース検索を行えば、
データベース検索回数は全部で4回で済みます。
また、どうせなら CD の制限なし(SQL文のWHERE句なし)で
全てを検索してしまい、ローカルでデータを振り分けても
いいですね。こうなるとデータベース検索回数は1回です。

そんなに難しい処理ではないので考えてみて下さい。

編集 削除
通りすがり  2004-07-26 16:19:35  No: 115029  IP: [192.*.*.*]

まるるうさん、ありがとうございます。初心者なもので勉強になります。
上記コードを参照し、精進します。
まずは把握からになりますが…
本当にありがとうございました。

編集 削除