【入門者向け④】スクリプトでInDesignを操作 ~変数について~
④にしてようやく変数の話。スクリプトの入門書はまずここから説明したりするのですが、敢えて後回しにしました。
for文の説明のときに軽く触れたとは思いますが、今回はもう少し踏み込んでみます。
なぜここまで変数を使わずに来たかというと、どこで何をしているかをわかりやすくするためです。
他人の書いたスクリプトを読むときは、まずどこでどんな変数を使っているかを頭に置きながら読まなくてはなりません。そして脳内で置換しながら読み解いていくのです。
初心者には結構大変ですよね。なので、入門者向けコラムでは変数なしで説明を進めてきたというわけです。
ここからは変数をどんどん使っていきます。まず変数とは何か?
一言で言えば、スクリプトの文章を、ユーザの好きな言葉に登録出来て、好きなときに呼び出せるというものです。
「スクリプトの文をユーザの好きな言葉に登録出来て、好きなときに呼び出せる」
をスクリプト的な言葉に置き換えると
「スクリプトの値をユーザの好きな変数に代入することが出来て、好きなときに参照できる」
という感じでしょうか。この、値を好きな変数に代入するという一連の行為を「変数の宣言」といいます。
日本語入力でいうところの単語登録のような感じですね。
変数を宣言するときは、次のような感じで書きます。
var 変数名 = 値
つまりはこんな感じ。
var myDoc = app.activeDocument;
var というのが変数宣言の命令文ですね。
ちなみにvariableの略で「可変的な」という意味があるそうです。
じつはvarを付けなくても変数宣言は出来てしまうのですが、基本的には必ず付けるようにしてください。理由はさらに変数を詳しく説明するときに書きます。
話がそれましたが、これで変数名「myDoc」が宣言され、「app.activeDocument」が代入されました。
web用のJavaScriptや、Excelなどで使うVBAではこの変数が「数値用」なのか「文字用」なのかそれとも…といったこと(型といいます)も指定するのですが、InDesignスクリプトではある程度自動で判断してくれちゃいます。ありがたいですね。
前回使ったサンプルを、変数を使った文に直してみます。
[例1]前回のまま
for (var i=0; i<app.activeDocument.textFrames.length; i++){ app.activeDocument.textFrames[i].fillColor = "Black"; }
[例1-A]変数を用いたパターン
var myDoc = app.activeDocument; var obj = myDoc.textFrames; for (var i=0; i<obj.length; i++){ obj[i].fillColor = "Black"; }
「app.activeDocument.textFrames」が「obj」で表せるようになりました。その直前に「app.activeDocument」も「myDoc」に代入していますね。
for文の中身もスッキリしました。
しかも、これからは変数の値を変更することで、全体を変更することができます。
たとえばあとで「textFrames」を「allPageItems」に変えたくなったときに、変数の値だけ直せば済んでしまいます。スクリプトが長いほど、変数のありがたみが分かるでしょう。
変数は「習うより慣れろ、もしくは真似ろ」だと思っています。
ベテランの人がどんなふうに変数名を付けているのか、どんなところで変数宣言するのか、書いたり真似たりして慣れていくのが一番です。
この先、関数なんかを取り入れていくと変数の範囲や寿命といったものを考えながら扱う必要が出てきますが、このブログでは必要時に都度説明するつもりです。
最後に、初心者がやりがちなミスを載せます。
[例1-B]ありがちなミス
var myDoc = app.activeDocument; var i = 0; var obj = myDoc.textFrames[i]; for (i=0; i<obj.length; i++){ obj.fillColor = "Black"; }
[例1-A]と大差なく見えますが、こいつを実行するとエラーが出ます。
「obj」をバラすと「myDoc.textFrames[i].length」になります。「length」を付けるときは[0]や[i]といった添字を付けてはいけないので、エラーになるのです。どうしても添え字を含めたいときは次のような書き方をしたりします。
[例1-C]
var myDoc = app.activeDocument; var obj = myDoc.textFrames; for (i=0; i<obj.length; i++){ var objs = obj[i]; objs.fillColor = "Black"; }