とあるDTPオペレーターのInDesignスクリプト備忘録

デザイナー上がりですがいまはDTP命。InDesign用スクリプトの解説などを綴っています。読者登録して戴けると励みになります。

スクリプトの暴発を食い止めろ!(つづき)

これまでのあらすじ……前回の記事を読んでください←

1 ファイル名を調べる

---スクリプトが暴発しない方法……関係ないドキュメントでスクリプトが作動しない方法…………



「あたし、夜食買ってくる」

そう言ってテグミが出ていったあと、ぼくは何気なく彼女のデスクに目をやった。
受注伝票が山のように積まれている。彼女もかなり忙しそうだ。なのにぼくに気を遣わせて申し訳ない。
山のいちばん上にあるのは、ぼくが対策を依頼されている仕事の伝票だった。
件名の欄に「中古車カタログ7月号」とある。

---中古車カタログ……か…

この中古車カタログ用に書いたスクリプトが、他の案件で動作しては困るのだ。特に新車カタログで動作してしまうと、紙面の作りが似ているだけにトラブルの原因になりやすい。

---ん……? ちょっと待てよ……

ぼくは自分のPCの前に戻ると、ヨウに託された「中古車カタログ」のファイルがまとまったフォルダを開いてみた。

 中古車/トヨタ車.indd
 中古車/日産車.indd
 中古車/輸入車.indd
  ・
  ・
  ・

やっぱりだ。中古車カタログに関するドキュメントは、すべてファイル名に「中古車」の文言が入っている。

---てことはだ、ファイル名の頭に「中古車」の文言が入っていないかをスクリプトで調べれば…

①app.activeDocument.name(※1)で編集中のドキュメントのファイル名を取り出す。
②次にslice(※2)を使って、ファイル名の中の「中古車」の部分だけを抽出する。
③あとはif文で文頭から三文字めまでが「中古車」かどうかを調べれば、「中古車」で始まるファイル名のドキュメントだけで動作するスクリプトが作れるのではないか。

※1 name……名前を調べる命令。activeDocumentのあとに付けることでファイル名を取得できる。
※2 slice……文字列の中から、指定した字数文の文字列を抽出する命令。


“いや、これじゃだめだ”

ぼくは画面を見て頭を振った。あらためて見ると、フォルダの中にはこんな名前の付けられ方をされたファイルもあった。

 その他中古車.indd
 ◆中古車◆1Cページ.indd
 7月号中古車広告page.indd

微妙に命名ルールが違うものがある……ぼくは頭を抱えた。
sliceは「何文字めから何文字めまでを抽出しろ」という指定の仕方だから、ファイルによって対象の文字位置が違う場合は使えない。

だとしたら、作業者にファイル名の付け方のルールを徹底させるしかない……かならずファイル名の頭に「中古車」と付けるように…

“いや、それもだめだ”

関係ないドキュメントでうっかりスクリプトを実行してしまう人間が、命名ルールを完璧に守れるとは思えない。
見くびっているわけではない。自分以外の人間が使うスクリプトは特に、あらゆる操作ミスを想定してリスクの少ない方法を模索する必要がある。

---答には近づいている気がする……しかし……

2 文字列の有無を調べるindexOfメソッド

そのとき、不意に首筋にひんやりとしたものが押し付けられ、ぼくは思わず悲鳴を上げた。振り返ると、いつの間にか買い出しから帰ってきたテグミが立っていた。
呼びかけても反応がないぼくに気づかせるために、キンキンに冷えたレッドブルを押し付けてきたのだ。

「大げさね、風都さんのぶんも夜食買ってきたから」

「ありが……」
次の瞬間、テグミが雷に打たれたように一瞬発光したと思うと、彼女は糸が切れた操り人形のようにその場に倒れ込んだ。

「お……おい、大丈夫かテグ……!」

うつぶせに倒れた突然彼女が、うわごとのように何かをつぶやき始めた。

テグミ「……ンデック……クスオ……ブ」

それは彼女の言葉でありながら、彼女自身の言葉ではなかった。
彼女はしばしばこうして何かが乗り移ったような状態になり、ぼくがスクリプト制作で壁にぶち当たったときにヒントをくれる時がある。
きっとスクリプトに詳しい霊が憑依しているんだろう。おそろしいまでのご都合主義。
「調べる→ヒントを見つける」というプロセスを漫画的に表現したものだと思っていただけると幸いである。

(彼女はいったいなんて言っているんだ?)
ぼくは耳を済ませた。

テグミ「……オーブ……インデックス……オ……ブ……

「インデックス……オブ……?」

たしかJavaにそんなメソッドがあった気がする。
ぼくは急いでAdobe JavaScriptリファレンスのページを繰り、indexOfの項を見つけた。

……文字列内に指定された文字列があるか調べ、その位置を知るメソッド!


書き方

結果用の変数 = 調査先の文字列.indexOf ("あああ");
↑を実行すると、"あああ"の有無を調べた結果が結果用の変数に入る


暗闇の中に、針で開けたような小さな光が見えた気がした。
気づくと、テグミは力尽きたように意識を失っている。憑依が解けるといつもこうだ。
いつもどおりであれば、いずれ目を覚ますだろう。ぼくは彼女に自分の上着をかけると、indexOfの詳細を調べた。

ふむふむ……「あるかないか」を調べる命令なのに、返り値がブール型(あるtrue/ないfalse)じゃないのか……
なになに……文字列が指定した文字列内に見つかった場合は、何文字目に出てくるかを返し、見つからなかった場合は……つまりブール式でいうところのfalseの状態であれば、「-1を返す」!
つまり、

indexOfで「中古車」を調査した結果が0か、0よりも大きければ、それはファイル名のどこかしらに「中古車」が含まれたファイルということ!

ぼくは早速件のスクリプトを書き直した。

3 そして書いてみた


[例]ファイル名に「中古車」が含まれたときだけ動作するスクリプト

var docName = app.activeDocument.name; //編集中ドキュメントのファイル名を得る
var result = docName.indexOf("中古車"); //ファイル名に文字列が含まれるか調べる

if(result >= 0){ //文字列がファイル名に見つかれば…
        /////処理をここに書く/////←ここに書いた処理を実行する!
} else {
        alert ("この種類のドキュメントでは実行できません");
        //関係ないファイルで実行しようとしたら、警告アラートを出す以外何もしない。
    }


作業中のドキュメントのファイル名を調べて変数に入れ、indexOfでその変数の中に「中古車」の文字が含まれているかを調べる。
その結果(返り値)は「あるかないか」ではなく「どこであるか」で返ってきて、「なし」の場合は「-1」という位置情報が返ってくる。
つまり位置情報が0以上(>=0)であれば、ファイル名のどこかしらに「中古車」という文字列が含まれているということになる。

なので、if文で0以上のときには処理を実行、そうでなければ(else)「この種類のドキュメントでは実行できない」という警告を出してそのほかの処理はしない、というスクリプトを書けば狙ったとおりの動作になる。
場合によっては即時関数で全体をくるみ、returnで能動的に抜けられるようにした方が良いかもしれない※3


---やれやれ、ミッションコンプリートだな。


こうして、ファイル名に特定の文字列が含まれていたときだけに動作するスクリプトが完成した。
テグミが目覚めたら彼女がぼくを助けてくれたように、ぼくも彼女の仕事を手伝おう。ありがとうテグミ。そしてスクリプトの霊。
~fin~


※3 まだ入門者向けコラムに登場していない即時関数や関数については、いつか入門者向けコラムに書きますです。


実験的にストーリー風にしましたが、途中で嫌になったので次回からは普通に書きます…………
でも、スクリプトを書いているときも、よく言われる何かがおりてくる感覚があるのは本当です。