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

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

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

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

C#

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

Q&A

解決済

2回答

7955閲覧

C#を用いてExcel CSVファイルを読み込む際のエラーを解決したい

ehyai

総合スコア43

CSV

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

C#

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

0グッド

0クリップ

投稿2017/07/11 17:56

編集2017/07/12 02:19

###前提・実現したいこと
toconuts C#でExcel CSVの読み込む」というサイトを参考にして、Excel CSVファイルを読み込むシステムを作ろうと考えています。
具体的には、ボタンとテキストボックスが存在するフォームを作り、ボタンを押すとExcel CSVファイルを読み込み、その内容をテキストボックスに書き込むというものを作ろうとしました。
###発生している問題・エラーメッセージ
しかし、「デバッグなしで開始」をしてみると、途中でエラーが発生してしまい、上手く稼働させることが出来ません。

アプリケーションのコンポーネントで、ハンドルされていない例外が発生しました。 [続行]をクリックすると、アプリケーションはこのエラーを無視し、続行しようとします。 [終了]をクリックすると、アプリケーションは直ちに終了します。 インデックスが配列の境界外です。

今度は「デバッグの開始」をしてみると、このようなエラーが出ました。

IndexOutOfRangeExceptionはハンドルされませんでした。 型'System.IndexOutOfRangeException'のハンドルされていない例外が(システムの名前.exe)で発生しました

このエラーの解決方法やアドバイス等を教えていただけたらと思いますので、よろしくお願いします。

ちなみに、C:~~\(システムの名前)\bin\Debugのところに読み込みたいExcel CSVファイルであるsample.csvを置いています
以下の画像がそのCSVファイルの内容です。
イメージ説明

###該当のソースコード

C#

1using System.IO; 2using System; 3using System.Collections.Generic; 4using System.ComponentModel; 5using System.Data; 6using System.Drawing; 7using System.Linq; 8using System.Text; 9using System.Threading.Tasks; 10using System.Windows.Forms; 11using Microsoft.VisualBasic.FileIO; 12 13namespace (システムの名前) 14{ 15 public partial class Form1 : Form 16 { 17 public Form1() 18 { 19 InitializeComponent(); 20 } 21 private void button1_Click(object sender, EventArgs e) 22 { 23 TextFieldParser parser = new TextFieldParser("sample.csv",System.Text.Encoding.GetEncoding("Shift_JIS")); 24 using (parser) 25 { 26 parser.TextFieldType = FieldType.Delimited; 27 parser.SetDelimiters(","); // デリミタ指定 28 29 // parser.HasFieldsEnclosedInQuotes = false; 30 // parser.TrimWhiteSpace = false; 31 32 while (!parser.EndOfData) 33 { 34 int n = 0; 35 string[] row = parser.ReadFields(); //今度はこの箇所でエラーが発生するようになりました 36 foreach (string field in row) 37 { 38 // 各処理 39 textBox1.Text += field[n]; //以前エラーが発生した箇所 40 n++; 41 } 42 textBox1.Text += "\r\n"; 43 } 44 parser.Close(); 45 } 46 } 47 } 48}

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

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

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

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

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

退会済みユーザー

退会済みユーザー

2017/07/11 22:33

ソースコードのどの行でそのエラーが出ているか書いてください。
ehyai

2017/07/12 01:26

指摘してくださってありがとうございます。エラーの発生した行を書きました。
guest

回答2

0

ベストアンサー

CSV Text file parser with TextFieldParser - MalformedLineException
参考になりませんか?

parser.HasFieldsEnclosedInQuotes = false;
のコメントを解除してみては?

投稿2017/07/12 02:40

suzu_cat

総合スコア81

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

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

ehyai

2017/07/12 02:45

回答してくださってありがとうございます。コメントを解除するとエラーは発生しなくなりましたが、テキストボックスに「PK・モオLクレb.j""%5エ...」といっためちゃくちゃな文字が表示されてしまいます。
suzu_cat

2017/07/12 02:56

メモ帳で良いのでcsvの文字コードを確認してみて欲しいのですが… 出来れば、Shift_JISで上書きして再度試せませんか?
ehyai

2017/07/12 06:04

suzu_catさんの回答を参考にしてCSVを保存し直したら、テキストボックスの文字化けがなくなり正しく表示されるようになりました。ありがとうございます!!
guest

0

CSV ファイルの一行の各フィールドの文字列を連結して、その結果を textBox1.Text に設定しているように見えますが、それに何か意味があるのかという話は置いておいて・・・

textBox1.Text += field[n]; //この箇所でエラーが発生しました

というところの field[n] に勘違いがあるようです。

field は string[] 型配列の要素(=string 型のオブジェクト)になるはずのので、field[n] は文字列 field の n 番目の要素(Char オブジェクト)になります。

ループのある時点で n が当該 field の文字列の長さを超えたからエラーになったのでしょう。

一行の各フィールドの文字列を連結したいのであれば、field[n] ⇒ field にしたらどうなりますか?

投稿2017/07/12 02:02

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

ehyai

2017/07/12 02:17

回答してくださってありがとうございます。fieldにしてからデバッグの開始を行うと、別の箇所でエラーが発生してしまいました。 「MalformedLineExceptionはハンドルされませんでした。型'Microsoft.VisualBasic.FileIO.MalformedLineException'のハンドルされていない例外が'Microsoft.VisualBasic.dll'で発生しました。 追加情報:現在の区切り記号を使用して、行29を解析できません」と表示されました。
退会済みユーザー

退会済みユーザー

2017/07/12 02:29

「別の個所」ってどこですか? 前にもエラーになる場所を示すようお願いしているのですから、そういう情報はきちんと書いていただきたく。こういう質問をする際の基本のキですので。
ehyai

2017/07/12 02:49

申し訳ありません。 while (!parser.EndOfData)の中のstring[] row = parser.ReadFields();のところです。 エラー自体はsuzu_catさんの指摘してくださったところ(parser.HasFieldsEnclosedInQuotes = false;のコメント解除)を直すと発生しなくなったのですが、テキストボックスにめちゃくちゃな文字が表示されてしまうという問題があります。
退会済みユーザー

退会済みユーザー

2017/07/12 04:23

何か話がおかしいのですが。 string[] row = parser.ReadFields(); は textBox1.Text += field[n]; の前の行にあるのですが?????
ehyai

2017/07/12 06:01

わたしもそこは不思議に思ったのですが、私の予想なのですが、おそらくwhile (!parser.EndOfData)で一度ループした後、二度目にstring[] row = parser.ReadFields();を通る時にエラーが起きたのではないかと思います。 このエラーはどうやらCSVを読み込む際の文字化けが原因だったみたいで、解決することができました。 話がややこしくしてしまい、申し訳ありませんでした。
退会済みユーザー

退会済みユーザー

2017/07/12 06:40

> 二度目にstring[] row = parser.ReadFields();を通る時にエラーが起きたのではないかと思います。 うーん、本当にそうなんでしょうかね? 質問者さんが書かれた情報によれば、CSV ファイルの文字は全部 ASCII 文字で、一列目と二列目の違いは各フィールドの文字数だけのように見えますが、それで一度目は OK で二度目が NG ということはないはずなのですが。きちんと原因を究明することをお勧めします。 HasFieldsEnclosedInQuotes プロパティの意味は理解されているでしょうか? TextFieldParser のコンストラクタが CSV ファイルを読むときは、ファイルの先頭の BOM を確認を確認し、BOM がなければ質問者さんが設定した Shift_JIS がエンコーディングとして適用されますが、そこのところは理解されてますか?
ehyai

2017/07/12 16:46

ありがとうございます。まだ理解が足りないところがあると感じたので、もう少し参考にしていたサイトを読んで理解するようにしたいと思います。 HasFieldsEnclosedInQuotes は、ファイルの解析を行うときに引用符で囲まれているかどうかを判断するためのものでありことがわかりました。 BOMに関しては、ファイルの文字コードが「UTF-8」であることを示すものであることは理解できています。BOMがないためにUTF-8ではなくShift_JIS がエンコーディングに使われたという感じで合っているでしょうか。
退会済みユーザー

退会済みユーザー

2017/07/13 02:15 編集

質問者さんの理解うんぬんというより、問題の原因を把握して、それをきちんと取り除いておくことをお勧めしています。「原因不明だけどとりあえず直ったみたいだから OK」ということにすると、根本的な原因が解決されてなくてまた問題に遭遇するということもよくある話ですので(体験談)。 > HasFieldsEnclosedInQuotes は、ファイルの解析を行うときに引用符で囲まれているかどうかを判断するためのものでありことがわかりました。 ちょっと理解が違うかも。ダブルクォートでフィールドの文字列を囲うのは、改行コードやデリミタ(コンマのような区切り文字)がフィールド値の中にある場合の対応です。詳しくは以下の記事の最初の方の「CSV形式とは?」を読んでください。 CSV形式のファイルをDataTableや配列等として取得する http://dobon.net/vb/dotnet/file/readcsvfile.html 今回の質問者さんの CSV ファイルにはそういうケースはないかもしれませんが、一般的に CSV ファイルを扱う場合はそういうケースも多々あるので、HasFieldsEnclosedInQuotes は true にしておくべきと思います。そうしておけば、ダブルクォートのないフィールドもあるフィールドも正しく処置してくれます。 > BOMに関しては、ファイルの文字コードが「UTF-8」であることを示すものであることは理解できています。 ここもちょっと理解が違います。BOM には 3 種類あって、UTF-8 の他に Unicode Little Endian, Unicode Big Endian というのがあります。 メモ帳でテキストファイルを保存するときのことを思い出してください。文字コードにはデフォルトの ANSI (Shift_JIS) の他に、上の 3 つが選択でき、それぞれに該当する BOM が付与されます。 > BOMがないためにUTF-8ではなくShift_JIS がエンコーディングに使われたという感じで合っているでしょうか。 質問者さんの CSV ファイルに BOM がないことは確認されたのでしょうか? であれば、そこの理解は合ってます。 BOM がなければ、質問者さんがコンストラクタの第二引数に指定した Shift_JIS と理解されます。
ehyai

2017/07/13 17:38

まだまだ理解が足りなかったみたいです。今は調べる時間がないのですが、少しずつ確認しておきたいと思います。 HasFieldsEnclosedInQuotesはtrueの方がよいのですね、今後はtrueにするようにします。 何度も私のコメントに答えてくださって、ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問