博多親不孝通りミッドナイト 悪魔のCSV
あまりに魔的な危険さとありえない仕様をもって” 悪魔のCSV ”と呼ばれるようになったそのファイルを解析すべく、真夜中の博多親不孝通りを常軌を逸した速度でサイゼにピットし今日もコーディングに熱中する、コールミーこうへい(以下コウヘイ)。プログラマーなら誰もがCSVの解析に夢中になったはず。・・・これはもうひとつの湾岸ミッドナイトである。

IT事務員を一瞬で虜にした悪魔のCSVの魅力
主人公コウヘイは平凡なIT事務員であったが、ある日、業務先から送られてきたCSVの解析を依頼される。これまでF#、VBA、SQLと着実にスキルアップを積みかねてきたコウヘイはCSVの解析に乗り出す。いつもなら順調に解析は終わるはず。しかし、そのCSVは見た目とは裏腹にとんでもない仕様にフルチューンされていたのだった。

悪魔のCSVに魅入られたツイッターランドのライバルたち
悪魔のCSVに惹かれるのはコウヘイだけではなかった。自分の業務とは何の関係もないツイッターランドの猛者たちが「このCSVを解析したい!」とコウヘイとともに悪魔のCSVを解析しようと挑み続ける。果たしてこの悪魔のCSVは解析できるのだろうか?

悪魔の仕様

悪魔のCSVを解析する関数を作成してください。問題を明確にするために入力されたCSV1行の文字列を解析する関数を作成するものとします。

前提条件
  • 行の中の各項目はダブルクオートでくくられていません(すなわち行中にダブルクオートは現れません)。
  • 行中にCR/LF/CRLFは含まれません。CRLFが現れるのは行末のみです。
  • 要素と要素はカンマで区切られ、要素-カンマ-要素の並びの間に不要な空白は存在しません(要素と項目につては後述)。
  • 数字項目にカンマが使われるのは3桁毎に区切る場合のみです(3桁以上の数字をカンマで区切らないケースは許容されます)。ただし、例を見てもわかるように名前またはメモ項目にもカンマが含まれる場合があります。
  • 上記に加え、業務上妥当と思われる制約、前提条件は追加してかまいせんがその旨明示してください。

関数IF(IFは適宜変更OK)
function akuma_no_csv(a_line) 
  • ‘@name       悪魔のCSVの1行を解析する
  • ‘@param     a_line    CSVの1行
  • ‘@return      解析結果配列
  • ‘    (0) 数量項目の先頭位置(文字列なので1文字目の位置を1とする。以下同じ)
  • ‘    (1) 単価項目の先頭位置
  • ‘    (2)合計金額の先頭位置
  • ‘    (3)メモの先頭位置
  • ‘解析に失敗した場合はarray(0,0,0,0)を返す。
仕様説明
この関数はCSVの1行を読み込んで解析結果配列を返します。カンマには2つの意味があります。各項目を区切る区切り記号としてのカンマと数字の3桁区切りを表すカンマです。前者を「区切りカンマ」、後者を「桁カンマ」と呼びます。

どの種類のカンマかを意識せずに単にカンマで区切られるものを「要素」と表現します。これに対して「項目」は区切りのカンマと桁カンマを区別し、区切りのカンマで区切られたものとします。

解析結果配列はこの各項目の最初の文字インデックスを返します。名前項目につては常に開始位置が1となりますので戻り値に含める必要はありません。たとえば、例示されている1行の解析結果はarray(7, 9, 15, 21)となります。

解析終了判定は、「数量項目*単価項目=合計金額」となる項目の組み合わせです。条件を満たす組み合わせが複数ある場合はどの組み合わせを戻り値としてもかまいません(1つ目の項目の組み合わせが判明した時点でその組み合わせを返してもかまいません)。


2020年1月12日  エクセルの真髄さんから解答といただきました。ありがとうございます。