InDesign:スクリプトでのセルの結合
今更なんですが、スクリプトでのセル結合をちゃんと理解してなかったのでメモ。これは先に書いた延長講座の質問に回答するために調べたものです。ちなみにInDesignのバージョンは17.0(2022)です。
次のような場合(図1)に、黄色く塗ったセルと他のセルを結合してみます。
ベースとなるスクリプトはこんな感じ。この後にセルを結合する命令文を書きます。
var tbl = app.documents[0].textFrames[0].tables[0]; var cel5 = tbl.cells[5]; //黄色く塗ったセル
操作1
まず、9と書かれたセルを結合対象にします。
cel5.merge(tbl.cells[9]);
まあこれは手動と同じ。こうなります。
操作2
ではこの状態で6と書かれたセルを結合しようとするとどうなるでしょう。手動の場合だとメニューがグレーアウトしていて実行できません。
cel5.merge(tbl.cells[6]);
スクリプトだとこのように、10と書かれたセルも含めて結合されます。
どうやらスクリプトでのセル結合は、指定した2つのセルを含んだ最小の矩形範囲で結合が行われるようです。
操作3
図1に戻って、離れた位置にあるセルの場合を見てみます。
手動ではそもそも「5と書かれたセル」と「13と書かれたセル」を同時に選択することはできませんので、この2つのセルを結合することはできません。ところがスクリプトで次のように書くとエラーなく実行されます。
cel5.merge(tbl.cells[13]);
操作4
また図1に戻って、今度は14と書かれたセルと結合してみます。
cel5.merge(tbl.cells[14]);
という具合になります。「指定した2つのセルを含んだ最小の矩形範囲で結合が行われる」という推論は当たっているようです。
もうひとつ、スクリプトでのセル結合に注意点があります。このmerge()メソッドは引数にCell、Column、Rowを指定できます。
操作5
例えば次のようなものです。
cel5.merge(tbl.rows[1]);
これは5と書かれたセルと、表の2行目(つまり5と書かれたセルを含む)を結合します。図1の状態で実行するとこうなります。
このように2行目が丸ごと結合されました。注意していただきたいのは、黄色で塗られた5と書かれたセルに対して実行したのに、セルの塗りが黄色ではなくなっているということです。これについては後ほど書きます。
操作6
図1に戻って、今度は最終行と結合してみます。
cel5.merge(tbl.rows[4]);
このようにその間のセルも全部結合されてしまいました。
操作7
結果は予想できますが、一応列の場合もやってみます。図1の状態から次のスクリプトを実行します。
cel5.merge(tbl.columns[3]);
ということで「指定した2つのセル(行、列)を含んだ最小の矩形範囲で結合が行われる」という推論は当たっているようです。
以上でスクリプトでセル結合を行った場合に、どの範囲で結合されるかというのは大体わかりました。では、セルの属性はどのセルのものが採用されるのでしょうか。
操作8
操作5をセルの塗りの色を変えて再度実行します。
cel5.merge(tbl.rows[1]);
このように左端のセルの属性が有効になることがわかりました。
操作9
次のようなケース(2と6が結合状態)だとどうなるでしょう。
cel5.merge(tbl.cells[2]);
結果はこのようになりました。つまり1と書かれたセルを巻き込んで結合し一番左上の1と書かれたセルの属性が有効になるということですね。
この状態で、結合したセルの結合解除を行ってみます。
元の属性が戻ってますね。実はセルを結合しても結合前の情報はどこかに保存されているということになります。
以上のことから私の結論としては、「スクリプトでのセル結合は手動でできないことができてしまうので、事前によくテストして挙動を確認しておかないと危険だよ」ということになります。特に結合してあるセルに更に別のセルを結合してしまうと、予測の範囲を超えてしまう可能性があるからです。
また、セルを結合しても、結合前の属性はどこかに保持されているので、結合解除も危険だということですね。どこに情報があるのか、またそれを取得できる手段があるのかも今後の調査が必要です。
セルが結合しているかどうかを調べる方法
おまけなんですが、セルが結合しているかどうかは、セルのrowSpanプロパティ、columnSpanプロパティを調べると分かります。
このケースで次のスクリプトを実行すると行数・列数が分かります。
var tbl = app.documents[0].textFrames[0].tables[0]; var cel5 = tbl.cells[5]; //黄色く塗ったセル alert(cel5.rowSpan); //→3と表示される alert(cel5.columnSpan); //→2と表示される
どちらも1であれば結合されていないセル、どちらかが1以外であれば結合されているセルと判断できます。
また、CellオブジェクトにはRowsプロパティ、Columnsプロパティがあるので、それを利用して次の書き方もできます。
var tbl = app.documents[0].textFrames[0].tables[0]; var cel5 = tbl.cells[5]; //黄色く塗ったセル alert(cel5.rows.length); //→3と表示される alert(cel5.colums.length); //→2と表示される
12月3日 追記
教室の質問者さんが追加調査をしてくださいました。
(クリックして別ウィンドウで拡大)
それによるとセルを結合した場合、
- Cell.indexプロパティは結合された分だけ繰り上がる
- Cell.nameプロパティは結合前のセルのうちの左上のものが有効になる
- 結合しても結合前のCell.nameプロパティを指定した操作は有効
ということです。またidプロパティについても調べていただきました。こちらは複雑なので図を見てもらえればと思います。