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

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

【入門者向け⑨】関数(function)についての初歩の初歩

1 Excelの関数とはちと違う

今回は関数についてです。
「私、Excel使ってたから関数は得意!」
「ぼくはvlookup関数が好きだなあ」
なんて方もいるかもしれませんが、InDesignスクリプトでいう関数は、Excelのそれとは全然違います

「なんだか難しそうだなあ」
関数という響きからそんな印象も持たれるかもしれませんが、スクリプトの関数は簡単で便利です。
とはいえなかなか奥が深いものなので、ここでは初歩中の初歩的な使い方を解説します。

2 ためしに普通に書いてみた

実際に動きを見ながら読みたいという方は、次のようなInDesignドキュメントを作成してください。
スウォッチ名と色が合っていれば、CMYKの配合は適当でいいです。

f:id:rokuyaN:20170711111608j:plain

この3つのテキストフレームの中に、
 ① 文字列(枠の色名)を入れる
 ② すべての文字列に同じ書式を設定する(文字サイズ、長体、ベースライン、回転)

という処理をするスクリプトが[例1]です。
まずは関数をまったく使わずに書いてみました。

[例1]関数を使わない場合
var myDoc = app.activeDocument;//アクティブドキュメント
var obj = myDoc.textFrames; //変数objはテキストフレームのこと

for (var i=0; i<obj.length; i++) {
        if (obj[i].strokeColor.name=="青") { //線が青なら
            obj[i].contents = "青"; //中の文字は青
                with (obj[i].parentStory) {
                        pointSize = "24 Q"; //文字サイズは24Q
                        horizontalScale = 70; //長体70%
                        baseLine = 5; //ベースライン+5
                        characterRotation = 45; //文字の回転45
                        }
            }
        if (obj[i].strokeColor.name=="赤") {
            obj[i].contents = "赤";
                with (obj[i].parentStory) {
                        pointSize = "24 Q"; //文字サイズは24Q
                        horizontalScale = 70; //長体70%
                        baseLine = 5; //ベースライン+5
                        characterRotation = 45; //文字の回転45
                        }    
            }
        if (obj[i].strokeColor.name=="黄") {
            obj[i].contents = "黄";
                with (obj[i].parentStory) {
                        pointSize = "24 Q"; //文字サイズは24Q
                        horizontalScale = 70; //長体70%
                        baseLine = 5; //ベースライン+5
                        characterRotation = 45; //文字の回転45
                        }                
            }
    }

実行すると次のような感じになるかと思います。

f:id:rokuyaN:20170711123849j:plain

3 次に、関数をからめて書いてみた

これで完成、めでたしめでたし…でも良いのですが、[例1]を関数を用いて書き直すと[例2]になります。

[例2]関数を使った書き方
var myDoc = app.activeDocument;
var obj = myDoc.textFrames;

for (var i=0; i<obj.length; i++) {
        if (obj[i].strokeColor.name=="青") {
            obj[i].contents = "青";
                    myFontStyle ();//関数呼び出し
            }
        if (obj[i].strokeColor.name=="赤") {
            obj[i].contents = "赤";
                    myFontStyle ();//関数呼び出し
            }
        if (obj[i].strokeColor.name=="黄") {
            obj[i].contents = "黄";
                    myFontStyle ();//関数呼び出し
            }
    }

function myFontStyle () { //処理を書き入れた関数
                with (obj[i].parentStory) {
                    pointSize = "24 Q"; //文字サイズは24Q
                    horizontalScale = 70; //長体70%
                    baseLine = 5; //ベースライン+5
                    characterRotation = 45; //文字の回転45
                        }    
    }

4 関数を使うメリット

まず、行数が短くなっていますね。
スクリプト自体も読みやすくなった気がしませんか? したと言って…

[例1]ではifごとに書式を設定していますが、[例2]は下の方に書いてあるfunction……という部分に書式設定がまとめられ、それぞれのifではfunctionを呼び出しているだけです。
このfunctionでくくられたブロックを関数と呼びます

基本的な書き方は次のような感じです。

 function 関数名 (){
  ここに処理を書く
 }

呼び出すときはただこれだけ。

 関数名()

関数名の横の()にも大事な役割があるのですが、今回は初歩の初歩なので説明しません。

関数化することによって受けられる恩恵はスクリプトが短くなるだけではありません。
まず、編集性が良くなります

たとえば[例2]の24Qの部分を32Qにしたいとき、[例1]では3箇所を直さなくてはなりませんが、[例2]では関数内の値を直すだけです。
なんだか変数のときの説明を思い出しますが、性質や役割的にはよく似ている部分があると個人的には思います。
また、スクリプトが長くなったときは特に、役割ごとに関数が分かれていれば修正するときやエラー箇所をさぐるときにスクリプトの見通しが良くなります

過去の記事に書いた「コマンドバトル」のスクリプトですが、あれはもともと関数の説明用に作ったものでした。
一度見ていただけると分かりやすいのですが、コマンドバトルスクリプトは「ダメージ計算」、「ターン処理」、「パラメータ画面の表示」といった具合に、処理ごとに細かく関数にしています。なので、あのスクリプト自体はめちゃ長いのに、書いてて混乱することはほとんどありませんでした。
もしあのスクリプトが全部ひとつながりになっていたら、ちょっとした修正や調整をしたい時にもひどく面倒だったでしょう。おそらく途中でわけがわからなくなって投げ出していたと思います…。

たとえばダメージ計算が関数として切り離されていることで、ダメージの処理法を変えたいときはほかの部分には影響を及ぼすことなくダメージ計算部分だけを直すことができます。
大きな組織ほど部署や個々の役割が細かく分かれているのと似ていますね

またスクリプトが長くなると{}括弧の数が膨大になって、どれがどの{}括弧なのかも分からなくなってきます。{}括弧をすっきりさせられるのも関数の利点だと思います。

スクリプトが長くなれば長くなるほど、複雑になれば複雑になるほど、上手に関数を使ってシンプルな構造にすることが大事です。