GASでスプレッドシートを
高速検索・一括置換する方法
大量データの検索や置換をgetValues()のループで書くと遅くなりがちです。GASのTextFinder(シート側の検索エンジンを使う仕組み)を使えば、少ないコードで高速に一致セルの取得・一括置換ができます。
Table of Contents
なぜTextFinderを使うのか
スプレッドシートから特定の文字列を探すとき、getValues()で全データを配列に取り出し、二重ループで1セルずつ照合する書き方をよく見かけます。動きはしますが、行数が増えるほど遅くなります。
TextFinder(createTextFinder()で作る検索オブジェクト)を使うと、検索処理をスプレッドシート側のエンジンに任せられます。GAS側に全データを転送しないぶん高速で、置換までワンライナーで書けるのが利点です。
getValuesループ
全セルをGASに転送し、JavaScriptで走査。行数に比例して遅くなる
TextFinder
シート側で一致を検索。転送量が少なく、置換も1メソッドで完結
findAllで一致セルを一括取得する
基本形はsheet.createTextFinder(検索文字列)です。findAll()を呼ぶと、一致したセルのRange(セル範囲を表すオブジェクト)が配列で返ります。既定では部分一致(セル内にその文字が含まれれば一致)です。
function findAllMatches() {
const sheet = SpreadsheetApp.getActive().getSheetByName("顧客リスト");
// シート全体から「未対応」を含むセルをすべて取得
const finder = sheet.createTextFinder("未対応");
const ranges = finder.findAll(); // Rangeの配列が返る
Logger.log("一致件数: " + ranges.length);
ranges.forEach((range) => {
// A1形式の位置と値をログに出す
Logger.log(range.getA1Notation() + " → " + range.getValue());
});
}findNextで最初の一致にジャンプする
「最初に見つかった1件だけ処理したい」ときはfindNext()を使います。一致するセルのRangeを1つ返し、見つからなければnullを返します。activate()でそのセルを選択状態にできます。
function jumpToFirstMatch() {
const sheet = SpreadsheetApp.getActive().getSheetByName("顧客リスト");
const finder = sheet.createTextFinder("要確認");
// findNext() は次の一致セル(Range)を返す。無ければ null
const first = finder.findNext();
if (first) {
first.activate(); // そのセルを選択状態にする
Logger.log("最初の一致: " + first.getA1Notation());
} else {
Logger.log("一致するセルはありません");
}
}大文字小文字・完全一致で絞り込む
検索条件はメソッドチェーンで足していきます。matchCase(true)で大文字・小文字を区別、matchEntireCell(true)でセル全体が一致したときだけヒットします。「NG」を探すときに「NG品」を除外したい、といった絞り込みに便利です。
function findWithOptions() {
const sheet = SpreadsheetApp.getActive().getSheetByName("在庫");
const ranges = sheet
.createTextFinder("NG")
.matchCase(true) // 大文字・小文字を区別(ng とは一致しない)
.matchEntireCell(true) // セル全体が "NG" のときだけ一致("NG品" は除外)
.findAll();
Logger.log("完全一致した件数: " + ranges.length);
}replaceAllWithで一括置換する
置換はreplaceAllWith(置換文字列)の1メソッドで完結します。戻り値は置換した件数です。対象はrange.createTextFinder()で範囲を絞ると、他の列を巻き込む事故を防げます。
function replaceStatus() {
const sheet = SpreadsheetApp.getActive().getSheetByName("案件管理");
// 対象範囲を D列(ステータス列)に限定して一括置換
const count = sheet
.getRange("D2:D1000")
.createTextFinder("進行中")
.matchEntireCell(true)
.replaceAllWith("対応中");
Logger.log(count + " 件を『対応中』に置換しました");
}正規表現で表記ゆれを整える
useRegularExpression(true)を付けると、検索文字列を正規表現(文字パターンの記法)として扱えます。電話番号の全角ハイフンや波ダッシュなど、紛らわしい記号をまとめて半角ハイフンに統一するといった正規化に向いています。
function normalizePhone() {
const sheet = SpreadsheetApp.getActive().getSheetByName("顧客リスト");
// 全角ハイフン・波ダッシュなどを半角ハイフンに統一
const count = sheet
.getRange("E2:E1000") // 電話番号列
.createTextFinder("[‐-―ー~〜]") // 紛らわしいハイフン類をまとめて指定
.useRegularExpression(true)
.replaceAllWith("-");
Logger.log(count + " 箇所のハイフンを半角に統一しました");
}※ TextFinderの正規表現はGoogle側(RE2系)の構文で解釈され、JavaScriptの正規表現と細部が異なる場合があります。複雑なパターンは事前に少量のデータで動作を確認してください。
一致セルをハイライトする実践例
findNext()をループで繰り返すと、一致セルを順番にたどれます。見つかったセルに背景色を付けて、確認漏れを防ぐ運用に使えます。
function highlightMatches() {
const sheet = SpreadsheetApp.getActive().getSheetByName("問い合わせ");
const finder = sheet.getRange("B2:B2000").createTextFinder("至急");
let range = finder.findNext();
let count = 0;
// findNext() を繰り返すと一致セルを順番に取得できる
while (range !== null) {
range.setBackground("#fff3b0"); // 黄色でマーキング
count++;
range = finder.findNext();
}
Logger.log(count + " 件の『至急』をハイライトしました");
}実務での注意点
1. 置換は取り消せないので範囲を絞る
replaceAllWith()は元に戻せません。シート全体ではなく対象列に範囲を限定し、実行前にfindAll().lengthで件数を確認してから置換するのが安全です。心配なときはシートをコピーしてから実行しましょう。
2. 検索対象は「表示テキスト」
TextFinderは既定でセルの表示上の値を対象にします。数式そのものを探したいときはmatchFormulaText(true)を指定します。日付や数値は書式によって見え方が変わるため、一致しないときは表示形式を確認してください。
3. 戻り値はRangeで、値ではない
findAll()やfindNext()が返すのはRangeオブジェクトです。値が欲しいときはgetValue()、位置が欲しいときはgetRow()やgetA1Notation()を呼びます。大量の一致セルに1件ずつsetValue()すると遅くなるため、まとめて処理できる場合はsetValuesの併用も検討します。
まとめ
GASのTextFinderは、getValuesループより少ないコードで、高速に検索・一括置換ができる仕組みです。findAll/findNextで一致セルを取得し、matchCaseやmatchEntireCell、useRegularExpressionで条件を絞り込み、replaceAllWithでまとめて置換できます。範囲を限定し、置換前に件数を確認する運用を守れば、日々のデータメンテナンスを安全に自動化できます。
よくある質問
多くのケースでTextFinderの方が高速です。getValues()は全セルの値を配列としてGAS側に転送してからJavaScriptで走査しますが、TextFinderはスプレッドシート側の検索エンジンで一致を探すため、大きなシートほど差が出ます。特に一致セルが少ない検索や、複数シートをまたいだ検索で効果的です。
できます。createTextFinder(text).matchCase(true) を付けると大文字・小文字を区別します。またmatchEntireCell(true)でセル全体の完全一致、useRegularExpression(true)で正規表現検索、matchFormulaText(true)で数式そのものを対象にできます。これらはメソッドチェーンでつなげて指定します。
createTextFinder(検索文字列).replaceAllWith(置換文字列) を使うと、対象範囲内の一致箇所を一度にすべて置換できます。戻り値として置換した件数が返るので、Logger.logで何件置き換えたかを確認できます。1件ずつ確認しながら置換したい場合はfindNext()とgetCurrentMatch()を使います。
できます。sheet.createTextFinder()はシート全体、range.createTextFinder()は指定した範囲だけを対象にします。例えばsheet.getRange('C2:C1000').createTextFinder('未対応')のように書くと、C列の指定範囲内だけを検索・置換できます。
findAll()やgetCurrentMatch()が返すのはRangeオブジェクトです。値そのものではないため、getValue()やgetValues()を呼んで値を取り出してから計算します。また、TextFinderは表示上のテキストを対象にするため、日付や数値の書式によって一致の挙動が変わる点に注意してください。
GAS開発・業務Webシステムを
相談する。
検索・置換の自動化以外にも、フォーム連携・帳票出力・Gmail自動化など、日々の業務を自動化するGAS開発をご相談いただけます。