体調報告忘れてない？～ChatGPTと共にGAS初心者が挑む！毎朝のルーティンにアプローチ！～

# GASと出会う
みなさん、こんにちは！きんたです！
現在、社会人10年目、小売りの会社で採用の仕事に携わっています！
noteで、自己紹介の記事を投稿していますのでよろしければご覧ください！

[■note（きんた）](https://note.com/kinta5960/n/n748af0d0823b)

### makeを知ったその先に

以前、makeを使ってLINE Botを作りました！
簡単なLINE Botですが、初心者全開の私にとって完成した時の感動はすごかったです！笑

https://qiita.com/kinta5960/items/986659fdae591ccb92a0

ただ、makeは英語表記で、日本語対応していないため、使用感に少し抵抗がありました。


そこで今回は！！
バリバリ日本語対応している、Google Apps Script（GAS）GASを使って、
プロトタイプを考えてみました！

# 毎朝のルーティンにアプローチ

私は、日々の業務のほんっっとに身近なところで、疑問に思っていたことがありました。
それは、毎朝出勤した時に実施する、「体調管理報告」です。

私の職場では、毎朝体調管理報告をしています。

この体調管理報告は、チェックシートになっており、
各部署のデスクまわりに１枚紙が置かれていて、それに記入する形で運用しています。
（私の部署はバインダーに挟みぶら下げ管理？しています笑）

![スクリーンショット (88).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3959920/01342699-dfa3-c08e-ab50-7ea35b752542.png)

:::note info

✓縦軸に部署メンバーの名前、横軸に日付
✓出勤時、毎朝自分の欄にチェック(良好は〇、休みは／、不調は上司に報告)
:::

最終的には、月度が変わるタイミングでチェックシートを総務に提出する流れなのですが、
これ見て思ったんですよね。
生産性あげるだの、紙の使用を減らすだの、なんだかんだと言っているなか、、

ここだけやけに、アナログチックッ！！！！！！

▲現状だと、こんなこともよく起こってます↓

:::note warn
✓ 毎朝のチェック忘れ（これが一番多い！）
→まとめて数日分の記入をするシーンはザラ 笑

✓ 出張などで不在の方は、当日チェックできない
→後日まとめて記入している

✓ 毎朝チェックシートを一人ひとり回しながら記入している
→なによりアナログチック！！笑　変えられるはず！
:::

そんなこんなで、GASを使って改善してみようと思いチャレンジしてみました！

とは言っても、GASやプログラミングに関しては初心者中の初心者。

なので今回は、「ChatGPT」という相方を引き連れてチャレンジしてみました！

# やりたいこと！
①体調管理報告を、紙ベースではなくGoogle フォームで！
②毎朝９時に、Google フォームを添付したメールを部署メンバーに自動送信
③回答結果は、指定の書式に自動保存される仕組みづくり


# 使用したツール
[■Google Apps Script](https://workspace.google.com/intl/ja/products/apps-script/)
[■ChatGPT](https://chatgpt.com/)
[■Google フォーム](https://docs.google.com/forms/d/1UX3oyFuNBeXgKQLtJfcfIUFkV8V4THVE7PG9aCgUWCw/edit?hl=ja)
[■Googleスプレッドシート](https://docs.google.com/spreadsheets/d/1NzwKmmZ8_WRgQ2s0R2LIvOxtuLmxlLWX344GhlmGAEw/edit?hl=ja&gid=0#gid=0)


# 体調管理を入力するGoogle フォームを作成
### ①Google フォームを作ります（これはすぐできる！）
毎朝体調を報告するようのフォームをGoogle フォームにて作成します。

項目は「日付・名前・勤務計画・体調・症状（不調の方のみ）」にしています。

![スクリーンショット (106).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3959920/202033a8-eb1d-f237-0b85-4115bb3a826e.png)

:::note info
日付と名前を選択式にしています。
※のちに別タブで作ったスプレッドシートに反映させる際、記入ミス等で元データとの不一致が起きないようにするため
:::

![スクリーンショット (108).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3959920/e775bd95-046d-b3e7-c469-5ba587748353.png)
![スクリーンショット (110).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3959920/930d4d2b-7819-42d8-7c64-08ca6fbec227.png)

:::note info
出勤の方は、体調の選択
休日の方は、フォーム送信へ　セクションを移します
:::


![スクリーンショット (111).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3959920/f89f9154-fd21-8e87-471a-0e65af3d742f.png)

:::note info
不調の方は、症状を選択するセクションに移り、フォーム送信します
:::

そして、Google フォームで回答のあった内容は、
自動的にスプレッドシートで保存され表示することができます。

![スクリーンショット (115).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3959920/c8fe4005-d50c-0f03-33a7-9a76b14bde26.png)

### ②回答結果を反映させるシートの作成
しかしこれだと、見にくいことこの上なし。
なので、自分で作成したシートに自動で反映させたい！！
そう思い、回答が自動保存されるスプレッドシートに別タブで、下記のようなシートを作成しました。

![スクリーンショット (116).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3959920/20762ec5-a51a-f7a0-8c59-f8527beabcad.png)

:::note info
今まで紙で運用していた体調管理シートに近い形で作成
「A列に部署メンバーの名前」、「B1～AF1に日付」をあらかじめ入力
:::

また、月度ごとシートを分けて管理し反映させたかったので、
あらかじめ別タブで月度ごとのシートを作成しています。

![スクリーンショット (117).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3959920/df3dec84-127d-ea2b-82b1-dd0a348bd781.png)

さて、ここからどうやって回答結果を作成したシートに反映させていくのか、、、

ここで、我が相棒！チャットGPTとのセッションの始まりです！！


# 毎朝9時に体調管理フォームを送信し自動で集計させる
ChatGPTとともに作り上げた、GASのスクリプトはこちらです！

### ①体調管理のメールを自動送信するスクリプト

```javascript:スプリクト
function sendHealthCheckEmail() {
  var sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
  var data = sheet.getDataRange().getValues();
  var subject = "【体調管理】確認メール";

  for (var i = 1; i < data.length; i++) {
    var name = data[i][0];  // 名前
    var email = data[i][1]; // メールアドレス

    if (!email) {  // メールアドレスが空欄ならスキップ
      Logger.log("メールアドレスがないためスキップ: " + name);
      continue;
    }

    var body = 
      name + "さん、おはようございます！\n\n" +
      "本日の体調はいかがでしょうか？\n" +
      "以下のフォームに入力してください。\n" +
      "https://forms.gle/yrGcAjHhBdcZ9W2a6 \n\n" +
      "よろしくお願いします！";

    try {
      MailApp.sendEmail(email, subject, body);
      Logger.log("メール送信成功: " + name + " (" + email + ")");
    } catch (e) {
      Logger.log("メール送信失敗: " + name + " (" + email + ") - " + e.message);
    }
  }
}
```


**毎朝９時に送信する設定**は、トリガーにて設定！

![スクリーンショット (133).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3959920/6977e0ba-acf2-c879-e70e-6f12c62cedeb.png)
![スクリーンショット (132).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3959920/9aa7cdc2-87f6-d838-49dd-ba5aa182ef4b.png)

メールを誰に送信するかは、別タブで作成したシートから拾ってくるように設定！

![スクリーンショット (140).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3959920/727cbb64-4db5-52e7-07e7-261639c716f4.png)

実際に届いた！！

![スクリーンショット (118).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3959920/764aa425-d013-a1c7-91cc-8223823626c6.png)

### ②フォームの回答結果を指定のシートに反映させるスクリプト

```javascript:スプリクト
function updateMonthlySheet() {
  const spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
  const formResponseSheet = spreadsheet.getSheetByName('フォームの回答 1'); // フォームの回答シート

  if (!formResponseSheet) {
    Logger.log("フォームの回答シートが見つかりません。");
    return;
  }

  // フォームの回答データを取得
  const formData = formResponseSheet.getDataRange().getValues();
  if (formData.length < 2) { // ヘッダー行を除外するため
    Logger.log("フォームの回答データがありません。");
    return;
  }

  // 最新の回答を取得（最終行）
  const latestResponse = formData[formData.length - 1]; // 最後の行が最新の回答
  const [timestamp, dateValue, name, workPlan, health, symptoms] = latestResponse;

  // 日付を取得し、月度を判定
  let targetDate;
  if (dateValue instanceof Date) {
    targetDate = dateValue;
  } else if (typeof dateValue === 'string') {
    try {
      targetDate = Utilities.parseDate(dateValue, Session.getScriptTimeZone(), "yyyy/MM/dd");
    } catch (error) {
      Logger.log(`日付の解析に失敗しました: ${dateValue}`);
      return;
    }
  } else {
    Logger.log(`日付の形式が不正です: ${dateValue}`);
    return;
  }

  // 月度のシート名を作成（例: "2025年01月"）
  const year = targetDate.getFullYear();
  const month = targetDate.getMonth() + 1; // getMonth() は 0-11 のため +1
  const monthlySheetName = `${year}年${month.toString().padStart(2, '0')}月`;

  // 月度管理表のシートを取得
  const monthlySheet = spreadsheet.getSheetByName(monthlySheetName);
  if (!monthlySheet) {
    Logger.log(`月度管理シート「${monthlySheetName}」が見つかりません。`);
    return;
  }

  // 月度管理表のデータを取得
  const monthlyData = monthlySheet.getDataRange().getValues();
  const headerRow = monthlyData[0].map(value => parseInt(value, 10)); // 1行目（日付）
  const names = monthlyData.slice(1).map(row => row[0]); // A列（名前）

  // 日付の取得
  const day = targetDate.getDate();

  // 名前の行を検索
  const nameIndex = names.indexOf(name);
  if (nameIndex === -1) {
    Logger.log(`名前が見つかりません: ${name}`);
    return;
  }

  // 日付の列を検索
  const dayIndex = headerRow.findIndex(value => value === day);
  if (dayIndex === -1) {
    Logger.log(`日付が見つかりません: ${day}`);
    return;
  }

  // 月度管理表の該当するセルを更新
  const targetCell = monthlySheet.getRange(nameIndex + 2, dayIndex + 1); // ヘッダー行を考慮
  if (workPlan === '出勤') {
    targetCell.setValue(health === '良好' ? '〇' : symptoms || "不調");
  } else if (workPlan === '休日') {
    targetCell.setValue('／');
  }

  Logger.log(`更新完了: ${name} の ${day}日 のデータを更新しました（シート: ${monthlySheetName}）。`);
}
```

Google フォームで回答があった内容は、スプレッドシートに自動保存されます。

![スクリーンショット (115).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3959920/ee6c4b43-04f2-2225-50cf-6acb921b5190.png)


自動保存された回答結果が、別タブのシートに反映される仕組みを作るため、
下記のように、あらかじめ月度管理表と名付けたシートを用意しました。
（日付と名前を管理する元データのようなもの）

![スクリーンショット (142).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3959920/0cab9aa7-39ff-266c-415c-d609d1fa144b.png)

:::note info
「A列に部署メンバーの名前」、「B1～AF1に日付」をあらかじめ入力
:::

回答結果と月度管理表の、日付と名前が一致した場合、月度ごとに分けたシートの該当箇所に結果が反映されます。
※月度管理表には結果は反映されません

ex）
**「日付」2025年1月1日**
**「名前」A2**
**「勤務計画」出勤**
**「体調」良好**
で回答した場合、2025年01月のシートに「〇」が自動反映

![スクリーンショット (122).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3959920/7cd23924-5b4c-71ce-7762-afe6411f6e00.png)

ex）
**「日付」2025年2月2日**
**「名前」A2**
**「勤務計画」休日**　
で回答した場合、2025年02月のシートに「／」が自動反映

![スクリーンショット (130).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3959920/a763cddf-6bd6-c636-20d2-b726accd4169.png)

:::note info
「出勤なら〇」、「休日なら／」、「不調なら症状」のように、回答結果に応じて該当箇所に表示されます。
:::

こんな具合です！！

# 完成に至るまで行ったChatGPTとのやりとり
完成するまで、ChatGPTとかなりのセッションを行いました。

### 1.体調管理メールの自動配信設定
まずは一発目の質問を投下！

![スクリーンショット (143).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3959920/1915afe7-29ff-fb96-5d03-d17f888dbf50.png)

すると、、スプレッドシートの準備から

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3959920/208e9bbf-522c-fa5f-290c-e2e6e9d007ff.png)

GASのスクリプトまで一瞬で教えてくれます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3959920/b634087d-1989-0405-795c-74f0ddc6e425.png)

毎朝9時に自動送信する設定は、トリガーを使うことも教えてくれました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3959920/5be8df3f-e713-1470-29c9-52dc8b5ffb90.png)


また、下記のように、初心者丸出しの些細なことまで寄り添ってくれます。
（ChatGPTありがとう。）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3959920/272f8066-cd02-7826-137e-2b918eb91df3.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3959920/1852dcc1-e9b7-bfdd-100c-921c72bbee42.png)

そして、ChatGPTとのセッションで得たスクリプトをGASエディタに貼付け実行！
こちらはChatGPTを使えば、割とすんなりとできました。

![スクリーンショット (144).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3959920/c563ee22-db76-0678-074d-8f9c49efebc3.png)

### 2.Google フォームの回答結果を指定のシートに反映
こちらがなかなかうまくできず、ChatGPTとはかなりセッションしました。
正直、1～100まで聞きましたね、、笑


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3959920/2dc41d42-569a-f4a0-2f5a-73df9714eee1.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3959920/16494743-c998-02f6-e05f-8fa59fa53802.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3959920/98051346-5e28-08b5-ac1c-c274a282ad5e.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3959920/56e1a585-dd0f-932c-a8fc-ba961cf196f1.png)


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3959920/525c0ad6-13fb-a43c-4c06-af67ecfbaaed.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3959920/3dcee502-6c12-db2c-91c5-827e4a8c7586.png)

なかなか回答結果がうまく反映されず、
せめて名前だけでも反映させてみたいと思い、ハードルを下げて聞いてみる瞬間も、、

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3959920/338b36b7-ccfa-e7a0-baa6-d65ed0fd0301.png)

ところが、ChatGPTに何度聞いてもなかなかうまくできず、
この場に来て手取り足取り操作してほしい気持ちになりました。

**■ここで、月度管理表とフォームの回答結果シートを改めて確認することに**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3959920/62300131-04af-1fe6-2398-0b39db1def63.png)

月度管理表は、問題なさそう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3959920/433747f7-3aae-0c1a-c7e8-44fdeb8f2c33.png)

ん？

ここでChatGPTと私の中で相違が見つかりました。
B列に名前がある前提のスクリプトだったようで、一向に反映されなかったようです。
実際のフォームの回答結果シートのB列には日付が入っていました。

![スクリーンショット (115).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3959920/be79dfa2-d12d-da3e-f438-13325e429c7a.png)

ChatGPTが修正したスクリプトに変更し月度管理表に反映されました！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3959920/2160c430-20fe-eeec-0b83-e6fb07cfce0a.png)

実は、はじめは月度管理表に反映させてゴールにしようとしていたのですが、
やっているうちに、月度ごとにシートを分け結果を反映させたいと思い、
最後の大詰めでChatGPTに聞いてみました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3959920/2e213a78-8a58-6307-c938-01935130dd84.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3959920/e491798b-3bbf-d314-f0d4-805099979bc0.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3959920/f60d0ebf-9740-0c19-7a97-b211e14119bf.png)

結果的に、月度ごとのシートに回答結果を反映させることに成功しました！！

![スクリーンショット (130).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3959920/92c681d9-5d41-3145-1f21-27fd7fbed3ed.png)

# メンバーから意見をもらいました

実は完成に至るまで、ほんの数人ですが
部署メンバーに意見をもらい、今回のプロトタイプに着地しました。

##### 「懸念点」
▲ ①Google フォームの結果と月度管理表の名前が一致しないとうまく反映されない

▲ ②当初は、Google フォームの結果が、月度管理表に集計される仕組みを考えていたが、
よくよく考えてみると、月度ごと分かれて反映されるわけではないので管理しづらそう


##### 「アドバイス」
① →Google フォームの名前の項目を記述式ではなく、”選択式”にしてみたらいいかも！
（些細なことですが自分の中では盲点でした）

② →月度管理表で集計したものをもとに、月度ごと反映させる仕組みが作れそう！また、シートに月度の記載があると管理するうえで楽そう！
（早速ChatGPTに聞き、月度ごとに反映させる仕組みを構築させました！）

##### 「Goodの声もいただきました！」
・忘れがちだから助かる！
・身近で画期的！
・社内検討を是非！（Xでコメントいただきました！）

[■X（きんた）](https://x.com/kinta5960/status/1884591142320373822)

※今後活用することで出てくる改善点は、一つひとつ取り入れブラッシュアップしていきたいです　

# 最後に！
今回、ChatGPTをつかってGASを動かしてみましたが、
ChatGPTの有能さをとても感じました！

コードを書いたことなければ、GASも使ったことのない私が、
ChatGPTを使うことで、できることの幅や可能性がかなり広がると思いました。

ただ、ChatGPTは万能なわけではないということも確かです。

:::note alert
質問内容が曖昧だと、知りたい情報とニュアンスが違った回答が返ってくる
:::

今回私も、何度か質問が曖昧で正確な回答を得られなかったり、
人と会話するときのように、相手は分かっているだろうといった変な前提を持ってしまい、
それが原因でうまく伝えられていなかったりすることがありました。

なので、ChatGPTを活用するには以下の事を気を付けていきたいです。

:::note warn
✓ 具体的に質問する
✓ 必要な情報を提供する
✓ 回答に対し間違ったポイントは伝えて正しい情報をもらう
:::

今回、ChatGPTを活用してGASを動かしてプロトタイプをつくった経験は、
私の中で大きな一歩だと感じています。

ChatGPTの特徴を理解し活用していけば、かなり大きな力になると思うので、
まずは、今回のプロトタイプを活用していってブラッシュアップしていくことと、
今後は、もっと実用性の高いものを考えていけたらと思います！