Google フォーム送信後に結果に応じた画面を出す(GASによる回答に応じたオリジナル画面の表示)

これは [Google Workspace 標準機能 Advent Calendar 2024 シリーズ2](https://qiita.com/advent-calendar/2024/google#seriesSelectorControl2) の24日目の記事です。

# 概要
アンケート調査をするときに、Google フォームを使うと簡単に素早くアンケートフォームが構築できますが、各項目をクロス集計したり、スコアに応じて画面を出しわけるには一工夫必要です。

- `DVS`(食品摂取の多様性評価)と`MNA®`(簡易栄養状態評価表)をアンケート調査し、個人の特性を求めたいアンケートを作成します
- `DVS`と`MNA®`について、それぞれに含まれる複数の項目をアンケートし、それぞれの合計スコア求める
- それぞれの合計スコアに応じてA～Bの３段階で評価し、低栄養や食事の多様性に関して、回答者にアドバイスを行う

:::note warn
私は予防医療や栄養学、看護学の専門家ではありません。そのため`DVS`や`MNA®`に関する誤った解釈が含まれている可能性があります。アンケートフォームの省力化をテーマにしています。
:::

## 完成イメージ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/30994/90ca53dc-5399-e248-29b7-1f6ec15acfc6.png)


# どうやって作るのか？
## アンケートフォームの作成（`Google フォーム`）
今回は、各質問の名義尺度からスコアを算出するので、各質問をダミー変数化して質問を作成します。
- まず`DVS`と`MNA®`の質問を記入するためのアンケートフォームを`Google フォーム`で作成する
- 名義尺度のまま回答してもらっても良いが、処理の簡単のため回答項目は『スコア値』としておく

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/30994/56230676-f4fe-6079-2932-b838772eb536.png)

## アンケート結果をためておく（`Google スプレッドシート`）
`Google フォーム`で回答した結果を、後で集計するために`Google スプレッドシート`に自動保存させる。そのための設定は、`Google フォーム`で行う。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/30994/f27ce777-fe0d-0d83-64f1-300e5079a572.png)

設定したら、『スプレッドシートで表示』リンクから`Google スプレッドシート`に移動する。
すると下記のようにアンケート結果が保存される。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/30994/16ec5789-c66c-5e1b-532b-a104794e7131.png)



## アンケートに応じてスコアを計算するアプリ（`Google Apps Script`）
アンケート結果の最新の１件に応じて、スコアを計算して表示する。

:::note alert
今回は簡単のため、①タブレットを使った対面式のアンケート、②１人ずつの回答 を想定している。
- 複数端末で同時にアンケート回答する場合は、排他制御を検討すること
- オンラインでの回答など、不正なパラメータが混入するケースが想定されるのであればバリデーションチェックを入れること
:::

```javascript
function getDVSMessage(dvsRank) {
  if (dvsRank === "A") {
    return "食品接種状況はとても良いです。毎日7点以上をこれから続けましょう。";
  } else if (dvsRank === "B") {
    return "食品接種状況が少し心配です。食べやすい食品をプラスして栄養バランスを向上させましょう。";
  } else if (dvsRank === "C") {
    return "食品接種状況が心配です。毎日の食生活に3ポイントプラスするように心がけましょう。";
  }

  // throw new Error("DVS Not Found.");
}

function doGet() {
  // スプレッドシートとシートの取得
  const sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
  const lastRow = sheet.getLastRow(); // 最新の行
  const headers = sheet.getDataRange().getValues()[0]; // ヘッダー
  const row = sheet.getRange(lastRow, 1, 1, headers.length).getValues()[0]; // 最新の行データ
  
  // MNA スコア (列 2~7 の範囲を仮定)
  const mnaScores = row.slice(1, 7);
  const dvsScores = row.slice(7, 17);

  // スコア合計の計算
  const mnaTotal = mnaScores.reduce((sum, score) => sum + (parseInt(score, 10) || 0), 0);
  const dvsTotal = dvsScores.reduce((sum, score) => sum + (parseInt(score, 10) || 0), 0);

  // MNA ランク判定
  let mnaRank = "C";
  if (mnaTotal >= 12) mnaRank = "A";
  else if (mnaTotal >= 8) mnaRank = "B";

  // DVS ランク判定
  let dvsRank = "C";
  if (dvsTotal >= 7) dvsRank = "A";
  else if (dvsTotal >= 4) dvsRank = "B";

  // メッセージ作成
  let mnaMessage = "";
  if (mnaRank === "A") {
    mnaMessage = "栄養状態は良好です。";
  } else if (mnaRank === "B") {
    mnaMessage = "低栄養の恐れがあります。";
  } else if (mnaRank === "C") {
    mnaMessage = "低栄養状態です。";
  }

  const dvsMessage = getDVSMessage(dvsRank);

  // HTML 出力 (TailwindCSS 適用)
  return HtmlService.createHtmlOutput(`
    <html>
      <head>
        <title>結果</title>
        <script src="https://cdn.tailwindcss.com"></script>
      </head>
      <body class="bg-gray-100 flex flex-col items-center justify-center min-h-screen">
        <div class="bg-white shadow-md rounded-lg p-8 max-w-md text-center">
          <h1 class="text-2xl font-bold text-green-500 mb-4">結果</h1>
          <ul class="list-disc text-left text-gray-700 space-y-2">
            <li><span class="font-semibold">MNA:<span class="text-red-600">${mnaTotal}</span></span> ${mnaMessage}</li>
            <li><span class="font-semibold">DVS:<span class="text-red-600">${dvsTotal}</span></span> ${dvsMessage}</li>
          </ul>
        </div>
      </body>
    </html>
  `).setXFrameOptionsMode(HtmlService.XFrameOptionsMode.ALLOWALL);
}
```

`Google Apps Script`でコードを作成したら、『ウェブアプリ』としてデプロイする。
> デプロイ > ⚙️ > ウェブアプリ

『ウェブアプリのURL』をコピーしておく（次の作業で必要）。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/30994/134d4f36-f698-312f-c8f5-0cf25fc09d63.png)


## アンケートに応じてスコアを表示（`Google フォーム`の設定）
`Google フォーム`で回答したデータを`Google スプレッドシート`に自動保存させるのは設定だけで可能だが、`Google フォーム`ではアンケート回答後のページをカスタマイズできない（たぶん）。そのため下記からアンケート回答後に表示されるメッセージへ、先ほどの『ウェブアプリのURL』を記載しておく。
> `Google フォーム`の設定 > 表示設定

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/30994/eaf73903-793b-c838-3b36-fc508675a1f3.png)

# 感想
お手軽にアンケートフォーム結果の集計＆結果に応じたメッセージの表示ができました。
Google Workspace、便利ですね！😇