GASでスプレッドシートの
セルを結合・結合解除する方法

見出しやタイトル行を整えるセルの結合を、GASのコードから自動化する方法を解説します。mergeでの範囲結合、行ごと・列ごとの結合、解除、結合セルの調べ方まで、動くコードと落とし穴つきで紹介します。

|対象: GAS / スプレッドシート / セル結合

Table of Contents

セル結合の基本と「値が消える」注意点

セルの結合とは、隣り合う複数のマス目を見た目上1つのセルにまとめる機能です。GAS(Google Apps Script。Googleのサービスを自動化できるスクリプト)では、範囲を表すRangeに対してmerge()を呼ぶだけで結合できます。請求書のタイトル行や、レポートの見出しを整えるときに使います。

最初に必ず押さえたい落とし穴が1つあります。結合すると、範囲の左上のセルの値だけが残り、それ以外のセルの値は消えます。これは画面操作と同じ挙動です。値を入れてから結合するときは、必ず左上のセルに値を入れてからmerge()を呼びましょう。

向いている用途

タイトル・見出し・区分ラベルなど、人が見る体裁を整える部分。1セルにまとめて見やすくする。

避けたい用途

並べ替え・フィルタ・GASで集計する「データ本体」。結合があると処理でつまずきやすい。

mergeで範囲を1つに結合する

基本形はgetRange("A1:E1").merge()です。指定した範囲全体が、1つの大きなセルに結合されます。下のコードは、請求書シートの1行目を横長のタイトルセルにする例です。値を入れてから結合し、そのあと中央揃え・太字で体裁を整えています。

function mergeTitleCell() {
  const sheet = SpreadsheetApp.getActive().getSheetByName("請求書");

  // 先にタイトルを左上セルへ入れておく(結合で左上以外は消えるため)
  sheet.getRange("A1").setValue("請求書");

  // A1:E1 を1つのセルに結合する(見出し用の横長セル)
  sheet.getRange("A1:E1").merge();

  // 見た目を整える(中央揃え・太字)
  sheet.getRange("A1")
    .setHorizontalAlignment("center")
    .setFontWeight("bold");
}

結合後にスタイルを設定するときは、左上セル(この例ではA1)を対象にすれば結合セル全体に反映されます。

mergeAcrossで行ごとに横結合する

複数行をまとめて「各行ごとに横結合」したいときはmergeAcross()を使います。merge()が範囲全体を1つにまとめるのに対し、mergeAcross()は行の高さを保ったまま、1行ずつ横方向に結合します。区切り見出しを何行も作るときに便利です。

function mergeEachRow() {
  const sheet = SpreadsheetApp.getActive().getSheetByName("見出し");

  // A2:C5 を「行ごとに」横結合する
  // A2:C2、A3:C3、A4:C4、A5:C5 がそれぞれ1セルに結合される
  // (範囲全体が1つになる merge() との違いに注意)
  sheet.getRange("A2:C5").mergeAcross();
}

mergeVerticallyで列ごとに縦結合する

縦方向にまとめたいときはmergeVertically()です。大分類のラベルを縦長のセルにして、複数の小分類にまたがせる、といった表でよく使います。下の例では、A列の6行分を1つの縦セルに結合し、上下中央に配置しています。

function mergeEachColumn() {
  const sheet = SpreadsheetApp.getActive().getSheetByName("分類");

  // A2:A7 を縦に結合して「大分類」ラベルのセルを作る
  sheet.getRange("A2").setValue("食品");
  sheet.getRange("A2:A7").mergeVertically();

  // 縦書き見出しのように上下中央・中央揃えにする
  sheet.getRange("A2")
    .setVerticalAlignment("middle")
    .setHorizontalAlignment("center");
}

breakApartで結合を解除する

結合を解除するにはbreakApart()を使います。解除しても、値は左上のセルに残ったままです(結合時に消えた他セルの値は戻りません)。テンプレートを作り直すときや、結合済みのシートをデータ処理向けに整えるときに使います。

function unmergeRange() {
  const sheet = SpreadsheetApp.getActive().getSheetByName("請求書");

  // A1:E1 の結合を解除する
  // 解除しても値は左上セルに残ったまま(他のセルは空のまま)
  sheet.getRange("A1:E1").breakApart();
}

結合を作り直したいときは、いったんbreakApart()で解除してから、あらためてmerge()し直すのが安全です。既存の結合と一部だけ重なる範囲を結合すると、意図せず広い範囲がまとまってしまうことがあるためです。

結合セルを調べる・一括解除する

ある範囲が結合されているかはisPartOfMerge()で判定できます。シート内の結合セルを一覧したいときはgetMergedRanges()を使うと、結合されている範囲(Range)の配列が返ります。

function inspectMerges() {
  const sheet = SpreadsheetApp.getActive().getSheetByName("請求書");

  // 特定の範囲が結合セルを含むか判定する
  const isMerged = sheet.getRange("A1:E1").isPartOfMerge();
  Logger.log("A1:E1 は結合を含む? " + isMerged);

  // シート内の結合セルを一覧する(Range の配列が返る)
  const dataRange = sheet.getDataRange();
  const merges = dataRange.getMergedRanges();
  merges.forEach((r) => {
    Logger.log("結合セル: " + r.getA1Notation());
  });
}

このgetMergedRanges()を使えば、GASで集計する前に結合をすべて解除する前処理も書けます。結合が残っているとgetValues()に空セルが混ざるため、機械処理の前に外してしまうのが安全です。

function unmergeAllBeforeProcessing() {
  const sheet = SpreadsheetApp.getActive().getSheetByName("データ");

  // データを機械処理する前に、シート内の結合をすべて解除する
  const merges = sheet.getDataRange().getMergedRanges();
  merges.forEach((r) => r.breakApart());

  // これで getValues() が空セルなしで安定して読める
  const values = sheet.getDataRange().getValues();
  Logger.log(values.length + " 行を読み込みました");
}

実務での注意点

1. 値は「結合前」に左上へ入れる

結合で左上以外の値は消えます。値を書いてから結合する場合は、必ず左上セルに入れてからmerge()を呼びましょう。逆の順番だと、せっかく書いた内容が消えてしまいます。

2. getValuesでは空セルが混ざる

結合セルは、データとしては元のマス目が残っています。左上以外は空文字として読まれるため、結合セルが混ざった範囲を集計すると件数や合計がずれます。データ本体は結合しない設計にするか、処理前に一括解除しましょう。

3. 並べ替え・フィルタと相性が悪い

結合セルを含む範囲は、並べ替えやフィルタでエラーになることがあります。人が見る見出し・表紙部分だけ結合し、集計対象のデータは結合しない、という切り分けが安全です。

まとめ

GASでのセル結合は、範囲全体ならmerge、行ごとならmergeAcross、列ごとならmergeVerticallyが基本です。解除はbreakApart、調査はgetMergedRangesを使います。ポイントは「結合で左上以外の値は消える」「データ本体は結合しない」の2点。見出しの体裁づくりと機械処理を切り分けて使えば、帳票やレポートの自動生成がぐっと楽になります。

よくある質問

結合すると、範囲の左上のセルの値だけが残り、それ以外のセルの値は削除されます。GASのmerge()も画面操作と同じ挙動で、左上以外の中身は消えます。消したくないデータがある場合は、事前に値を退避しておくか、結合する範囲に本当に不要なセルだけを含めるようにしてください。

結合セルは左上のセルにだけ値が入り、それ以外のセルは空文字("")として返ります。見た目上は1つのセルでも、データとしては元の行・列のマス目が残っているためです。結合セルが混ざったシートをGASで集計すると、空セルのせいで件数や合計がずれることがあるので注意が必要です。

すでに結合されている範囲に対してmerge()を呼んでもエラーにはならず、そのまま結合状態が保たれます。ただし、別の結合セルと一部だけ重なる範囲を結合しようとすると、意図せず広い範囲がまとめて結合されることがあります。作り直したいときは、いったんbreakApart()で解除してから結合し直すのが安全です。

できます。範囲に対してisPartOfMerge()を呼ぶと、その範囲が結合セルの一部を含む場合にtrueが返ります。シート全体の結合セルを一覧したいときは、getMergedRanges()で結合されている範囲の配列を取得できます。結合を解除してからデータ処理したい、といった前処理で役立ちます。

見出しやレポートの体裁を整える用途では便利ですが、GASやフィルタ・並べ替えで機械的に処理するデータ範囲では避けた方が無難です。結合があると並べ替えでエラーが出たり、getValuesで空セルが混ざったりします。人が見る「表紙・見出し部分」だけ結合し、集計対象のデータ本体は結合しない、という切り分けがおすすめです。

GAS開発・業務Webシステムを
相談する。

請求書・帳票のレイアウト整形から、集計シートの自動化・フォーム連携・Gmail自動化まで、日々の業務を自動化するGAS開発をご相談いただけます。

GAS Webシステム開発を見る