SECTION 11

スプレッドシート × AI データ処理

データの力を引き出す — AIクレンジングから分析まで

LCREATOR.Inc Google AI 研修プログラム

SECTION 11

データ品質の重要性

STEP 01

Garbage In, Garbage Out
汚いデータを入れれば、汚い結果しか出てこない。

27%
データ品質不良による
売上損失率(Gartner調べ)
60%
データ分析業務のうち
クレンジングに費やす時間

汚いデータの業務コスト

意思決定の誤り

不正確なデータに基づくレポートが誤った経営判断を招く

業務の手戻り

顧客名の表記ゆれで請求書を再発行、住所間違いで再配送

AI精度の低下

Gemini APIに汚いデータを渡しても正確な分析は不可能

信頼性の喪失

データの品質が低いと、組織全体でデータ活用が進まなくなる

SECTION 11

データクレンジングとは

STEP 02

データクレンジングとは、データセットから誤り・不整合・重複を検出し修正するプロセスです。

🔄

重複除去

同一レコードの重複を検出・統合(名寄せ)

🔤

表記統一

「(株)」と「株式会社」、全角/半角の統一

🔍

欠損値処理

空欄のデータを補完または除外

異常値検出

明らかに範囲外のデータを検出・修正

📝

フォーマット統一

日付形式、電話番号形式の統一

バリデーション

メールアドレス・郵便番号の形式チェック

💡
従来: Excel関数・正規表現で対応 → AI時代: Gemini APIが「意味を理解」してクレンジング。「LCREATOR」と「エルクリエイター」を同一と判断できる。

SECTION 11

GASでのデータクレンジング

STEP 03

重複除去

GAS function removeDuplicates() { const sheet = SpreadsheetApp .getActiveSheet(); const data = sheet.getDataRange() .getValues(); const header = data[0]; // メールアドレス列(C列)で重複判定 const seen = new Set(); const unique = [header]; for (let i = 1; i < data.length; i++) { const key = data[i][2] .toLowerCase().trim(); if (!seen.has(key)) { seen.add(key); unique.push(data[i]); } } // 元データをクリアして書き戻し sheet.clearContents(); sheet.getRange( 1, 1, unique.length, header.length ).setValues(unique); Logger.log( `${data.length - unique.length}件` + ` の重複を除去しました` ); }

表記統一(正規表現)

GAS function normalizeData() { const sheet = SpreadsheetApp .getActiveSheet(); const range = sheet.getDataRange(); const data = range.getValues(); for (let i = 1; i < data.length; i++) { // 全角数字→半角 data[i][3] = data[i][3] .toString() .replace(/[0-9]/g, s => String.fromCharCode( s.charCodeAt(0) - 0xFEE0 ) ); // 電話番号フォーマット統一 data[i][4] = data[i][4] .toString() .replace(/[^\d]/g, '') .replace( /^(\d{2,4})(\d{2,4})(\d{3,4})$/, '$1-$2-$3' ); // (株) → 株式会社 data[i][1] = data[i][1] .replace(/[\((]株[\))]/g, '株式会社'); } range.setValues(data); }

SECTION 11

AIによる住所・名前の正規化

STEP 04

表記ゆれの例

元データ正規化後
東京都港区六本木1-2-3東京都港区六本木一丁目2番3号
東京 港区 六本木 1丁目2-3東京都港区六本木一丁目2番3号
トウキョウト ミナトク東京都港区
田中太郎田中 太郎(タナカ タロウ)
たなか たろう田中 太郎(タナカ タロウ)
💡
正規表現だけでは対応できない「意味的な同一性」をAIが判断します。
GAS function normalizeAddresses() { const sheet = SpreadsheetApp .getActiveSheet(); const data = sheet.getDataRange() .getValues(); // 住所列(D列)をバッチでAI処理 const addresses = data .slice(1) .map(row => row[3]) .join('\n'); const result = callGemini( `以下の住所リストを正規化して ください。各行を正式な日本語住所 に変換し、同じ行数で返してください。 ${addresses}` ); const normalized = result .split('\n'); // 正規化結果をシートに書き戻し for (let i = 0; i < normalized.length; i++) { sheet.getRange(i + 2, 4) .setValue(normalized[i]); } }

SECTION 11

AIデータ分類: 自由記述テキストの分析

STEP 05

ユースケース: アンケート自由記述の分類

回答テキストAI分類結果
「価格が高すぎる」価格
「サポートの対応が遅い」サポート
「機能が充実していて使いやすい」機能
「UIが分かりにくい」UI/UX
「配送が早くて助かった」配送
手動分類だと数百件で数時間 → AIなら数秒で完了
GAS function classifySurveyData() { const sheet = SpreadsheetApp .getActiveSheet(); const data = sheet.getDataRange() .getValues(); for (let i = 1; i < data.length; i++) { const text = data[i][1]; // B列: 回答 const category = callGemini( `以下のアンケート回答を分類して ください。 カテゴリ: 価格, 機能, UI/UX, サポート, 配送, その他 感情: ポジティブ, ネガティブ, 中立 回答: ${text} JSON形式で返してください: {"category": "...", "sentiment": "..."}` ); const result = JSON.parse( category ); // C列: カテゴリ, D列: 感情 sheet.getRange(i + 1, 3) .setValue(result.category); sheet.getRange(i + 1, 4) .setValue(result.sentiment); Utilities.sleep(500); } }

AI関数の活用

=AI_SUMMARIZE(A1) のようなカスタム関数をGASで実現

SECTION 11 — AI関数

カスタム関数の作り方

STEP 06

GASカスタム関数とは

GASで定義した関数をスプレッドシートのセルから =関数名(引数) の形式で直接呼び出せます。

使い方イメージ

=AI_SUMMARIZE(A2)
=AI_CLASSIFY(B2, "価格,機能,サポート")
=AI_EXTRACT(C2, "メールアドレス")
=AI_TRANSLATE(D2, "英語")

制約: カスタム関数は最大30秒で完了する必要があります。大量データ処理には別関数で一括処理を推奨。
GAS // AI要約カスタム関数 // セルに =AI_SUMMARIZE(A2) と入力 function AI_SUMMARIZE(text) { if (!text) return ''; return callGemini( `以下のテキストを1行で要約して ください。要約のみ返してください: ${text}` ); } // Gemini API共通関数 function callGemini(prompt) { const API_KEY = ScriptApp.getOAuthToken(); const url = 'https://generativelanguage.' + 'googleapis.com/v1beta/models/' + 'gemini-2.5-flash:generateContent' + ``; const res = UrlFetchApp.fetch(url, { method: 'post', contentType: 'application/json', headers: { 'Authorization': `Bearer ${token}` }, payload: JSON.stringify({ contents: [{ parts: [{ text: prompt }]}] }) }); return JSON.parse( res.getContentText() ).candidates[0].content.parts[0].text; }

SECTION 11 — AI関数

AI_CLASSIFY関数: テキスト分類

STEP 07

使用例

セルに入力: =AI_CLASSIFY(B2, "苦情,要望,質問,感謝")

docs.google.com/spreadsheets
AI_CLASSIFY関数の実行結果画面
GAS /** * テキストを指定カテゴリに分類 * @param {string} text 分類対象テキスト * @param {string} categories * カンマ区切りのカテゴリ一覧 * @return {string} 分類結果 * @customfunction */ function AI_CLASSIFY(text, categories) { if (!text) return ''; const result = callGemini( `以下のテキストを分類してください。 カテゴリ候補: ${categories} テキスト: ${text} 回答はカテゴリ名のみを返して ください。候補にない場合は 「その他」と返してください。` ); return result.trim(); }
💡
@customfunction JSDocタグを付けると、セルの入力候補に表示されます。

SECTION 11 — AI関数

AI_EXTRACT関数: 情報抽出

STEP 08

非構造化データから情報を抽出

自由テキスト(メール本文、議事録など)から特定の情報を取り出します。

入力テキスト抽出指示結果
「田中太郎(090-1234-5678)です」電話番号090-1234-5678
「納期は3月15日希望です」日付3月15日
「合計金額: 54,800円(税込)」金額54,800円
GAS /** * テキストから指定情報を抽出 * @param {string} text 対象テキスト * @param {string} target 抽出したい情報 * @return {string} 抽出結果 * @customfunction */ function AI_EXTRACT(text, target) { if (!text) return ''; const result = callGemini( `以下のテキストから「${target}」を 抽出してください。 該当する情報のみを返してください。 見つからない場合は「N/A」と返して ください。 テキスト: ${text}` ); return result.trim(); }
使い方: =AI_EXTRACT(A2, "メールアドレス")

SECTION 11 — AI関数

AI_TRANSLATE関数: 翻訳

STEP 09
GAS /** * テキストを指定言語に翻訳 * @param {string} text 翻訳対象 * @param {string} targetLang 翻訳先言語 * @return {string} 翻訳結果 * @customfunction */ function AI_TRANSLATE(text, targetLang) { if (!text) return ''; const result = callGemini( `以下のテキストを${targetLang}に 翻訳してください。 翻訳結果のみを返してください。 テキスト: ${text}` ); return result.trim(); }

使用例

=AI_TRANSLATE(A2, "英語")
=AI_TRANSLATE(A2, "中国語")
=AI_TRANSLATE(A2, "韓国語")

AI関数まとめ

関数名機能使い方
AI_SUMMARIZE要約=AI_SUMMARIZE(A2)
AI_CLASSIFY分類=AI_CLASSIFY(A2, "カテゴリ")
AI_EXTRACT情報抽出=AI_EXTRACT(A2, "日付")
AI_TRANSLATE翻訳=AI_TRANSLATE(A2, "英語")
パフォーマンス注意: カスタム関数は1セルずつAPI呼び出しが発生します。大量データ(100行以上)には一括処理関数を使いましょう。

データ分析

スプレッドシート + AI で高度な分析を自動化

SECTION 11 — データ分析

ピボットテーブル活用

STEP 10

ピボットテーブルとは

大量のデータを集計・分析するための強力な機能。ドラッグ&ドロップで柔軟な集計が可能です。

1

データ範囲を選択

ヘッダー行を含めてデータ全体を選択

2

挿入 > ピボットテーブル

新しいシートまたは既存シートに作成

3

行・列・値を設定

集計したい軸と集計方法を指定

docs.google.com/spreadsheets
ピボットテーブルの操作画面
💡
Tips: ピボットテーブルの結果をAI関数で更に分析することで、人間では気づかない傾向を発見できます。

SECTION 11 — データ分析

AIによるデータ分析

STEP 11

CSVデータをGeminiに投げて傾向分析

GAS function analyzeDataWithAI() { const sheet = SpreadsheetApp .getActiveSheet(); const data = sheet.getDataRange() .getValues(); // データをCSV形式に変換 const csv = data .map(row => row.join(',')) .join('\n'); // AIに分析を依頼 const analysis = callGemini( `以下の売上データを分析し、 次の観点でレポートしてください: 1. 全体的な傾向 2. 上位3商品の特徴 3. 改善が必要な点 4. 来月の予測 データ: ${csv}` ); // 分析結果を新しいシートに出力 const ss = SpreadsheetApp .getActiveSpreadsheet(); let resultSheet = ss .getSheetByName('AI分析結果'); if (!resultSheet) { resultSheet = ss .insertSheet('AI分析結果'); } resultSheet.getRange(1, 1) .setValue(analysis); }

分析レポートの活用

トレンド分析

月次売上の推移から季節性パターンを自動検出

異常検知

通常と大きく異なるデータポイントをAIが指摘

予測

過去データのパターンから将来の傾向を予測

アクション提案

分析結果に基づく具体的な改善アクションを提案

注意: Gemini APIに送信するデータは最大入力トークン制限があります。大量データは集計済みのサマリーを送りましょう。

SECTION 11 — データ分析

データバリデーション

STEP 12

入力規則の設定(GAS)

GAS function setValidationRules() { const sheet = SpreadsheetApp .getActiveSheet(); // B列: メールアドレス形式 const emailRule = SpreadsheetApp .newDataValidation() .requireTextContains('@') .setAllowInvalid(false) .setHelpText( '有効なメールアドレスを入力' ) .build(); sheet.getRange('B2:B1000') .setDataValidation(emailRule); // C列: 数値範囲(0〜1000000) const numRule = SpreadsheetApp .newDataValidation() .requireNumberBetween( 0, 1000000 ) .build(); sheet.getRange('C2:C1000') .setDataValidation(numRule); // D列: プルダウン選択 const listRule = SpreadsheetApp .newDataValidation() .requireValueInList( ['未対応', '対応中', '完了'] ) .build(); sheet.getRange('D2:D1000') .setDataValidation(listRule); }

AIによる異常値検出

GAS function detectAnomalies() { const sheet = SpreadsheetApp .getActiveSheet(); const data = sheet.getDataRange() .getValues(); const csv = data .map(r => r.join(',')) .join('\n'); const anomalies = callGemini( `以下のデータの異常値を検出して ください。行番号と理由をJSON配列 で返してください: [{"row":2,"reason":"..."}] データ: ${csv}` ); const results = JSON.parse( anomalies ); // 異常値の行を赤色でハイライト results.forEach(item => { sheet.getRange(item.row, 1, 1, sheet.getLastColumn()) .setBackground('#fce8e6'); }); }

SECTION 11 — データ分析

レポート自動生成

STEP 13

GAS + Docs APIで自動レポート

📊スプレッドシートのデータ
🤖Gemini APIで分析・要約
📄Google Docsにレポート出力
📧関係者にメールで共有
GAS function generateReport() { const sheet = SpreadsheetApp .getActiveSheet(); const data = sheet.getDataRange() .getValues(); const csv = data .map(r => r.join(',')).join('\n'); // AIに分析レポートを生成させる const report = callGemini( `以下のデータから月次レポートを 作成してください。 - エグゼクティブサマリー - 主要KPIの推移 - 注目ポイント - 来月のアクション提案 データ:\n${csv}` ); // Google Docsに出力 const doc = DocumentApp.create( `月次レポート_${new Date() .toLocaleDateString()}` ); const body = doc.getBody(); body.setText(report); // メールで共有 GmailApp.sendEmail( 'team@example.com', '月次レポートが作成されました', `レポートURL: ${doc.getUrl()}` ); }

ハンズオン

実際にスプレッドシート + AI を体験しよう

SECTION 11 — ハンズオン

ハンズオン1: データクレンジング実践

HANDS-ON 01

課題: 汚いデータを修正しよう

1

サンプルデータを用意

新しいスプレッドシートに以下のデータを入力:
「(株)ABC」「株式会社ABC」「ABC Inc」を含む顧客リスト

2

GASエディタを開く

拡張機能 > Apps Script

3

normalizeData関数を実行

スライド4のコードを貼り付けて実行

4

結果を確認

「(株)」が「株式会社」に統一されたことを確認

サンプルデータ

名前会社名電話番号
田中太郎(株)ABC0312345678
TANAKA TARO株式会社ABC03-1234-5678
鈴木花子(株)XYZ09012345678
佐藤一郎DEFカンパニー06-9876-5432
田中太郎(株)ABC03-1234-5678
💡
チェックポイント:
- 全角数字が半角になっているか
- (株)が株式会社に統一されているか
- 電話番号のフォーマットが統一されているか
- 重複行(田中太郎の2行目)が除去されているか

SECTION 11 — ハンズオン

ハンズオン2: AIカスタム関数を作る

HANDS-ON 02
1

Gemini APIキーを設定

GCPプロジェクトIDをコード冒頭のPROJECT_ID変数に設定を追加

2

callGemini関数を追加

スライド8のGemini API共通関数をコピー

3

AI_SUMMARIZE関数を追加

スライド8のカスタム関数コードをコピー

4

セルで実行

A列にテキストを入力し、B1に =AI_SUMMARIZE(A1) と入力

テスト用テキスト

「本日の会議では、来期の予算配分について議論しました。マーケティング部門から20%増額の要望があり、人事部門からは新卒採用費用の確保が急務との意見がありました。最終的に、各部門の優先度を精査したうえで次回会議で決定することになりました。」

期待される結果

「来期予算配分の会議で、マーケティング20%増額と新卒採用費の確保を議論し、次回会議で決定予定。」

初回実行時は「承認が必要です」というダイアログが出ます。URLFetchAppの外部接続権限を承認してください。

SECTION 11 — ハンズオン

ハンズオン3: AIデータ分析

HANDS-ON 03

課題: 売上データの傾向分析

1

サンプル売上データを用意

商品名、月、売上金額の3列で12行のデータを入力

2

analyzeDataWithAI関数を実行

スライド14のコードを貼り付けて実行

3

「AI分析結果」シートを確認

AIが生成した分析レポートを確認

発展: プロンプトを変えて「競合比較」「季節性分析」など異なる角度の分析を試してみましょう。

サンプルデータ

商品売上(万円)
商品A1月120
商品A2月95
商品A3月180
商品B1月200
商品B2月210
商品B3月195
商品C1月50
商品C2月45
商品C3月30

SECTION 11

一括処理のテクニック

ADVANCED

カスタム関数の制約を回避

カスタム関数は1セルずつAPI呼び出しが発生し、100行で100回のAPI呼び出しになります。一括処理関数を使うと効率的です。

GAS function batchClassify() { const sheet = SpreadsheetApp .getActiveSheet(); const data = sheet.getDataRange() .getValues(); // 全テキストをまとめて1回で処理 const texts = data.slice(1) .map((r, i) => `${i+1}. ${r[0]}`) .join('\n'); const result = callGemini( `以下のテキストを各行ごとに 分類してください。 カテゴリ: 苦情,要望,質問,感謝 番号. カテゴリ の形式で返して: ${texts}` ); // 結果をパースしてシートに書き込み const lines = result.split('\n'); lines.forEach((line, i) => { const cat = line .replace(/^\d+\.\s*/, ''); sheet.getRange(i + 2, 2) .setValue(cat.trim()); }); }

比較: 1件ずつ vs 一括処理

1件ずつ一括処理
API呼び出し100回1回
実行時間約100秒約3秒
コスト高い低い
精度高いやや低下
💡
使い分け:
- 10行以下: カスタム関数でOK
- 10〜100行: 一括処理関数を使用
- 100行以上: バッチに分割して処理

SECTION 11

キャッシュとパフォーマンス最適化

STEP 14

CacheServiceの活用

GAS function callGeminiCached(prompt) { const cache = CacheService .getScriptCache(); // キャッシュキーを生成 const key = Utilities .computeDigest( Utilities.DigestAlgorithm.MD5, prompt ).map(b => (b < 0 ? b + 256 : b) .toString(16) .padStart(2, '0') ).join(''); // キャッシュがあればそれを返す const cached = cache.get(key); if (cached) return cached; // なければAPIを呼び出し const result = callGemini(prompt); // 6時間キャッシュ cache.put(key, result, 21600); return result; }

パフォーマンスTips

  • 同じプロンプトにはキャッシュを活用
  • getValues()でデータを一括取得
  • setValues()でデータを一括書き込み
  • Utilities.sleep()でAPIレート制限を回避
  • 大量データはバッチ分割(50件ずつ等)

GAS実行時間制限

無料アカウント: 6分/回
Workspace: 30分/回
大量データは複数回に分けて処理し、途中経過をシートに保存しましょう。

SECTION 11

カスタムメニューで使いやすく

STEP 15

メニューバーに独自メニューを追加

GAS function onOpen() { SpreadsheetApp.getUi() .createMenu('AI データ処理') .addItem( 'データクレンジング', 'normalizeData' ) .addItem( '重複除去', 'removeDuplicates' ) .addSeparator() .addItem( 'AI一括分類', 'batchClassify' ) .addItem( 'AIデータ分析', 'analyzeDataWithAI' ) .addItem( '異常値検出', 'detectAnomalies' ) .addSeparator() .addItem( 'レポート自動生成', 'generateReport' ) .addToUi(); }
docs.google.com/spreadsheets
カスタムメニュー「AI データ処理」が追加されたスプレッドシート画面
onOpen関数はスプレッドシートを開くたびに自動実行されます。非エンジニアの同僚もメニューからワンクリックで実行できます。

SECTION 11

ベストプラクティス: データ管理の10原則

BEST PRACTICES
  • 1シート1テーマ — 異なるデータは別シートに分ける
  • ヘッダー行は必須 — 列の意味を明確にする
  • セル結合しない — GASでの処理が困難になる
  • 空行を入れない — getDataRange()が途中で止まる
  • 日付は統一形式 — yyyy/mm/dd に統一
  • 数値に単位を入れない — 「100万円」ではなく「1000000」
  • マスターデータを作る — プルダウンで入力を制限
  • 定期バックアップ — 版管理 or コピーを保存
  • アクセス権限を管理 — 編集/閲覧を適切に設定
  • 変更履歴を残す — スプレッドシートの版履歴を活用

「きれいなデータは、きれいなスプレッドシートから生まれる」 — データ品質は入力の段階で8割が決まります。

SECTION 11

全体ワークフロー: データ活用パイプライン

OVERVIEW
📥 データ収集
🧹 クレンジング
🤖 AI分類・抽出
📊 分析
📄 レポート
📧 共有

セクション10で学んだこと

Gmailからのデータ収集・外部通知

セクション11で学んだこと

クレンジング・AI関数・分析・レポート生成

💡
セクション10(Gmail自動化)とセクション11(データ処理)を組み合わせることで、「メール受信 → データ抽出 → クレンジング → 分析 → レポート」まで完全自動化が実現できます。

SECTION 11

まとめ

SUMMARY

学んだこと

  • データ品質の重要性(GIGO原則)
  • GASによるクレンジング(重複除去・表記統一)
  • AIによる住所正規化・テキスト分類
  • カスタム関数(AI_SUMMARIZE / CLASSIFY / EXTRACT / TRANSLATE)
  • AIデータ分析とレポート自動生成
  • 一括処理とキャッシュによるパフォーマンス最適化
  • カスタムメニューで非エンジニアにも使いやすく

次のステップ

  • 自社のスプレッドシートで表記ゆれを確認
  • AI_SUMMARIZE関数を1つ作ってみる
  • 定例レポートの自動化を検討
  • チームに展開してフィードバックを収集

データの品質を上げることが、AI活用の最大の近道です。

セクション11 完了

お疲れさまでした!次のセクションに進みましょう。

次へ → セクション12
学習項目
8
ハンズオン
3
AI関数
4
所要時間
50分
🏠 研修ポータル ▶ この章の動画 📺 動画一覧