改行を含むTSVファイルを使ってデータ結合を行う方法
InDesignのデータ結合では、フィールドデータに改行が含まれているとデータの読み込みが正常に行われません。姑息な手段ですが、以下のようなワークアラウンドを考えました。
- Excelから出力したTSV(Tab Separated Values)ファイルの、フィールドデータに含まれる改行を @@@ に置換
- InDesignでデータ結合を実行
- 全文検索により @@@ を改行に置換
というわけで、Excelから出力したTSVファイルを処理するPerlスクリプトを作りました。
●エンコードの問題
ExcelからTSVファイルを出力するとき、「テキスト(タブ区切り)」を選択するとTSVファイルはShift-JISになります。人名や地名を含むデータの場合、Excel上では正しく表示されているのに、TSVファイルにすると文字化け(?で表示される)することがよくあります。そこで、ExcelからTSVファイルを保存するときに「Unicodeテキスト」を選択する運用としました(TSVファイルのエンコーディングはUTF-16)。
InDesignのデータ結合で読み込めるユニコードもUTF-16なので、Perlスクリプトから生成されるTSVファイルもUTF-16にしたかったのですがうまくいきません。仕方なく、PerlスクリプトからはUTF-8のTSVファイルを出力し、秀丸でBOM付きUTF-16に変換することにしました。ちょっと余計な手間が残りますが、何とか使えるようになりました。
【動作確認】
Windows7 x64
Perl v5.10.1
InDesign CS4
#!perl # # ====================================================== # TSVファイルのフィールドに含まれる改行を@@@に置換する # ====================================================== # # [変更履歴] # # Ver1.00 2010/07/05 初版 # Ver2.00 2010/12/23 入力ファイルをShift-JIS CSVファイルから、Unicode TSVファイルに変更した。 # Excel上での文字の表示にはUnicodeが使われるが、通常の方法でCSVファイルに保存するとShift-JIS # になるため、文字化けが発生することがある。 # # [スクリプトの解説] # # InDesignのデータ結合でCSV/TSVファイルの流し込みをするとき、フィールドの中に # 改行が含まれていると、正しく流し込みができない。この問題を解決するために、 # データ結合の前に、フィールドの中に含まれる改行を"@@@"に置換する。 # InDesignでデータ結合した後に、"@@@"を改行に置換することにより、フィールド # の中の改行を再現できる。 # # 変換後、***_OUT.TXT という名称のファイルに結果を出力する。 # 出力されるTSVファイルのエンコーディングはUTF-8で、InDesignが読めるのはUTF-16なので、 # 秀丸エディタでBOM付きのUTF-16に変換して保存する。 # # [使用方法] # # コマンド・プロンプトより、以下の書式に従ってコマンドを入力する。 # # 書式: # cr-u.exe -i <ソースのTSVファイル名称> # # ファイル名 => *.txt # # 【 重 要 】 # # ExcelからTSVファイルを保存するときに、Unicodeテキストを指定すること。 # # 参考ページ: # http://www.din.or.jp/~ohzaki/perl.htm#CSVwithCRLF # use warnings; use strict; use utf8; binmode STDOUT, ":encoding(shiftjis)"; # 標準出力をShift-JISにする binmode STDERR, ":encoding(shiftjis)"; # 標準エラー出力をShift-JISにする use Encode qw/encode decode from_to/; use Getopt::Std; use File::Basename; print "*** TSVファイルの改行処理スクリプト Ver 2.00 ***\n\n"; # ― グローバル変数宣言 ――――――――――――――――――――――――――┐ our $opt_i = undef; # -iオプションを取得するための変数 # ―――――――――――――――――――――――――――――――――――――┘ # ― 引数を取得する ――――――――――――――――――――――――――――┐ $opt_i = undef; unless( getopts('i:')) { print "エラー:引数の取得に失敗しました。\n"; &display_usage(); die; } # -iオプションが指定されていない場合は、使い方を表示してスクリプトを終了する if (!$opt_i) { &display_usage(); exit; } # -iオプションで指定されたファイルが存在するかどうか確認する my $input_fname = decode('shiftjis', $opt_i); # ファイル名をShift-JISにデコードする unless (-e $opt_i) { die "エラー:指定されたテキスト・ファイルがありません; ファイル名=$input_fname\n"; } # ―――――――――――――――――――――――――――――――――――――┘ # ― 出力ファイルをオープンする ――――――――――――――――――――――┐ my $output_fname = basename($input_fname, ".txt"); $output_fname = $output_fname . "_OUT.txt"; # # open OUTPUT_TSV_FILE, '>:encoding(utf16)', encode('shiftjis', $output_fname) # ※ 出力ファイルをutf16にすると文字化けする # open OUTPUT_TSV_FILE, '>:encoding(utf8)', encode('shiftjis', $output_fname) or die "エラー:出力ファイルをオープンできません; ファイル名=$output_fname\n"; # ―――――――――――――――――――――――――――――――――――――┘ # ― 入力テキスト・ファイルをパースする ――――――――――――――――――┐ open INPUT_TSV_FILE, '<:encoding(utf16)', $opt_i or die "エラー:入力ファイルをオープンできません; ファイル名=$input_fname\n"; while (my $line = <INPUT_TSV_FILE>) { $line .= <INPUT_TSV_FILE> while ($line =~ tr/"// % 2 and !eof(INPUT_TSV_FILE)); $line =~ s/(?:\x0D\x0A|[\x0D\x0A])?$/\t/; my @values = map {/^"(.*)"$/s ? scalar($_ = $1, s/""/"/g, $_) : $_} ($line =~ /("[^"]*(?:""[^"]*)*"|[^\t]*)\t/g); # 各フィールドデータの中に改行が含まれていたら、"@@@"に置換する my $one_tsv_line = ""; my $column_cnt = 0; foreach my $field (@values) { #print "$field\n"; $field =~ s/\n/@@@/g; $one_tsv_line .= $field; if ($column_cnt < @values - 1) { $one_tsv_line .= "\t"; } $column_cnt++; } print OUTPUT_TSV_FILE "$one_tsv_line\n"; } print "\n$output_fname が作成されました\n\n"; close INPUT_TSV_FILE; close OUTPUT_TSV_FILE; exit; # ―――――――――――――――――――――――――――――――――――――┘ ################################################################################ # 処理概要: 本スクリプトの使い方を表示する # sub display_usage { my $msg = <<EOF; [使用方法] コマンド・プロンプトより、以下の書式に従ってコマンドを入力する。 書式: cr-u.exe -i <ソースのTSV名称> ファイル名 => *.txt 【 重 要 】 ExcelからTSVファイルを保存するときに、Unicodeテキストを指定すること。 EOF print $msg; }
【 免 責 】
上記スクリプトの使用により発生する、データの破損などのあらゆる不具合・不利益については、一切の責任を負いかねますのでご了解ください。
【 蛇 足 】
このスクリプトのテストをしていて気が付いたのですが、InDesignはデータ結合の際にフィールドデータに含まれるダブルクォートを破棄してしまうらしい。。。