さて、今回もライトなGAS記事です。
GASを書く方からすると、おいっ!てなるスプレッドシートの一つに、セル結合されているシートがあるかと思います。1行1レコードにしてくれよ、ってなるとき多いですよね。
そんなちょっといらっとしてしまう、セル結合もGASで解消する方法があります。
今回はセル結合をGASで解除する方法を紹介していきます。
GASでセルの結合を一括解除する方法
まずは一括解除の方法を紹介します。目視で解除って方法ももちろんありますが、そんなことはしたくないですよね。
そこで、GASを利用して一括解除していきましょう。
セル結合解除:対象のシート
今回利用するシートはこんな感じにバラバラとセルの結合がされているシートです。

1は2カラムを結合、2は2行を結合、3は2×3セルが結合されてます。全部パパッと解消していきましょう。
セル結合解除:GASスクリプト
では、どんなスクリプトになるか、というと以下の感じです。
function breakMultiCells() {
let sht = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("シート1");
let data_range = sht.getDataRange();
let multi_bind_cell = data_range.getMergedRanges();
multi_bind_cell.map(a => Logger.log(a.getA1Notation()))
multi_bind_cell.map(a => a.breakApart())
}
やっていることのイメージは以下になります。
- step1セル結合されているrangeを全て取得する
datarange全体に対してgetMergedRangeメソッドを使い、セル結合されているrangeの一覧を配列で取得する
- step2セル結合を解除する
breakApartメソッドを利用して、セル結合対象セルの結合を解除する
セル結合解除:スクリプト解説
さて、簡単なスクリプトの解説をしていきたいと思います。今回ちょっと目新しいのは以下の2つかなぁと思います。
一つづつ少しだけ解説を加えていきましょう。
getMergedRangesメソッドとは?
さて、これまで紹介したことのないメソッドの一つですが、getMergedRangeメソッドというメソッドがあります。
mergedセルの特定を行う際にはこれを利用すると早いです。
実際今回活用したスクリプトだと以下の部分です。
let data_range = sht.getDataRange();
let multi_bind_cell = data_range.getMergedRanges();
getDataRangeメソッドでデータ範囲を全て取得したあと、当該rangeオブジェクトに対してメソッドを当てていいます。
breakApartメソッドとは?
もう一つが、breakApartメソッドです。
実際今回活用したスクリプトだと以下の部分です。
multi_bind_cell.map(a => a.breakApart())
mapで配列全てに一括処理を実施していますが、やってることは先ほど紹介したgetMergedRangesで返された配列(結合セルのrangeが配列化されたもの)に対して、一つづつbreakApartメソッドを当てています。
mapがよくわからない方はfor系統でも同様の処理は可能です。
セル結合解除:結果
さて、最後に実行結果もみていきましょう。こんな感じになります。

無事セルの結合が解除されてますね!めでたし、めでたし。。。。
なのか?
これでめでたしというわけにもいかないことが実務では多くないですか?だって、セル結合解除したあと、本来同一のデータとして表示されて欲しい部分がほとんどブランクになってしまっています。
セル結合におけるデータのアロケーション
さて、上記のようになった理由を理解するためにはセル結合した場合のデータの保持セルの話を最低限理解する必要があります。
セル結合された場合、データってどのセルが保持してると認識されているかわかりますか?簡単に理解できるように、一旦以下のような計算式を入れてみてください。

わかりますか?H1に計算式(+式)を入れて、結合セルを選択した画像になります。どこが指定されてます?
そうなんです、B3セルが指定されてますよね?
もう一個やると理解できると思うので、もう一つサンプルで数値3の部分の結合で試してみます。

今度はB8セルが指定されているのがわかります。
つまりはどういうことかというと、以下なんです。
そう、全てのセルが同一の値を保持しているのではなく、あくまで一番左上にあるセルだけが数値を保持しているのです。
この前提を理解していると、breakApartメソッドで分割したときに先の結果になったのが理解できるかと思います。
じゃぁどうやって対応するのよ?って話になりますよね。もちろん準備してますよ(というか、自分はこっちしか使ってませんw)
GASでセルの結合を一括解除+値を展開する方法
同じデータを対象としますので、スクリプトの紹介と結果画面だけ共有します。
セル結合解除+値展開:GASスクリプト
スクリプトは以下の感じになります。
function breakMultiCells() {
let sht = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("シート1");
let data_range = sht.getDataRange();
let multi_bind_cell = data_range.getMergedRanges();
multi_bind_cell.map(a => Logger.log(a.getA1Notation()))
multi_bind_cell.map(function(a){
a.breakApart();
let data_cell = a.getA1Notation().slice(0,2);
let value = sht.getRange(data_cell).getValue();
a.setValue(value)
})
}
多分ここまで読み進められてる方なら、コード解説はなくても理解できると信じて、コード解説は省きます!w(わかんなかったらコメントなどしてください汗)
セル結合解除+値展開:実行結果
こんな感じに綺麗に値展開もできます。

これで、うざったいセル結合ともおさらばできますね。
まとめ
今回は、【スレッドシートのセルの結合をGASで解除する方法〜単純解除と結合セルの値の展開方法〜】ということで、GASの書き手側からするとうざったいセル結合に対応する方法を紹介してきました。
いや、そもそもセル結合なんてするなよって思いが強いのですが、いまだにやってくる人いるんですよねぇ。。。リテラシー。。。
そんなデータでも対応できるので、セル結合解除、そしてセル結合範囲への値展開の方法は自分の心を落ち着かせるために必要なメソッドになっています。