DTPab

DTPにまつわるあれこれ

1if-1for:書き捨ての小さなスクリプトたち

f:id:uske_S:20180721002323p:plain

最近自分が手がけるスクリプトが、1000行を超える中〜大規模なスクリプトか、こまごまと5分くらいで書いて捨てる30行以内くらいのごく小規模のスクリプトのどちらかになりつつあります。というのも、同僚たちから依頼されたスクリプトに細やかに対応する時間が取れないのが大きな原因です。必然的に休み時間や仕事の合間に書けるような小さなものが増えているというわけです。

それはさておき、そうした「必要になって書いたけど数回実行したら捨ててしまう」スクリプトだからこそ、中身はけっこうシンプルです。
まず、自分しか使わない、作ったその時しか使わないという前提のため、動作条件をスクリプト側に設けないことが多い。要するに、スクリプトを使うときに、アプリケーションをスクリプトの条件に合うような状態にしてからスクリプトを実行するのです。
そうすると、普段必ずと言っていいほど実装している実行条件の絞り込み(ドキュメントを開いているか、選択しているオブジェクトの状態や種別の判別等)やアプリケーションのバージョンチェック等、そういう前提条件をすっ飛ばして行いたい処理のみを書くことができます。

言い方を変えると、そういうスクリプトは中長期的には使えません。なぜならスクリプト実行の前提条件を覚えていられないからです。作った案件の校正回転が一通り終わった頃にはもう忘れてます。それ以上長く使えそうなスクリプトであれば、きちんと実行条件を書き加えたり、汎用性を持たせるためにコードの一部を変数にしたり関数にしたりして「一人前のスクリプト」に仕立てます。
そのような「一人前のスクリプト」になる前の、いわば「半人前のスクリプト」って、ひとつのif文とひとつのfor文でそこそこ書けるのです。

んで、普段書いて捨ててしまっていたような規模の小さなスクリプトですが、その処理のメインエンジン部分にだけ焦点を当てると意外とスクリプトの勉強にいいんじゃなかろうかと思ったのです。そこで「1 if, 1 for」というシリーズで、ひとつのif文とひとつのfor文でどんなスクリプトが作れるのか、不定期に紹介していけたら面白いかなと。

記念すべき第1回目は、ついこの間書いて捨ててしまった「表組みの空のセルに文字列を入れる」スクリプトです。

まずはコードをどうぞ。

var doc = app.activeDocument;
var sel = doc.selection[0];
var cel = sel.cells; //セルを選択しているという前提

for (var i=0; i<cel.length; i++) {
    if (cel[i].contents === "") {
        cel[i].contents = "★";
    }
}

これがその「半人前のコード」です。表組みのセルを選択して実行することを前提としています。
そしてご覧のとおり、for文とif文はひとつずつしか使っていません。これでも立派なスクリプトです。「選択した表組の空のセルに文字列を入れる」という目標を達成できるのですから。

冒頭の3行は変数を定義しているだけです。3行目だけにまとめても問題ないです。

var cel = app.activeDocument.selection[0].cells; //セルを選択しているという前提

ただ、Documentオブジェクト(doc)や選択したオブジェクトのメンバー(sel)などは、もう少し処理の複雑なコードでは頻繁に使います。そういう意味でこれらのオブジェクトは変数に代入しておいたほうが、のちのち便利なことが多いです。

表組のセルはCellオブジェクトです。その中の文字列はCell.contentsで参照します。if文では「i番目のセルの中の文字列」が「""(=空の文字列)」である場合、条件式が真と評価されて{ }の中の処理を実行します。

中の処理では文字列「★」をCell.contentsに代入していますが、代入演算子+=としても同じです(空の文字列の後ろに★を追加するという意味なので)。

以上、「1 if, 1 for」シリーズの第一回目でした。こんな感じで簡単なスクリプトをちょこちょこっと紹介していけたらと思っています。
次回は「非アクティブな合成フォントをすべて削除する」を予定しています。