【データクレンジング】Google Apps Script(GAS)で電話番号の表記揺れを自動解消!(そのまま使える無料テンプレート配布)

電話番号データクレンジング記事のアイキャッチ画像 自動化事例

顧客リストやアンケート結果にある電話番号の形式がバラバラで、困っていませんか?

「全角と半角が混在している」「ハイフンがあったりなかったりする」「+81から始まっている」…。
これらを手作業で修正するのは、非常に時間がかかり、ミスも発生しがちです。

表記揺れが放置されると、データを正しく比較・照合(データ突合)できなかったり、CRM(顧客管理システム)へのインポートが失敗したりと、業務上のトラブルにつながりかねません。

この記事では、GoogleスプレッドシートとGoogle Apps Script(GAS)を活用し、そうした電話番号の表記揺れを自動的に修正する(データクレンジングする)方法を、コピーしてすぐに使えるテンプレートとコード付きで解説します。

無料配布:電話番号データクレンジング用テンプレート

電話番号の表記揺れを自動修正できる「スプレッドシート+GAS テンプレート」を無料で配布しています。
プログラムを書く必要はなく、コピーしてすぐに利用可能です。

【テンプレートで自動化できること】

  • 全角・半角やハイフンの有無を統一
  • 「+81」などの国際表記を国内表記(0始まり)に変換
  • 携帯・IP・固定電話ごとに正しい位置へハイフンを挿入
  • 条件に合わない番号を「対象外データ」として自動判別

普段の手作業や目視チェックが、「データを貼る → ボタンを押す」の2ステップで完了します。
以下のフォームから、今すぐテンプレートをお受け取りください。

    法人名(必須)

    氏名(必須)

    メールアドレス(必須)

    電話番号(必須)

    テンプレート使用手順

    Step1:対象データの更新

    コピーしたスプレッドシートに変換したいデータを貼り付けます。

    電話番号の対象データを更新

    Step2:電話番号変換の実行

    以下画像の赤枠(「電話番号変換開始」ボタン)をクリック後、
    Google Apps Script(GAS)の実行許可を行います。

    許可後に再度ボタンをクリックして実行してください。

    電話番号データクレンジング記事の変換開始

    Step3:実行結果を確認

    電話番号の表記が修正されたデータが、B列に更新されます。

    電話番号データクレンジング記事の変換完了

    自動修正のルール(前提条件)

    改めてここで紹介するGAS(Google Apps Script、自動化プログラムのこと)が、どのようなルールで電話番号を修正するのかを明確にしておきます。

    (1)対応可能な表記揺れパターン

    • 全角と半角の数値が混在している。
    • 不要記号(スペース、括弧、スラッシュなど)が含まれている。
    • 国際電話フォーマット表記(例:日本の場合は「+81」)が使用されている。
    • 桁数が不正確(10桁または11桁以外の場合)。
    • ハイフンがない、または先頭の0が欠落している(数値として扱った際に起こる現象)。

    (2)修正後の統一ルール

    日本国内の電話番号表記へ、以下の条件に基づいて修正を行います。

    • 数値はすべて半角に統一する。
    • 不要な記号(スペース、括弧、スラッシュなど)を削除する。
    • 国際フォーマット表記(例:+81)は、日本国内形式に変換する。
       ※日本以外の国番号(例:+82など)は、「対象外データ」として処理します。
    • 桁数の統一
      • 携帯電話番号(070、080、090)およびIP電話番号(050)は、11桁で出力する。
      • 固定電話番号(フリーダイヤル含む)は、10桁で出力する。
      • 上記以外の桁数(11桁のフリーダイヤル0800等を含む)は対象外として処理します。
    • 市外局番に基づき、適切なハイフンを自動付与する。
    • 数値変換時に先頭の0が欠落した場合は、補正を行う。
    • 上記パターンに該当しない場合は、「対象外データ」として扱います。

    GASコードの簡単な解説

    ここでは、Step2で実行したGoogle Apps Script(GAS)のコード内容を簡単に解説します。
    GASの基本的な操作については、こちらの記事をご確認ください。

    コードは大きく分けて2つの「関数(処理をまとめたもの)」で構成されています。

    /**
     * 電話番号変換メイン処理
     * 
     * 【処理内容】
     * 1. 出力シート(「電話番号変換」)のB3以降のデータをクリア
     * 2. 変換対象の電話番号データを取得(A6以降)
     * 3. 市外局番マスタ(「市外局番マスタ」)を取得し、長い順にソート
     * 4. 各電話番号をフォーマット変換
     * 5. 変換結果を「電話番号変換」シートのB3以降に書き込む
     */
    function ConvertPhoneNumbers() {
      const ss = SpreadsheetApp.getActiveSpreadsheet();
    
      // 【1】出力シートのB3以降のデータをクリア
      const phoneNumberSheet = ss.getSheetByName("電話番号変換");
      phoneNumberSheet.getRange("B3:B").clearContent();
    
      // 【2】変換対象の電話番号データを取得(A6以降)
      const lastRowSource = phoneNumberSheet.getLastRow();
      const phoneNumberRange = phoneNumberSheet.getRange(`A3:A${lastRowSource}`);
      const phoneNumberData = phoneNumberRange.getValues();
    
      // 【3】市外局番マスタデータを取得(A2以降)し、長い順にソート
      const areaCodeSheet = ss.getSheetByName("市外局番マスタ");
      const lastRowMaster = areaCodeSheet.getLastRow();
      const areaCodeRange = areaCodeSheet.getRange(`A2:A${lastRowMaster}`);
      const areaCodeData = areaCodeRange.getValues();
    
      const sortedAreaCodes = areaCodeData
        .flat()
        .map(code => {
          const s = String(code).trim();
          return (s.length < 2 && Number(s) < 10) ? s.padStart(2, '0') : s;
        })
        .filter(code => code)
        .sort((a, b) => b.length - a.length);
    
      // 【4】各電話番号を変換し、リスト化
      const validPhoneNumberData = phoneNumberData.filter(row => String(row[0]).trim() !== "");
      const formattedPhoneNumbers = validPhoneNumberData.map(row => {
        const originalPhoneNumber = row[0];
        const formattedPhoneNumber = processPhoneNumber(originalPhoneNumber, sortedAreaCodes);
        return [formattedPhoneNumber];
      });
    
      // 【5】変換結果をB3以降に書き込む
      phoneNumberSheet.getRange(3, 2, formattedPhoneNumbers.length, 1).setValues(formattedPhoneNumbers);
    }
    
    
    /**
     * 電話番号の正規化とフォーマット変換
     * 
     * 【処理内容】
     * 1. 全角数字を半角に変換
     * 2. 不要な記号(スペース・ハイフン・括弧)を削除
     * 3. +81 の場合は先頭を 0 に置換
     * 4. 10桁または11桁に統一
     * 5. 携帯番号・IP電話(11桁)は「***-****-****」の形式にフォーマット
     * 6. 固定電話番号(10桁)は市外局番に基づきハイフンを挿入
     * 7. 条件に合わない場合は「対象外データ」を返す
     *
     * @param {string|number} input 変換前の電話番号
     * @param {Array} sortedAreaCodes 市外局番リスト(長い順にソート済み)
     * @return {string} 変換後の電話番号、または「対象外データ」
     */
    function processPhoneNumber(input, sortedAreaCodes) {
      if (!input) return "対象外データ";
    
      // 【1】全角数字を半角に変換
      let numStr = String(input).trim().replace(/^'/, "");
      numStr = numStr.replace(/[0-9]/g, ch => String.fromCharCode(ch.charCodeAt(0) - 65248));
    
      // 【2】不要な記号を削除(スペース・ハイフン・括弧・スラッシュ・ドット・アンダースコア・特殊記号)
      numStr = numStr.replace(/[\s \-()\(\)._☎📞-ー\/_()]/g, "");
    
      // 【3-1】+81(日本の国番号)の場合、先頭を0に変換
      if (/^\+81/.test(numStr)) {
        if (numStr.length > 3 && numStr.charAt(3) === "0") {
          numStr = numStr.substring(3);
        } else {
          numStr = numStr.replace(/^\+81/, "0");
        }
      }
    
      // 【3-2】81から始まる番号も日本の番号として処理
      if (/^81/.test(numStr)) {
        numStr = numStr.replace(/^81/, "0");
      }
    
      // 【4】+81以外の国番号がある場合は対象外
      if (/^\+/.test(numStr)) {
        return "対象外データ";
      }
    
      // 【5】数字以外が含まれている場合は対象外
      if (!/^\d+$/.test(numStr)) {
        return "対象外データ";
      }
    
      // 【6】先頭が0でない場合、0を補完して桁数を調整
      if (!numStr.startsWith("0")) {
        const padded = "0" + numStr;
        if (padded.length === 10 || padded.length === 11) {
          numStr = padded;
        } else {
          return "対象外データ";
        }
      }
    
      // 【7】桁数チェック(10桁または11桁のみ許可)
      if (numStr.length !== 10 && numStr.length !== 11) {
        return "対象外データ";
      }
    
      // 【8】携帯電話・IP電話(11桁)の処理
      const MOBILE_PREFIXES = ["050", "070", "080", "090"];
      if (MOBILE_PREFIXES.includes(numStr.substring(0, 3))) {
        if (numStr.length !== 11) return "対象外データ";
        return numStr.substring(0, 3) + "-" + numStr.substring(3, 7) + "-" + numStr.substring(7);
      }
    
      // 【9】固定電話(10桁)の処理
      if (numStr.length !== 10) return "対象外データ";
    
      // 【10】市外局番を取得(長い順にソート済みリストから最長一致)
      const matchedCode = sortedAreaCodes.find(code => numStr.startsWith(code));
      if (!matchedCode) return "対象外データ";
    
      // 【11】市外局番を除いた残りの番号を2分割し、適切にハイフンを挿入
      const rest = numStr.substring(matchedCode.length);
      const splitPoint = Math.floor(rest.length / 2);
      const firstBlock = rest.substring(0, splitPoint);
      const secondBlock = rest.substring(splitPoint);
    
      return matchedCode + "-" + firstBlock + "-" + secondBlock;
    }

    1. ConvertPhoneNumbers 関数

    こちらは、メニューをクリックしたときに実行される「メインの処理」です。
    以下の作業を順番に行っています。

    1. 結果欄のクリア: まず、前回実行した結果が残っている「電話番号変換」シートのB列をクリアします。
    2. 変換対象の取得: A列に入力されている、変換したい電話番号データをすべて取得します。
    3. 市外局番マスタの取得: 「市外局番マスタ」シート(非表示)から、ハイフン付けの基準となる市外局番データを取得します。
    4. 各電話番号の変換: 2で取得した電話番号データを1行ずつ取り出し、後述する processPhoneNumber 関数を使って整形処理を行います。
    5. 結果の書き込み: 4で整形した結果を、B列に一括で書き込みます。

    2. processPhoneNumber 関数

    こちらは、電話番号1件ずつの具体的な「整形処理」を担当する関数です。
    ConvertPhoneNumbers 関数から呼び出されて、以下の処理(「自動修正のルール」で定義したルール)を実行します。

    1. 全角→半角変換: まず、全角の数字があれば半角に直します。
    2. 記号削除: スペース、ハイフン、括弧など、電話番号に関係ない記号をすべて削除します。
    3. 国番号の処理: +81 や 81 から始まる番号は、先頭を 0 に置き換えます。(例:+8190… → 090…)
    4. 例外処理: +81 以外の国番号(例:+82など)や、途中に数字以外の文字(例:ABC)が残っている場合は、「対象外データ」として処理を終了します。
    5. 桁数調整: 先頭の 0 が抜けている場合(例:9012345678)は 0 を補い、10桁または11桁になるように調整します。
    6. 桁数チェック: この時点で10桁または11桁でなければ、「対象外データ」とします。
    7. ハイフン付与(携帯・IP): 11桁で、かつ 090 080 070 050 から始まる番号は、090-XXXX-XXXX の形式にハイフンを付けます。
    8. ハイフン付与(固定電話): 10桁の番号は、「市外局番マスタ」と照合し、市外局番-市内局番-加入者番号 の形式(例:03-XXXX-XXXX)にハイフンを付けます。
    9. 最終結果を返す: 整形された電話番号(または「対象外データ」)を ConvertPhoneNumbers 関数に返します。

    このように、メイン処理と整形処理を分けることで、コードが読みやすく、管理しやすくなっています。

    まとめ

    電話番号の表記揺れは、手動で修正しようとすると非常に手間がかかります。
    本記事でご紹介したスプレッドシートとGASを用いた自動修正手法を活用することで、効率的かつ正確なデータクレンジングが実現できます。

    解説は以上です。
    プログラムの作成などをスキップしたい方は、以下の配布テンプレートをご利用ください。
    ▶︎ ページ上部のフォームからテンプレートを受け取る(無料)

    この記事の方法で解決できないケースが発生した場合は、【お問い合わせフォーム】からお気軽にご連絡ください。別途、最適な解決策をご提案いたします。

    ※Googleサービスは、Google LLC の商標であり、この記事はGoogleによって承認されたり、Google と提携したりするものではありません。