忍者ブログ

VB.NET-TIPS などプログラミングについて

VB.NETのTIPS(小技集)を中心に、Javascript、PHP その他のプログラミングについて少し役に立つ情報を発信します。いわゆる個人的な忘備録ですが、みなさんのお役に立てれば幸いです。

DataGridView からCSVファイルへの書込について

以前の記事でCSVファイルに書込む処理を紹介しましたが、 今回はその関数を利用して DataGridViw コントロールからCSVファイルへのデータ書込みを行います。
CSVファイルの書込について      :[System.IO.StreamWriter]

DataGridViw から WriteCsv:CSVファイル書込処理 に指示する文字列配列を作成し、ファイル書込みを行います。 DataGridViw の列ヘッダーからCSVの先頭行のヘッダーデータを取得します。 更に DataGridViw の各行データから、その行のセルデータから文字列配列を作成します。

最初フォームに DataGridView コントロールを配置すると AllowUserToAddRows プロパティが True なので、 DataGridView の最後の行に新規行(*行)が表示される様になります。 (この設定のままで、どんどん新規のデータを入力できます。)

この新規行は何も入力がされていない状態ですので、 CSVファイルにはデータとして登録しない様に DataGridView の行の IsNewRow プロパティが True の場合には 処理しない様にしています。

尚、以下の例ではフォームロードイベント処理で DataGridView の列数を5個として生成を行っています。

DataGridView からCSVファイルへの書込

Public Class frmDGV2CSV

    ' フォームロード時処理
    Private Sub frmDGV2CSV_Load(sender As Object, e As EventArgs) Handles Me.Load
        Try
            'DataGridView列数を5に固定
            Dim arrColName() As String = {"COL1", "COL2", "COL3", "COL4", "COL5"}
            For Each strName As String In arrColName
                Me.dgv.Columns.Add(strName, strName)
            Next
        Catch ex As Exception
            'エラー
            MsgBox(ex.Message)
        End Try
    End Sub

    ' [WriteCSV From DataGridView]ボタンクリック処理
    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        Try
            'DataGridViewからCSVファイルへの書込処理の呼出
            If WriteCsvFromDGV(Me.dgv, "testw.csv") = True Then
                MsgBox("CSVファイル書込・正常")
            Else
                MsgBox("CSVファイル書込・エラー")
            End If

        Catch ex As Exception
            'エラー
            MsgBox(ex.Message)
        End Try
    End Sub

    ''' -----------------------------------------------------------------------------
    ''' <summary>
    ''' DataGridViewからCSVファイルへの書込処理
    ''' (WriteCsv:CSVファイルの書込処理の利用による)
    ''' </summary>
    ''' <param name="dgv">DataGridView</param>
    ''' <param name="astrFileName">ファイル名</param>
    ''' -----------------------------------------------------------------------------
    Private Function WriteCsvFromDGV(ByVal dgv As DataGridView,
                                     ByVal astrFileName As String) As Boolean
        WriteCsvFromDGV = False
        Try
            'DataGridView全体のデータ領域
            Dim arrData()() As String = Nothing

            '1行分を読込
            Dim arrHead As String() = Nothing
            '列ヘッダの名称取得
            For col As Integer = 0 To Me.dgv.Columns.Count - 1
                '1列分の領域拡張
                ReDim Preserve arrHead(col)
                '列のヘッダデータ退避
                arrHead(col) = CStr(Me.dgv.Columns(col).HeaderCell.Value)
            Next
            '1行分の領域拡張
            ReDim Preserve arrData(0)
            '列ヘッダ名退避
            arrData(0) = arrHead

            'データ行数分の処理
            For row As Integer = 0 To Me.dgv.Rows.Count - 1
                '新規行は処理しない
                If Me.dgv.Rows(row).IsNewRow Then
                    Continue For
                End If

                '1行分を読込
                Dim arrLine As String() = Nothing
                '列数分の処理
                For col As Integer = 0 To Me.dgv.Columns.Count - 1
                    '1列分の領域拡張
                    ReDim Preserve arrLine(col)
                    '列データ退避
                    arrLine(col) = CStr(Me.dgv.Rows(row).Cells(col).Value)
                Next

                '1行分の領域拡張
                ReDim Preserve arrData(row + 1)
                '1行データ退避
                arrData(row + 1) = arrLine
            Next

            '実際のCSVファイルの書込み
            Return WriteCsv(astrFileName, arrData)

        Catch ex As Exception
            'エラー
            MsgBox(ex.Message)
        End Try
    End Function

    ''' -----------------------------------------------------------------------------
    ''' <summary>
    ''' CSVファイルの書込処理
    ''' </summary>
    ''' <param name="astrFileName">ファイル名</param>
    ''' <param name="aarrData">書込データ文字列の2次元配列</param>
    ''' <returns>True:結果OK, False:NG</returns>
    ''' <remarks>カラム名をファイルに出力したい場合は、書込データの先頭に設定すること</remarks>
    ''' -----------------------------------------------------------------------------
    Private Function WriteCsv(ByVal astrFileName As String,
                              ByVal aarrData As String()()) As Boolean
        WriteCsv = False
        'ファイルStreamWriter
        Dim sw As System.IO.StreamWriter = Nothing

        Try
            'CSVファイルに書込に使うEncoding
            Dim enc As System.Text.Encoding = System.Text.Encoding.GetEncoding("Shift_JIS")
            '書き込むファイルを開く
            sw = New System.IO.StreamWriter(astrFileName, False, enc)

            For Each arrLine() As String In aarrData
                Dim blnFirst As Boolean = True
                Dim strLIne As String = ""
                For Each str As String In arrLine
                    If blnFirst = False Then
                        '「,」(カンマ)の書込
                        sw.Write(",")
                    End If
                    blnFirst = False
                    '1カラムデータの書込
                    str = """" & str & """"
                    sw.Write(str)
                Next
                '改行の書込
                sw.Write(vbCrLf)
            Next

            '正常終了
            Return True

        Catch ex As Exception
            'エラー
            MsgBox(ex.Message)
        Finally
            '閉じる
            If sw IsNot Nothing Then
                sw.Close()
            End If
        End Try
    End Function

End Class


DataGridView にデータを入力したところのフォームの表示は以下の様になります。


[WriteCSV From DataGridView] ボタンを押下すると以下の様なCSVファイルが書き込まれます。

CSVファイルの内容

"COL1","COL2","COL3","COL4","COL5"
"111","22222","33333","4444","55555"
"aaa","bbb","cccccc","ddd","ee"
"AAA","22","CCCCC","DDDD","EEE"

関連する記事

CSVファイルの読込について      :[Microsoft.VisualBasic.FileIO.TextFieldParser]
CSVファイルの書込について      :[System.IO.StreamWriter]
CSVファイルの DataGridView への読込について











PR

コメント

1. Conversion from type 'DBNull' to type 'Integer' is not valid エラーが出てきます

このコードを参考にさせていただいておりますが
表題の通りエラーが出てきます。

項目にnullが入っているからだと思いますが
対応をどうしたらいいのか・・・というところが分からずコメントさせていただきました。
すみませんがご教授お願いいたします

2. 無題

ご訪問有難うございます。
こちらで、PGを動作テストしましたが、ご連絡のエラーが再現できません。
エラーが発生した個所を教えて頂けないでしょうか。

なお、こちらはVS2012でテストしています。

3. 無題

返信ありがとうございます。
VS2022です。

WriteCsvFromDGV内

For col As Integer = 0 To dgv.Columns.Count - 1
'1列分の領域拡張
ReDim Preserve arrLine(col)
'列データ退避
arrLine(col) = CStr(dgv.Rows(row).Cells(col).Value)
Next
のあたりかと思います
grid内の項目にnullが存在しているので、そこでエラーが出ているのかと思います
すみません・・よろしくお願いいたします

4. 無題

私の環境ではエラーが再現できないのですが、どの様にすればDBNULLのデータを入力できるのでしょうか?

なお、便宜的ですが、エラーが発生するであろう所にTRY…Catchを以下の様にいれてみては如何でしょうか?
Try
arrLine(col) = CStr(Me.dgv.Rows(row).Cells(col).Value)
Catch ex As Exception
arrLine(col) = ""
End Try

以上、よろしくお願い致します。

5. 無題

返信ありがとうございます。
VS2022です。

WriteCsvFromDGV内

For col As Integer = 0 To dgv.Columns.Count - 1
'1列分の領域拡張
ReDim Preserve arrLine(col)
'列データ退避
arrLine(col) = CStr(dgv.Rows(row).Cells(col).Value)
Next
のあたりかと思います
grid内の項目にnullが存在しているので、そこでエラーが出ているのかと思います
すみません・・よろしくお願いいたします

6. 無題

DBNULLというか

例えば住所で
住所1、住所2、住所3とあり
住所1:東京都〇〇区
住所2:1-1-1
住所3:ビル名
などという設定をしていた時にビル名は入らないこともあります。
そういうときは項目がカラ(null)になることもあるかと思いますが・・・?

これをdbnullと呼ばないのであればすみません、勉強不足ですので勉強してまいります

7. 無題

DBNULLというか

例えば住所で
住所1、住所2、住所3とあり
住所1:東京都〇〇区
住所2:1-1-1
住所3:ビル名
などという設定をしていた時にビル名は入らないこともあります。
そういうときは項目がカラ(null)になることもあるかと思いますが・・・?

これをdbnullと呼ばないのであればすみません、勉強不足ですので勉強してまいります

8. 無題

プログラムですが、ここの記事のソースをそのままではないということでしょうか?
ここのソースを元に改編されている様でしたら、ソースをみないと何とも言えませんが。
もし、該当する部分のソースを開示可能であれば、ここにのせて頂ければ、お答えできるかもしれません。

以上、よろしくお願い致します。

9. 無題

DBは会社のDBを利用しています。

活用させていただいているのは、以下のサブルーチン以下になります
Private Function WriteCsvFromDGV(ByVal dgv As DataGridView,ByVal astrFileName As String) As Boolean

エラーが出ているところ以下の部分で
'列データ退避
arrLine(col) = CStr(dgv.Rows(row).Cells(col).Value)


Len(dgv.Rows(row).Cells(col).Value)で調べると
typemissmatch
で落ちるようでした。
nullの場合は0が返ってきていたのですがエラーの場合は上記のタイプミスマッチとなります
これは変換方法を変える必要があるのでしょうか?
全ての型を一文で処理するのは難しい気がしていますが・・・。
accessならNZ関数みたいなのがあるようですが、VBだとこういう処理は無いことになりますか・・・?

すみません、いろいろお手間をおかけしてしまっています。
よろしくお願いいたします

10. 無題

arrLine(col) = CStr(dgv.Rows(row).Cells(col).Value)

ここを以下の様にしてはどうでしょうか?

If IsDBNull(Me.dgv.Rows(row).Cells(col).Value) = True Then
arrLine(col) = ""
Else
arrLine(col) = CStr(Me.dgv.Rows(row).Cells(col).Value)
End If

11. 無題

対応ありがとうございます!!!

無事に出力出来ました。
詳細確認しておきます

ありがとうございました!

12. 無題

そうですか。上手くいって何よりです。
では、失礼致します。
コメントを書く