Closed9
【GAS】Googleカレンダーに同期させる方法
Googleスプレッドシートで作成したスケジュール表をGoogleカレンダーに同期したい。
手動でカレンダーにイベントを作成するのは面倒なので、GASで同期するようにした。
手順はシンプルで
- 指定したシートのデータを取得(開始時間、終了時間、メモなど)
- そのデータに基づいたカレンダーイベント作成する
- イベントIDをスプレッドシートに書き込む
スプレッドシートは以下のような形式にしてる。
日時にはひとつのセルでも出来るけど、日時を変更するときに別々にした方が簡単なのと、時間がコピペしやすいので今回はこのようにしている。
title | year | month | day | start time | end time | description | calendar id | event id |
---|---|---|---|---|---|---|---|---|
my event 1 | 2022 | 4 | 8 | 9:30 | 10:00 | some description | example@gmail.com | |
my event 2 | 2022 | 4 | 10 | 13:30 | 14:30 | some description | example@gmail.com |
データを取得
function isCellData(e) {
// 空のデータはいらない
return e.join().replace(/,/g, '').length;
}
function scheduler() {
// schedule というシートのデータを取得
const scheduleSheet = SpreadsheetApp.getActive().getSheetByName('schedule');
const scheduleList = scheduleSheet.getRange(2, 1, scheduleSheet.getLastRow(), 9).getValues().filter(isCellData);
...
}
カレンダーイベントを作成
配列に格納されているカレンダー情報をループして、createEvent
でイベントを作成する。
function isCellData(e) {
return e.join().replace(/,/g, '').length;
}
function scheduler() {
const scheduleSheet = SpreadsheetApp.getActive().getSheetByName('schedule');
const scheduleList = scheduleSheet.getRange(2, 1, scheduleSheet.getLastRow(), 9).getValues().filter(isCellData);
for (const [index, schedule] of scheduleList.entries()) {
const title = schedule[0];
const year = schedule[1];
const month = schedule[2];
const day = schedule[3];
const startTime = schedule[4];
const endTime = schedule[5];
const description = schedule[6];
const calendarId = schedule[7];
const calendar = CalendarApp.getCalendarById(calendarId);
const startDateTime = new Date(`${year}-${month}-${day} ${startTime} GMT+9`);
const endDateTime = new Date(`${year}-${month}-${day} ${endTime} GMT+9`);
// 新しいイベントを作成
calendar.createEvent(title, startDateTime, endDateTime, { description });
}
}
イベントIDをスプレッドシートに書き込む
イベントを編集した場合、カレンダーもアップデートしてほしいので、スプレッドシートにイベントIDを書き込む。もしイベントIDがあった場合、そのイベントを削除してから新しいイベントを作成する。
function isCellData(e) {
return e.join().replace(/,/g, '').length;
}
function scheduler() {
const scheduleSheet = SpreadsheetApp.getActive().getSheetByName('schedule');
const scheduleList = scheduleSheet.getRange(2, 1, scheduleSheet.getLastRow(), 9).getValues().filter(isCellData);
for (const [index, schedule] of scheduleList.entries()) {
count = count + 1;
const title = schedule[0];
const year = schedule[1];
const month = schedule[2];
const day = schedule[3];
const startTime = schedule[4];
const endTime = schedule[5];
const description = schedule[6];
const calendarId = schedule[7];
const eventId = schedule[8];
const calendar = CalendarApp.getCalendarById(calendarId);
if (eventId) {
const existingEvent = calendar.getEventById(eventId);
// 既存のイベントを削除してセルを空にする
existingEvent.deleteEvent();
scheduleSheet.getRange(2 + index, 9).setValue('');
}
const startDateTime = new Date(`${year}-${month}-${day} ${startTime} GMT+9`);
const endDateTime = new Date(`${year}-${month}-${day} ${endTime} GMT+9`);
calendar.createEvent(title, startDateTime, endDateTime, { description });
// イベントIDを書き込む
scheduleSheet.getRange(2 + index, 9).setValue(newEventId);
}
}
これはオマケですが、ログを表示すると見やすいので。
function isCellData(e) {
return e.join().replace(/,/g, '').length;
}
// 日時をフォーマットする
function formatDate(date) {
return Utilities.formatDate(date, 'Asia/Tokyo', 'yyyy-MM-dd E HH:mm');
}
function scheduler() {
let count = 0;
const scheduleSheet = SpreadsheetApp.getActive().getSheetByName('schedule');
const scheduleList = scheduleSheet.getRange(2, 1, scheduleSheet.getLastRow(), 9).getValues().filter(isCellData);
for (const [index, schedule] of scheduleList.entries()) {
count = count + 1;
const title = schedule[0];
const year = schedule[1];
const month = schedule[2];
const day = schedule[3];
const startTime = schedule[4];
const endTime = schedule[5];
const description = schedule[6];
const calendarId = schedule[7];
const eventId = schedule[8];
const calendar = CalendarApp.getCalendarById(calendarId);
if (eventId) {
const existingEvent = calendar.getEventById(eventId);
existingEvent.deleteEvent();
scheduleSheet.getRange(2 + index, 9).setValue('');
}
const startDateTime = new Date(`${year}-${month}-${day} ${startTime} GMT+9`);
const endDateTime = new Date(`${year}-${month}-${day} ${endTime} GMT+9`);
const newEvent = calendar.createEvent(title, startDateTime, endDateTime, { description });
const newEventId = newEvent.getId();
scheduleSheet.getRange(2 + index, 9).setValue(newEventId);
const startAt = formatDate(newEvent.getStartTime());
const endAt = formatDate(newEvent.getEndTime());
// 新しいイベントの情報
Logger.log(`New event created: ${title} at ${startAt} to ${endAt}, event ID: ${newEventId}`);
}
// 何イベント作成したか確認するように
Logger.log(`Created ${count} schedules`);
}
イベント開始日と終了日が1日以上の場合、上記ではできないので修正する必要がある。
このスクラップは2022/04/08にクローズされました