フォーム回答を分析したいとき、いきなりグラフを作ると失敗しやすいです。
理由は単純で、まだ「何を1件として数えるか」「何を除外するか」「どれを未対応と呼ぶか」が決まっていないからです。
フォーム分析で最初に作るべきものは、ダッシュボードではありません。CSVの列です。列が弱いままグラフ化すると、問い合わせ、予約、採用、イベント、アンケートの回答が、ただの「回答数」に潰れてしまいます。
この記事では、フォーム回答を分析・レポート・AI要約・Slack通知・担当者管理に回す前に、CSVへ落としておくべき指標と列を整理します。
まず集計対象を分ける
フォーム分析で最初に決めるのは、総回答数ではなく、有効回答数です。
同じフォームに届く回答でも、実務で見るべきものと、通常集計から外すべきものがあります。
| 種類 | 例 | 通常集計 |
|---|---|---|
| 有効回答 | 問い合わせ、予約希望、採用応募、イベント申込 | 入れる |
| 対応不要 | 自動返信テスト、社内確認、重複送信 | 外す |
| ノイズ | 営業メール、スパム、意味のない入力 | 外す |
| 要確認 | 低評価、クレーム、返信可否不明、個人情報を含む長文 | 入れるが別扱い |
そのため、CSVには exclude_from_report と exclude_reason を持たせます。
exclude_from_report
exclude_reason
この2列がないと、営業メールが増えた週を「需要が増えた」と誤読します。テスト送信が残ったまま、コンバージョン改善の議論をしてしまいます。フォーム分析の精度は、可視化ツールではなく、除外条件で決まります。
最初に見るKPI
最初に見るKPIは、次の7つで十分です。
| KPI | 見たいこと | 必要な列 |
|---|---|---|
| 有効回答数 | 実際に読むべき回答が何件あるか |
response_id, exclude_from_report
|
| 流入元別回答数 | どの導線から来ているか |
source, utm_source, landing_page
|
| 内容分類 | 何についての回答か |
category, subcategory
|
| 未対応数 | 放置されている回答があるか |
status, first_response_at
|
| 担当者未設定数 | 誰も持っていない回答があるか | owner |
| 高優先度数 | 先に見るべき回答があるか |
priority, priority_reason
|
| 次アクション未設定数 | 見た後に止まっていないか | next_action |
ポイントは、分析を「件数」だけにしないことです。
フォーム回答は、読まれ、分類され、担当者へ渡され、返信・確認・レポート・外部連携に進みます。つまり、分析対象であると同時に、業務のチケットでもあります。
CSV列の推奨スキーマ
最小構成なら、このくらいから始めます。
response_id
submitted_at
form_slug
source
utm_source
landing_page
category
subcategory
message
message_length
priority
priority_reason
status
owner
owner_candidate
first_response_due_at
first_response_at
followup_permission
contains_personal_data
exclude_from_report
exclude_reason
next_action
last_activity_at
すべてを手入力する必要はありません。自動で埋められるもの、AIに候補を出させるもの、人間が確定するものを分けます。
| 列 | 埋め方 | 注意点 |
|---|---|---|
submitted_at |
自動 | タイムゾーンを固定する |
source, utm_source
|
URL/hidden field | 空欄の場合の扱いを決める |
category |
ルールまたはAI候補 | 確定値と候補値を混ぜない |
priority |
条件分岐またはAI候補 | 緊急度の理由を残す |
status |
人間またはワークフロー | 未対応と完了だけにしない |
owner |
人間または明示ルール | AI候補をそのまま確定扱いにしない |
followup_permission |
フォーム入力 | 返信してよいかを後から推測しない |
exclude_from_report |
人間確認 | 営業メール、テスト、重複を混ぜない |
分析のための列と、運用のための列を同じCSVに置くのが重要です。分析だけなら category や source で足りますが、実務では status、owner、next_action がないと止まります。
まず出すべき集計
CSVができたら、最初に見るのはこの順番です。
1. 有効回答数
2. 除外件数と除外理由
3. 未対応件数
4. 担当者未設定件数
5. 高優先度件数
6. カテゴリ別件数
7. 流入元別件数
8. 次アクション未設定件数
回答数から見るのではなく、除外と未対応を先に見ます。
たとえば、100件届いていても、営業メールが40件、重複が10件なら、有効回答は50件です。さらに未対応が12件なら、見るべき課題は「100件来た」ではなく「50件中12件が止まっている」です。
SQLで見るなら
DBやBigQueryに入れている場合は、まずこの程度で十分です。
select
date(submitted_at) as submitted_date,
count(*) as total_responses,
count(*) filter (where exclude_from_report = false) as valid_responses,
count(*) filter (
where exclude_from_report = false
and status in ('new', 'triaged', 'assigned', 'in_progress')
) as open_responses,
count(*) filter (
where exclude_from_report = false
and owner is null
) as unassigned_responses,
count(*) filter (
where exclude_from_report = false
and priority = 'high'
) as high_priority_responses
from form_responses
group by 1
order by 1 desc;
ここで大事なのは、count(*) だけを信じないことです。
valid_responses、open_responses、unassigned_responses を別々に見ると、フォーム回答が「集まったか」だけでなく「業務として進んでいるか」が分かります。
Google Sheetsで始めるなら
Sheetsで始める場合も、最初の集計は難しくありません。
たとえば、exclude_from_report が FALSE の有効回答だけ数えるなら次のようにします。
=COUNTIF(exclude_from_report_range, FALSE)
未対応を数えるなら、ステータスを条件にします。
=COUNTIFS(exclude_from_report_range, FALSE, status_range, "new")
+COUNTIFS(exclude_from_report_range, FALSE, status_range, "triaged")
+COUNTIFS(exclude_from_report_range, FALSE, status_range, "assigned")
担当者未設定は、空欄を見ます。
=COUNTIFS(exclude_from_report_range, FALSE, owner_range, "")
最初からBIツールへ行くより、Sheetsで「何を数えるべきか」を固めたほうが速いことがあります。グラフは、KPIの定義が固まってからで十分です。
AI分析に渡す前の必須列
AIで自由記述を分類したり、週次レポートを作ったりする場合も、本文だけを渡すのは避けます。
本文だけを渡すと、AIは文章の意味を要約できます。でも、業務上の状態は分かりません。
message
status
owner
priority
followup_permission
exclude_from_report
contains_personal_data
最低でもこの7つは一緒に渡します。
AIには、次のような役割を持たせます。
| AIに任せる | 人間が確認する |
|---|---|
| 自由記述の要約 | 実返信するか |
| カテゴリ候補 | 最終カテゴリ |
| 優先度候補 | 本当に緊急か |
| 営業メールらしさの候補 | 除外確定 |
| 週次レポート下書き | 外部共有してよい内容か |
AIを使うほど、列設計は重要になります。AIの出力を信用するためではなく、AIに何を見せ、何を判断させないかを固定するためです。
用途別に足す列
共通列だけでは足りない場合は、用途別に列を足します。
| 用途 | 追加したい列 | 理由 |
|---|---|---|
| 問い合わせ |
company_name, inquiry_type, reply_required
|
返信要否と担当者を決める |
| 予約 |
preferred_date, reservation_status, change_request
|
日時が近いものを先に見る |
| 採用 |
position, experience_level, screening_status
|
応募フローへ渡す |
| イベント |
event_date, attendance_status, pre_event_question
|
当日準備へつなげる |
| アンケート |
score, sentiment, theme
|
改善レポートに使う |
「フォーム回答」とひとことで言っても、運用は違います。だから、共通列で土台を作り、その上に用途別の列を足します。
グラフ化する前の品質チェック
最後に、グラフ化する前にこのチェックを通します。
response_id は一意か
submitted_at は空でないか
source の空欄をどう扱うか決めたか
exclude_from_report の理由が残っているか
status の値が定義済みのものだけか
owner_candidate と owner を混ぜていないか
followup_permission が未確認のまま返信対象に入っていないか
contains_personal_data をAIや外部連携の条件に使っているか
next_action が空の回答を見つけられるか
このチェックを通らないCSVは、グラフにしても実務で使いにくいです。見た目は整っていても、誰が何をすればよいか分からないからです。
まとめ
フォーム分析は、きれいなグラフを作ることではありません。
回答を次の業務へ渡すために、数える対象、除外条件、未対応、担当者、優先度、次アクションを列として残すことです。
CSV列が決まると、Sheets集計、ダッシュボード、Slack通知、AI要約、週次レポートまで同じ定義でつながります。
より広いフォーム分析の考え方は、FORMLOVA側で整理しています。