LoginSignup
3
2

More than 3 years have passed since last update.

【C#】CSVのインデックスはenumで持ちたい

Last updated at Posted at 2019-12-07

はじめに

最近関わったプロジェクトで出くわしたCSV処理について、備忘の意味も込めて書きます。
恐らく今時こんな書き方をしている箇所を見ることはないだろうけど、参考までに。

何をしたかったのか

内容はいたってシンプルで、システムの既存機能として存在しているCSV取り込みに手を加えるというもの。
具体的には、CSVのフォーマットが変わって、取り込むデータが1列増えたので対応する。
既存のCSVはA列、B列、C列、D列というフォーマットだが、今回はB列とC列の間にBα列を追加したいとのこと。

ソース

メソッド名等々は適当にぼかしてあります。

using Microsoft.VisualBasic.FileIO;

// ...略

private void LoadCsv(string csvPath){
    // TextFieldParserでCSVを読み込み
    TextFieldParser parser = new TextFieldParser(csvPath, Encoding.GetEncoding("shift_jis"));
    parser.TextFieldType = FieldType.Delimited;
    parser.SetDelimiters(",");

    while (parser.EndOfData == false) {
        string[] datas = parser.ReadFields();
        int cols = datas.length;

        // 列数が不正だったら終了
        if(cols != 4){
            return;
        }

        // A列処理
        if(string.IsNullOrEmpty(datas[0])){
            // ...略
        }

        // B列処理
        if(string.IsNullOrEmpty(datas[1])){
            // ...略
        }

        // C列処理
        if(string.IsNullOrEmpty(datas[2])){
            // ...略
        }

        // D列処理
        if(string.IsNullOrEmpty(datas[3])){
            // ...略
        }

        // 取得したデータをDBに書き込んだり...
        // その結果を画面に表示させたり...
    }
}

ぼく「うわぁ・・・、まじかよ・・・」

見ての通り取り込むCSVのフォーマットに合わせてインデックスをハードコーディングしてあるので、先に書いた通りB列とC列の間にBα列を追加するとなると、C列はdatas[2]ではなくdatas[3]になり、D列は・・・
といった風に、Bα列以降のインデックスをインクリメントしないといけなくなってくる。
もっと言うと、合計列数は4から5になるので列数不正となる条件はif(cols != 4)からif(cols != 5)になる。
まだ元々のフォーマットが4列だったから良かったものの、もしこれが10数列もあったら・・・と考えるとゾッとする。

というわけで、以下のようにCSVのインデックスをenumで持たせることにしました。


// 列のインデックス定義
private enum CsvCols
{
    // A列
    ColA = 0,
    // B列
    ColB = 1,
    // Bα列
    ColBalpha = 2,
    // C列
    ColC = 3,
    // D列
    ColD = 4
}

// 列数
private static int CSV_COLS = Enum.GetNames(typeof(CsvCols)).Length;

そんでもって、各インデックスのハードコーディング箇所を以下のように修正


// 列数が不正だったら終了(修正前)
//if(cols != 4){
//    return;
//}

// 列数が不正だったら終了(修正後)
if(cols != CSV_COLS){
    return;
}

// A列処理(修正前)
//if(string.IsNullOrEmpty(datas[0])){
//    // ...略
//}

// A列処理(修正後)
if(string.IsNullOrEmpty(datas[(int)CsvCols.ColA])){
    // ...略
}

おわりに

これなら今後対象となるCSVのフォーマットが変わっても、enumの中身を変える(追加・削除する)だけで対応できます。
もしかしたらもっといいやり方があるのかもしれない(あったら教えてください)

3
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
2