Google Form で「休暇申請用フォーム」を作成し、申請内容を共有カレンダーに自動登録する。
※このネタが Google Apps 以外でイケるかどうかは検証しておりません。
グループウェアとして Google Apps を利用してスケジュール共有する場合に案外困るのは「いつ、誰が休暇の予定を入れているか」が分かりづらいことだと思います。
そこでこういう運用を考えてみました。
- 「全員の休暇予定を登録する共有カレンダー」を作る。
- 休暇を取得する方は「自分のカレンダー」に予定登録しつつ、その予定のゲストとして「全員の休暇予定を登録する共有カレンダー」を登録しておく。
この運用をスムースに行うために「サテライトオフィス 組織カレンダー」を利用していて、概ね上手く行ってはいます。しかしこの方法の欠点は「全員の休暇予定を登録する共有カレンダー」を見た時に「誰かが休むことはわかるけれど、誰が休むかは分かりづらい」という点にあります。予定の詳細を見れば予定の登録者は分かります。でも日、週、月の予定一覧には予定の登録者情報は出ないからです。
よって、このような運用を行う場合は「件名に休暇取得予定者の名前を記入する」というルールを運用でカバーせねばなりません。しかし運用でカバーするのは案外面倒くさい。
だから代わりに「休暇申請用フォーム」を Google Form で作成しておき、その Form の送信時に動くスクリプトでスケジュール登録することにより、件名の文字列を正規化することにします。
Calendar を作る。
「休暇取得予定」を全員で閲覧共有するためのカレンダーを作ります。特筆すべき点はありませんが、全員が編集可能であることが多分必要。あるいは Form のオーナーを特権管理者とかにしておけば、閲覧専用で作ってもよいかもしれんけど。
また作成した Calendar ID は後ほど説明するスクリプトに埋め込む必要があります。
Form を作る
Form はこんな要件で作ります。
- 2ページ構成の Form にします。
- 1ページ目は「休暇種別」「休暇取得期間」「休暇取得目的」を入力する。なお、「休暇種別」と「休暇取得期間」は必須項目にする。
- 2ページ目は2種類作る。1つは「1日または半日の休暇取得時の日付入力用」。もう一つは「日付の期間指定を行う」ため。
1ページ目の例
2ページ目の例
1ページ目→2ページ目の遷移は「休暇取得期間」の回答内容に合わせて変える。
Form に連動するScriptを作る。
Script を作る前に Form 編集画面左下の「以前のGoogleフォームに戻す」を選んでおきます。「新しい Google フォーム」で Script を組み合わせる方法がイマイチわからないので。。。
で、「ツール」「スクリプトエディタ」からスクリプトを作ります。作り終わったら「リソース」→「現在のプロジェクトのトリガー」から、スクリプトがフォーム送信時に動くように設定します。
スクリプトの例
holiday calendar の情報だけ差し替えればとりあえず動くはず……
// 「休暇取得予定者」のカレンダー情報。 var holidaycalendar = "xxxxxxxxxx@group.calendar.google.com"; // フォームの内容に元づいてスケジュール登録する。 function sendThingToCalendar(e) { var holidaytype = "夏季休暇"; var holidayterm = "終日"; // 午前半休、午後半休、終日、複数日 var holidaystart = "2015-08-04"; var holidayend = "2015-08-04" var holidaystarttime = "00:00:00" var holidayendtime = "00:00:00"; var holidayreason = ""; var itemResponses = e.response.getItemResponses(); // var editURL = e.response.getEditResponseUrl(); for ( var i = 0 ; i< itemResponses.length ; i++ ) { switch( itemResponses[i].getItem().getTitle() ) { case "休暇種別": holidaytype = itemResponses[i].getResponse(); break; case "休暇取得期間": holidayterm = itemResponses[i].getResponse(); break; case "休暇取得開始日": holidaystart = itemResponses[i].getResponse(); break; case "休暇取得終了日": holidayend = itemResponses[i].getResponse(); break; case "休暇取得日": holidaystart = itemResponses[i].getResponse(); holidayend=holidaystart; break; case "休暇取得目的": holidayreason = itemResponses[i].getResponse(); break; } // 午前半休、午後半休の場合は開始終了時刻を予定に追加する。 switch( holidayterm ) { case "午前半休": holidaystarttime = "00:00:00"; holidayendtime = "15:00:00"; holidaytype = holidaytype + ":" + holidaytype; break; case "午後半休": holidaystarttime = "15:00:00"; holidayendtime = "23:59:59"; holidaytype = holidaytype + ":" + holidaytype; break; } } // 休暇種別の文字列に休暇申請者のメールアドレスを追記する。 holidaytype = holidaytype + ":" + e.response.getRespondentEmail(); // フォーム送信者のメールアドレスに対応するカレンダーにスケジュール登録するためにカレンダーIDを取得する。 var calendar = CalendarApp.getCalendarById(e.response.getRespondentEmail()); // 予定の開始日時、終了日時の文字列から、 // 日付文字列と時刻文字列を組み合わせて、日付時刻型にする。 var holidaystartDate = dateString2Date( holidaystart, holidaystarttime ); var holidayendDate = dateString2Date( holidayend, holidayendtime ); var calendar_event; if ( holidaystartDate < holidayendDate ) { // 開始日時 < 終了日時なら、期間指定のイベントとして登録する。 calendar_event = calendar.createEvent( holidaytype, holidaystartDate, holidayendDate, { guests: holidaycalendar, description: holidayreason } ); } else if ( holidaystart == holidayend && holidaystarttime == holidayendtime ) { // 開始日と終了日が同じ、かつ開始時刻と終了時刻が同じならば、 // 終日の予定として登録する。 calendar_event = calendar.createAllDayEvent( holidaytype, holidaystartDate, { guests: holidaycalendar, description: holidayreason } ); } var calendar_eventid = calendar_event.getId() var logmessage = holidaytype; logmessage = logmessage + " " + holidayterm; logmessage = logmessage + " " + holidaystartDate; logmessage = logmessage + " " + holidayendDate; Logger.log( logmessage ); } function dateString2Date( datestring, timestring ) { var datearray = datestring.split( "-" ); var timearray = timestring.split( ":" ); if ( datearray.length == 3 ) { string2date = new Date( datearray[0], datearray[1]-1, datearray[2], timearray[0], timearray[1], timearray[2] ); } return string2date; }