メインコンテンツへスキップ
Tooletto

スプレッドシートのCSVエクスポートが変換時に壊れる理由

CSVのエクスポートは、一見して単純で明らかに構造化されたデータに見えます。しかし実際の住所やゼロから始まる番号、セル内の改行が登場した瞬間、その単純さは幻想だったことが分かります。

· 読了時間 1

CSVが単純に見えて実はそうではない理由

CSVファイルは、データ形式としてこれ以上ないほど単純に見えます。各行をカンマで区切り、先頭行を列見出しとして扱えばそれで完成、というわけです。しかしこの見かけの単純さこそが、実際のデータが登場した瞬間にこの形式を扱い間違えやすくしている原因でもあります。単純にカンマで分割するという素朴な方式は、おもちゃのような例では完璧に機能しますが、実際のデータの値がたまたま自身のカンマを含んでいる最初の行で破綻します。これは例外的なケースではなく、ごくありふれた出来事です。「東京都千代田区丸の内1-1, 3階」のような住所や、「田中, 鈴木商事」のような屋号、「赤, 青, 緑からお選びいただけます」のようにたまたま列挙を含む商品説明は、いずれもまったく普通の値でありながら、素朴なパーサーがフィールドの区切り文字として使っているのと同じ文字を、正当な内容として含んでいます。

CSVは実際の値の中にあるカンマをどう扱うのか — そして素朴なツールはどこで間違えるのか

CSVの仕様は、フィールドを二重引用符で囲むことを許すことで、埋め込まれたカンマの問題を解決しています。引用符の中では、カンマも、さらには改行さえも、構造ではなく単なる文字どおりのデータとして扱われます。`"田中, 鈴木商事"`のように正しく引用符で囲まれたフィールドは、カンマで区切られた2つの別々の値ではなく、カンマを含む1つの値として理解されます。現在フィールドが引用符の中にあるかどうかを追跡せずに、すべてのカンマで素朴に分割するパーサーには、この区別をつける方法がありません。そのため、この1つの社名を静かに2つの見せかけの列に分割してしまいます。しかも通常はエラーを一切出しません。これこそが、この種のバグを危険にしている本質です。変換は成功したように見え、破損が発見されるのはずっと後になってから、多くの場合、その不正なデータがすでに何かに使われた後になってからです。

1つのセルの中にある改行

複数行にわたるメモや住所を含むスプレッドシートのセルはまったく普通のものであり、そのセルがCSVにエクスポートされるとき、仕様は埋め込みカンマを扱うのと同じ方法でこれを扱います。フィールド全体が引用符で囲まれ、その中の改行は本当にそのフィールドのデータの一部であって、新しい行が始まった合図ではありません。ファイル内のすべての改行が新しいレコードの始まりを示すと想定し、現在開いた引用符付きフィールドの中にいるかどうかを追跡しないパーサーは、その1つの複数行セルを、いくつもの別々の行であるかのように分割してしまいます。そして壊れたセルが持ち込んだ余分な見せかけの行の数だけ、それに続くすべての行がずれてしまうため、ファイル内でそれ以降に続くものすべての行構造を静かに破壊します。

型の曖昧さ — 先頭のゼロ、電話番号、そして本当は数値ではない「数値」

生のCSVファイル内の値はすべてプレーンテキストとして保存されており、ある値が「本当に」数値なのか、真偽値なのか、それとも単に数字らしく見える文字列にすぎないのかを示す組み込みの手段は一切ありません。これは、変換ツールが型を自動推定して親切にしようとした瞬間に、本物の問題になります。「007」のような郵便番号や「042」のようなIDには意味のある先頭のゼロが含まれています。これは固定幅の識別子であり、「7」と「007」は同じ数を表していても異なる識別子です。しかし、数字らしく見える文字列を積極的に実際の数値として解析する変換ツールは、その先頭のゼロを静かに落としてしまいます。数値の7には、かつて自分の前に何個のゼロがあったかという概念がそもそもないからです。「+81 90 0000 0000」のような電話番号は部分的に数字らしく見えますが、そもそも算術的なデータではまったくなく、これを数値に変換すると本当に意味のないものが生成されます。安全で正しい既定の振る舞いは、値が曖昧さなく安全に数値であると言える場合を除いて、曖昧な値をテキストのままにしておくことです。ここで判断を誤ると、目に見えて捕捉可能なエラーを出すのではなく、静かにデータを破損させてしまうからです。

Excelが特有の、まったく別のトラブルの層を追加する理由

CSV形式そのものが抱える本物のエッジケースに加えて、Microsoft Excelは、CSVの仕様そのものとは無関係の追加の摩擦を持ち込みます。多くの欧州などの地域設定のExcelでは、フィールドの区切り文字として既定でカンマではなくセミコロンが使われます。これらのロケールではカンマがすでに小数点の区切りとして使われているためで、そうしたExcelの設定からエクスポートされたCSVファイルは、カンマ区切りのパーサーではまったく正しく解析されません。Excelにはまた、CSVファイルを表示のために開いたときに、認識したと思い込んだ値を自動的に再フォーマットしてしまうよく知られた癖もあります。たとえば長い数値のIDを指数表記に変えてしまうといった具合です。これはExcel側の表示時の誤解釈であって、元となるCSVファイル自体の欠陥ではありませんが、エクスポートそのものにおける実際のデータ破損だと日常的に誤解されています。

関連ツール

ブログの他の記事