崩れないパイプライン管理表を作るには、チュートリアルによく出てくる10行のサンプルデータではなく、実際に届くエクスポートを前提に設計する必要があります。
3層構造はシンプルです。CRMエクスポート(またはIMPORTRANGEで接続したシート)を受け取る「生データタブ」、ゆれたデータを吸収する「計算レイヤー」、そして毎週の営業会議でマネージャーが必ず聞く3つの問い——加重パイプライン合計はいくらか、フォローが止まっている案件はどれか、ファネルのどこで失注が集中しているか——に答える「サマリービュー」です。
CRMエクスポートの実態
SalesforceやHubSpotのエクスポートは、一見きれいに見えます。しかし「クローズ予定日」列を確認すると実態がわかります。実際の数万行規模のSalesforceエクスポートには、「2026-05-01」「5/1/2026」「May 1, 2026」、そして空白が同じ列に混在します。18ヶ月の間に3つの異なる入力フローがレコードを触った結果です。ステージ名も「Proposal」「proposal」「PROPOSAL - REVISED」、そして誰かが修正する前に新人SDRが入力した独自の文字列が混在しています。
これはイレギュラーなデータではありません。これが「普通のエクスポート」です。パイプライン管理表はどんな数式よりも先に、このゆれを吸収できなければなりません。
崩れないパイプライン管理表のスキーマ設計
生データタブは絶対に手を加えないでください——元データへの直接変換は禁物です。代わりに Pipeline_Clean タブを作り、読み込みながら標準化します。7列あれば、パイプライン報告の9割はカバーできます。
| 列 | ヘッダー | 補足 |
|---|---|---|
| A | 案件ID | 重複排除のユニークキー |
| B | 案件名 | テキスト、変換不要 |
| C | 担当者 | TRIM + UPPER で表記ゆれを吸収 |
| D | ARR(年間契約金額) | VALUE() でラップ必須 |
| E | ステージ | ルックアップテーブルで正規化 |
| F | クローズ予定日 | DATEVALUE() でパース |
| G | 最終活動日 | 失効案件フラグ用 |
ほとんどの管理表が崩れるのはステージ列です。生データを直接クレンジングしようとするのではなく、Stage_Map という小さなルックアップタブを別途管理してください。「proposal」「Proposal - Revised」「PROP」といったすべての表記ゆれを、正規のステージ名にマッピングします。それをPipeline_Cleanに引き込む数式はこちらです:
=IFERROR(VLOOKUP(TRIM(LOWER(Raw!E2)), Stage_Map!$A:$B, 2, 0), "UNKNOWN")
IFERRORは必須です。新しいステージ名が出現したとき(四半期途中に必ず出ます)、数式はエラーではなく「UNKNOWN」を返します。ファネル集計表に「UNKNOWN」が現れれば一目でわかります。しかしSUMIFが壊れてゼロを返す場合は、誰も気づきません。
加重パイプライン:マネージャーが本当に知りたい数字
加重パイプラインは、各案件のARR(年間契約金額)にそのステージの成約確率を掛け合わせた合計値です。多くの営業組織はステージごとに大まかな確率を設定しています。たとえば、ヒアリング段階10%、提案書提出30%、条件交渉60%、口頭合意85%といった具合です。
この確率は数式にハードコードせず、Weights という専用タブで管理してください。ステージ名と確率は数四半期ごとに見直されます。そのたびに12箇所のSUMPRODUCT数式を探して修正するのは現実的ではありません。
5,000行以内であれば、SUMPRODUCTが有効です:
=SUMPRODUCT(
(Pipeline_Clean!E2:E5001<>"Closed Lost") *
(Pipeline_Clean!E2:E5001<>"Closed Won") *
IFERROR(VLOOKUP(Pipeline_Clean!E2:E5001, Weights!$A:$B, 2, 0), 0) *
IFERROR(VALUE(Pipeline_Clean!D2:D5001), 0)
)
5,000行を超えたらQUERYに切り替えて集計します:
SELECT E, SUM(D)
WHERE E <> 'Closed Lost' AND E <> 'Closed Won' AND D IS NOT NULL
GROUP BY E
LABEL SUM(D) 'Total ARR'
集計結果にWeightsタブの確率をヘルパー列で掛け合わせます。エレガントではありませんが、3万行のシートでも2秒以内に再計算できます。同じデータで入れ子のSUMPRODUCTを使うと18秒以上かかります。週次の営業会議前にダッシュボードを開く場面では、この差は致命的です。
ステージ転換率:ファネルのどこで失注しているか
加重パイプライン合計はパイプラインの「規模」を教えてくれます。ステージ転換率は「どこで案件が死んでいるか」を教えてくれます。マネージャーへの報告では、後者のほうが重要なことが多いです。
COUNTIFベースのファネル集計表を作りましょう。各行に正規化済みのステージ、列に案件数・ARR合計・次ステージへの転換率を並べます:
=COUNTIF(Pipeline_Clean!$E:$E, A2)
隣接ステージ間の転換率はこちら:
=IFERROR(B3/B2, 0)
B2が第Nステージの案件数、B3が第N+1ステージの案件数です。必ずIFERRORでラップしてください。四半期初めの月曜日はヒアリング件数がゼロになることもあり、マネージャーへの報告資料に#DIV/0!が表示されては困ります。
B2B SaaSの成約率については、Salesforceが毎年発行する「State of Sales」レポートで有効パイプラインの20〜25%が成約に至るという数字が示されています。ただし、自社の過去データのほうがいかなる外部ベンチマークよりも実態に即しています。ファネル集計表を継続的に蓄積することで、自社固有の転換率データが構築されていきます。
月曜会議前に失効案件を特定する
30日間活動記録のない未クローズ案件は、実質的に死んでいるか、早急なフォローが必要な状態です。そしてそれは会議の場で発覚するのではなく、前日までに把握されている必要があります。Pipeline_Cleanに Stale_Flag 列を追加しましょう:
=IF(
AND(
E2<>"Closed Won",
E2<>"Closed Lost",
IFERROR(TODAY()-VALUE(G2), 999)>30
),
"STALE",
""
)
IFERROR(TODAY()-VALUE(G2), 999) の部分が重要です。最終活動日が空欄だったり、テキスト文字列として届いたりした場合、VALUE()が失敗し、IFERRORが999を返し、案件が失効フラグを立てます——これは正しい判断です。活動日の記録がない案件は、実質的に失効しているとみなすべきだからです。
サマリーダッシュボードには =COUNTIF(Pipeline_Clean!H:H, "STALE") で失効件数を表示し、担当者別の内訳と組み合わせてください。これにより、週次の定例前に営業マネージャーや営業企画担当者が優先してフォローすべき案件を特定できます。
Google SheetsのSales Pipeline Trackerが限界を迎えるとき
| 行数 | 推奨アプローチ |
|---|---|
| 5,000行未満 | ARRAYFORMULA + SUMPRODUCTを自由に使用 |
| 5,000〜2万行 | 集計にはQUERY、行レベル変換にはARRAYFORMULA |
| 2〜5万行 | 集計はQUERYのみ。TODAY、NOWなどの揮発性関数を最小化 |
| 5万行超 | 分割アーキテクチャ——Sheetsは表示レイヤーのみに |
Google Workspace公式ドキュメント『Google Sheets limits』ではスプレッドシートあたり1,000万セルが上限と定められていますが、実際のパフォーマンスはその遥か手前で劣化します。5万行・15列の数式が入ったパイプライン管理表は再計算に30秒以上かかることがあり、「ライブダッシュボード」としての用途が成り立ちません。
解決策はアーキテクチャの分割です。生エクスポートは1つ目のスプレッドシートに置き、クレンジングと集計を2つ目のシートで実行し、IMPORTRANGEで処理済みのサマリーデータだけを参照させます。マネージャー向けダッシュボードはそのサマリーシートを見ます。3タブ、1つの信頼できる情報源、読み込み時間3秒以内——これが現実的な設計です。
すべてを壊す列(正直な警告)
誰も教えてくれない障害パターンがあります。CRM管理者が月曜と火曜の間にSalesforceエクスポートへ列を追加します。IMPORTRANGEの参照範囲は Raw!A:M で固定されています。新しい列が挿入されることで、ARRが列Dから列Eにずれます。列Dを位置で参照しているすべての数式は、エラーも出さずに静かに誤った値を返し続けます。
対策は「防御的参照」です。MATCHで列ヘッダーの位置を探し、INDEXで列番号ではなく名前で値を取得します:
=INDEX(Raw!$A:$Z, ROW(), MATCH("ARR", Raw!$1:$1, 0))
数式のオーバーヘッドは増えますが、スキーマ変更に耐えられます。ライブCRM連携では、スキーマの変更は「もしあれば」ではなく「いつあるか」の問題です。2026年5月現在、Google Sheetsにはネイティブの名前付き列参照機能がないため(構造化テーブル機能の範囲外では)、MATCH/INDEXがスキーマ耐性のある管理表の標準的なアプローチです。
誰も直さない部分:手動エクスポートという運用コスト
パイプライン管理表の最大の運用負荷は数式ではありません。「毎週月曜の朝、SalesforceからCSVをダウンロードし、Driveにアップロードし、IMPORTRANGEを貼り直し、列がずれていないことを祈る」という作業そのものです。週に20分、担当者が休むと即座に止まる属人的なワークフローです。
ModelMonkeyはSalesforce(読み取り専用)およびHubSpotと直接連携し、スケジュール実行でエクスポートをSheetsの構造に取り込み、インポート時にクレンジング処理を実行します。組み込みのSQLエンジンは SELECT Stage, SUM(ARR) FROM pipeline GROUP BY Stage のようなクエリをシートデータに対して直接実行でき、複雑なQUERY数式なしで集計が完結します。週次パイプラインレビューを運営している営業オペレーションチームにとって、この手動エクスポート作業を完全に自動化できる点が最も大きなメリットです。
ModelMonkeyのプランを選ぶ — Google SheetsとExcelの両方に対応しています。
よくある質問
Q. Google SheetsでSales Pipeline Trackerを作るのに、どのシート構成がベストですか? 生データタブ・クレンジングタブ(Pipeline_Clean)・サマリービューの3タブ構成が基本です。生データには絶対に手を加えず、クレンジングタブで標準化し、サマリービューで集計結果を表示します。この分離により、CRMエクスポートのスキーマが変わっても影響が局所化されます。
Q. 加重パイプラインはどうやって計算しますか?
各案件のARR(年間契約金額)に、そのステージの成約確率を掛けた合計値です。確率は数式にハードコードせず、専用の Weights タブで一元管理してください。5,000行以内であればSUMPRODUCT、それ以上ではQUERYで集計した後にヘルパー列で確率を掛けます。
Q. CRMのステージ名の表記ゆれにはどう対処すればいいですか?
Stage_Map というルックアップタブを別途作成し、「proposal」「Proposal - Revised」「PROP」などすべての揺れを正規のステージ名にマッピングします。Pipeline_CleanタブではVLOOKUP+IFERRORでこのマップを参照し、未知のステージ名は「UNKNOWN」として返すことで、サマリービューで即座に検知できます。
Q. Google SheetsのSales Pipeline Trackerは何行まで現実的に使えますか? Google Workspace公式ドキュメント『Google Sheets limits』では上限を1,000万セルとしていますが、パフォーマンスの観点では5万行が実質的な限界です。それ以上になるとQUERY中心のアーキテクチャへの移行と、生データ・集計・表示レイヤーの分割が必要になります。
Q. 失効案件(放置案件)を自動で検知する方法はありますか?
Pipeline_Cleanタブに Stale_Flag 列を追加し、最終活動日から30日以上経過している未クローズ案件に「STALE」フラグを立てます。最終活動日が空欄の場合も失効とみなすようIFERRORで999日を代入する設計にすることで、記録漏れの案件も安全に検知できます。
Q. 列が追加されてARRの位置がずれると管理表が壊れます。対策はありますか?
列番号ではなくヘッダー名で参照する「防御的参照」が有効です。=INDEX(Raw!$A:$Z, ROW(), MATCH("ARR", Raw!$1:$1, 0)) のようにMATCH/INDEXを組み合わせることで、列の挿入・移動が発生しても数式が正しい列を追い続けます。