タイダログ

もっと怠けますか? (y/n)

Google フォームと Google カレンダーで空き時間を視覚化する

タスク管理のために自分の空き時間を Google カレンダーに入力して視覚化しようと思ったのですが、手入力したらそれだけで空き時間が終わってしまいますので、Google フォーム + GAS で時短する方法を考えました。

作業環境

  • Google アカウント(個人用)
  • Windows 10 Home 22H2 (OS Build 19045.2965)
  • FireFox 114.0.1 (64 ビット)

やりたいこと

Google フォームで日付と空き時間を入力すると、Google カレンダーに空き時間が入るようにします。

私は高校教員ですので、「今日は1限と5限が空いている」「今日は3限だけ」のように、日によって空いている時間帯が異なります(そういうものなんです)。ですが「何限が何時から何時まで」という箇所は変わりませんから、空いているコマを選択したらそのコマの時間帯を空き時間としてカレンダーに登録するようにします。

完成図

完成図 (フォーム)

完成図 (カレンダー)

手順

Google にログインする

まずは Google にログインします。Google のトップページを開いた時に、画面右上に自分の名前やアイコンが出ていれば既にログインしています。

ログインしていない場合は、画面右上の「ログイン」の文字をクリックしてください。

空き時間用のカレンダーを作る

先にカレンダーを作りましょう。

Google のトップページの画面右上にある点9個のボタンをクリックしてください。Google のサービス一覧が出ます。ちなみにこの点9個のボタンをチョコレートボタンと呼ぶそうです。

Google カレンダーを開く図

この一覧から「カレンダー」を探してクリックしてください。すると「Google カレンダー」というページに移動します。

画面左端にある「他のカレンダー」という文字の右にある「+」をクリックし、[新しいカレンダーを作成] をクリックしてください。

新しいカレンダーを作成する図 (1)

新しいカレンダーを作成する図 (2)

「新しいカレンダーを作成」の画面で、[名前] の欄に適当な名前を入力して [カレンダーを作成] をクリックしてください。名前は何でもいいです。ここでは「空き時間」にしました。

作成したカレンダーに名前を付ける図

続けて、画面左端のカレンダー一覧から先ほど作成した空き時間カレンダーをクリックしてください。「カレンダーの設定」という画面になるはずです。

カレンダーの設定を開く図 (1)

ならなかった場合は、一度カレンダーのトップ画面に戻って、画面左端のカレンダー一覧にある空き時間カレンダーにカーソルを乗せ、縦3つの点のボタンをクリックして [設定と共有] をクリックしてください。すると「カレンダーの設定」という画面になるはずです。ちなみにこの縦3つの点のボタンを「ケバブボタン」と呼ぶそうです。

カレンダーの設定を開く図 (2)

「カレンダーの設定」画面の下の方にスクロールすると、「カレンダーの統合」という項目の下に「カレンダー ID」があるはずです。後ほどこれをプログラムのコード内に貼り付けるので、今開いているページを閉じずに残しておくか、カレンダー ID をコピーしてメモ帳などに貼り付けておくか、あるいは暗記してください。

カレンダー ID を確認する図

ちなみにカレンダーの色は、先ほどのケバブボタンから変更できます。「あき」時間カレンダーなので秋っぽいオレンジにしました。

カレンダーの操作はこれで終了です。

入力フォームを作成する

続いて、Google フォームの画面でフォームの作成とプログラムの設定を行います。プログラムはこのページからコピペするだけです。

Google のトップページの画面右上にある点9個のボタンをクリックし、Google のサービス一覧から「フォーム」を探してクリックしてください。「Google フォーム」というページに移動します。

Google フォームを開く図

左上にある「+」ボタン(空白と書いてあるやつ)をクリックしてください。そうするとフォームの作成画面が開きます。

「空白」をクリックする図

フォームを編集する前に、真っ先にタイトルを付けてください。今回は「空き時間」としました。

タイトルを付ける図

次に、ファイル名を付けましょう。画面左上の「無題のフォーム」という文字をクリックしてください。すると先程決めたタイトルに変わるはずです。変わらなかったら手入力してください。

ファイル名を付ける図

ファイル名が「無題のフォーム」のままだと、Google ドライブ上でこのフォームを探すときに苦労します。

ここまで出来たら質問を追加してください。今回は必要な項目は以下の通りです。

質問のタイトル 質問の形式
日付 日付
1コマの長さ(分) ラジオボタン
空き時間 チェックボックス

このようになるはずです。

全体像

「日付」は、その名の通り空き時間を入力したい日付を入力する項目です。スマホからではデイトピッカー(カレンダーから日付をクリックするやつ)が使えないみたいです。不便。

「1コマの長さ(分)」は、その日の1コマの長さが50分か45分かを指定する項目です。お勤めの学校に合わせて変更できますが、後のプログラム内で授業の終了時刻の計算に用いるため、半角数字で指定してください。午前は45分で午後は50分ということもあるかもしれませんが、そんな特殊な日はとりあえず45分で入力して午後の分のみ手作業で修正するなどしてください。

「空き時間」も読んで字のごとくです。ここの表現は「1限」でも「一時間目」でも何でもいいです。

カレンダーに合わせて秋っぽい色にしました。色は画面右上のパレットのアイコンから変更できます。

フォームの色を変更する図

フォームにプログラムを追加する

フォームに入力した空き時間をカレンダーに登録するためのプログラムを作成します。といっても基本的にコピペで済みます。

画面右上の縦3つの点のボタン(ケバブボタン)をクリックして [スクリプトエディタ] をクリックしてください。

スクリプトエディタを開く図

「Apps Script」という画面が開くはずです。この画面をスクリプトエディタ、あるいは単にエディタと呼びます。このエディタで、Google フォームなどの Google 製サービス上で動く GAS というプログラミング言語でプログラムを書くことがでます。

スクリプトエディタの図

何はともあれ、画面左上の「無題のプロジェクト」の部分を変更しましょう。「無題の○○」が増えていくとどれがどれだか分からなくなりますので。ここでは「空き時間」としました。

プロジェクト名を変更する図

名前を変更したところで、カレンダーに登録するためのプログラムを書きましょう。

まず、Google カレンダー用のプログラムを書くための設定を行います(VBA の経験がある方には、参照設定と言えば伝わるでしょう)。画面左側の [サービス] の「+」をクリックして、「サービスを追加」画面で [Google Calendar API] をクリックし、右下の [追加] をクリックしてください。利用規約は適宜お読みください。

Google Calendar API を追加する図

追加に成功すれば、先ほどの [サービス] の下に「Calendar」という名前が出ます。

次に、エディタにもともと入っているであろう

function myFunction() {
  
}

というコードを全て消してから、以下のコードを貼り付けて保存 (Ctrl + S) してください。その際、2行目の 0123456789abcdefghijklmnopqrstuvwxyz@group.calendar.google.com の部分を、先ほど作成した空き時間カレンダーのカレンダー ID に置き換えてください。また、プログラム後半の periodNameToDateTimes 関数内の授業開始時刻(.setHours(~, ~, ~, ~))は、実際の時間に書き換えてください。(時, 分, 秒, ミリ秒) の形式です。終了時刻は計算で求めるので不要です。

function formToCalendar() {
  const calendarId = "0123456789abcdefghijklmnopqrstuvwxyz@group.calendar.google.com"
  
  // このフォームへの回答のうち、一番最後のものを取得
  const lastResponse = FormApp.getActiveForm().getResponses().slice(-1)[0].getItemResponses()
  
  // 各質問項目への回答を取得
  const date = new Date(lastResponse.find(x => x.getItem().getTitle() === "日付").getResponse() + "T00:00:00.000")
  const classLength = Number(lastResponse.find(x => x.getItem().getTitle() === "1コマの長さ(分)").getResponse())
  const periods = lastResponse.find(x => x.getItem().getTitle() === "空き時間").getResponse().toString().split(",")

  // 空き時間ごとにカレンダーに登録
  periods.
    map(x => {
      // "1限" などの文字列を、{ 時限, 開始時刻, 終了時刻 } に変換
      const t = periodNameToDateTimes(date, classLength, x)
      return {
        "title": x,
        "start": t.start,
        "end": t.end
      }
    }).
    forEach(x => {
      // カレンダーに登録
      CalendarApp.getCalendarById(calendarId).createEvent(x.title, x.start, x.end)
    })
}

function periodNameToDateTimes(date, classLength, periodString) {
  // "1限" などの文字列を、{ 時限, 開始時刻, 終了時刻 } に変換する関数
  // どうしても `const` しか使いたくないのでアロー関数を使用
  const startTime = (() => {
    switch (classLength) {
      case 50:
        // 50分授業の時の各時限の開始時刻
        switch (periodString) {
          case "1限": return new Date(new Date(date).setHours(9, 0, 0, 0))
          case "2限": return new Date(new Date(date).setHours(10, 0, 0, 0))
          case "3限": return new Date(new Date(date).setHours(11, 0, 0, 0))
          case "4限": return new Date(new Date(date).setHours(12, 0, 0, 0))
          case "5限": return new Date(new Date(date).setHours(13, 30, 0, 0))
          case "6限": return new Date(new Date(date).setHours(14, 30, 0, 0))
          case "7限": return new Date(new Date(date).setHours(15, 30, 0, 0))
        }
      case 45:
        // 45分授業の時の各時限の開始時刻
        switch (periodString) {
          case "1限": return new Date(new Date(date).setHours(9, 0, 0, 0))
          case "2限": return new Date(new Date(date).setHours(9, 55, 0, 0))
          case "3限": return new Date(new Date(date).setHours(10, 50, 0, 0))
          case "4限": return new Date(new Date(date).setHours(11, 45, 0, 0))
          case "5限": return new Date(new Date(date).setHours(13, 10, 0, 0))
          case "6限": return new Date(new Date(date).setHours(14, 05, 0, 0))
          case "7限": return new Date(new Date(date).setHours(15, 0, 0, 0))
        }
    }
  })()

  // 開始時刻と終了時刻のペアを返す
  return {
    "start": startTime,
    "end": new Date(new Date(startTime).setMinutes(startTime.getMinutes() + classLength, 0, 0))
  }
}

コードを貼り付けた図 (1)

コードを貼り付けた図 (2)

貼り付けて保存したら、一度テストしてみましょう。フォーム画面に戻り、画面右上の目のアイコン(プレビューアイコン)をクリックしてください。フォームの回答画面が開きますので、適当に入力して送信してください。

フォームのプレビューを開く図

あるいは、画面右上の [送信] ボタンをクリックし、開いた [フォームを送信] 画面でリンクのアイコンをクリックしてリンクをコピーし、ご自分のスマートフォンなどに送ってそちらから回答してください。

フォームのリンクをコピーする図

送信したら、エディタに戻って画面上部の [デバッグ] ボタンの左の部分が formToCalendar になっていることを確認して、なっていなければそれにしてから [実行] ボタンをクリックしてください。

プログラムを実行する図

初回のみ、[承認が必要です] というメッセージが出るはずです。

「承認が必要です」の図

承認の流れはこちらのページでご覧ください。個人用アカウントと学校用または職場用アカウントで多少異なりますが、とにかく自分のアカウントを選択して注意事項を読み、問題なければ [許可] をクリックしてください。

note.com

承認したらプログラムが動き、カレンダーに空き時間が入ったはずです。見に行きましょう!

おー入ってる。もっと空いて!

カレンダーに空き時間が入った図

最後に、今の流れを自動化しましょう。つまりフォームに送信する度に今のプログラムを自動で実行するように設定します。画面左端の時計のアイコン(トリガーアイコン)をクリックしてください。

トリガーアイコンをクリックするず

「トリガー」という画面になるはずです。

画面右下の [+ トリガーを追加] ボタンをクリックし、

[+ トリガーを追加] ボタンの図

以下のように設定して保存してください。

項目 設定内容
実行する関数を選択 formToCalendar
実行するデプロイを選択 Head
イベントのソースを選択 フォームから
イベントの種類を選択 フォーム送信時
エラー通知設定 今すぐ通知を受け取る

トリガーの設定の図

以下のようになっていれば成功です。

トリガーの設定成功の図

ではフォームに空き時間を入れてみて、カレンダーに自動登録できるかテストしましょう。フォームに空き時間を打ち込んで、

フォーム送信の図

送信。

数秒のタイムラグの後、反映。

カレンダーに空き時間が入った図

やったね!

これで全ての工程が完了しました。お疲れ様でした!

結び

いとも簡単に自分の空き時間の視覚化ができるようになりました。あとは忘れずに入力するだけですね。

このくらい手帳に書けばいいじゃないかと思いました? まあそうかもしれませんね。しかし、Google カレンダーに登録するメリットがちゃんとあるのです。

次回は、Google カレンダーならではの方法で、空き時間とタスクを同時に管理をする方法を紹介します。乞うご期待!

参考