C# と VB.NET の質問掲示板

わんくま同盟

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

ツリー一括表示

CSV読込時のループ処理中にHEADとDATAを取得する方法 /河童 (18/02/06(Tue) 20:32) #86496
Re[1]: CSV読込時のループ処理中にHEADとDATAを取得する方法 /shu (18/02/07(Wed) 07:36) #86498
│└ Re[2]: CSV読込時のループ処理中にHEADとDATAを取得する方法 /河童 (18/02/07(Wed) 17:30) #86519
Re[1]: CSV読込時のループ処理中にHEADとDATAを取得する方法 /PANG2 (18/02/07(Wed) 19:00) #86521
  └ Re[2]: CSV読込時のループ処理中にHEADとDATAを取得する方法 /河童 (18/02/16(Fri) 16:51) #86581 解決済み


親記事 / ▼[ 86498 ] ▼[ 86521 ]
■86496 / 親階層)  CSV読込時のループ処理中にHEADとDATAを取得する方法
□投稿者/ 河童 (2回)-(2018/02/06(Tue) 20:32:46)

分類:[C#] 

いつも大変お世話になっております。

CSV読込時のループ処理中にHEADとDATAを取得する方法
について教えてください。

★やりたいこと
CSVファイルを行で繰返処理をするとき
1行目(HEAD)に対応する2行目(DATA)の値を取得して
値を結合したいと思っています。

本当は、取得したHEADとDATAを
データベースに登録したいのですが、
とりあえず、値はテキストボックスに表示しています。


★CSVファイル(test.csv)
1行目はヘッダ情報
2行目はデータ
ファイルは必ず2行のみ
カラム数はファイルにより変わるがHEADとDATAのカラム数は同じ
DATAには空白あり

------------------------------------------------------------------------------------------------------
HEAD,担当者,帳票名称,MKAL0110011/S,KAL0110011,MKAL0120021/S,MKAL0390011/S,KAL0390011,MKAL03110031/S
DATA,担当者A,記録表,test1,担当者A,,test2,担当者A,
------------------------------------------------------------------------------------------------------

★現状のテキストボックスの表示結果
MKAL0110011/S,
MKAL0120021/S,
MKAL0390011/S,
MKAL03110031/S,
===
DATA
担当者A
記録表
test1
担当者A

test2
担当者A

===

★希望の結果
MKAL0110011/S,test1
MKAL0120021/S,
MKAL0390011/S,test2
MKAL03110031/S,

★わからないこと
HEADの値が
左端1文字目が「M」または「S」
かつ右端2文字が「/S」のときに対応する
DATAの値を取得する方法がわかりません。
HEADの判定は出来るのですが、
DATAの値をどのように判定すればよいか
教えてください。
よろしくお願いします。


★コード
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using Microsoft.VisualBasic.FileIO;

private void button7_Click(object sender, EventArgs e)
        {
            // CSVファイルの選択
            TextFieldParser parser = new TextFieldParser(@"C:\temp\test.csv", Encoding.GetEncoding("Shift_JIS"));

            parser.TextFieldType = FieldType.Delimited;
            parser.SetDelimiters(",");// ","区切り

            // 行数カウンタ(0:HEAD、1:DATA)
            int cnt = 0;

            // CSVファイルの読込
            while (parser.EndOfData == false) {

                //行セット
                string[] column = parser.ReadFields();

                if (cnt == 0) // HEADの処理
                {
                    //1行分のカラムで繰り返し処理
                    for (int i = 0; i < column.Length; i++)
                    {
                        // 値セット
                        string s = column[i];
                        // 空の文字列
                        if (s == null || s == "")
                        {
                        }
                        else
                        {
                            // 左端から1文字目
                            string s2 = s.Substring(0, 1);
                            // 右端から2文字
                            string s3 = s.Substring(s.Length - 2, 2);
                            // HEAD情報から登録する値を判定
                            if ((s2 == "M" || s2 == "S") && (s3 == "/S"))
                            {
                                textBox999.Text += column[i] + "," + "\r\n";
                                
                            }
                            else
                            {
                            }
                        }

                    }
                }
                else // DADAの処理
                {
                    //1行分のカラムで繰り返し処理
                    for (int i = 0; i < column.Length; i++)
                    {
                        // 値セット
                        string s = column[i];
                        // HEAD情報から登録する値を判定(空の文字列も含める)
                            textBox999.Text += column[i] + "\r\n";
                    }
                }

  
                textBox999.Text += "===\r\n";

                cnt++;
            }
        
        }

[ □ Tree ] 返信 編集キー/

▲[ 86496 ] / ▼[ 86519 ]
■86498 / 1階層)  Re[1]: CSV読込時のループ処理中にHEADとDATAを取得する方法
□投稿者/ shu (1091回)-(2018/02/07(Wed) 07:36:26)
No86496 (河童 さん) に返信

項目情報を格納するクラスを1つ用意して例えばColumnInfoとします。
そのプロパティに必要なものを用意します。

Head行を格納するためのList<ColumnInfo>型のリストを用意します。例えばcolumnsとします。
Head行を解析したときにcolumnsに情報を設定します。

Data行を解析中にcolumnsのiの場所より項目情報を取得すれば対応列の項目情報に合わせ処理を
行うことが出来ます。
[ 親 86496 / □ Tree ] 返信 編集キー/

▲[ 86498 ] / 返信無し
■86519 / 2階層)  Re[2]: CSV読込時のループ処理中にHEADとDATAを取得する方法
□投稿者/ 河童 (3回)-(2018/02/07(Wed) 17:30:19)
No86498 (shu さん) に返信
shuさん、お返事ありがとうございました。

HEAD用のリストにカラムの場所と値をセット。
headlist.Add(i + "," + csvdata[i]);

DATA用のリストにHEADの値とDATAの値をセット。
カラムの場所は、HEADリストに格納されている
カンマ区切りの最初の値から判定。
datalist.Add(stArrayData[1] + "," + strdata);

一応希望通りの結果を取得することが出来ました。

まだオブジェクト指向というものが理解できていない状態で
コードの記述を色々勉強しています。

>項目情報を格納するクラスを1つ用意して例えばColumnInfoとします。
>そのプロパティに必要なものを用意します。
ここがよく理解できずに、今回クラスは作成できませんでした。
List<ColumnInfo>型にどのように値をセットするのかわかりませんでした。
例えば、リストの1行に
「MKAL0110011/S」と「test1」を別々に格納できるのでしょうか?
今回この部分はカンマで結合した値を格納して
出力するときは、分割して値を取り出しています。
無駄な処理をなくして、すっきりできたらいいなと思います。
何かアドバイスがございましたら、よろしくお願いいたします。


        private void button7_Click(object sender, EventArgs e)
        {
            // CSVファイルの選択
            TextFieldParser parser = new TextFieldParser(@"C:\temp\test.csv", Encoding.GetEncoding("Shift_JIS"));

            parser.TextFieldType = FieldType.Delimited;
            parser.SetDelimiters(",");// ","区切り
            //parser.SetDelimiters("\t");                    // タブ区切り(TSVファイルの場合)

            // 行数カウンタ(0:HEAD、1:DATA)
            int rowcnt = 0;

            List<string> headlist = new List<string>(); // 空のListを作成(入力項目ありの図番を格納)
            List<string> datalist = new List<string>(); // 空のListを作成(入力項目ありの図番と実績を格納)

            // CSVファイルの読込
            while (parser.EndOfData == false)
            {

                //行セット
                string[] csvdata = parser.ReadFields();

                if (rowcnt == 0) // HEADの処理
                {
                    //1行分のカラムで繰り返し処理
                    for (int i = 0; i < csvdata.Length; i++)
                    {
                        // 値セット
                        string s = csvdata[i];
                        // 空の文字列
                        if (s != null || s != "")
                        {
                            // 左端から1文字目
                            string s2 = s.Substring(0, 1);
                            // 右端から2文字
                            string s3 = s.Substring(s.Length - 2, 2);
                            // HEAD情報から登録する値を判定
                            if ((s2 != "M" || s2 != "S") && (s3 == "/S"))
                            {
                                // 入力項目のカラムidexと図番をリストに追加
                                headlist.Add(i + "," + csvdata[i]);
                            }

                        }

                    }
                }
                else // DATAの処理
                {
                    // headlistのindexでDATAの項目を取得
                    foreach (string str in headlist)
                    {
                        string[] stArrayData = str.Split(',');
                        // HEADのカラムIndexを取り出す
                        int cint = int.Parse(stArrayData[0]);
                        // HEADのカラムIndexの場所のDATAを取得
                        string strdata = csvdata[cint];

                        // 入力項目の図番と実績をリストに追加
                        datalist.Add(stArrayData[1] + "," + strdata);

                    }
                }

                //textBox999.Text += "===\r\n";
                rowcnt++;

            }

        }

[ 親 86496 / □ Tree ] 返信 編集キー/

▲[ 86496 ] / ▼[ 86581 ]
■86521 / 1階層)  Re[1]: CSV読込時のループ処理中にHEADとDATAを取得する方法
□投稿者/ PANG2 (211回)-(2018/02/07(Wed) 19:00:09)
No86496 (河童 さん) に返信
> ★CSVファイル(test.csv)
> 1行目はヘッダ情報
> 2行目はデータ
> ファイルは必ず2行のみ
> カラム数はファイルにより変わるがHEADとDATAのカラム数は同じ
> DATAには空白あり

string[] heads = parser.ReadFields();
string[] datas = parser.ReadFields();

で全データを取得するのが簡単かと。
[ 親 86496 / □ Tree ] 返信 編集キー/

▲[ 86521 ] / 返信無し
■86581 / 2階層)  Re[2]: CSV読込時のループ処理中にHEADとDATAを取得する方法
□投稿者/ 河童 (4回)-(2018/02/16(Fri) 16:51:24)
No86521 (PANG2 さん) に返信

PANG2さん、お返事ありがとうございました。

> string[] heads = parser.ReadFields();
> string[] datas = parser.ReadFields();

一度にHEADとDATAのデータを取得する方法がわからなかったので、
1行目と2行目に分けてデータを取得するようにしました。

HEADをDATAのカラム数は同じなので、
HEADの解析中に入力項目だと判定したときと同じindexの
DATAの値を取得するようにしました。

少しコードを整理することが出来ました。

           // CSVファイルの選択
            TextFieldParser parser = new TextFieldParser(@"C:\temp\test.csv", Encoding.GetEncoding("Shift_JIS"));

            parser.TextFieldType = FieldType.Delimited;
            parser.SetDelimiters(",");// ","区切り
            //parser.SetDelimiters("\t");                    // タブ区切り(TSVファイルの場合)

            // 行数カウンタ(0:HEAD、1:DATA)
            int rowcnt = 0;

            string[] heads = {};
            string[] datas = {};

            // CSVファイルの読込
            while (parser.EndOfData == false)
            {

                if (rowcnt == 0)
                {
                    // 1行目
                    heads = parser.ReadFields();

                }
                else
                {
                    // 2行目
                    datas = parser.ReadFields(); 
                }
               rowcnt++;

            }

            // HEADの解析(入力項目があるかどうか)
            for (int i = 0; i < heads.Length; i++)
            {
                // 値セット
                string s = heads[i];
                // 空の文字列
                if (s != null || s != "")
                {
                    // 左端から1文字目
                    string s2 = s.Substring(0, 1);
                    // 右端から2文字
                    string s3 = s.Substring(s.Length - 2, 2);
                    // HEAD情報から登録する値を判定
                    if ((s2 != "M" || s2 != "S") && (s3 == "/S"))
                    {
                        // DATAの値を取得(HEADのindexを使用)
                        MessageBox.Show(heads[i] + "," + datas[i]);
                    }
                }

            }


解決済み
[ 親 86496 / □ Tree ] 返信 編集キー/


管理者用

- Child Tree -