見出し画像

C#で出●館インセンティブ情報を通知するbot作ってみた②

押忍!

某youtuberの登場キャラでおなじみ残心ニキこと「鎖骨打ちのサトJ」です!

前の記事

の冒頭で書いたように燃え尽き症候群になってたわけですが

そんな中出た試合の動画がアップされましたw

自分の試合は
1回戦が16:40~
2回戦が56:30~
です。

1回戦の試合見れば残心ニキなのがわかると思いますw

あと

当然優勝はできませんでした

この試合はフルコンタクト系団体で最大手の一角である新極真会
シニア全日本的な感じの大会でした

つまりシニアデビュー戦です

シニアなんでサポーターありの試合なんですが最後にサポーターありの試合に出たのが高校2年生の時なんで14年ぶりのフル装備での試合になります

久しぶりにフル装備で試合したけどヘッドガード息苦しすぎる、、、

ヘッドガード+飛沫防止フェイスシールドなんで秒でガス欠しましたw

似たような構造のヘッドガードをしながら組技、寝技までやる空道の選手を改めてすごいなって思いました

ってわけで本題に

今日のテーマは前回の記事のフローチャートのこの部分

の解説です。

■そもそもなんでCSVにしたか

可変の値を使うときにどのようにデータを渡すかを考えた場合以下の案が浮かびました

  1. DB

  2. Configファイル

  3. コマンドライン引数

  4. CSVあるいはテキストファイル

まず1は維持費とかの問題で速攻却下。詳しい理由はこの記事で書いてます

2はXML形式で書くことになるがこのツールを普及させると考えてXMLは一般曹にはなじみ薄いので却下

3に関しても一般ユーザーから見れば難しいかもだし、渡した後のデータ加工が難しそうだったので消去法で4にしました

CSVのサンプルはこんな感じです

1行目はひな形で各列に入力する項目を記載してます

2行目以降は実際に通知する地域の値を入力します

A列は地域、B列は都道府県、C列は市区町村です

写真はCSVファイルをエクセルで開いた例ですが

メモ帳とかで開く場合は「関東,東京都,千代田区」って感じでカンマ区切りで入力します

■CSVファイルの読み取り方

ここからは実際にコードで説明していきます

C#やVB.NETでファイル読み取りによく使われるのがStreamReaderクラスです

大変便利なのですがこのStreamReaderクラスだと以下の場合だとうまく機能しません

  1. 要素内にカンマや改行が含まれている時

  2. CSVがダブルクォート(「""」)で囲まれている形式だった場合

今回の場合だとあまり気にしなくてもいいことですが、ユーザーは何するかわかりません。あらゆるケースを想定しないといけないです

機能の実装はできて当たり前。バリデーションなどエラーチェックなどの配慮がちゃんとできるかどうかが腕の見せ所だと先輩から習いました

なので今回はStreamReaderクラスではなくTextFieldParserクラスを使うことにしました。TextFieldParserクラスを使うことで上記問題が解消できます

使い方はStreamReaderと似てますがこちらはそのままじゃ使えないので
Microsoft.VisualBasic.FileIOをインポートさせる必要があります

using Microsoft.VisualBasic.FileIO;

宣言の仕方はこんな感じです

var txtParser = new TextFieldParser([読み取るファイルのフルパス]);

TextFieldParserクラスはIDisoisableインターフェースを継承してるのでusingで宣言してあげると実装が楽です

IDisoisableやusingが不明な方はこちら見てください

TextFieldParserを宣言した後はまずは区切り文字を設定します。
今回はカンマ区切りなので引数には「,」を設定します

txtParser.SetDelimiters(",");

あとはループ処理で1行ずつ読み取って値をListなどに格納していきます

var ret = new List<string[]>();
txtParser.SetDelimiters(",");
//一行目はヘッダー
txtParser.ReadFields();
while (!txtParser.EndOfData)
{
    string[]? value = txtParser.ReadFields();
    if (value != null)
    {
        ret.Add(value);
    }
}

ヘッダーの値はいらないのでループ処理をする前に一度ReadFieldsを書くことでループスタート地点を2行目からにしております

string[]? value = txtParser.ReadFields();

ReadFieldsで一行ずつ読み取って結果を文字列配列で取得するわけですが
ReadFieldsには少しめんどくさい挙動があります

ReadFieldsは対象の行のフィールドが空の行の場合にNullを返します

なんでReadFieldsを使うときはNullチェックはしたほうがいいです。

他の対策としてはReadLineで文字列として取得した後にString.Splitを使って文字列配列にするなどがあります

終わりに

いかがだったでしょうか

自分も実は普段StreamReaderを使っており今回作るにあたってTextFieldParserは初めて知りました。

今後使っていきたいと思います。

次回は実際に出前館インセンティブサイトをスクレイピングしていきます


この記事が気に入ったらサポートをしてみませんか?