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

デザイナー上がりですがいまはDTP命。InDesign用スクリプトの解説などを綴っています。コメント、読者登録歓迎

【入門者向け②】スクリプトでInDesignを操作 ~forによるくり返し 前編~

引き続き、前回用意していただいたドキュメントを使用してスクリプトの説明をします。
まず、前回黒塗りにしたテキストフレームの塗りを「なし」に戻してください。もちろんスクリプトでも出来ますが、これから説明する内容と前後する部分が出てきてしまうので、今回はInDesign上の操作で「なし」にしてください。
白紙ドキュメント上に塗りのないテキストフレームが3つ置かれた状態になったら、先に進みます。

それではこの3つのフレームすべてを「黒」塗りにしてみましょう。
以下のように書いて、ESTKから実行してみてください。

[例1]

app.activeDocument.textFrames[0].fillColor = "Black";
app.activeDocument.textFrames[1].fillColor = "Black";
app.activeDocument.textFrames[2].fillColor = "Black";

3つとも黒塗りになったでしょうか。うまく行かないという方は、前回の記事に書いた、間違いやすい部分を確認してみてください。
[例1]ではテキストフレームの番号を[数字]で指定しながら、3つのテキストフレームに黒塗りの指定をしていきました。
テキストフレームの番号って[1][2][3]じゃないの? という方は前回の記事を読んでください。

スクリプトは基本的には1行めから下へ下へと書かれた内容を実行していきます。
[例1]では、テキストフレーム[0]から始まって[1]、[2]と処理していきます。


こうして無事に[例1]でも『ページ上のアイテム全てに塗りを設定』という処理はできましたが、実際にはこんな書き方はしません。
「別にこれでもよくね?」と思われる方もいるかもしれませんが、もしテキストフレームが100個あったら、[0]から[99]までapp.activeDocument…と記述していくのはウンザリしますよね。もしかしたら数え間違いで101個あるかもしれない。その場合、1個だけ塗られないフレームができてしまいます。

そのため、こういう場合は「繰り返し」という命令の仕方をします。前置きは一旦おいといて、まずは[例1]を繰り返し文を用いた書き方に直してみます。
黒塗りになったテキストフレームの塗りを「なし」に戻した上で、下の[例2]をESTKより実行してください。

[例2]

for (var i=0; i<3; i++){
app.activeDocument.textFrames[i].fillColor = "Black";
}

テキストフレームを指定する行は1行だけになりましたが、[例1]同様、すべてのテキストフレームが黒塗りになったと思います。
上手く行かないという方は、見本と違う部分がないかをよく確認してください。特に1行めと3行めにある「{と}」の有無と個数、textFramesの隣の[i]は重要です。
[例2]にあって[例1]にはない部分を赤字にしてみます。


for (var i=0; i<3; i++){
app.activeDocument.textFrames[i].fillColor = "Black";
}


1行めの「for (var i=0; i<3; i++){」の部分が繰り返し文です。ループ文とも呼ばれます。特に重要になるのはカッコの中身です。for文を日本語に直すとこんな意味があります。


for (①開始条件; ②続行条件; ③カウンタ加算値){④繰り返したい処理}


セミコロンごとに項目が区切られているのが分かりますね。一つずつ説明します。

①開始条件とは
 繰り返し文が「iは0だよ」と「宣言」しています。のちに詳しく説明しますが、スクリプト上では、ユーザが好きな言葉に好きな意味を与えることが出来ます。
 たとえば「app.activeDocument.textFrames」という長い長い英文を「myFrame」とか「obj」という名前にしてしまうことができちゃいます。
 友達の名前を略して呼んだり(例:深田恭子フカキョン)、元々の名とはまったく異なる名で呼んだりしますよね(剛田武ジャイアン

 こうして付けられた名前は「あだ名」「愛称」「ニックネーム」などと呼びますが、スクリプトの場合は「変数」と呼びます。
 スクリプトの製作者は、変数を使って長い名前を略したり、役割を与えることができます。これを「代入」と呼んだりします。
 そして、変数を作成することを「変数を宣言する」と言ったりもします。
 変数とか代入とか数学みたいですが、数学のそれとは少し意味合いが違いますね。
 
 開始条件の説明に戻りましょう。ここでは「i」という変数が作成され、iという変数には「0」という数字が代入されました。
 ここから先、iは繰り返し文のカウンタの役割を担うことになります。もちろん「loopCounter」とかいうかっちょいー名前でもかまわないのですが、繰り返し文の中にはこのカウンタが沢山出てくるので、あまり長い変数名だと見づらくなります。
 そこでたった一文字で済むようにと「i」がカウンタ変数に選ばれたわけです。見た目はアルファベットですが、この瞬間からiは数字として扱われることになったのです。
 このブログに限らず、この「i」がカウンタとして使われることは非常に多いです。Javaの慣習的な部分も大きいので、ルーツを知りたい方はググってください。
 通常、変数名はあとで見ても内容が推察できる名を付けるのが常識ですが、Javaスクリプトを書いたことがある人は「i=カウンタ」という認識を持っているので、安心して「i」を使って大丈夫です。

 長くなりましたが、開始条件はこう設定されました。

 「カウンタは0からスタート(i=0)」


② 続行条件とは
 開始に条件があれば続行にも条件があります。ここの書き方次第では「永遠に終わらないスクリプト」を作ることも可能です。「無限ループ」というやつですね。うっかり無限ループさせてしまうこともスクリプト作成中には付き物なのですが、そのときはInDesignを強制終了させることになります。ESTKから実行していてうっかり無限ループさせてしまった場合は、停止ボタンを押せば強引に止めることが出来ます。
ここで終了条件はこう設定されました。

 「カウンタの数字より『3』の方が大きい(i<3)」

この式の答が○として成立しているあいだ(カウンタの値が0~2)はforの隣にある「{」から、3行めに書かれた「}」の中身を実行し続けます。
iが3になった途端、「i<3ではなくi=3」になってしまうため、繰り返し処理が終了します。
3と設定したのは、テキストフレームが3個あるからです。たとえば「i<2」なら2個のテキストフレームだけが黒塗りになります。
そして式の答が×(カウンタが3より小さくない)になったらそこで繰り返し文の実行が停止されます。


③ カウンタ加算値
 ①でカウンタが0に設定され、②で続行条件が「カウンタが3より小さいあいだ」に設定されました。そしてカウンタを回すのがこの③です。
 繰り返し文を実行中は、「{}」の中身を1回処理するたびに「()」の中身に戻ってきます。そして、戻ってくるたびに「③を実行し(カウンタを回す)、②式が○として成立しているかを確認する」という処理をします。

 では[例2]で実際のカウンタ加算値を見てみましょう。「i++」とあると思います。「数字がないじゃん!」と驚く方もいるかと思います。
 これはもうJavaスクリプトの約束事で、「1を足す」は「++」で表現できることになっているのです。もしこの「++」が使えないと、「i=i+1」というちょっと面倒くさい書き方をしなくてはなりません。
 「++で1足してくれてラッキー!」とむしろ喜ぶべきです。ちなみに「--」で「1引く」が表現できます。勘のいい人はピンと来ていたかもしれませんね。
 かくしてカウンタ加算値はこう設定されました。
 
 「{}の中を1回処理するたびにiを++(iに1を足す)しろ」

 iの初期値は0でしたね。スクリプトは{}の中を1回処理し終えるたびにiの中に入っている数字に1を足していきます。
 こうして{}の処理からスクリプトが戻るたびにiは「0、1、2」とカウントアップしていきます。

④繰り返したい処理について
ようやく、実際に繰り返して行う処理の部分までやってきました。
 {}の中身をスクリプトはfor文の書き方に沿って実行します。
 ただし、

[間違った書き方①]

for (var i=0; i<3; i++){
app.activeDocument.textFrames[0].fillColor = "Black";
}

こんな書き方をしてしまうと、せっかくの繰り返し文が台無しになります。一件[例2]そっくりですが、よく見るとtextFramesの添字が[0]になっていますね。
これを実行すると、「1個めのテキストフレームを黒く塗れ」を3回繰り返すことになります。
エラーが出ずに、一見ちゃんと動いちゃうのが困りますね。
やりたいのは同じフレームに3回塗ることではなく、「1個め、2個め、3個め…」と、繰り返すたびにテキストフレームを切り替えながら色を塗っていくという処理ですよね。

ではどうしたら繰り返すたびに違うテキストフレームを選んでもらえるのでしょうか?

「ああ…添字が勝手に増えてくれればなあ…」

あれ? 勝手に増えてくれる数字ならありますよね。そう、「i」です。こんなふうに書いたらどうでしょう

textFrames[i]

iはスクリプト実行時点では「0」であり、{}の処理から戻るたびにスクリプトはiを1ずつカウントアップしていきます。

つまりfor文で書かれたスクリプトはこんな動作をするわけです



1 for(①iの初期値は0) {テキストフレーム[0]に処理}→最初に戻る

2 for(③iに1を足す(iが1になる) ②iより3の方が大きい はまだ成立中 {テキストフレーム[1]に処理}→最初に戻る

3 for(③iに1を足す(iが2になる) ②iより3の方が大きい はまだ成立中 {テキストフレーム[2]に処理}→最初に戻る

4 for(②iより3の方が大きい は、iと3が同じ大きさになったため成立しない →繰り返し処理終了



ここで物凄く勘のいい方は「初期値は毎回0にしとけば良さそう、カウンタ加算値も毎回1ずつで良さそう、でも続行条件ってなんか設定すんのめんどくさっ」
ってなんとなくめんどくささを感じるかもしれません。
たとえばテキストフレームが1000個近くあったとしても、何個あるか数えなくてはいけないのでしょうか?

そう、数えなくてはいけません。でもそれ、ちょこっと[例2]の書き方を変えるだけでスクリプトが数えてくれますヨ。


次回はその説明をします(つづく)