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

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

ループ(for文)でフレームを消し切る書き方

つづき

前回の例がフレームを消しきれない理由……それは、

ループでテキストフレームの数を減らしていくスクリプトなのに、ループの内側でテキストフレームの数を数えさせていたから

です。
「remove()」によりループするたびにテキストフレームが減っていってしまい、カウンタは増えていく。そのためループ回数の真ん中辺りでカウンタと終了条件が成立してしまうのです。
出題の元ネタは、過去に自分がやらかした書きミスです…


最後に、例題のスクリプトをうまく動かす模範解答的なものも載せておきます。

[解1]ループ前にテキストフレームの数を代入する方法

var myDoc = app.activeDocument;
var obj = myDoc.textFrames;
var objLen = obj.length;//←ループ前にテキストフレームの数を代入

for (var i=0; i<objLen; i++) {//条件文にはループの外で宣言した変数を使用
    obj[0].remove(); //削除実行
    }

…これが一番ポピュラーかな?
ループの前に宣言した変数の値は、ループによる影響を受けません。

↓のような書き方でも一応はちゃんと動きます。あまりこういう書き方はしないかもですが…


[解2]無限ループさせて、エラーが発生したら止める方法

var myDoc = app.activeDocument;
var obj = myDoc.textFrames;
var objLen = obj.length;

for (;;) {//式がないのでこのままだと無限ループする
    try {//ここでエラー処理
    obj[0].remove(); //削除実行
    } catch (e) {break}//エラーが出たらループを抜ける
}

try...catchって便利! かなり無茶苦茶な書き方なのにちゃんと動きます。

あるいは、最大値から始めてカウンタを減算していくという方法も…

[解答3]最大値からスタートして、カウンタを減らしていく方法

var myDoc = app.activeDocument;
var obj = myDoc.textFrames;

for (var i = obj.length; 0<i; i--) {
    obj[0].remove(); //削除実行
    }

この書き方だと、ループの前にフレーム数を代入する必要がありません。

もし主流のやり方をしらなかったとしても、いろんな方法を模索できるのがスクリプトの面白いところですね。
レイヤーやページを消す場合も、こうした書き方をする必要があります。
ただしレイヤーやページはその数を0にはできないので、その点は気をつける必要があります。