朧の.Netの足跡
問合せ先:support@oborodukiyo.info サイト内検索はこちら
基本 CSVファイルをDataTableに読み込んで表示する





ここではCSVファイルをDataTableに読み込んで、DataGridViewに表示するサンプルを紹介します。
CSVデータの解析はTextFieldParserクラスを利用しています。
フォームにはコンボボックスが3つあり、区切り文字、クォーテーション、ファイルのエンコーディングをそれぞれ選択でき、CSVファイルにヘッダーがあるかどうかを指定できます。
DataTableのデータをCSVファイルに保存するサンプルはDataTableをCSVにして保存を参考にしてみてください。
こちらも参考にしてみてください。
Visual Studio 2008版の解説

(注)TextFieldParserクラスは何も書かれてない行があるとそこは飛ばして結果に表示されない動きをします。
多くの方はこれは好ましくない動作であると捉えているようですが私は悪い動作だとは思いません。
例えば最後のデータがある行でそれと同じ行にEOFがない場合、つまり最後の行がEOFだけの行があった場合、現在の動作であれば空のデータが表示されないので良い動作だと思います。
もし空行を飛ばさない場合はこの場合においては空のデータが最後に表示されてしまいます。
空のデータが必要ならば、きちんとそのCSVのフォーマットに沿った空データを挿入するのが良いと思います。

Form1.Designer.csの一部

        /// 
        /// デザイナー サポートに必要なメソッドです。このメソッドの内容を
        /// コード エディターで変更しないでください。
        /// >
        private void InitializeComponent()
        {
            this.panel1 = new System.Windows.Forms.Panel();
            this.cmbEncoding = new System.Windows.Forms.ComboBox();
            this.ckOutputColumnName = new System.Windows.Forms.CheckBox();
            this.btnOpen = new System.Windows.Forms.Button();
            this.cmbSeparator = new System.Windows.Forms.ComboBox();
            this.cmbQuote = new System.Windows.Forms.ComboBox();
            this.dataGridView1 = new System.Windows.Forms.DataGridView();
            this.openFileDialog1 = new System.Windows.Forms.OpenFileDialog();
            this.btnSave = new System.Windows.Forms.Button();
            this.saveFileDialog1 = new System.Windows.Forms.SaveFileDialog();
            this.panel1.SuspendLayout();
            ((System.ComponentModel.ISupportInitialize)(this.dataGridView1)).BeginInit();
            this.SuspendLayout();
            // 
            // panel1
            // 
            this.panel1.Controls.Add(this.btnSave);
            this.panel1.Controls.Add(this.cmbEncoding);
            this.panel1.Controls.Add(this.ckOutputColumnName);
            this.panel1.Controls.Add(this.btnOpen);
            this.panel1.Controls.Add(this.cmbSeparator);
            this.panel1.Controls.Add(this.cmbQuote);
            this.panel1.Dock = System.Windows.Forms.DockStyle.Top;
            this.panel1.Location = new System.Drawing.Point(0, 0);
            this.panel1.Name = "panel1";
            this.panel1.Size = new System.Drawing.Size(745, 42);
            this.panel1.TabIndex = 0;
            // 
            // cmbEncoding
            // 
            this.cmbEncoding.FormattingEnabled = true;
            this.cmbEncoding.Items.AddRange(new object[] {
            "SHIFT_JIS",
            "UTF-8",
            "EUC-JP"});
            this.cmbEncoding.Location = new System.Drawing.Point(330, 13);
            this.cmbEncoding.Name = "cmbEncoding";
            this.cmbEncoding.Size = new System.Drawing.Size(121, 20);
            this.cmbEncoding.TabIndex = 4;
            // 
            // ckOutputColumnName
            // 
            this.ckOutputColumnName.AutoSize = true;
            this.ckOutputColumnName.Location = new System.Drawing.Point(475, 14);
            this.ckOutputColumnName.Name = "ckOutputColumnName";
            this.ckOutputColumnName.Size = new System.Drawing.Size(66, 16);
            this.ckOutputColumnName.TabIndex = 3;
            this.ckOutputColumnName.Text = "列名あり";
            this.ckOutputColumnName.UseVisualStyleBackColor = true;
            // 
            // btnOpen
            // 
            this.btnOpen.Location = new System.Drawing.Point(547, 11);
            this.btnOpen.Name = "btnOpen";
            this.btnOpen.Size = new System.Drawing.Size(75, 23);
            this.btnOpen.TabIndex = 2;
            this.btnOpen.Text = "読み込む";
            this.btnOpen.UseVisualStyleBackColor = true;
            this.btnOpen.Click += new System.EventHandler(this.btnOpen_Click);
            // 
            // cmbSeparator
            // 
            this.cmbSeparator.FormattingEnabled = true;
            this.cmbSeparator.Items.AddRange(new object[] {
            "カンマ区切り",
            "タブ区切り",
            "スペース区切り"});
            this.cmbSeparator.Location = new System.Drawing.Point(182, 12);
            this.cmbSeparator.Name = "cmbSeparator";
            this.cmbSeparator.Size = new System.Drawing.Size(121, 20);
            this.cmbSeparator.TabIndex = 1;
            // 
            // cmbQuote
            // 
            this.cmbQuote.FormattingEnabled = true;
            this.cmbQuote.Items.AddRange(new object[] {
            "\"",
            "なし"});
            this.cmbQuote.Location = new System.Drawing.Point(13, 13);
            this.cmbQuote.Name = "cmbQuote";
            this.cmbQuote.Size = new System.Drawing.Size(121, 20);
            this.cmbQuote.TabIndex = 0;
            // 
            // dataGridView1
            // 
            this.dataGridView1.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
            this.dataGridView1.Dock = System.Windows.Forms.DockStyle.Fill;
            this.dataGridView1.Location = new System.Drawing.Point(0, 42);
            this.dataGridView1.Name = "dataGridView1";
            this.dataGridView1.RowTemplate.Height = 21;
            this.dataGridView1.Size = new System.Drawing.Size(745, 297);
            this.dataGridView1.TabIndex = 1;
            // 
            // openFileDialog1
            // 
            this.openFileDialog1.FileName = "openFileDialog1";
            // 
            // btnSave
            // 
            this.btnSave.Location = new System.Drawing.Point(641, 11);
            this.btnSave.Name = "btnSave";
            this.btnSave.Size = new System.Drawing.Size(75, 23);
            this.btnSave.TabIndex = 5;
            this.btnSave.Text = "保存する";
            this.btnSave.UseVisualStyleBackColor = true;
            this.btnSave.Click += new System.EventHandler(this.btnSave_Click);
            // 
            // Form1
            // 
            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.ClientSize = new System.Drawing.Size(745, 339);
            this.Controls.Add(this.dataGridView1);
            this.Controls.Add(this.panel1);
            this.Name = "Form1";
            this.Text = "Form1";
            this.panel1.ResumeLayout(false);
            this.panel1.PerformLayout();
            ((System.ComponentModel.ISupportInitialize)(this.dataGridView1)).EndInit();
            this.ResumeLayout(false);
        }
        
        private System.Windows.Forms.Panel panel1;
        private System.Windows.Forms.ComboBox cmbSeparator;
        private System.Windows.Forms.ComboBox cmbQuote;
        private System.Windows.Forms.Button btnOpen;
        private System.Windows.Forms.DataGridView dataGridView1;
        private System.Windows.Forms.OpenFileDialog openFileDialog1;
        private System.Windows.Forms.CheckBox ckOutputColumnName;
        private System.Windows.Forms.ComboBox cmbEncoding;
        private System.Windows.Forms.Button btnSave;
        private System.Windows.Forms.SaveFileDialog saveFileDialog1;

Form1.cs

        using System.IO;
        //プロジェクトの参照設定でMicrosoft.VisualBasicを設定してください。
        using Microsoft.VisualBasic.FileIO;

        //CSVファイルのデータを保存する変数
        private DataTable _dt = new DataTable();

        //dt:データを入れるDataTable
        //hasHeader:CSVの一行目がカラム名かどうか
        //fileName:ファイル名
        //separator:カラムを分けている文字(,など)
        //quote:カラムを囲んでいる文字("など)
        //ed:CSVファイルのエンコーディング
        private void ReadCSV(DataTable dt, bool hasHeader, string fileName, string separator, bool quote, Encoding ed)
        {
            //CSVを便利に読み込んでくれるTextFieldParserを使います。
            TextFieldParser parser = new TextFieldParser(fileName, ed);
            //これは可変長のフィールドでフィールドの区切りのマーカーが使われている場合です。
            //フィールドが固定長の場合は
            //parser.TextFieldType = FieldType.FixedWidth;
            parser.TextFieldType = FieldType.Delimited;
            //区切り文字を設定します。
            parser.SetDelimiters(separator);
            //クォーテーションがあるかどうか。
            //但しダブルクォーテーションにしか対応していません。シングルクォーテーションは認識しません。
            parser.HasFieldsEnclosedInQuotes = quote;
            string[] data;
            //ここのif文では、DataTableに必要なカラムを追加するために最初に1行だけ読み込んでいます。
            //データがあるか確認します。
            if (!parser.EndOfData)
            {
                //CSVファイルから1行読み取ります。
                data = parser.ReadFields();
                //カラムの数を取得します。
                int cols = data.Length;
                if (hasHeader)
                {
                    for (int i = 0; i < cols; i++)
                    {
                        dt.Columns.Add(new DataColumn(data[i]));
                    }
                }
                else
                {
                    for (int i = 0; i < cols; i++)
                    {
                        //カラム名にダミーを設定します。
                        dt.Columns.Add(new DataColumn());
                    }
                    //DataTableに追加するための新規行を取得します。
                    DataRow row = dt.NewRow();
                    for (int i = 0; i < cols; i++)
                    {
                        //カラムの数だけデータをうつします。
                        row[i] = data[i];
                    }
                    //DataTableに追加します。
                    dt.Rows.Add(row);
                }
            }
            //ここのループがCSVを読み込むメインの処理です。
            //内容は先ほどとほとんど一緒です。
            while (!parser.EndOfData)
            {
                data = parser.ReadFields();
                DataRow row = dt.NewRow();
                for (int i = 0; i < dt.Columns.Count; i++)
                {
                    row[i] = data[i];
                }
                dt.Rows.Add(row);
            }
        }

        private void btnOpen_Click(object sender, EventArgs e)
        {
            bool quote = false;
            string separator = "";
            Encoding ed = null;
            //クォーテーションの設定
            switch (this.cmbQuote.SelectedIndex)
            {
                case 0:
                    //クォーテーションあり
                    quote = true;
                    break;
                case 1:
                    //クォーテーションなし
                    quote = false;
                    break;
            }
            //区切り文字の設定
            switch (this.cmbSeparator.SelectedIndex)
            {
                case 0:
                    //カンマ区切り
                    separator = ",";
                    break;
                case 1:
                    //タブ区切り
                    separator = "\t";
                    break;
                case 2:
                    //スペース区切り
                    separator = " ";
                    break;
            }
            //エンコーディングの設定
            switch (this.cmbEncoding.SelectedIndex)
            {
                case 0:
                    //SHIFT-JIS
                    ed = Encoding.GetEncoding("shift_jis");
                    break;
                case 1:
                    //UTF-8
                    ed = Encoding.GetEncoding("utf-8");
                    break;
                case 2:
                    //EUC-JP
                    ed = Encoding.GetEncoding("euc_jp");
                    break;
            }
            //ファイルの選択
            if (this.openFileDialog1.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                //データのクリア
                this._dt.Columns.Clear();
                this._dt.Clear();
                //CSVの読み込み処理の呼び出し
                ReadCSV(this._dt, this.ckOutputColumnName.Checked, this.openFileDialog1.FileName, separator, quote, ed);
                //CSVデータの表示
                this.dataGridView1.DataSource = this._dt;
            }
        }

    

Form1.vb

'プロジェクトの参照設定でMicrosoft.VisualBasicを設定してください。
Imports Microsoft.VisualBasic.FileIO
Imports System.IO
Imports System.Text
Public Class Form1
    'CSVファイルのデータを保存する変数
    Private _dt As New DataTable()
    'dt:データを入れるDataTable
    'hasHeader:CSVの一行目がカラム名かどうか
    'fileName:ファイル名
    'separator:カラムを分けている文字(,など)
    'quote:カラムを囲んでいる文字("など)
    'ed:CSVファイルのエンコーディング
    Private Sub ReadCSV(ByVal dt As DataTable, ByVal hasHeader As Boolean, ByVal fileName As String, ByVal separator As String, ByVal quote As Boolean, ByVal ed As Encoding)
        'CSVを便利に読み込んでくれるTextFieldParserを使います。
        Dim parser As TextFieldParser = New TextFieldParser(fileName, ed)
        'これは可変長のフィールドでフィールドの区切りのマーカーが使われている場合です。
        'フィールドが固定長の場合は
        'parser.TextFieldType = FieldType.FixedWidth;
        parser.TextFieldType = FieldType.Delimited
        '区切り文字を設定します。
        parser.SetDelimiters(separator)
        'クォーテーションがあるかどうか。
        '但しダブルクォーテーションにしか対応していません。シングルクォーテーションは認識しません。
        parser.HasFieldsEnclosedInQuotes = quote
        Dim data() As String
        'ここのif文では、DataTableに必要なカラムを追加するために最初に1行だけ読み込んでいます。
        'データがあるか確認します。
        If Not parser.EndOfData Then
            'CSVファイルから1行読み取ります。
            data = parser.ReadFields()
            'カラムの数を取得します。
            Dim cols As Integer = data.Length
            If hasHeader Then
                For i As Integer = 0 To cols - 1 Step 1
                    dt.Columns.Add(New DataColumn(data(i)))
                Next i
            Else
                For i As Integer = 0 To cols - 1 Step 1
                    'カラム名にダミーを設定します。
                    dt.Columns.Add(New DataColumn())
                Next i
                'DataTableに追加するための新規行を取得します。
                Dim row As DataRow = dt.NewRow()
                For i As Integer = 0 To cols - 1 Step 1
                    'カラムの数だけデータをうつします。
                    row(i) = data(i)
                Next i
                'DataTableに追加します。
                dt.Rows.Add(row)
            End If
        End If

        'ここのループがCSVを読み込むメインの処理です。
        '内容は先ほどとほとんど一緒です。
        While Not parser.EndOfData
            data = parser.ReadFields()
            Dim row As DataRow = dt.NewRow()
            For i As Integer = 0 To dt.Columns.Count - 1 Step 1
                row(i) = data(i)
            Next i
            dt.Rows.Add(row)
        End While
    End Sub

    Private Sub btnOpen_Click(sender As System.Object, e As System.EventArgs) Handles btnOpen.Click
        Dim quote As Boolean = False
        Dim separator As String = ""
        Dim ed As Encoding = Nothing
        'クォーテーションの設定
        Select Case Me.cmbQuote.SelectedIndex
            Case 0
                'クォーテーションあり
                quote = True
            Case 1
                'クォーテーションなし
                quote = False
        End Select

        '区切り文字の設定
        Select Case Me.cmbSeparator.SelectedIndex
            Case 0
                'カンマ区切り
                separator = ","
            Case 1
                'タブ区切り
                separator = "\t"
            Case 2
                'スペース区切り
                separator = " "
        End Select

        'エンコーディングの設定
        Select Me.cmbEncoding.SelectedIndex
            Case 0
                'SHIFT-JIS
                ed = Encoding.GetEncoding("shift_jis")
            Case 1
                'UTF-8
                ed = Encoding.GetEncoding("utf-8")
            Case 2
                'EUC-JP
                ed = Encoding.GetEncoding("euc_jp")
        End Select

        'ファイルの選択
        If Me.OpenFileDialog1.ShowDialog() = System.Windows.Forms.DialogResult.OK Then
            'データのクリア
            Me._dt.Columns.Clear()
            Me._dt.Clear()
            'CSVの読み込み処理の呼び出し
            ReadCSV(Me._dt, Me.ckOutputColumnName.Checked, Me.OpenFileDialog1.FileName, separator, quote, ed)
            'CSVデータの表示
            Me.DataGridView1.DataSource = Me._dt
        End If
    End Sub
End Class








良いやや良い普通やや悪い悪い
3 0 1 0 6

投稿日時評価コメント
2023/01/11 普通 エラーですがスタブを生成して解決しました。
2023/01/11 良い this.btnSave_Clickが定義されていないとエラーが出ます どう解決すればよいでしょうか?