質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
CSV

CSV(Comma-Separated Values)はコンマで区切られた明白なテキスト値のリストです。もしくは、そのフォーマットでひとつ以上のリストを含むファイルを指します。

DataGrid

GUIの一種であり、データを表の形式でみることが可能です。

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

Q&A

解決済

1回答

1713閲覧

DataGridに複数のcsvファイルを並べる

kkg_No_05

総合スコア13

CSV

CSV(Comma-Separated Values)はコンマで区切られた明白なテキスト値のリストです。もしくは、そのフォーマットでひとつ以上のリストを含むファイルを指します。

DataGrid

GUIの一種であり、データを表の形式でみることが可能です。

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

1グッド

0クリップ

投稿2020/02/15 16:57

編集2020/02/16 02:53

前提・実現したいこと

csvファイルをDataGridに下記の様に表示したいです。
各csvファイルは1列目(AAAなど)が共通、2列目(1, 2など)が異なります。
1ファイル目から1列目と2列目、2ファイル目以降は2列目のみを表示し、一覧表示したいです。
(この質問ではファイル・コード共に簡略化しており、実際に扱いたいファイルは1列目が10数文字以上、数十行となります)

Param_001.csvParam_002.csvParam_003.csvParam_004.csvParam_005.csv
AAA,1AAA,2AAA,3AAA,4AAA,5
BBB,11BBB,22BBB,33BBB,44BBB,55
CCC,1.1CCC,2.2CCC,3.3CCC,4.4CCC,5.5
DDD,11.1DDD,22.2DDD,33.3DDD,44.4DDD,55.5

||001|002|003|004|005|
|:--:|:--:|:--:|:--:|:--:|
|AAA|1|2|3|4|5|
|BBB|11|22|33|44|55|
|CCC|1.1|2.2|3.3|4.4|5.5|
|DDD|11.1|22.2|33.3|44.4|55.5|

発生している問題・エラーメッセージ

下記のコードでは、次のように同じ列になってしまいます。
Listの要素に次のファイルの読み込み内容を付け足していきたいのですが、上手くいきません。

|||||
|:--|:--:|:--:|
|AAA|1|||
|BBB|11|||
|CCC|1.1|||
|DDD|11.1|||
|AAA|2|||
|BBB|22|||
|CCC|2.2|||
|DDD|22.2|||
|///|///|||

該当のソースコード

xaml

1<Window x:Class="WpfApp3.MainWindow" 2 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 3 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 4 xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 5 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 6 xmlns:local="clr-namespace:WpfApp3" 7 mc:Ignorable="d" 8 Title="MainWindow" Height="450" Width="800"> 9 <Grid> 10 11 <DataGrid x:Name="DataGrid_CSV" 12 AutoGenerateColumns="False" > 13 <DataGrid.Columns> 14 <DataGridTextColumn Header="Param" 15 Binding="{Binding [0]}" /> 16 <DataGridTextColumn Header="Val_001" 17 Binding="{Binding [1]}" /> 18 <DataGridTextColumn Header="Val_002" 19 Binding="{Binding [2]}" /> 20 <DataGridTextColumn Header="Val_003" 21 Binding="{Binding [3]}" /> 22 <DataGridTextColumn Header="Val_004" 23 Binding="{Binding [4]}" /> 24 <DataGridTextColumn Header="Val_005" 25 Binding="{Binding [5]}" /> 26 </DataGrid.Columns> 27 </DataGrid> 28 </Grid> 29</Window> 30

c#

1using System; 2using System.Collections.Generic; 3using System.IO; 4using System.Text; 5using System.Windows; 6 7namespace WpfApp3 8{ 9 /// <summary> 10 /// MainWindow.xaml の相互作用ロジック 11 /// </summary> 12 public partial class MainWindow : Window 13 { 14 public MainWindow() 15 { 16 InitializeComponent(); 17 18 // ファイル情報を格納するリスト 19 List<string[]> list_file= new List<string[]>(); 20 21 // ファイル1~5の内容を取得する 22 for (int i = 1; i <= 5; i++) 23 { 24 string path_read = @"Param_" + i.ToString("000") + ".csv"; 25 FileRead2(path_read, list_file); 26 } 27 28 // DataGridにリストの内容を表示する 29 DataGrid_CSV.ItemsSource = list_file; 30 } 31 32 33 // ファイル読み込みメソッド 34 public void FileRead2(string path_read, List<string[]> list_file) 35 { 36 try 37 { 38 // エンコードを指定して、csvファイルを開く 39 using (var sr = new StreamReader(path_read, Encoding.GetEncoding("shift_jis"))) 40 { 41 42 // ストリームの末尾まで繰り返す 43 while (!sr.EndOfStream) 44 { 45 // CSVファイルの一行を読み込む 46 string line = sr.ReadLine(); 47 // 読み込んだ一行をカンマ毎に分けて配列に格納する 48 string[] csv_array = line.Split(','); 49 50 // 配列からリストに格納する 51 list_file.Add(csv_array); 52 } 53 } 54 } 55 catch (Exception e) 56 { 57 // ファイルを開くのに失敗したとき 58 //MessageBox.Show(e.Message); 59 } 60 } 61 62 } 63}

試したこと

・2列目のみを取得 してみる
List<string[]> list_file= new List<string[]>(); と list_file.Add(csv_array); を
List<string> list_file= new List<string>(); と list_file.Add(csv_array[1]); に変更して、
2列目を取得しようとしたが、DataGridに表示すると行と列が逆になった。

AAABBBCCCDDD

補足情報(FW/ツールのバージョンなど)

VisualStudio2019

前回
https://teratail.com/questions/241547

TN8001👍を押しています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

YAmaGNZ

2020/02/15 23:09

各CSVのAAA、BBB、CCC~の並びは同じなのですか?
退会済みユーザー

退会済みユーザー

2020/02/16 00:26

質問にある表ではファイルの数は 3 つ、コードでは 5 つのように見えますが、実際どうなってます?
kkg_No_05

2020/02/16 02:36 編集

説明不足で済みません。 各csvファイルは1列目が同じで、2列目の数字がそれぞれ異なる形式になります。 それらを一覧表示したいのです。
guest

回答1

0

ベストアンサー

DataGridは、行をひとつの塊として追加していく作りです(有償のものですと行列を簡単に入れ替えられるものがあるようです)

ですので、

AAABBBCCCDDD
0011111.111.1
0022222.222.2
0033333.333.3

のような形でよければ簡単です(DataGrid_CSV1・NewMethod1 無駄に凝ってしまったので、あんまり簡単に見えませんが^^;


方向にこだわる場合は、List<List<string>>にして列を追加していく感じがいいんじゃないでしょうか(DataGrid_CSV2・NewMethod2)

xml

1<Window 2 x:Class="Questions241581.MainWindow" 3 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 4 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 5 Width="800" 6 Height="450"> 7 <Grid> 8 <Grid.RowDefinitions> 9 <RowDefinition /> 10 <RowDefinition /> 11 </Grid.RowDefinitions> 12 <DataGrid 13 x:Name="DataGrid_CSV1" 14 AutoGenerateColumns="False" 15 HeadersVisibility="All"> 16 <!-- 行ヘッダーにしてみた --> 17 <DataGrid.RowHeaderStyle> 18 <Style TargetType="{x:Type DataGridRowHeader}"> 19 <Setter Property="Content" Value="{Binding [0]}" /> 20 </Style> 21 </DataGrid.RowHeaderStyle> 22 <DataGrid.Columns> 23 <!--<DataGridTextColumn Binding="{Binding [0]}" Header="Param" />--> 24 <DataGridTextColumn Binding="{Binding [1]}" /> 25 <DataGridTextColumn Binding="{Binding [2]}" /> 26 <DataGridTextColumn Binding="{Binding [3]}" /> 27 <DataGridTextColumn Binding="{Binding [4]}" /> 28 <!--<DataGridTextColumn Binding="{Binding [5]}" />--> 29 </DataGrid.Columns> 30 </DataGrid> 31 32 <DataGrid 33 x:Name="DataGrid_CSV2" 34 Grid.Row="1" 35 AutoGenerateColumns="False" 36 HeadersVisibility="All"> 37 <!-- 行ヘッダーにしてみた --> 38 <DataGrid.RowHeaderStyle> 39 <Style TargetType="{x:Type DataGridRowHeader}"> 40 <Setter Property="Content" Value="{Binding [0]}" /> 41 </Style> 42 </DataGrid.RowHeaderStyle> 43 <DataGrid.Columns> 44 <!--<DataGridTextColumn Binding="{Binding [0]}" Header="Param" />--> 45 <DataGridTextColumn Binding="{Binding [1]}" Header="Val_001" /> 46 <DataGridTextColumn Binding="{Binding [2]}" Header="Val_002" /> 47 <DataGridTextColumn Binding="{Binding [3]}" Header="Val_003" /> 48 <DataGridTextColumn Binding="{Binding [4]}" Header="Val_004" /> 49 <DataGridTextColumn Binding="{Binding [5]}" Header="Val_005" /> 50 </DataGrid.Columns> 51 </DataGrid> 52 </Grid> 53</Window>

cs

1using System; 2using System.Collections.Generic; 3using System.Data; 4using System.IO; 5using System.Linq; 6using System.Text; 7using System.Windows; 8 9namespace Questions241581 10{ 11 public partial class MainWindow : Window 12 { 13 public MainWindow() 14 { 15 InitializeComponent(); 16 17 NewMethod1(); 18 NewMethod2(); 19 } 20 21 private void NewMethod1() 22 { 23 List<string[]> all_data = new List<string[]>(); 24 25 for(int i = 1; i <= 5; i++) 26 { 27 string path_read = @"Param_" + i.ToString("000") + ".csv"; 28 29 List<string[]> list_file = new List<string[]>(); 30 31 // 行ヘッダーになる部分("Val001")を先に追加しておく *1 32 list_file.Add(new string[] { "", @"Val" + i.ToString("000") }); 33 FileRead(path_read, list_file); 34 35 // 最初のファイルの時は"AAA"部分を列ヘッダーに設定する 36 if(i == 1) 37 { 38 // list_fileから0番目の要素("AAA"等)を集めて配列にする 39 // *1で""が入ってしまっているのでいっこ飛ばす(Skip(1)) 40 string[] names = list_file.Skip(1).Select(x => x[0]).ToArray(); 41 for(int j = 0; j < names.Length; j++) 42 { 43 // 列ヘッダーはcsvを読むまで決まらないのでここで設定する 44 DataGrid_CSV1.Columns[j].Header = names[j]; 45 } 46 } 47 48 // list_fileから1番目の要素("1"等)を集めて配列にする 49 // *1のおかげで先頭は"Val001"等になっている 50 string[] values = list_file.Select(x => x[1]).ToArray(); 51 all_data.Add(values); 52 } 53 54 DataGrid_CSV1.ItemsSource = all_data; 55 } 56 57 private void NewMethod2() 58 { 59 // List<string>のList 60 // 列を追加していきたいので配列ではなくリストに 61 // 列数がわかっているので配列でもいいのだが、Listのほうがわかりやすそう 62 List<List<string>> all_data = new List<List<string>>(); 63 64 for(int i = 1; i <= 5; i++) 65 { 66 string path_read = @"Param_" + i.ToString("000") + ".csv"; 67 68 List<string[]> list_file = new List<string[]>(); 69 FileRead(path_read, list_file); 70 71 // 最初のファイルの時は内側のList(1行分のデータ)を作成する 72 if(i == 1) 73 { 74 for(int j = 0; j < list_file.Count; j++) 75 { 76 // 内側のListを作成する 77 List<string> row_data = new List<string>(); 78 79 // j行目の0番目 "AAA"等 を内側のListに追加する 80 row_data.Add(list_file[j][0]); 81 82 // 外側のListに内側のListを追加する 83 all_data.Add(row_data); 84 } 85 } 86 87 // 作成済みの内側のListに各数字を追加していく 88 for(int j = 0; j < list_file.Count; j++) 89 { 90 // j行目の1番目 "1"等 を内側のListに追加する 91 all_data[j].Add(list_file[j][1]); 92 } 93 } 94 95 DataGrid_CSV2.ItemsSource = all_data; 96 } 97 98 public void FileRead(string path_read, List<string[]> list_file) 99 { 100 try 101 { 102 using(var sr = new StreamReader(path_read, Encoding.GetEncoding("shift_jis"))) 103 { 104 while(!sr.EndOfStream) 105 { 106 string line = sr.ReadLine(); 107 string[] csv_array = line.Split(','); 108 list_file.Add(csv_array); 109 } 110 } 111 } 112 catch(Exception e) { } 113 } 114 } 115}

AAA,BBB,CCC,DDDは各ファイルに同じ順にあるとする。
各ファイルは同じ行数で、各行には一つ以上のカンマがあるとする。


追記
値の編集をする場合DataTableを使ったほうがお手軽かもしれません。

xml

1<Window 2 x:Class="Questions241581.MainWindow" 3 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 4 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 5 Width="800" 6 Height="450"> 7 <Grid> 8 <Grid.RowDefinitions> 9 <RowDefinition /> 10 <RowDefinition Height="Auto" /> 11 </Grid.RowDefinitions> 12 <DataGrid x:Name="DataGrid_CSV" /> 13 <Button 14 Grid.Row="1" 15 Click="Button_Click" 16 Content="Save" /> 17 </Grid> 18</Window>

cs

1using System; 2using System.Collections.Generic; 3using System.Data; 4using System.IO; 5using System.Linq; 6using System.Text; 7using System.Windows; 8 9namespace Questions241581 10{ 11 public partial class MainWindow : Window 12 { 13 private DataTable table; 14 15 public MainWindow() 16 { 17 InitializeComponent(); 18 19 table = new DataTable(); 20 table.Columns.Add("Param"); 21 table.Columns.Add("Val__001"); 22 table.Columns.Add("Val__002"); 23 table.Columns.Add("Val__003"); 24 table.Columns.Add("Val__004"); 25 table.Columns.Add("Val__005"); 26 27 for(int i = 1; i <= 5; i++) 28 { 29 string path_read = @"Param_" + i.ToString("000") + ".csv"; 30 31 List<string[]> list_file = new List<string[]>(); 32 FileRead(path_read, list_file); 33 34 // 最初のファイルの時はDataRow(1行分のデータ)を作成する 35 if(i == 1) 36 { 37 for(int j = 0; j < list_file.Count; j++) 38 { 39 DataRow row = table.NewRow(); 40 41 // j行目の0番目 "AAA"等 をDataRowに追加する 42 row[0] = list_file[j][0]; 43 table.Rows.Add(row); 44 } 45 } 46 47 // 作成済みのDataRowに各数字を追加していく 48 for(int j = 0; j < list_file.Count; j++) 49 { 50 table.Rows[j][i] = list_file[j][1]; 51 } 52 } 53 54 DataGrid_CSV.ItemsSource = table.DefaultView; 55 } 56 private void Button_Click(object sender, RoutedEventArgs e) 57 { 58 for(int i = 1; i <= 5; i++) 59 { 60 string path_write = @"new_Param_" + i.ToString("000") + ".csv"; 61 62 // 名前と値のペアのリストを作る 63 var list_file = table.AsEnumerable() 64 .Select(x => new object[] { x[0], x[i] }) 65 .ToList(); 66 67 FileWrite(path_write, list_file); 68 } 69 } 70 71 public void FileRead(string path_read, List<string[]> list_file) 72 { 73 try 74 { 75 using(var sr = new StreamReader(path_read, Encoding.GetEncoding("shift_jis"))) 76 { 77 while(!sr.EndOfStream) 78 { 79 string line = sr.ReadLine(); 80 string[] csv_array = line.Split(','); 81 list_file.Add(csv_array); 82 } 83 } 84 } 85 catch(Exception e) { } 86 } 87 88 public void FileWrite(string path_write, List<object[]> list_file) 89 { 90 using(var sw = new StreamWriter(path_write, false, Encoding.GetEncoding("shift_jis"))) 91 { 92 foreach(object[] csv_array in list_file) 93 { 94 sw.WriteLine(string.Join(",", csv_array)); 95 } 96 } 97 } 98 } 99}

投稿2020/02/16 02:37

編集2023/07/20 14:32
TN8001

総合スコア9321

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kkg_No_05

2020/02/16 02:51

ご回答ありがとうございます。 表示の方向は質問に書いた形にしたいのです。というのも、質問のためにファイル・コード共に簡略化しており、実際に扱いたいファイルの1列目は10数文字、項目数も数十個となるため、ご回答いただいた方向だと非常に見づらくなってしまうのです。 List<List<string>>を試みていますが、上手くいっておりません。
TN8001

2020/02/16 02:54

NewMethod2のほうですね? どのようにうまくいかないか、説明していただけますか?
kkg_No_05

2020/02/16 03:38

NewMethod2の方を試していましたが、VisualStudioを再起動したら無事動きました。 NewMethod1の方ですが、 <!--<DataGridTextColumn Binding="{Binding [5]}" />--> がコメントアウトされていたため、 DataGrid_CSV1.Columns[j].Header = names[j]; でインデックス範囲エラーが発生しました。 コメント解除で無事動きました。 ありがとうございました。
kkg_No_05

2020/02/16 06:23 編集

値の編集・保存まで、先回りされてしまいました。(笑) ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問