GASのメール列の形式がおかしい行を、見つける

GAS
目次

スプレッドシートで集計した顧客データや問い合わせフォームのログを確認していると、送信エラーの原因が単なるメールアドレスの入力ミスだったという事態によく遭遇します。ドメインのドットが抜けていたり、全角のアットマークが混ざっていたり、文字の前後に余計な空白が入っているだけで、メール送信スクリプトは途中で停止し、業務の進行を妨げます。数百行から数千行に及ぶデータの中から、目視だけで不備のある行を探し出すのは極めて非効率であり、見落としの原因にもなります。Google Apps Script(GAS)を用いてメール列の形式がおかしい行を見つける仕組みを作っておけば、データ抽出やバッチ処理の前にエラーを未然に防ぐことができます。

現場でメールアドレスの入力ミスが及ぼす実務上の影響

スプレッドシートに入力されたメールアドレスをそのまま一括送信スクリプトに流し込んだり、外部の顧客管理システムへ連携したりする運用では、データ形式の事前検証が不可欠です。たった1行でもフォーマットがおかしいデータが混入していると、APIの呼び出しで例外が発生して後続の処理がすべてストップするか、バウンスメールが大量に返ってきて送信元ドメインの信用スコアが低下するリスクが生じます。

実務でよく見られる不備のパターンは多岐にわたります。最も多いのは、ユーザーや入力担当者が全角英数字や全角のアットマークを入力してしまうケースです。見た目には正常なメールアドレスと似ていても、内部的には別物として扱われるため、標準的なメール送信ロジックでは無効なアドレスと判定されます。また、他のツールからコピー&ペーストを行った際に、文字列の末尾に目に見えない改行コードや半角スペースが付着している場合もあります。

このような表記揺れや入力ミスを事前に発見するために、GAS メール列 形式チェックを定期的に実行するスクリプトを業務フローに組み込んでおくことが有効です。行ごとに「OK」か「要確認」かの判定フラグを別列に出力しておけば、スプレッドシートのフィルター機能を使って不備のある行だけを瞬時に抽出し、データの修正作業に入ることができます。大量のデータを扱う現場において、事前チェックなしで送信処理を実行するのは非常に大きな運用リスクを抱えることになります。

配列サイズと書き込み範囲のズレによって発生するエラー

GASでスプレッドシートのデータを処理する際、多くの人が直面するトラブルの一つが、取得したデータの配列サイズと書き込み先のセル範囲(Range)の不一致です。B列の2行目から最終行までを一括で取得し、それを処理した結果をC列に書き戻す際、行数の計算が1行でもずれていると、範囲の不整合を示すエラーが発生して処理が停止します。

具体的には、シートのデータ取得範囲と書き込み範囲の行数が完全に同一でなければなりません。例えば、ヘッダー行を除いた2行目からデータを取得した場合、書き込み先の範囲も2行目を起点とし、取得した配列の要素数と同じ行数を指定する必要があります。取得した配列を繰り返し処理する過程で要素数を減らしてしまったり、空欄の行を配列から除外してしまったりすると、書き込み時にエラーになるか、最悪の場合はデータの行位置がずれて隣の行の判定結果が書き込まれてしまう現象が発生します。

不備のあるデータを見つけるロジックを組む際は、空欄のセルであっても配列の要素として保持し続け、元のスプレッドシートの行構造と1対1で対応する2次元配列の形状を維持することが求められます。データが存在しないセルは空文字として処理し、全体の行数を変更せずにそのまま書き戻すアプローチをとることで、範囲の不一致によるエラーを防ぎ、安全に判定結果をシートへ反映できます。

メール列の判定を実行するスクリプトの記述

以下は、B列に入力されたメールアドレスの形式をチェックし、C列に判定結果を出力する具体的なコード例です。B2セルからB列の末尾までのデータを一括で取得し、簡易的な正規表現を用いてメールアドレスの基本的なフォーマットを満たしているかを判定します。未入力のセルについてはフラグを立てず、空文字のまま出力することで、不要な判定によるデータの混乱を防ぎます。

const sheet = SpreadsheetApp.getActiveSheet();
const emails = sheet.getRange("B2:B").getValues();
const flags = emails.map(([email]) => {
  if (!email) return [""];
  return [/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(String(email)) ? "OK" : "要確認"];
});
sheet.getRange(2, 3, flags.length, 1).setValues(flags);

このコードは、1行ずつセルにアクセスして判定結果を書き込むのではなく、getValues() で全データを2次元配列としてメモリ上に読み込み、map() による繰り返し処理を行った後、setValues() で一括書き込みを行っています。スプレッドシートへのアクセス回数を最小限(取得1回、書き込み1回)に抑えているため、数千行のデータが存在する場合でも極めて短い時間で処理が完了します。

コード内で使用している正規表現 /^[^\s@]+@[^\s@]+\.[^\s@]+$/ は、厳密なRFC規格の検証を行うものではなく、実務上で明らかに壊れているデータ(アットマークが無い、ドメイン部分のドットが無い、途中にスペースが含まれているなど)を検出するための軽量なパターンです。また、email の値を判定する直前に String(email) と記述して文字列型にキャストしているのは、数値や日付データが万が一混入していた場合でも型エラーを発生させずに安全に判定を行うための回避策です。

全角文字と余計な空白が及ぼす判定結果への影響とその補正

標準的な正規表現による判定では、全角文字や前後の空白が含まれているアドレスはすべて「要確認」として判定されます。しかし、現場の運用によっては「全角のアットマークや全角英数字を自動的に半角に変換したうえでチェックしたい」あるいは「前後の空白は自動で除去したうえで判定したい」というニーズも存在します。

例えば、「 user@example.com 」のように末尾にスペースが入っているデータは、そのまま判定にかけると正規表現の空白文字判定に引っかかり、「要確認」判定となります。この動作自体は仕様通りですが、送信処理のロジック側で自動的に trim() をかけて送信する設計になっている場合、形式チェックの段階で「要確認」と判定してしまうと、判定ロジックと送信ロジックの間で評価のズレが生じることになります。

同様に、入力フォームの設計不備で全角文字の入力が許可されてしまっている場合、GAS側で全角英数字を半角に変換する前処理を行わずに判定を行うと、修正が必要なデータとして判定される件数が膨大になります。形式チェックを行うスクリプトを設計する際は、どこまでを「自動補正して判定を通過させるか」、どこからを「手動修正が必要なNGデータとするか」を業務ルールに基づいて明確に切り分ける必要があります。データの完全性を保つためには、単にフラグを立てるだけでなく、必要に応じて修正後の文字列を別列に出力するなどの工夫を凝らすことが、現場での作業効率化につながります。

膨大なデータ量に対応するための実行パフォーマンス設計

スプレッドシートの行数が数万行規模に達する場合、getRange("B2:B") でシート全体の最下部まで一括取得する方法は、メモリ使用量や処理時間の観点で注意が必要です。GASには1回の実行時間上限が設定されているため、データが存在しない空行まで無駄に配列に読み込んで繰り返し処理を行うと、スクリプトの実行が途中でタイムアウトする要因になります。

処理速度を最適化するためには、実際にデータが存在する最終行を取得し、必要なセル範囲だけを指定してデータを読み込む手法が効果的です。データが存在しない無駄な空セルに対する判定処理をスキップすることで、メモリ消費量を抑え、処理時間を削減することができます。

また、データが日常的に追加・更新されるスプレッドシートの場合、すでに「OK」と判定済みの行まで毎回再判定を行うのは非効率です。判定結果の列が空欄になっている行だけを対象にして処理を行う条件分岐を追加したり、フォーム送信時のイベントトリガーを利用して新規追加された1行だけを即座にチェックする運用を導入したりすることで、システムにかかる負荷を最小限に抑えることができます。全体を一括処理するスクリプトと、差分だけを処理するスクリプトを適切に使い分けることが、大規模なスプレッドシート運用を維持するためのポイントです。

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