弊社にて、アンケート調査の企画から回答収集・集計分析・帳票出力までをワンストップで扱える Web アプリケーション 「調査集計システム」 を開発しました。
フォーム作成サービスは世の中に数多く存在しますが、本システムは「集計」に特化した業務システムとして設計されているのが特徴です。本記事では、実装した機能を一つひとつ詳しく紹介していきます。

プロジェクト概要
項目 | 内容 |
|---|---|
種別 | 業務用 Web アプリケーション |
ユースケース | 従業員満足度調査、実態調査、マーケティングリサーチ等 |
想定回答規模 | 数千件 |
管理者 | 調査担当者(管理画面利用) |
回答者 | 一般ユーザー(認証不要の公開URL) |
課題:クロス集計が困難すぎる

アンケートをとること自体はとてもシンプルで、googleフォームで簡単に作成・取得ができます。ただその集計にはとても時間がかかることがあります。
例えば、単純に「Q1:所属部署はなんですか?」という質問の答えを集計するならGoogleフォームとエクセルで一瞬です。しかし、「Q1が営業部と答えた人のQ2の回答を集計」となったり、そのQ2が「単一選択」ではなく「複数選択」であったりすると、、、非常に複雑でエクセルの限界を超えてしまいます。
この膨大な手作業を解決するのが今回のアンケート集計ツールです。
技術スタック
カテゴリ | 技術 |
|---|---|
フロントエンド | Next.js 15(App Router)/ React 19 / TypeScript |
UI | Tailwind CSS |
バックエンド | Next.js Route Handlers / Server Actions |
データベース | PostgreSQL(Neon) |
ORM | Prisma |
認証 | iron-session |
Excel出力 | xlsx |
AI翻訳 | Anthropic Claude API |
ホスティング | Vercel |
開発環境 | Docker Compose |
実装機能
1. 調査票管理機能


調査票の下書き状態から公開・締め切り前で、一通り必要な機能を管理できるよう実装しました。
1-1. 調査のライフサイクル管理
下書き / 公開中 / 締切 の3ステータスで調査の状態を管理
「ステータス変更」ボタンで公開中から締切へ即時切り替え可能
回答受付期間(開始日・終了日)を設定でき、期間外は回答フォームが自動で無効化
1-2. 調査の複製機能
既存の調査を1クリックで複製
設問・選択肢・マトリクス行列・数値区分・多言語翻訳まで全て含めて深いコピー
条件分岐の参照先を新IDにマッピングする2パス処理を実装(単純コピーだと元設問を参照してしまう問題に対応)
1-3. 公開URL管理
編集画面に公開URLを表示し、ワンクリックでクリップボードにコピー可能
プレビュー画面(認証済み管理者のみ)で回答者視点の挙動を確認可能
2. 設問管理機能

2-1. 7種類の設問タイプに対応
単一、複数だけではなく、複数回答のマトリクス形式のような複雑な形式にも対応しました。
タイプ | 用途 |
|---|---|
単一選択 | 性別、所属部署など1つだけ選ぶ設問 |
複数選択 | 「当てはまるものを全て」のような設問 |
数値入力 | 年齢、勤続年数、スコア等 |
自由記述 | コメント、ご意見 |
単一回答マトリクス | 各行で1列選択(満足度5段階など) |
複数回答マトリクス | 各行で複数選択(認知・利用状況など) |
数値入力マトリクス | 各セルに数値を入力(月別売上など) |
2-2. 設問の詳細制御
設問コード(Q1, Q2など)を自由に設定可能
必須フラグ / 集計対象フラグ / クロス集計軸フラグ を個別に設定
排他選択肢(「該当なし」など他とは両立しない選択肢)の制御
自由記述可選択肢(「その他( )」のような補足記入欄)に対応
2-3. 条件分岐表示
「Q1で特定の回答をした場合のみQ3を表示」といった分岐設定
回答フォームでリアルタイムに判定して表示/非表示を切り替え
2-4. 設問の並び替え
▲▼ボタンで設問の順番を入れ替え可能
orderNum を transaction で安全にスワップ
2-5. インライン編集
選択肢・マトリクス行・列・数値区分をリスト上で直接編集できるUI
モーダルを開かずに高速に項目修正可能
3. 回答フォーム(公開URL)
回答フォームは外国人回答者にも対応し、AIによる翻訳で複数言語対応も可能としました。



3-1. 回答者体験
認証不要でアクセス可能な公開URL
PC・スマートフォン両対応のレスポンシブデザイン
必須項目の未入力バリデーション
二重送信防止(submitting state flag)
条件分岐表示によって不要な設問は非表示
3-2. 多言語対応(回答画面のみ)
日本語・英語・中国語・韓国語・ベトナム語・ポルトガル語 に対応
言語切替をワンタップで実行
設問文、選択肢、マトリクス行列の全てを多言語化
3-3. AI自動翻訳機能 🎯
Anthropic Claude API と連携し、日本語の設問をワンクリックで全言語に自動翻訳
翻訳エディタで「AI自動翻訳」ボタンを押すと、空の項目を一括翻訳
言語切替時には未翻訳の項目を自動検出して翻訳を走らせる
調査担当者の翻訳作業工数を大幅に削減
3-4. 回答完了画面
調査ごとにカスタマイズ可能な完了メッセージ
多言語の完了メッセージにも対応
4. 回答データ管理
4-1. 回答一覧
回答ID、日時、言語、ステータスを一覧表示
ページネーション対応
4-2. 多段階フィルタリング
調査で絞り込み
回答日時範囲(開始日〜終了日)で絞り込み
特定設問の値 で絞り込み(設問選択+値指定)
自由記述検索
4-3. 回答詳細画面
1回答の全設問への回答を閲覧
選択肢コード → ラベル解決(多言語対応)
マトリクスの回答は表形式で表示
4-4. 一括Excel出力
絞り込み条件をそのままエクスポートに適用
1回答1行の「フラット形式」で出力
5. 単純集計機能

5-1. 設問タイプ別の集計
タイプ | 集計内容 |
|---|---|
単一選択 | 選択肢別件数、割合、無回答件数 |
複数選択 | 選択肢別件数、選択率、無回答件数 |
数値入力 | 件数、平均、最小、最大、中央値、区分別件数 |
自由記述 | 集計対象外(一覧表示のみ) |
マトリクス | 行ごとの列別件数・割合・無回答 |
5-2. 重要な統計仕様
割合の母数は「設問の回答者数」 を採用(設問ごとに異なる)
無回答も1カテゴリとして明示(画面・Excelの両方に注記)
複数回答の注記:「割合の合計は100%を超える場合があります」を自動表示
中央値は偶数件の場合、中央2値の平均を返す正確な実装
5-3. 数値設問の区分(ビニング)
「0〜2年」「3〜5年」「6〜10年」のような数値区分を管理画面で設定
単純集計では区分別件数、クロス集計では区分をカテゴリとして利用可能
5-4. 可視化
件数に応じたCSS水平バーチャートで視覚的に比較
自由記述は折りたたみ可能な一覧で展開/収納
6. クロス集計機能(本システムの核)
ここが本システムの中核部分であり最も複雑な部分です。クロス集計がしたい方はぜひお声がけください。お問い合わせはこちら → https://citrusapp.jp/consult



6-1. 自由な軸選択
管理画面で 行軸設問・列軸設問を自由に選べる
固定パターンの集計ではなく、分析者の意図に応じた組み合わせが可能
6-2. 全設問タイプでクロス可能
組み合わせ | 対応 |
|---|---|
単一 × 単一 | ○(標準的なクロス表) |
単一 × 複数 | ○(列側で重複計上) |
単一 × 数値 | ○(数値は区分でカテゴリ化) |
複数 × 複数 | ○(延べ件数で表示) |
数値 × 数値 | ○(両軸とも区分使用) |
マトリクス × 任意 | ○(行×列の組み合わせで展開) |
6-3. 割合の母数と注記
行百分率(row%) を標準採用
複数回答を含む場合は自動的に「延べ件数」表記に切替
「無回答を含む」注記を画面・Excelの両方に明示
6-4. 件数 / 割合 切替タブ
件数表示と割合表示をワンクリックで切り替え
6-5. フィルタ機能との連動
日時範囲・特定設問値でフィルタした結果に対してクロス集計可能
フィルタは単純集計・クロス集計・Excel出力で共通利用
7. Excel出力機能
7-1. ローデータ出力
1回答1行の平たい形式
回答ID、日時、言語、各設問の回答値(ラベル解決済み)
絞り込み条件適用可能
7-2. 単純集計結果出力
設問ごとにテーブル形式
設問コード、設問文、選択肢、件数、割合、無回答、母数
母数と無回答の取扱注記を明記
7-3. クロス集計結果出力
行軸ラベル × 列軸ラベルの表
各セルに件数と行百分率
合計行・合計列を含む
母数ルール注記を明記
8. セキュリティ・認証
管理者向け簡易認証(iron-session)
管理画面の全ルートで認証必須
公開回答フォームから管理画面へのアクセスを遮断
削除系操作は全て確認ダイアログで二段階承認
9. 実装上の工夫
9-1. 回答データ構造の設計
1回答1行の平たい形式ではなく、正規化された回答明細構造
回答をあとから自由に集計し直せる
複数回答、マトリクス、数値区分、条件分岐のどれにも耐える設計
9-2. パフォーマンス最適化
N+1クエリの解消:集計時に設問ごとに発行していた全クエリを1クエリに統合
DBインデックス最適化:surveyId, questionId, responseSessionId に複合インデックスを追加
Next.js loading.tsx でページ遷移時に即座にスケルトンUI表示(体感速度改善)
数千件の回答データでも実用的な速度で集計可能
9-3. 堅牢性
全サーバーアクションに try-catch エラーハンドリング
バリデーションエラー時は詳細なメッセージを表示
マトリクス値の format(配列 / カンマ区切り文字列)両対応で互換性確保
今後の展望
本システムは「集計」に特化したサンプルプロダクトとして実装しましたが、以下のような拡張が考えられます。
集計条件の保存機能(よく使う絞り込み条件をテンプレート化)
グラフ画像としてのエクスポート(PNG/PDF)
回答データのリアルタイム可視化ダッシュボード
Webhook連携(回答送信時に外部システムへ通知)
監査ログ機能
最後に
調査票作成 + 回答収集 + 集計 + 出力を一気通貫で扱えるシステムは、既製品では「ここが足りない」となりがちな領域です。業務に合った集計ロジックを自由に組み込めるスクラッチ開発ならではの価値を、本プロジェクトでしっかり出せたと感じています。
類似のシステム開発をご検討の企業様、ぜひお気軽にご相談ください。
このような複雑なアプリもAIなどの技術を使うことで以前よりもスピーディかつ柔軟に開発できるようになってきました。コストを抑えて素早くシステム開発をご希望の方はご相談ください。
