none
2つのテーブルを開けたいのですが、うまく動きません。 RRS feed

  • 質問

  • 2つのテーブルを開けたいのですが、うまく動きません。
    うまく、説明できないかもしれませんので、コードを記述します。
    また、DataSetでは、複数のテーブルを利用できる。って聞いてます。
    下記のコードで、どこがいけないのでしょうか?
    ご指導をお願い申し上げます。

            Dim oConn As New System.Data.OleDb.OleDbConnection()
            Dim oCommand As New OleDbCommand()
            Dim oDataAdapter As New OleDbDataAdapter()
            Dim MayakuDataSet As New DataSet()

            Dim h As Integer
            Dim i As Integer
            Dim j As Integer
            Dim dfsworks As String
            Dim dfiworks As Integer
            Dim dcworks As String

            Dim roadData(0 To 3) As String
            Dim listData(0 To 3) As String
            Dim listLine As String


            Try
                'DB接続文字列の設定
                'プロジェクトファイルフォルダ下のbinフォルダにsampl.mdbを置く
                oConn.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0; Data Source=c:\Mayaku\Data\Mayaku.mdb"

                'コネクションの設定
                oCommand.Connection = oConn

                'DB接続を開く
                oConn.Open()

                'SQL文の設定
                Const strSelect As String = "SELECT * FROM dmaster ORDER BY dname"
                oCommand.CommandText = strSelect

                'データを取得する
                oDataAdapter.SelectCommand = oCommand
                oDataAdapter.Fill(MayakuDataSet, "dmaster")

                'リストボックスに部門名を表示する設定

                Me.ListBox1.Items.Clear()

                For i = 0 To MayakuDataSet.Tables("dmaster").Rows.Count - 1

                    dfiworks = CInt(Trim(MayakuDataSet.Tables("dmaster").Rows(i).Item("dfcount")))
                    dcworks = Trim(MayakuDataSet.Tables("dmaster").Rows(i).Item("dcode"))

                    'SQL文の設定
                    Const MstrSelect As String = "SELECT * FROM mdata WHERE dcode = @minID ORDER BY mainkey"
                    oCommand.CommandText = MstrSelect

    ※dmasterのdcodeで、mdataのレコードを収得するためのパラメーター

                    oCommand.Parameters.Add(New OleDbParameter("@minID", OleDbType.Char, 20))
                    oCommand.Parameters("@minID").Value = Trim(dcworks)

                    'データを取得する
                    oDataAdapter.SelectCommand = oCommand
                    oDataAdapter.Fill(MayakuDataSet, "mdata")

                    rm = MayakuDataSet.Tables("mdata").Rows.Count

                    If MayakuDataSet.Tables("mdata").Rows.Count = 0 Then
                        'daworks2 = MMDataSet.Tables("mdata").Rows(i).Item("dname")
                        'oCommand.Clone()
                    Else
                        For j = 0 To MayakuDataSet.Tables("mdata").Rows.Count - 1

                            If Trim(MayakuDataSet.Tables("mdata").Rows(j).Item("skubun")) = "0" Then
                                dfiworks = dfiworks - CInt(Trim(MayakuDataSet.Tables("mdata").Rows(i).Item("dsuu1")))
                            End If
                            If Trim(MayakuDataSet.Tables("mdata").Rows(j).Item("skubun")) = "1" Then
                                dfiworks = dfiworks + CInt(Trim(MayakuDataSet.Tables("mdata").Rows(i).Item("dsuu2")))
                            End If
                            If Trim(MayakuDataSet.Tables("mdata").Rows(j).Item("skubun")) = "2" Then
                                dfiworks = dfiworks - CInt(Trim(MayakuDataSet.Tables("mdata").Rows(i).Item("dsuu3")))
                            End If
                            If Trim(MayakuDataSet.Tables("mdata").Rows(j).Item("skubun")) = "3" Then
                                dfiworks = dfiworks + CInt(Trim(MayakuDataSet.Tables("mdata").Rows(i).Item("dsuu4")))
                            End If

                        Next j
                        'oCommand.Clone()
                    End If

                    dfsworks = CStr(dfiworks)
                    roadData(0) = Trim(MayakuDataSet.Tables("dmaster").Rows(i).Item("dcode"))
                    roadData(1) = Trim(MayakuDataSet.Tables("dmaster").Rows(i).Item("dname"))
                    roadData(2) = Trim(dfsworks)

                    listData(0) = StrConv(LSet(Trim(roadData(0)), 13), VbStrConv.Narrow)
                    listData(1) = StrConv(LSet(Trim(roadData(1)), 12), VbStrConv.Wide)
                    listData(2) = StrConv(LSet(Trim(roadData(2)), 3), VbStrConv.Wide)

                    listLine = listData(0) & listData(1) & listData(2)
                    Me.ListBox1.Items.Add(listLine)
                Next i

            Catch oExcept As Exception
                '例外が発生した時の処理
                MessageBox.Show(oExcept.Message, "例外発生")

            Finally
                'DB接続を閉じる
                If Not oConn Is Nothing Then
                    oConn.Close()
                End If

            End Try

    長々と記述してすみません。
    最初のループでiが0の時は
    MayakuDataSet.Tables("mdata").Rows.Countは2で正解です。
    ↑はきちんとRowsCountは収得できてました。

    しかし、
    iが1の時、
    MayakuDataSet.Tables("mdata").Rows.Countは0であるはずなのですが、
    RowsCountは2のままです。
    ※データベースを確認しましたが、dcodeに対応するmdataの行はないはずですが、2から0に、何故か変わっていません。
    DataAdapterの取り方がわるいのでしょうか?
    それとも、DataSetの取り方がわるいのでしょうか?
    ※DataSetの名前を変えて、2種類にしても、同じ結果でした。
    例えば、MayakuDataSet  と、  MMDataSet としても。
    それとも、Tableをそれぞれ、宣言してないかなのでしょうか?

    少し、理解できなかったので、投稿いたしました。
    どうか、ご指導のほど、よろしくお願い申し上げます。

    2009年3月5日 5:13

回答

  •  2回目以降 "mdata" という DataTable を Fill する前に Clear したらどうなりますか?
    • 回答としてマーク タッチ2 2009年3月7日 6:30
    2009年3月5日 14:36
  • > MayakuDataSet.Tables("mdata").Clear()
    > でもないですよね。

    それでいいんですけど。

    なぜ試してみないんですか? 間違えていたからといって PC が壊れるわけでは
    あるまいし。
    • 回答としてマーク タッチ2 2009年3月7日 15:06
    2009年3月7日 12:16
  •  余談ですが、上記の処理であればSQL文一つで済みそうです。

    select max(dmaster.dcode) dcode, max(dmaster.dname) dname,
        
    max(dmaster.dfcount) +    
                         sum(case 
                               when mdata.skubun = '0' then mdata.dsuu1 * -1  
                               when mdata.skubun = '1' then mdata.dsuu2  
                               when mdata.skubun = '2' then mdata.dsuu3 * -1  
                               when mdata.skubun = '3' then mdata.dsuu4  
                          end) dfsworks  
    from mdata  
    inner join dmaster on dmaster.dcode = mdata.dcode  
    group by dmaster.dcode  
    order by dmaster.dcode 


    テーブルの詳細がわからないので、うまく行かなければごめんなさい。
    ★良い回答には回答済みマークを付けよう! わんくま同盟 MVP - Visual C# http://blogs.wankuma.com/trapemiya/
    • 回答としてマーク タッチ2 2009年3月9日 15:42
    2009年3月9日 15:08
    モデレータ

すべての返信

  •  2回目以降 "mdata" という DataTable を Fill する前に Clear したらどうなりますか?
    • 回答としてマーク タッチ2 2009年3月7日 6:30
    2009年3月5日 14:36
  • SurferOnWwwさんありがとうございます。
    oDataAdapter.Fill(MayakuDataSet, "mdata")をClearして、
    MayakuDataSet.Tables("mdata").Rows.Countを0にもどさなければいけない。
    ってことですね。

    ただ、
    oDataAdapter.Fill(MayakuDataSet, "mdata")をClearする方法がわからなくて。
    MSDNでみてみたのですが、
    http://msdn.microsoft.com/ja-jp/library/system.data.common.dbdataadapter.fill(VS.71).aspx

    詮索するページが違っているのでしょうか?
    お礼の送信がおそくなってすみませんでした。
    MayakuDataSet.Tables("mdata").Clear()
    でもないですよね。

    申し訳ありません。

    2009年3月7日 6:42
  • > MayakuDataSet.Tables("mdata").Clear()
    > でもないですよね。

    それでいいんですけど。

    なぜ試してみないんですか? 間違えていたからといって PC が壊れるわけでは
    あるまいし。
    • 回答としてマーク タッチ2 2009年3月7日 15:06
    2009年3月7日 12:16
  •  SurferOnWwwさんありがとうございます。
    実は、質問を投稿する前に、
    MayakuDataSet.Tables("mdata").Clear()
    を試していたのですが、実行させるタイミング(コードを記述する位置)が悪かったのか
    エラー
    「オブジェクト参照がオブジェクトインスタンスに設定されていません。」
    が表示されてたので、悩んでいました。
    MayakuDataSet.Tables("mdata").Clear()
    が正解かどうかも自信がなかったのです。

    MayakuDataSet.Tables("mdata").Clear()
    を、
    Next i
    の前に記述すると、うまく動きました。
    ありがとうございました。
    本当に、申し訳ありませんでした。
    2009年3月7日 15:13
  •  SurferOnWwwさんありがとうございます。
    前回、質問を投稿する前と書きましたが、
    >oDataAdapter.Fill(MayakuDataSet, "mdata")をClearする
    と、教えていただいた、後に、でした。

    本当に助かりました。
    重ねて、ありがとうございました。

    2009年3月7日 15:17
  •  余談ですが、上記の処理であればSQL文一つで済みそうです。

    select max(dmaster.dcode) dcode, max(dmaster.dname) dname,
        
    max(dmaster.dfcount) +    
                         sum(case 
                               when mdata.skubun = '0' then mdata.dsuu1 * -1  
                               when mdata.skubun = '1' then mdata.dsuu2  
                               when mdata.skubun = '2' then mdata.dsuu3 * -1  
                               when mdata.skubun = '3' then mdata.dsuu4  
                          end) dfsworks  
    from mdata  
    inner join dmaster on dmaster.dcode = mdata.dcode  
    group by dmaster.dcode  
    order by dmaster.dcode 


    テーブルの詳細がわからないので、うまく行かなければごめんなさい。
    ★良い回答には回答済みマークを付けよう! わんくま同盟 MVP - Visual C# http://blogs.wankuma.com/trapemiya/
    • 回答としてマーク タッチ2 2009年3月9日 15:42
    2009年3月9日 15:08
    モデレータ
  • trapemiyaさん。
    アドバイスをありがとうございます。
    初めて見るコードでおどろいています。
    Select 文で、場合分けしてあるようですが、Select文の間の
    コードですが、頑張って、理解してます。
    ありがとうございました。
    2009年3月9日 15:47
  •  すみません。mdbでしたね。私が書いたSQL文はSQL Server用です。mdbだとcaseの代わりにswitchで動くんじゃないかなぁ?
    試してなくてすみません。

    (参考)
    SELECT文の中で条件分岐
    http://penhagi.com/access/ota2002/6830.htm

    SQL の CASE を Access で使いたければ Switch か
    http://dhive.jp/blog/yama/?p=227

    SELECT文の中で条件分岐するには?
    http://homepage1.nifty.com/kojama/works/rdbms/jet/sql.html#term04
    ★良い回答には回答済みマークを付けよう! わんくま同盟 MVP - Visual C# http://blogs.wankuma.com/trapemiya/
    2009年3月10日 0:16
    モデレータ