Google Apps Script(GAS)でスプレッドシートを自動化するとき、「文字列検索」を効率よく扱えるかどうかは業務効率を大きく左右します。その代表的な手段が indexOf
です。しかし「見つからない」「二次元配列に使えない」など、初心者がつまずくポイントも多いのが実情です。本記事では、indexOf
の基本から includes
・match
との比較、正規表現の活用まで、現場で役立つ実践的な使い方を解説します。
indexOfで文字列を検索する基本を理解する方法
まずは indexOf
の基本を押さえておきましょう。これは「ある文字列の中に、検索したい文字列が含まれているか」を探すためのメソッドです。見つかった場合は位置(インデックス番号)を返し、見つからなければ -1
を返します。
例えば以下のようなコードです。
function testIndexOf() {
var text = "ロロメディアでSEO記事を学ぶ";
var position = text.indexOf("SEO");
Logger.log(position); // 5 が返る
}
この場合「SEO」という文字列は6文字目(0から数えて5番目)にあるため、5
が返されます。
背景や理由
なぜ indexOf
がよく使われるかというと、検索スピードが速くシンプルだからです。複雑な正規表現を使わなくても、単純な文字列検索であればこれだけで十分なことが多いのです。
ビジネス現場での事例
たとえば営業部門では、スプレッドシートに大量の顧客リストが入っており、「メールアドレスに @gmail.com を含む顧客を探す」といった作業があります。こうしたときに indexOf
を使うと、一瞬で判定が可能です。
if (email.indexOf("@gmail.com") !== -1) {
// Gmailアドレスの処理
}
このようにシンプルなコードで条件分岐できます。
他業種・海外との比較
海外の開発者フォーラムを見ると、includes
のほうがコードが読みやすいとする意見も多くあります。しかし日本では業務システムで古いブラウザや互換性を重視するケースがまだあり、その場合 indexOf
を使う場面が残っています。
メリットとデメリット
- メリット: 処理が速く、サポート範囲も広い。初心者でも理解しやすい。
- デメリット: 見つからない場合が
-1
になるため、条件式を少し工夫する必要がある。
実践手順
- 文字列を変数に格納する
indexOf("検索したい文字列")
を実行する- 戻り値が
-1
でなければ検索成功
注意点や失敗事例
初心者によくあるのは「完全一致でしか検索できると思い込む」ことです。実際には部分一致の検索ができます。例えば "株式会社ロロント"
の中で "ロロント"
を検索すれば問題なくヒットしますよ。
indexOfが見つからないときの原因と対処法
「確かに文字列があるのに indexOf
で見つからない」という相談はよくあります。これにはいくつか典型的な原因があります。
主な原因
- 全角・半角の違い
例えば「スペース」が全角になっていると別の文字と判定されます。 - 大文字・小文字の違い
SEO
とseo
は別の文字列です。 - 改行や余分な文字が含まれている
見えない改行コードが含まれていると検索に失敗します。
実際の事例
経理部で顧客名簿を扱っていたケースでは、「株式会社」と「㈱」が混在していたため、indexOf("株式会社")
で検索しても一部がヒットしませんでした。この場合は正規表現を使うか、事前に文字列を統一する処理が必要です。
text = text.replace("㈱", "株式会社");
解決の手順
- 文字列を
trim()
で前後の余分なスペースを削除する toLowerCase()
を使って小文字に統一する- 必要に応じて正規表現で複数パターンを一括処理する
if (text.toLowerCase().indexOf("seo") !== -1) {
Logger.log("SEOを含む");
}
注意点
「見つからない」原因の多くはデータの揺れにあります。ですから、検索の前に必ず前処理(整形)を入れることを意識しましょう。これを怠ると、思わぬデータ抜けが発生してレポートが不正確になるリスクがあります。
二次元配列にindexOfを使う方法と限界
スプレッドシートを扱う際に避けて通れないのが「二次元配列」です。シートのデータを getValues()
で取得すると、行と列の形を持った二次元配列として返されます。
indexOfは二次元配列にそのまま使えない
indexOf
は一次元配列に対しては使えますが、二次元配列にそのまま適用しても期待通りに動きません。例えば以下のようなコードではエラーや -1
しか返ってこないことがあります。
var data = sheet.getDataRange().getValues();
Logger.log(data.indexOf("ロロント")); // 常に -1
解決策
- ループを回して一行ずつ検索する
flat()
を使って一次元化する
var data = sheet.getDataRange().getValues();
var flatData = data.flat();
Logger.log(flatData.indexOf("ロロント"));
このように一次元配列に変換すれば検索が可能になります。
ビジネス現場での応用
人事部で従業員リストを検索するとき、苗字や部署名がどの行にあるか探す処理があります。このとき二次元配列を扱うため、そのままでは indexOf
が効きません。そこで for
文で行をチェックするか、flat()
を使うことで効率的に解決できます。
他業種・海外との比較
海外の開発者は、二次元配列検索には findIndex
や some
を組み合わせる方法をよく推奨しています。一方、日本の現場では「とりあえず for
文で回す」ケースがまだまだ多い印象です。
メリットとデメリット
- メリット: 二次元配列を一次元に変換すると、シンプルに検索可能。
- デメリット: どの行・列にあったかを特定するには追加処理が必要。
注意点
業務で「セルの位置」を特定したい場合は indexOf
よりも findIndex
や filter
を使ったほうが便利なことが多いです。indexOf
は存在確認やシンプルな検索に留め、用途を絞って使いましょう。
正規表現で柔軟に検索する方法
indexOf
は便利ですが、「完全一致」または「部分一致」のシンプルな検索しかできません。もっと柔軟に「数字で始まる文字列だけ探したい」「株式会社や有限会社をまとめて見つけたい」といった要望が出てきます。そんなときに役立つのが 正規表現 です。
実践例
function testRegex() {
var text = "株式会社ロロント";
if (/^(株式会社|有限会社)/.test(text)) {
Logger.log("法人名で始まる文字列です");
}
}
このように書けば、「株式会社」でも「有限会社」でも先頭にあればマッチします。
ビジネス現場での事例
マーケティング部で問い合わせメールを仕分けるとき、件名に「【緊急】」「[要対応]」などのパターンが入っているものを振り分けたいことがあります。この場合、indexOf
だと複数条件のチェックが煩雑になりますが、正規表現なら一文でスマートに書けます。
メリットとデメリット
- メリット: 曖昧検索や複数条件のまとめ処理ができる
- デメリット: パターンの書き方が難しく、初心者には学習コストが高い
正規表現は強力ですが、無理に使いすぎると可読性が落ちるため、他の人が見ても理解できるレベルに留めるのがコツです。
if文やmatchとの組み合わせで条件分岐する方法
indexOf
だけでなく、if
文や match
を組み合わせると条件分岐がしやすくなります。
実践例
var text = "ロロメディアでSEOを学ぶ";
if (text.match(/SEO/)) {
Logger.log("SEOを含んでいます");
}
match
は正規表現を直接使えるため、「パターンに一致したかどうか」を簡単に判定できます。
事例
営業チームで、顧客の問い合わせ文に「価格」「料金」「費用」という単語が含まれている場合だけフラグを立てる処理を行ったケースがあります。indexOf
だと3回条件式を書く必要がありましたが、match(/価格|料金|費用/)
と書けば一発で解決できました。
注意点
ただし、match
は見つからなかった場合に null
を返すため、そのまま処理を進めるとエラーになることがあります。必ず if
でチェックすることを忘れないようにしてください。
特定の文字列を含むセルを取得する方法
スプレッドシートを業務で扱うと、「特定の文字列を含むセルを探したい」という要望は頻繁に出てきます。例えば「メールアドレスに @yahoo.co.jp を含むセルを抽出したい」といったケースです。
実践コード
function findCell() {
var sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
var data = sheet.getDataRange().getValues();
for (var i = 0; i < data.length; i++) {
for (var j = 0; j < data[i].length; j++) {
if (String(data[i][j]).indexOf("@yahoo.co.jp") !== -1) {
Logger.log("見つかりました: " + (i+1) + "行" + (j+1) + "列");
}
}
}
}
ビジネス現場での事例
顧客リストの中から特定のドメインを持つメールアドレスを抽出し、メールマーケティングの対象にするケースがあります。この処理を手動でやると数時間かかりますが、上記のコードなら一瞬で終わります。
注意点
データ量が多いとループ処理に時間がかかるため、必要な列だけを検索するように工夫しましょう。また、見つかった結果を新しいシートにまとめるなど、次のアクションを自動化するとさらに効率が上がります。
includesでシンプルに書く方法
最近では includes
が使えるようになり、コードがより読みやすくなりました。
実践例
var text = "ロロメディアでSEOを学ぶ";
if (text.includes("SEO")) {
Logger.log("SEOを含んでいます");
}
メリット
- 条件式がシンプルで直感的
-1
判定が不要- 可読性が高い
事例
開発チームの新人研修で、indexOf
よりも includes
を使わせるケースが増えています。特に非エンジニア職の社員でもコードが読めるようになる点は大きなメリットです。
注意点
ただし、includes
は古い環境では動作しないことがあります。レガシーな業務システムと連携している場合は、互換性に注意が必要です。
まとめ
GASの indexOf
は、文字列検索を行ううえで基本かつ強力な手段です。シンプルな検索なら十分ですが、二次元配列や複数条件になると工夫が必要になります。
- シンプル検索:
indexOf
- 柔軟なパターン検索: 正規表現や
match
- 存在確認をシンプルに:
includes
- スプレッドシートのセル探索: 二次元配列のループや
flat()
業務効率化のカギは「状況に応じてどの方法を選ぶか」です。見つからないときの原因を理解し、適切な方法を選択することで、文字列検索のストレスが一気に減りますよ。