none
データテーブルのCSV保存について RRS feed

  • 質問

  • 下記のコードでデータテーブルをCSV保存しようと試みましたが一番下の行が消えてしまいます。

    どのように修正すればいいでしょうか?

    ご教示お願い致します。

    Private Sub btn_hozon_Click(sender As Object, e As EventArgs) Handles btn_hozon.Click
     ConvertDataTableToCsv(database_DataTable, "C:test.csv", True)
    End Sub

      ''' <summary>
        ''' DataTableの内容をCSVファイルに保存する
        ''' </summary>
        ''' <param name="dt">CSVに変換するDataTable</param>
        ''' <param name="csvPath">保存先のCSVファイルのパス</param>
        ''' <param name="writeHeader">ヘッダを書き込む時はtrue。</param>
    Public Sub ConvertDataTableToCsv(dt As DataTable, csvPath As String, writeHeader As Boolean)
            'CSVファイルに書き込むときに使うEncoding
            Dim enc As System.Text.Encoding =
            System.Text.Encoding.GetEncoding("Shift_JIS")

            '書き込むファイルを開く
            Dim sr As New System.IO.StreamWriter(csvPath, False, enc)

            Dim colCount As Integer = dt.Columns.Count
            Dim lastColIndex As Integer = colCount - 1
            Dim i As Integer

            'ヘッダを書き込む
            If writeHeader Then
                For i = 0 To colCount - 1
                    'ヘッダの取得
                    Dim field As String = dt.Columns(i).Caption
                    sr.Write(field)
                    'カンマを書き込む
                    If lastColIndex > i Then
                        sr.Write(","c)
                    End If
                Next
                '改行する
                sr.Write(vbCrLf)
            End If

            'レコードを書き込む
            Dim row As DataRow
            For Each row In dt.Rows
                For i = 0 To colCount - 1
                    'フィールドの取得
                    Dim field As String = row(i).ToString()
                    'フィールドを書き込む
                    sr.Write(field)
                    'カンマを書き込む
                    If lastColIndex > i Then
                        sr.Write(","c)
                    End If
                Next
                '改行する
                sr.Write(vbCrLf)
            Next

            '閉じる
            sr.Close()
    End Sub

    2018年3月14日 7:18

回答

  • 見る限りコードは問題なさそうです。DataTableに取り込む時点で1行欠けていただけではありませんか?
    2018年3月14日 7:53
  • ざっとコードを見ただけですが、最後の行が消えるようなコードではないと思います。
    ConvertDataTableToCsvメソッドの引数のデータテーブルには望むデータが全て入っているのでしょうか?デバッグしてみて下さい。
    ひょっとすると画面には表示されているが、データテーブルに書き込まれていないのかもしれません。



    ★良い回答には質問者は回答済みマークを、閲覧者は投票を!

    • 回答の候補に設定 佐祐理 2018年3月14日 13:52
    • 回答としてマーク T.K.Tora 2018年3月14日 23:13
    2018年3月14日 7:57
    モデレータ
  • DataGridView の入力値が確定前の状態であり、該当行がまだ DataTable に追加されていない状態なのでしょう。(Esc キーを押すと、最終行の内容がロールバックされる状態ではありませんか?)

    DataSource として BindingSource 等を用いてバインドしている場合には、BindingSource の EndEdit メソッドを呼び出すことで、現在行の編集が確定されます

    DataSource に DataSet / DataTable / DataView を割り当てている場合には、下記のようにすることも出来ます。

    • 回答としてマーク T.K.Tora 2018年3月14日 13:35
    2018年3月14日 9:50

すべての返信

  • 見る限りコードは問題なさそうです。DataTableに取り込む時点で1行欠けていただけではありませんか?
    2018年3月14日 7:53
  • ざっとコードを見ただけですが、最後の行が消えるようなコードではないと思います。
    ConvertDataTableToCsvメソッドの引数のデータテーブルには望むデータが全て入っているのでしょうか?デバッグしてみて下さい。
    ひょっとすると画面には表示されているが、データテーブルに書き込まれていないのかもしれません。



    ★良い回答には質問者は回答済みマークを、閲覧者は投票を!

    • 回答の候補に設定 佐祐理 2018年3月14日 13:52
    • 回答としてマーク T.K.Tora 2018年3月14日 23:13
    2018年3月14日 7:57
    モデレータ
  • 佐祐理さん、trapemiyaさん回答ありがとうございます。

    データテーブルへのデータの追加は下記のコードで行っているのですがこのボタンに問題があるのでしょうか?

    '追加ボタン
        Private Sub btn_add_Click(sender As Object, e As EventArgs) Handles btn_add.Click

            Dim aaa As String = Me.txt_aaa.Text
            Dim iii As String = Me.txt_iii.Text
            Dim uuu As String = Me.txt_uuu.Text
            Dim eee As String = Me.txt_eee.Text
            Dim ooo As String = Me.label_ooo_result.Text
            Dim kkk As String = Me.label_kkk_result.Text  


         ' Create new DataTable and DataSource objects.
            Dim database_DataAddTable As DataTable = New DataTable()

            ' Declare DataColumn
            Dim column As DataColumn

            ' Create new DataColumn, set DataType, ColumnName and add to DataTable.    
            column = New DataColumn()
            column.DataType = Type.GetType("System.String")
            column.ColumnName = "あああ"
            database_DataAddTable.Columns.Add(column)

            column = New DataColumn()
            column.DataType = Type.GetType("System.String")
            column.ColumnName = "いいい"
            database_DataAddTable.Columns.Add(column)

            column = New DataColumn()
            column.DataType = Type.GetType("System.String")
            column.ColumnName = "ううう"
            database_DataAddTable.Columns.Add(column)

            column = New DataColumn()
            column.DataType = Type.GetType("System.String")
            column.ColumnName = "えええ"
            database_DataAddTable.Columns.Add(column)

            column = New DataColumn()
            column.DataType = Type.GetType("System.String")
            column.ColumnName = "おおお"
            database_DataAddTable.Columns.Add(column)

            column = New DataColumn()
            column.DataType = Type.GetType("System.String")
            column.ColumnName = "かかか"
            database_DataAddTable.Columns.Add(column)

            ' Create new DataRow objects and add to DataTable.    
            Dim database_DataView As DataView = database.DataSource
            Dim database_DataRowView As DataRowView = database_DataView.AddNew

            database_DataRowView("あああ") = aaa
            database_DataRowView("いいい") = iii
            database_DataRowView("ううう") = uuu
            database_DataRowView("えええ") = eee
            database_DataRowView("おおお") = ooo
            database_DataRowView("かかか") = kkk
            database_DataAddTable.Rows.Add(database_DataRowView)

    2018年3月14日 8:30
  • 登録できている行があるわけですから、おそらくこの1行を登録するだけのコードには問題がないと思います。

    プログラムが意図したように動かない場合、デバッグすることになります。
    前述したように、まずデータテーブルに望んでいる全ての行が格納されているかを確認してみて下さい。
    その結果により、CSVを書き出す部分に問題があるのか、それともデータテーブルに書き込む部分に問題があるのかを切り分けられます。このようにして、どこに問題があるのかを絞っていきます。


    ★良い回答には質問者は回答済みマークを、閲覧者は投票を!

    2018年3月14日 9:00
    モデレータ
  • データテーブルの中身をDatasetビジュアライザーで確認すると一番最後に追加した行(一番下の行)が表示されていませんでした。

    アプリケーション上のデータグリッドビューには表示されています。

    ここからどうすればいいでしょうか?

    ちなみにデバッグ自体初めてです。

    2018年3月14日 9:36
  • DataGridView の入力値が確定前の状態であり、該当行がまだ DataTable に追加されていない状態なのでしょう。(Esc キーを押すと、最終行の内容がロールバックされる状態ではありませんか?)

    DataSource として BindingSource 等を用いてバインドしている場合には、BindingSource の EndEdit メソッドを呼び出すことで、現在行の編集が確定されます

    DataSource に DataSet / DataTable / DataView を割り当てている場合には、下記のようにすることも出来ます。

    • 回答としてマーク T.K.Tora 2018年3月14日 13:35
    2018年3月14日 9:50
  • 入力値が確定前の状態であることが原因であろうことがわかりましたが提示して頂いたリンク先を見てもよくわかりませんでした。(汗

    Dim database_DataView As DataView = database.DataSource

    上記のコードでデータソースはdatabase_DataViewになっているはずですがどうすればいいでしょうか?

    2018年3月14日 10:27
  • 新規行の選択を行う処理をいれることでDataTableに最後の行が追加され、無事に考えていたプログラムになりました。

    回答して頂いたみなさん、ありがとうございました。

    2018年3月14日 13:40
  • 質問者さんの抱えている課題に対する回答は魔界の仮面弁士さんの投稿かもしれませんが、質問文に対する回答ではありませんよね? (もちろん有意義な回答であることには変わりませんが。)
    # 後日、第三者がこのスレッドを閲覧することを想像していただけたらと思います。
    2018年3月14日 13:54