前提・実現したいこと
DataGridViewにOpenDialogで選択したCSVファイルを表示させたい。
ここに質問の内容を詳しく書いてください。
WindowsFormsを使ってOpenDialogで選択したCSVファイルをDataGridViewを表示させたい。
■■な機能を実装中に以下のエラーメッセージが発生しました。
発生している問題・エラーメッセージ
エラー文
Microsoft.VisualBasic.FileIO.MalformedLineException: '現在の区切り記号を使用して、行 5 を解析できません。'
C#エラー場所
1while (!parser.EndOfData) 2 { 3 data = parser.ReadFields(); 4 int fieldCount = data.Length; 5 DataRow row = dt.NewRow(); 6 for (int i = 0; i < fieldCount; i++) 7 { 8 row[i] = data[i]; 9 } 10 dt.Rows.Add(row); 11 }
該当のソースコード
C#
1using System; 2using System.Collections.Generic; 3using System.ComponentModel; 4using System.Data; 5using System.Drawing; 6using System.Linq; 7using System.Text; 8using System.Threading.Tasks; 9using System.Windows.Forms; 10using System.IO; 11using Microsoft.VisualBasic.FileIO; 12 13namespace WIN課題7 14{ 15 public partial class Form1 : Form 16 { 17 DataTable dt = new DataTable(); 18 19 public Form1() 20 { 21 InitializeComponent(); 22 } 23 24 25 private void ReadCSV(DataTable dt, bool hasHeader, string FileName) 26 { 27 //CSVを便利に読み込んでくれるTextFieldParserを使います。 28 TextFieldParser parser = new TextFieldParser(FileName, Encoding.GetEncoding("shift_jis")); 29 //これは可変長のフィールドでフィールドの区切りのマーカーが使われている場合です。 30 //フィールドが固定長の場合は 31 //parser.TextFieldType = FieldType.FixedWidth; 32 parser.TextFieldType = FieldType.Delimited; 33 34 string[] data; 35 //ここのif文では、DataTableに必要なカラムを追加するために最初に1行だけ読み込んでいます。 36 //データがあるか確認します。 37 if (!parser.EndOfData) 38 { 39 //CSVファイルから1行読み取ります。 40 data = parser.ReadFields(); 41 //カラムの数を取得します。 42 int cols = data.Length; 43 if (hasHeader) 44 { 45 for (int i = 0; i < cols; i++) 46 { 47 dt.Columns.Add(new DataColumn(data[i])); 48 } 49 } 50 else 51 { 52 for (int i = 0; i < cols; i++) 53 { 54 //カラム名にダミーを設定します。 55 dt.Columns.Add(new DataColumn()); 56 } 57 //DataTableに追加するための新規行を取得します。 58 DataRow row = dt.NewRow(); 59 for (int i = 0; i < cols; i++) 60 { 61 //カラムの数だけデータをうつします。 62 row[i] = data[i]; 63 } 64 //DataTableに追加します。 65 dt.Rows.Add(row); 66 } 67 } 68 //ここのループがCSVを読み込むメインの処理です。 69 //内容は先ほどとほとんど一緒です。 70 while (!parser.EndOfData) 71 { 72 data = parser.ReadFields(); 73 DataRow row = dt.NewRow(); 74 for (int i = 0; i < dt.Columns.Count; i++) 75 { 76 row[i] = data[i]; 77 } 78 dt.Rows.Add(row); 79 } 80 } 81 82 83 84 private void button1_Click(object sender, EventArgs e) 85 { 86 //OpenFileDialogクラスのインスタンスを作成 87 OpenFileDialog ofd = new OpenFileDialog(); 88 89 //はじめのファイル名を指定する 90 //はじめに「ファイル名」で表示される文字列を指定する 91 ofd.FileName = "default"; 92 //はじめに表示されるフォルダを指定する 93 //指定しない(空の文字列)の時は、現在のディレクトリが表示される 94 ofd.InitialDirectory = @"C:\"; 95 //[ファイルの種類]に表示される選択肢を指定する 96 //指定しないとすべてのファイルが表示される 97 ofd.Filter = "CSVファイル(*.csv;*.csv)|*.html;*.htm|すべてのファイル(*.*)|*.*"; 98 //[ファイルの種類]ではじめに選択されるものを指定する 99 //2番目の「すべてのファイル」が選択されているようにする 100 ofd.FilterIndex = 2; 101 //タイトルを設定する 102 ofd.Title = "開くファイルを選択してください"; 103 //ダイアログボックスを閉じる前に現在のディレクトリを復元するようにする 104 ofd.RestoreDirectory = true; 105 //存在しないファイルの名前が指定されたとき警告を表示する 106 //デフォルトでTrueなので指定する必要はない 107 ofd.CheckFileExists = true; 108 //存在しないパスが指定されたとき警告を表示する 109 //デフォルトでTrueなので指定する必要はない 110 ofd.CheckPathExists = true; 111 //ダイアログを表示する 112 if (ofd.ShowDialog() == DialogResult.OK) 113 { 114 115 ReadCSV(this.dt, true, ofd.FileName); 116 this.dataGridView1.DataSource = this.dt; 117 Console.WriteLine(ofd.FileName); 118 } 119 MessageBox.Show("CSVデータの読込みが完了しました。"); 120 121 122 123 } 124 125 private void textBox1_TextChanged(object sender, EventArgs e) 126 { 127 128 } 129 private void Form1_Load(object sender, EventArgs e) 130 { 131 132 } 133 134 135 private void dataGridView1_CellContentClick(object sender, DataGridViewCellEventArgs e) 136 { 137 138 } 139 } 140}
試したこと
ここに問題に対して試したことを記載してください。
Console.WriteLine(odf.FileName);
でOpenDialogからファイルの受け渡しが出来ているのは出来ているのでReadCSVが未完成状態が原因だと考えています。
補足情報(FW/ツールのバージョンなど)
visual studio2019
↑現在の状況
###
↑完成形
↑CSVの中身
ここにより詳細な情報を記載してください。
追記ーーーーーーーーーーー
SurferOnWww様回答ありがとうございます。参考サイトをみて変更してみたのですが、DataGridViewには何も表示されませんでした。自分で原因はここだろうと絞り込んで見たのですが、私の考えとしましてはこれは、""や,の含まれている処理が機能できていないため、何も返ってこないと考えております。CSVの中身も記載しておきます。
C#
1問題点 2private void ReadCSV(DataTable dt, bool hasHeader, string FileName, string separator, bool quote) 3 { 4 //CSVを便利に読み込んでくれるTextFieldParserを使います。 5 TextFieldParser parser = new TextFieldParser(FileName, Encoding.GetEncoding("shift_jis")); 6 Console.WriteLine("OK"); 7 //これは可変長のフィールドでフィールドの区切りのマーカーが使われている場合です。 8 //フィールドが固定長の場合は 9 //parser.TextFieldType = FieldType.FixedWidth; 10 parser.TextFieldType = FieldType.Delimited; 11 parser.Delimiters = new string[] { "," }; 12 // 空白文字をトリム 13 parser.TrimWhiteSpace = true; 14 parser.HasFieldsEnclosedInQuotes = true; 15 Console.WriteLine("OK!"); 16 string[] data; 17 //ここのif文では、DataTableに必要なカラムを追加するために最初に1行だけ読み込んでいます。 18 //データがあるか確認します。 19 if (!parser.EndOfData) 20 { 21 //CSVファイルから1行読み取ります。 22 data = parser.ReadFields(); 23 //カラムの数を取得します。 24 int cols = data.Length; 25 if (hasHeader) 26 { 27 for (int i = 0; i < cols; i++) 28 { 29 dt.Columns.Add(new DataColumn(data[i])); 30 } 31 } 32 else 33 { 34 for (int i = 0; i < cols; i++) 35 { 36 //カラム名にダミーを設定します。 37 dt.Columns.Add(new DataColumn()); 38 } 39 //DataTableに追加するための新規行を取得します。 40 DataRow row = dt.NewRow(); 41 for (int i = 0; i < cols; i++) 42 { 43 //カラムの数だけデータをうつします。 44 row[i] = data[i]; 45 } 46 //DataTableに追加します。 47 dt.Rows.Add(row); 48 } 49 } 50 Console.WriteLine("ここまで"); 51 //ここのループがCSVを読み込むメインの処理です。 52 //内容は先ほどとほとんど一緒です。 53 ↓ここからが原因だと考えます。 54 while (!parser.EndOfData) 55 { 56 data = parser.ReadFields();←エラー 57 int fieldCount = data.Length; 58 DataRow row = dt.NewRow(); 59 for (int i = 0; i < fieldCount; i++) 60 { 61 row[i] = data[i]; 62 } 63 dt.Rows.Add(row); 64 } 65 }
回答1件
あなたの回答
tips
プレビュー