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

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

ただいまの
回答率

90.00%

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

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 2,332

ehyai

score 41

前提・実現したいこと

toconuts C#でExcel CSVの読み込む」というサイトを参考にして、Excel CSVファイルを読み込むシステムを作ろうと考えています。
具体的には、ボタンとテキストボックスが存在するフォームを作り、ボタンを押すとExcel CSVファイルを読み込み、その内容をテキストボックスに書き込むというものを作ろうとしました。

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

しかし、「デバッグなしで開始」をしてみると、途中でエラーが発生してしまい、上手く稼働させることが出来ません。

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

インデックスが配列の境界外です。


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

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


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

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

該当のソースコード

using System.IO;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Microsoft.VisualBasic.FileIO;

namespace (システムの名前)
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
        private void button1_Click(object sender, EventArgs e)
        {
            TextFieldParser parser = new TextFieldParser("sample.csv",System.Text.Encoding.GetEncoding("Shift_JIS"));
            using (parser)
            {
                parser.TextFieldType = FieldType.Delimited;
                parser.SetDelimiters(",");     // デリミタ指定

                // parser.HasFieldsEnclosedInQuotes = false;
                // parser.TrimWhiteSpace = false;

                while (!parser.EndOfData)
                {
                    int n = 0;
                    string[] row = parser.ReadFields(); //今度はこの箇所でエラーが発生するようになりました
                    foreach (string field in row)
                    {
                        // 各処理
                        textBox1.Text += field[n]; //以前エラーが発生した箇所
                        n++;
                    }
                    textBox1.Text += "\r\n";
                }
                parser.Close();
            }
        }
    }
}
  • 気になる質問をクリップする

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • SurferOnWww

    2017/07/12 07:33

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

    キャンセル

  • ehyai

    2017/07/12 10:26

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

    キャンセル

回答 2

checkベストアンサー

+1

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

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

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/07/12 11:45

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

    キャンセル

  • 2017/07/12 11:56

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

    キャンセル

  • 2017/07/12 15:04

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

    キャンセル

+1

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

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

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

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

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

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

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/07/13 01:46

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

    キャンセル

  • 2017/07/13 09:41 編集

    質問者さんの理解うんぬんというより、問題の原因を把握して、それをきちんと取り除いておくことをお勧めしています。「原因不明だけどとりあえず直ったみたいだから 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 と理解されます。

    キャンセル

  • 2017/07/14 02:38

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

    キャンセル

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

  • ただいまの回答率 90.00%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる