CSVファイルをExcelで開く(なでしこでツール作成)
こんにちは。
ゆめみに長らく居座っている樽八といいます。
コネタ中心で投稿させていただきたいと思います。
1. はじめに
サイト開発者や運営者の中にはお客様とのデータのやり取りや、システムとのデータのやり取りにCSVファイルを用いることは多いかと思います。
そして、Windows上で表計算データの操作といえば一般的にはExcelを利用します。
CSVファイルに関しても例外ではないでしょう。Excelに紐付けられている環境がほとんどかと思われます。
しかしながら、CSVファイルをExcelで開くと元のデータをこわしてしまうという大きな危険が伴っています。
※ 最大の問題は、ファイルの破損に気がつかないことがあることです。
ここではその危険な例および解決策を紹介したいと思います。
2. CSVファイルを開くとデータが壊れる危険な例
以下の手順によりCSVファイルが壊れてしまう例を再現することができます。
2.1 Excelを起動し、以下のデータを入力します。
※ 0で始まる数値は入力できませんので、先頭に’をつけておきます。
※ 生年月日の先頭にも’をつけて入力します。
2.1 CSVファイルとして保存します。
2.2 生成されたCSVファイルをメモ帳で開いて確認します。
2.3 生成されたCSVファイルを再度Excelから開くと、以下の不具合が発生していることが確認できます。
Excelが起動する際に何か不安になるようなことを言われますが、これは気にする必要がありません。
- 生年月日のフォーマットが変更されている
- 電話番号の先頭の0が抜け落ちている
- 郵便番号の先頭の0が抜け落ちている
2.4 そのまま上書き保存します。
2.4 生成されたCSVファイルをメモ帳で開いて確認します。
2.2 で確認したデータとは異なったデータとして保存されてしまっていることがわかります。
※ 今回確認をしませんでしたが、分数のデータ”1/3″などが、”1月3日”などと化けたりするのも大きな問題です。(エクセル上で一度化けてしまうと、後から書式設定しなおしても戻りません。)
3. 解決策
こちらの問題の解決策には大きく分けて下記の4つの方法があります。
- 先頭が0になる可能性があるときは、数値のみのデータを扱うことをあきらめる
- データをテキストファイルで開き、TSVに変換、それをあらかじめ全てのセルを書式設定でテキスト型に変更したExcelに貼り付ける
- 拡張子をtxtに変更した上で、ファイル名を指定して開くから、セルの書式設定をしながら開く
- ツールの助けを借りる
1. は各セルの中味のデータを"0100000"とは書かずに、"010-0000"と記載するなどの工夫を指しますが、日付データなどが勝手に変更されてしまうことを防ぐのは難しいです。
※数値セルをダブルクオート(")で囲んでも、文字列として認識はしてくれません。
2. も、3.も正直めんどくさいです。第一、ダブルクリックで勝手に開いてしまうのも問題です。
そこで、4. のツールの助けを借りることとなるのですが、軽く探した範囲ではいいソフトウエアはありませんでした。
自分で実装するとすると、、、CSVファイルを別のソフトに関連付けし、CSVファイルをダブルクリックされるとそちらのソフトウエアが立ち上がり、そのソフトウエアからExcelを起動、データを流し込むという方法でいけそうな予感です。
とはいえ、普段はPHPばかり扱っておりますので、Windows上での開発に適した言語を探すことからはじめました。
4. 開発言語選定基準
- CSVファイルの扱いが楽であること
- Excelの扱いが楽であること
- 言語の習得が簡単であること
- 配布可能な実行ファイルが作成できること
今回は上記要件を満たす言語として、「なでしこ」を利用することとしました。
なでしこのCSVパーサーはExcelのセル内改行なども正常に処理可能なようです。
なでしこ公式サイトURL
http://nadesi.com/
5. いきなりソースコード紹介
なでしこで作成したソースコードは以下のとおりです。
なんと、日本語がそのままコードとなります。
!母艦設計=「母艦の可視はオフ」 ファイルはコマンドライン[1] もし、ファイルが空ならば 「CSVファイルを指定してください。」と言う 終わる # CSVファイルを取得 ファイルを読む 配列データはそれをCSV取得。 もし、配列データが空ならば 「ファイルの読み込みに失敗しました。」と言う 終わる もしエクセルインストールチェックが偽ならば 「Excelがインストールされていません。」と言う 終わる # エクセルを起動して、余分なシートを削除する オンでエクセル起動 エクセル新規ブック エクセルシート列挙 それを反復 もし回数>1ならば、それをエクセルシート削除 # エクセルにCSVデータを記入する 行タイトルIDは1 配列データを反復 行データはそれ 列タイトルIDは1 行データを反復 記入データは「'」 記入データにそれを追加 記入セルはCELL(行タイトルID,列タイトルID) 記入セルへ記入データをエクセルセル設定 列タイトルIDに1を足して、列タイトルIDに代入 行タイトルIDに1を足して、行タイトルIDに代入 # CSVファイルとエクセルを紐付ける ファイルにエクセルCSV保存 # エクセルが終了したら本プログラムも終了する エクセル起動中は真 (エクセル起動中)の間 1秒待つ。 エクセル起動中は偽 窓列挙。 それをCSV取得して反復 Fタイトル=対象[2] Fタイトルが「Microsoft Excel - *」にワイルドカード一致? もし、そうならば エクセル起動中は真 終了
6. 使い方
上記ファイルを実行ファイルに落としたものを作成いたしました。
このファイルおよび、plug-insを適当なディレクトリに放り込んだ後、拡張子がcsvのファイルを「プログラムから開く」を利用して同梱の実行ファイル(csv2excel.exe)から開いてください。
「この種類のファイルを開くときは・・・」にチェックを入れておくことにより関連付けができます。
このプログラムは立ち上げたExcelファイルを閉じるまでバックグラウンドで実行されます。
(※Excelを終了させずにプログラムだけ終了させる方法がわかりませんでした。)
7. おわりに
- このソフトウエアを利用することによって発生したいかなる不都合にも責任をおうことはできませんのでご了承ください。
- 重量級の記事が並びそうな雰囲気だったので簡単なものを紹介しようとしたのですが、意外と長くなってしまいました。
- 今回、なでしこをはじめて触ったのですが、いろんな意味で”面白い”言語ですね。他にもこういったツールが簡単にできそうです。
- 初めて使う言語なので、未熟であたりまえと割り切ってソースコードを公開しています。
- 今回はなでしこのプログラム紹介でしたが、今後はPHPやGD中心で紹介していきたいと考えています。
追記
その後の調査で、CSVファイルを作成するときに以下のようにセルの先頭にタブ文字を入力しておくことで値を文字列データとして保存可能であることがわかりました。
名前,生年月日,郵便番号 ゆめみ太郎,t2000-01-01,t0100000
CSVファイルをシステムで作成するときには使えるテクニックとなりそうです。
※ 逆にシステムから利用するときには必ずtrimする必要が出てきますので、場合に応じてご利用を検討ください。