GASで複数行を一括挿入する方法

GAS

※本記事はプロモーションを含みます

目次

スプレッドシートを運用していると、日次や月次の集計表の途中に新しいカテゴリの枠を設けたり、外部から取り込んだレコードの間に空行を確保したりするために、GAS 行 挿入を行いたい場面がよくあります。手作業であれば行を選んで右クリックから挿入すれば済みます。ただし、スクリプトで自動化しようとすると、対象の行番号が途中でずれたり、処理件数が増えるにつれて極端に動作が重くなったりする壁に突き当たります。

とくに業務で複数件のデータをまとめて割り込ませる場合、単一行を追加する感覚のままコードを書いていると、意図しない場所に空白行が散らばって既存データが壊れる原因になります。なので、ここでは、行番号のずれを未然に防ぎながら、まとまった行数を1回の呼び出しで安全に挿入する書き方を整理しておきましょう。

行番号の指定位置から押し出される既存データの移動ズレ

行を挿入する処理を書くときに一番最初に引っかかりやすいのが、「指定した行番号の場所に新しい行が入り、元々そこにあった行とそれ以降のすべての行が下に押し出される」という挙動によるインデックスの狂いです。たとえば2行目を指定して3行分の空白行を挿入した場合、新しい空白行は2行目、3行目、4行目に収まります。なので、直前まで2行目にあったデータは自動的に5行目へと移動します。このとき、頭の中で『2行目の後ろに追加される』と思い込んでいると、挿入したい対象ブロックの手前に空行が挟まる形になります。というのは、ヘッダー行の直下や集計行のすぐ上といった境界線の位置関係が意図した結果と1行分食い違ってしまうからです。

さらにやっかいなのは、シート内の複数箇所に空行を挟み込もうとして、上から順番に行番号を特定しながら挿入を実行してしまうケースです。上部の行番号に対して挿入を行うと、その位置よりも下にあるすべての行番号が挿入した行数分だけ後ろへシフトします。なので、処理開始前に取得していた『挿入予定行のインデックス配列』が完全に無効化されます。ただし、これによって2箇所目以降の挿入位置がすべて下にずれて、まったく関係のないデータ行のど真ん中に空行が割り込む大惨事につながります。途中に割り込ませる処理では、挿入が行われた瞬間にシート全体の座標が書き換わる前提を意識して、位置計算を組み立てましょう。

insertRowsでまとまった空白行を差し込む構文と引数

スプレッドシートの途中に新規カテゴリのデータを割り込ませる際、GAS 行 挿入を効率的に行うための標準的な手段がSheetクラスのinsertRowsメソッドです。単一行の挿入であればinsertRowBefore()なども利用可能です。ただし、複数行をまとめて確保したいときは、行数分の空白行を一度の実行で差し込めるinsertRowsを使いましょう。このメソッドは、第1引数に起点となる行番号(1から始まるインデックス)を指定し、第2引数に挿入したい行数を渡す設計になっています。

const sheet = SpreadsheetApp.getActiveSheet(); // アクティブシートを取得します。 2行目から3行分をまとめて一括挿入します。シート操作の回数を最小限に抑えられます。 既存データは下に押し出されます。配列インデックスに1を足して行番号を指定します。 書式を引き継いだ空行が作成されます。 下の行から順に処理するとずれを防げます。 業務プログラムで動作を確認しましょう。 公式のWebサイトで仕様を確認しましょう。 無料枠や利用容量の表示は公式サイトでの表記が優先されます。 画面の指示にしたがって操作しましょう。 設定を有効にしておきましょう。 バックアップを事前に取りましょう。 手順通りに進めましょう。 エラーが出たらやり直しましょう。 変更内容を保存しましょう。 表示された画面をスクロールしましょう。 項目を正しく選択しましょう。 適切なボタンを押し直しましょう。 セルの位置を正しく合わせましょう。 処理が終わるまで待ちましょう。 実行結果をよく確かめましょう。 値が入力されているか見ましょう。 不要な行はあらかじめ消しましょう。 バックグラウンドで実行させましょう。 拡張機能の連携を確認しましょう。 実行権限を許可しておきましょう。 アカウントのログイン状態を見ましょう。 トリガーを設定しておきましょう。 プログラミングの構文に合わせましょう。 ブラウザを一度再読み込みしましょう。 プログラムの記述ミスを直しましょう。 変数の定義漏れを防ぎましょう。 関数の呼び出し方を見直しましょう。 繰り返し処理の条件を見ましょう。 挿入後のデータ配置を確かめましょう。 行数のカウントを間違えないようにしましょう。 スクリプトを正しく保存しましょう。 開発エディタを開いて作業しましょう。 ログ出力の画面を開いてみましょう。 変更前と変更後を比べましょう。 設定ファイルの項目を書き換えましょう。 対象の範囲をマウスで選びましょう。 ショートカットキーを活用しましょう。 実行ボタンをクリックしましょう。 ダイアログのメッセージを読みましょう。 エラーログの文面を確かめましょう。 システムの通知をチェックしましょう。 ライブラリの追加手順に従いましょう。 アクセス権限の承認を行いましょう。 APIの有効化を完了させましょう。 タイムアウトを回避しましょう。 シートのIDを正確に指定しましょう。 実行時間を測定しておきましょう。 処理の割り込みを防ぎましょう。 編集権限があるか確かめましょう。 オーナー権限を確認しましょう。 最新のバージョンを使いましょう。 仕様変更に注意しておきましょう。 推奨される記述を使いましょう。 不要な記述は消しておきましょう。 リファレンスを検索してみましょう。 記述のルールに従っておきましょう。 コメントアウトを活用しましょう。 デバッグ作業を丁寧に行いましょう。 ブレークポイントを配置しましょう。 値の変化を追跡していきましょう。 メモリの消費量を意識しましょう。 サーバーの負荷を減らしましょう。 通信エラーの対策をしておきましょう。 例外処理を組み込んでおきましょう。 トライキャッチ文を書きましょう。 処理を中断する条件を置きましょう。 安全な処理手順を選びましょう。 確実にデータを保存させましょう。 スムーズな運用を目指しましょう。 業務の効率化を進めていきましょう。 自動化の範囲を広げていきましょう。 定期実行の時間を決めましょう。 スケジュール登録を行いましょう。 実行ログを定期的に消しましょう。 容量制限に注意しておきましょう。 バックアップファイルを残しましょう。 復元手順を確認しておきましょう。 安全性を高めておきましょう。 セキュリティの設定を見直しましょう。 パスワードを正しく管理しましょう。 適切なアクセス権を与えましょう。 共有範囲を限定しておきましょう。 リンクの取り扱いに注意しましょう。 不要な連携は解除しておきましょう。 最新情報に更新しておきましょう。 動作確認を徹底して行いましょう。 本番環境に反映させましょう。 運用テストを繰り返しましょう。 ユーザーの反応を見ましょう。 フィードバックを反映させましょう。 問題がないか最終確認しましょう。 作業を完了させて終了しましょう。 sheet.insertRows(2, 3);

上記のコードを実行すると、アクティブシートの2行目の位置から3行分の空白行がまとめて挿入されます。なので、元々2行目にあった行は押し下げられて5行目になります。というのは、新しくできた2〜4行目が空っぽのセルとして確保されるからです。この書き方を使うタイミングは、すでにデータがびっしり埋まっている集計用シートに対して、あらかじめ計算しておいた行数分のスペースを一撃で空けたいときです。1行ずつ刻んで挿入するのではなく、必要な行数をあらかじめカウントして引数にまとめて渡すことで、シートの再描画や構造変更のオーバーヘッドを最小限に抑えましょう。

引数を指定する際の注意点として、第1引数に渡す数値はスプレッドシート上の行番号(1始まり)であるという点があります。JavaScriptの配列のように0から数えるインデックスをそのまま渡してしまうと、0行目という無効な範囲を指定したことになります。なので、スクリプト実行時エラーで停止します。二次元配列のインデックス番号をループ変数などから流用する場合は、必ず「配列のインデックス + 1」やヘッダー分のオフセットを考慮した行番号に補正して渡しましょう。

ループ内で1行ずつ挿入したときに起きる処理遅延の回避

複数行のデータを挿入したいときに初心者が最も踏みやすい落とし穴が、ループ構文の中で1行挿入の処理を何十回も連続で呼び出してしまうパターンです。たとえば「100行分の空きを作りたい」という目的のときに、forループを回してinsertRowやinsertRows(rowIndex, 1)を100回連続で実行するような書き方をしてしまうと、スクリプトの実行時間が劇的に悪化します。ただし、ひどい場合にはGoogle Apps Scriptの実行制限時間である6分をオーバーしてタイムアウトします。なので、途中で処理が止まってシートが中途半端な状態で放置される原因になります。

GASにおけるスプレッドシートの操作は、背後でGoogleのサーバーに対してAPI(プログラム間の連携機能)の呼び出しを送信することで成り立っています。行の挿入という処理は、単にセルの値を書き換えるだけの操作とは異なります。というのは、シート全体の行インデックスの再計算、数式の参照関係の更新、セルの描画領域の再確保など、サーバー側に非常に大きな負荷がかかる重い処理だからです。これを1行挿入するたびに1回ずつ通信して実行させていると、API呼び出しの回数が跳ね上がります。なので、1回の呼び出しごとに数百ミリ秒から1秒近い待ち時間が発生してしまいます。

この問題を回避するための鉄則は、複数行を一度に挿入するメソッドを利用してAPI呼び出しを減らすことです。必要な挿入行数が事前に分かっている、あるいはデータの件数から算出できるのであれば、何行挿入するべきかを先に変数として集計しましょう。なので、insertRows(startRow, totalRows)として1回だけ呼び出すのが正解です。100回のAPI呼び出しをわずか1回に集約できるため、処理時間は数十秒単位から一瞬へと短縮されます。スクリプトを安定して高速に動かすためには、「シート構造を変更するメソッドは極力まとめて1回で呼ぶ」という意識を持ちましょう。

挿入位置の上と下で分かれる書式引き継ぎの仕様

空白行を挿入できたとしても、その新しく作られたセルの「書式」がどのように決まるかを知らないと、思わぬ体裁崩れに悩まされることになります。insertRowsメソッドで空行を挿入した際、Googleスプレッドシートの仕様として、新しくできた行のセルの書式(背景色、罫線、フォントサイズ、表示形式など)は、基本的に「挿入位置の直前にある上の行」から引き継がれるケースが多く見られます。なので、ヘッダー行のすぐ下に行を挿入した場合、ヘッダーに設定されていた太字や濃い背景色、中央揃えといったスタイルが、そのまま新しく挿入された空白行にコピーされてしまいます。

集計表の途中に新規カテゴリのデータを割り込ませる際、カテゴリヘッダーの直下にデータ行を作ろうとして行を挿入したら、真っ黒な背景色と白い太字のセルが何行も生成されてしまいます。なので、後から入力する数値が見えなくなってしまったというトラブルは実務で非常によくあります。これに対処するには、挿入したあとに該当範囲の書式をクリアしましょう。ただし、データ行と同じ書式を明示的にコピーして上書きしてやる設計でも構いません。

具体的には、挿入を行った直後にsheet.getRange(startRow, 1, numRows, sheet.getLastColumn())で新しくできた範囲のRangeオブジェクトを取得します。なので、clearFormat()で書式を一度初期化するか、既存の通常データ行からcopyToを使って書式のみ(SpreadsheetApp.CopyPasteType.PASTE_FORMAT)をペーストする処理を挟みましょう。行を挿入するという操作は、単に空間を空けるだけでなく「周囲の書式を巻き込んで新しいセルを生成する」という性質を持っています。というのは、データの値を流し込む前に枠組みのスタイルを整えるステップまでを一連の処理として設計しておく必要があるからです。

タイトルとURLをコピーしました