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

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

ただいまの
回答率

88.58%

C#でExcelで作成されたCSVファイルを読みこみ、配列に格納したいです。

解決済

回答 5

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 1,600

keion327

score 12

C#を始めて1か月も経たない初心者です。初質問で緊張しています。

C#でExcelで作成された"Item.csv"というファイルを読み込み、配列に格納するプログラムをご教授頂きたいです。

また、Excelで作成されたCSVファイルを読み込む場合、行全体だけでなく、行列を指定することは可能なのでしょうか?

例えば一番下の行の"A75004M05"を指定し、この文字であれば次のダイアログ画面へ行く。
それ以外なら進めないといった処理を行います。

その際に一番下の行の"A75004M05"を抽出したいです。

初心者プログラマーのため、質問が理解できなかったり、足りない場合は申し訳ないです。

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

エラーメッセージ

 該当のソースコード

 public void ReadCSV1(string [] args)
        {
            var parser = new TextFieldParser(@"Item*.csv", Encoding.GetEncoding("Shift_JIS"));
            using (parser)
            {
                parser.TextFieldType = FieldType.Delimited;
                parser.SetDelimiters(",");

                parser.HasFieldsEnclosedInQuotes = true;

                parser.TrimWhiteSpace = false;
                while (!parser.EndOfData)
                {
                    string[] row = parser.ReadFields();
                    foreach (string field in row)
                    {
                        Console.Write(field + "\t");
                    }
                    Console.WriteLine();
                }
            }
            Console.ReadKey();

        }

 試したこと

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

ここにより詳細な情報を記載してください。

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

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

  • papinianus

    2018/11/07 12:11

    私の回答に寄せられたコメントからすると質問者様にこのファイルを渡しているオヤブンがcsvでないものをexcelに読ませた結果としてcsvになっているのだろうと思います。こんなiniっぽいcsv作る処理をかくなんてまともじゃないと思うので。

    キャンセル

  • papinianus

    2018/11/07 12:20

    当初質問に貼ってたのは、秀丸で開いている、Scan.iniじゃないですよね…みんなiniだって言ってたよね…

    キャンセル

  • Zuishin

    2018/11/07 12:20

    もしかしてコピペ知りませんか? メモ帳でテキストファイル(この場合 CSV)を開いたら、Ctrl+A ですべて選択し、Ctrl+C でクリップボードにコピーします。そして質問を編集し、Ctrl+V で貼り付け、貼り付けたデータをマウスでドラッグして選択し、<code> というボタンを画面から探して押してください。

    キャンセル

回答 5

+2

多分、読み込んだ結果の1項目(例えばrow[1])が"S/N_LEN=11"となっているかと思います。
その位置が固定なのであれば、指定行、指定列の値を"="でsplitするなどで対応できるのではないでしょうか?

String.Splitに関してはこちらを参考にしてみてください。

上記でsplitのほうを紹介しましたが、"="でも分割していいよという話であれば下記のようにデリミタを設定すれば、"S/N_LEN=11"というデータがあった場合、"S/N_LEN"と"11"に分かれるかと

parser.SetDelimiters(new string[]{ "," , "=" });

他の方も言っておられますが、iniファイルとして扱ったほうがよろしいかと思われる内容のファイルだと思います。

 追記

なんとなく考え方の勘違いをされている気がします。
「最後の行の2列目を指定して、CSVファイルを読み込む」
のではなく、
「CSVファイルを全部(処理によっては行ごと)読み込んでから、指定行、指定列のデータを配列等から取り出す」
です。
提示されているソースにて、CSVファイルを1行づつ読み込めますので、1行読み込んだところでrow[1]=="A75004M05"とでも判断すればよろしいかと思います。

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2018/11/07 15:15

    焦らずにゆっくり進めてください。
    コンパイルエラーが出るのであれば、まずはそれを修正することが先かと思います。
    提示ソースの場合、TestDlg.mSettingData4へ代入する部分をコメントアウトしてもrowの配列の中身は確認できるかと思います。
    提示されたCSVですと、row[0]には日時、row[1]には"A75004M05"などの文字列、それ以降はさまざまな数字が格納されるかと思います。

    キャンセル

  • 2018/11/07 15:28

    本当にありがとうございます。

    row[0]やrow[1]はこの状態だと最後の行のみしか格納されていないのでしょうか?

    本当は最初から最後の行まで格納したいです。

    難しいですね。。。

    キャンセル

  • 2018/11/07 15:34

    「C# CSV 読み込み 配列」などで検索して、他の人のコードを参考にしてみてください。
    現状のソースですと、1行読んでrowに格納を繰り返すので、最終的に最後の行の値のみが残るのですが、rowの定義がループ内なので、ループを抜けるとスコープから外れてrow自体がなくなります。

    キャンセル

+1

ここを参考にしたのでしょうか。
年齢が25歳の行のときだけOKとするようにかいてみました。

using System;
using System.Linq;
using System.Text;
using Microsoft.VisualBasic.FileIO;

namespace CsvParser
{
    class Program
    {
        static void Main(string[] args)
        {
            var parser = new TextFieldParser(@"C:\work\test.csv", Encoding.GetEncoding("Shift_JIS"))
            { TextFieldType = FieldType.Delimited, HasFieldsEnclosedInQuotes = true, TrimWhiteSpace = false, Delimiters = new[] { "," } };
            using (parser)
            {
                var header = parser.ReadFields().Select((field, index)=>new { field, index}).ToDictionary(a => a.field, a => a.index);
                // ファイルの終端までループ
                while (!parser.EndOfData)
                {
                    // フィールドを読込
                    string[] row = parser.ReadFields();
                    if(row[header["年齢"]] == "25") { Console.Write("OK"); }
                    Console.WriteLine("←");
                }
            }
            Console.ReadKey();
        }
    }
}

--- iniについて
ライブラリつかってパースはもしかしたら今はつらいのかもしれないので、ご提示の要件からするともう単純にテキスト比較すればいいんじゃないと思い、こういうコードを書いてみました。

using System;
using System.Text;
using System.IO;

namespace CsvParser
{
    class Program
    {
        static void Main(string[] args)
        {
            var txt = File.ReadAllText(@"C:\work\test.ini", Encoding.GetEncoding("shift_jis"));
            if(txt.Contains("S/N_LEN=11")) { return; }
            if(txt.Contains("ShutDown=OFF")) { return; }
//ここから処理を継続すれば、↑のパターンを除外できます
        }
    }
}

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2018/11/07 12:13

    C++は関係ないです。これを新人?である質問者様にcsvで頼むと言っている職場は危険です

    キャンセル

  • 2018/11/07 14:58

    色々とありがとうございました。

    なんとか今頑張っております。

    ちなみに上記の画像の.csvで以下の処理を行った場合、row[]が格納されたTestDlg.mSettingData4[]はそれぞれ何が入っているのでしょうか?(エラー出すぎてデバッグできません)

    public void ReadCSV1(string[] args)
    {

    StringBuilder sb = new StringBuilder(1024);

    var parser = new TextFieldParser(@"Stand_Item.csv", Encoding.GetEncoding("Shift_JIS"));
    using (parser)
    {
    parser.TextFieldType = FieldType.Delimited;
    parser.SetDelimiters(",");

    parser.HasFieldsEnclosedInQuotes = true;

    parser.TrimWhiteSpace = false;
    while (!parser.EndOfData)
    {
    string[] row = parser.ReadFields();

    TestDlg.mSettingData4[0] = row[0];
    TestDlg.mSettingData4[1] = row[1];
    TestDlg.mSettingData4[2] = row[2];
    TestDlg.mSettingData4[3] = row[3];

    for (int n = 0; n < row.Length; n++)
    Console.Write(" ");
    Console.WriteLine(" ");

    }
    }
    Console.ReadKey();
    }

    キャンセル

  • 2018/11/07 15:07

    エラーが出すぎるとは?visual studioですよね?実行時エラーがそんなに出ますか?
    エラーが出ているのであれば、何とも言えません。
    エラーがなければ、Console.ReadKey()の時点で、TextDlg.mSettingData4は、{"2013なんとかかんとか", "A75004M05", "1", "95"}になると推測します。

    無関係なsbとかがありますが、そういう分からないのを手当たり次第入れるのはやめましょう。無関係なヤツの無関係なエラーになんて対処できないでしょう。

    キャンセル

check解決した方法

0

みなさん本当にありがとうございました。

この案件未熟ながら頑張ります。

機会がありましたらまたよろしくお願い致します。

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

0

データ起こししました

,,,,,,,,,,,
S/N_LEN=11,,,,,,,,,,,
DATABase=OFF,,,,,,,,,,,
'''''''''''''''' ImageFolder=\\192.168.200.11\file_share\Scanner_Test,,,,,,,,,,,
ScanWaitTime=2.0,,,,,,,,,,,
ShutDown=Off,,,,,,,,,,,
Operator=Off,,,,,,,,,,,
,,,,,,,,,,,
[TextItem],,,,,,,,,,,
番号,測定項目名,コメント,測定コマンド,,,,,,,,,,,
,,,INIT,1,,,,,,,
,,,WAIT_T,100,,,,,,,
,,,DISP,,,,,,,,
,,,MEAS,BLUR,2,48,1,,,,
using System;
using System.Linq;
using System.Collections.Generic;
using System.Text;
using System.IO;

namespace CsvParser
{
    class Program
    {
        static void Main(string[] args)
        {
            var txt = File.ReadLines(@"C:\work\Item.csv", Encoding.GetEncoding("shift_jis")).ToArray();
            if (IsShutDownOff(txt)) { Console.WriteLine("中断(シャットダウンオフ)"); Console.ReadKey(); return; }
            if (IsSerialNumberLength11(txt)) { Console.WriteLine("中断(S/N_LEN=11)"); Console.ReadKey(); return; }
            var initVal = findNextOfKey(txt, "INIT");
            var waitVal = findNextOfKey(txt, "WAIT_T");
            Console.WriteLine($"INIT = {initVal} , WAIT_T = {waitVal}");
        }
        static bool IsShutDownOff(IEnumerable<string> lines) => lines.Any(line => line.Contains("Shutdown=OFF"));
        static bool IsSerialNumberLength11(IEnumerable<string> lines) => lines.Any(line => line.Contains("S/N_LEN=11"));
        static string firstLineWhichHas(IEnumerable<string> lines, string key) => lines.FirstOrDefault(line => line.Contains(key));
        static string getNextOf(string line, string key) => line?.Split(',').SkipWhile(col => col.Trim().ToLower() != key.ToLower()).ElementAt(1).Trim() ?? string.Empty;
        static string findNextOfKey(IEnumerable<string> lines, string key) => getNextOf(firstLineWhichHas(lines, key), key);
    }
}

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2018/11/07 12:13

    起こしたデータも書いたコードも無になった。

    キャンセル

  • 2018/11/07 14:59

    めちゃくちゃなことして申し訳ありません。

    ちなみに上記の画像の.csvで以下の処理を行った場合、row[]が格納されたTestDlg.mSettingData4[]はそれぞれ何が入っているのでしょうか?(エラー出すぎてデバッグできません)

    public void ReadCSV1(string[] args)
    {

    StringBuilder sb = new StringBuilder(1024);

    var parser = new TextFieldParser(@"Stand_Item.csv", Encoding.GetEncoding("Shift_JIS"));
    using (parser)
    {
    parser.TextFieldType = FieldType.Delimited;
    parser.SetDelimiters(",");

    parser.HasFieldsEnclosedInQuotes = true;

    parser.TrimWhiteSpace = false;
    while (!parser.EndOfData)
    {
    string[] row = parser.ReadFields();

    TestDlg.mSettingData4[0] = row[0];
    TestDlg.mSettingData4[1] = row[1];
    TestDlg.mSettingData4[2] = row[2];
    TestDlg.mSettingData4[3] = row[3];

    for (int n = 0; n < row.Length; n++)
    Console.Write(" ");
    Console.WriteLine(" ");

    }
    }
    Console.ReadKey();
    }

    キャンセル

0

質問欄が長すぎるのでこちらに。

例えば一番下の行の"A75004M05"を指定し、この文字であれば次のダイアログ画面へ行く。
それ以外なら進めないといった処理を行います。
その際に一番下の行の"A75004M05"を抽出したいです。

作りたいものは何ですか?
ダイアログとは何ですか?
ダイアログはnewできますか?
ダイアログにデータを渡すことで要件を満たしますか?
進めないというのはどういう画面処理ですか?
指定するのは誰で、抽出するのは誰ですか?
指定する行為が画面での操作なのであれば、あらかじめ"A75004M05"は決まっているのではないですか?都度抽出するのですか?
一番下の行の左から2列目を抽出すればよいのですか? ←ここに対応したコードを書いてます。

回答欄なんで回答をはっときます
CSVであっても、ヘッダ行がないので、もう2番目、ということ以外の手掛かりはない。

// 一番下
var A75004M05 = File.ReadLines(@"C:\work\Item.csv", Encoding.GetEncoding("shift_jis")).Last().Split(',').ElementAt(1);
//Aなんちゃらが事前にわかっている場合の該当する一行のデータを取得する
var A75004M05Line = File.ReadLines(@"C:\work\Item.csv", Encoding.GetEncoding("shift_jis")).SkipWhile(line => !line.Contains("A75004M05")).ElementAt(0);

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2018/11/07 14:59

    色々とありがとうございました。

    なんとか今頑張っております。

    ちなみに上記の画像の.csvで以下の処理を行った場合、row[]が格納されたTestDlg.mSettingData4[]はそれぞれ何が入っているのでしょうか?(エラー出すぎてデバッグできません)

    public void ReadCSV1(string[] args)
    {

    StringBuilder sb = new StringBuilder(1024);

    var parser = new TextFieldParser(@"Stand_Item.csv", Encoding.GetEncoding("Shift_JIS"));
    using (parser)
    {
    parser.TextFieldType = FieldType.Delimited;
    parser.SetDelimiters(",");

    parser.HasFieldsEnclosedInQuotes = true;

    parser.TrimWhiteSpace = false;
    while (!parser.EndOfData)
    {
    string[] row = parser.ReadFields();

    TestDlg.mSettingData4[0] = row[0];
    TestDlg.mSettingData4[1] = row[1];
    TestDlg.mSettingData4[2] = row[2];
    TestDlg.mSettingData4[3] = row[3];

    for (int n = 0; n < row.Length; n++)
    Console.Write(" ");
    Console.WriteLine(" ");

    }
    }
    Console.ReadKey();
    }

    キャンセル

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

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

関連した質問

同じタグがついた質問を見る