回答編集履歴

2

追記

2022/05/26 02:28

投稿

退会済みユーザー
test CHANGED
@@ -10,3 +10,143 @@
10
10
  http://surferonwww.info/BlogEngine/post/2020/09/11/show-date-in-csv-file-on-datagridview.aspx
11
11
 
12
12
  紹介した記事には TextFieldParser を使う案と ADO.NET + OelDb + JET を使う案が書いてありますが、CSV ファイルの列が不定ということであれば前者のコードが使えると思います。
13
+
14
+ ---
15
+
16
+ **【追記】**
17
+
18
+ 質問者さんの言う「CVS ファイル」の形式を以下のように(いわゆる一般的に言う CVS 形式に)見直す余地はありませんか?
19
+
20
+ 場所,取引先,商品
21
+ 東京,株式会社A,食品
22
+ ...他の行(もしあれば)...
23
+
24
+ 実績,商品,取引先,場所,実店舗
25
+ あり,文具,株式会社B,大阪,あり
26
+ ...他の行(もしあれば)...
27
+
28
+ 上の形にすることができるなら、それぞれの CSV の DataTable を作ってそれを Merge メソッドで合体する方法を取ることをお勧めします。そうすれば Dictionary がどうのこうのと悩まずに簡単に DataTable が得られます。
29
+
30
+ サンプルを載せておきます。
31
+
32
+ CSV ファイルは以下の通り。(質問者さんのサンプルに一行追加)
33
+
34
+ ![イメージ説明](https://ddjkaamml8q8x.cloudfront.net/questions/2022-05-26/1c491b99-032c-46bd-a25e-fb76a6113857.jpeg)
35
+
36
+ ![イメージ説明](https://ddjkaamml8q8x.cloudfront.net/questions/2022-05-26/06d95227-7fe4-4b6e-95ae-c47b150a6026.jpeg)
37
+
38
+ コードは以下の通り。先に紹介した記事とほぼ同じです。違うのは 2 つの CSV ファイルから 2 つの DataTable を作って、それを Merge してから DataDridView に表示しているところです。
39
+
40
+ ```C#
41
+ using System;
42
+ using System.ComponentModel;
43
+ using System.Data;
44
+ using System.Text;
45
+ using System.Windows.Forms;
46
+ using Microsoft.VisualBasic.FileIO;
47
+
48
+ namespace WindowsFormsApp1
49
+ {
50
+ public partial class Form4 : Form
51
+ {
52
+ private BindingSource bindingSource1;
53
+ private DataTable table;
54
+
55
+ public Form4()
56
+ {
57
+ InitializeComponent();
58
+
59
+ this.components = new Container();
60
+ this.bindingSource1 =
61
+ new BindingSource(this.components);
62
+ this.dataGridView1.DataSource = this.bindingSource1;
63
+ }
64
+
65
+ private void Form4_Load(object sender, EventArgs e)
66
+ {
67
+ // CVS ファイルのパス
68
+ string path1 = @"C:\Users...\CsvData1.csv";
69
+ string path2 = @"C:\Users...\csvData2.csv";
70
+
71
+ // CSV ファイルを読む際の文字エンコーディングを指定
72
+ Encoding encoding = new UTF8Encoding();
73
+
74
+ this.table = CreateDataTable(path1, encoding);
75
+ DataTable table2 = CreateDataTable(path2, encoding);
76
+
77
+ this.table.Merge(table2);
78
+ this.table.AcceptChanges();
79
+
80
+ this.bindingSource1.DataSource = this.table;
81
+ }
82
+
83
+ // ================ 以下ヘルパメソッド ================
84
+
85
+ // TextFieldParser 版
86
+ // 指定されたパスから CSV ファイルを読んできて DataTable
87
+ // を作成。CSV ファイルのカラム数とその型は不定という前提
88
+ // なので、全カラムを string 型として扱わざるを得ない。
89
+ // TextFieldParser は CSV ファイルに BOM が付与されていれ
90
+ // ばそれからエンコーディングを自動判別。BOM 無しの場合は
91
+ // 引数の encoding の指定に従う
92
+ protected DataTable CreateDataTable(string path,
93
+ Encoding encoding)
94
+ {
95
+ // TextFieldParser は Microsoft が提供している Visual
96
+ // Basic .NET 用のクラスライブラリ。C# のアプリでも
97
+ // Microsoft.VisualBasic.dll を参照に追加すれば利用可
98
+ using (TextFieldParser tfp =
99
+ new TextFieldParser(path, encoding))
100
+ {
101
+ //フィールドがデリミタで区切られている
102
+ tfp.TextFieldType = FieldType.Delimited;
103
+
104
+ // デリミタを , とする
105
+ tfp.Delimiters = new string[] { "," };
106
+
107
+ // フィールドを " で囲み、フィールド内に改行文字、
108
+ // デリミタを含めることができるか
109
+ tfp.HasFieldsEnclosedInQuotes = true;
110
+
111
+ // 空白文字をトリム
112
+ tfp.TrimWhiteSpace = true;
113
+
114
+ // CSV ファイルは 1 行目がヘッダであることが条件
115
+ string[] headers = tfp.ReadFields();
116
+ int fieldCount = headers.Length;
117
+
118
+ DataTable dt = new DataTable();
119
+ DataRow dr;
120
+ DataColumn dc;
121
+
122
+ // DataTable の列の設定
123
+ for (int i = 0; i < fieldCount; i++)
124
+ {
125
+ dc = new DataColumn(headers[i], typeof(String));
126
+ dt.Columns.Add(dc);
127
+ }
128
+
129
+ // CSV のデータから DataRow を作り DataTable
130
+ // に追加していく
131
+ while (!tfp.EndOfData)
132
+ {
133
+ string[] fields = tfp.ReadFields();
134
+
135
+ dr = dt.NewRow();
136
+ for (int i = 0; i < fieldCount; i++)
137
+ {
138
+ dr[headers[i]] = fields[i];
139
+ }
140
+ dt.Rows.Add(dr);
141
+ }
142
+
143
+ return dt;
144
+ }
145
+ }
146
+ }
147
+ }
148
+ ```
149
+
150
+ 結果は以下のようになります。
151
+
152
+ ![イメージ説明](https://ddjkaamml8q8x.cloudfront.net/questions/2022-05-26/1db29e66-1d25-446e-9923-21a11dd1267b.jpeg)

1

訂正

2022/05/21 00:32

投稿

退会済みユーザー
test CHANGED
@@ -1,4 +1,4 @@
1
- CSV からカスタムクラスのオブジェクトを作りたいと言うのは手段であって目的ではなく、目的は CSV ファイルの内容をユーザーに表示しユーザーがそれを編集して編集結果を CSV ファイルに書き出すというようなことではなかろうかと想像してます。
1
+ CSV からカスタムクラスのオブジェクトを作りたいと言うのは手段であって目的ではなく、目的は CSV ファイルの内容をユーザーに表示しユーザーがそれを編集して編集結果を CSV ファイルに書き出すというようなことではなかろうかと想像してます。
2
2
 
3
3
  その想像が当たっていれば、CSV ファイルから DataTabe を作成し、それを Windows Forms アプリの DataGridView にバインドして表示してはいかがですか?
4
4