最近看到一個詢問,大意是:
他們團隊的行程都共同記錄在 Google Calendar 上,有一個共同的日曆。但主管要求所有人,要再把行程填寫到另一個他自製的表格。所有人在日曆上看,不是很清楚嗎?抄寫不難,但每個同事都會把時間耗在這種細碎、重複的事情上。主管需要的其實是一個秘書每天唸行程給他聽吧?
這問題挺有趣,我把它拆解成兩個部分
主管為何這樣要求?
有沒有更好的解決辦法?
主管為何要求再抄寫到另一個表格?
假設主管會用 Calendar,但他為何不用?
性子急的人可能會直接說: 「因為他就是固執,只用自己熟悉的工具。」
沒錯,每個人都會有工具使用的偏好。但如果往第二層思考,為何他不改用更好用的工具呢?有沒有可能這個工具才能夠滿足他的需求呢?
其實發問者提到了一些關鍵,主管堅持使用表格管理,通常是有其他考量。
日曆雖然可以很簡單的做到記錄、邀請、提醒、甚至整合地址、線上會議連結等資訊。但如果這些資訊需要再處理,就沒那麼容易。例如說,做成日報或週報、統計行程類型或時數、備份或印出(離線使用),等等需求。
因此,要求再抄寫一次,可能是基於某些工作流程的需求,必須用表格來管理行程資料。

有沒有更好的解決辦法?
既然從 Calendar 抄寫到 Sheets 是重複性的作業,在運作一段時間後流程也穩定的話,就蠻適合把它自動化進行同步作業。
以這題為例,它的資料方向可以是:
所有人登錄行程到 Calendar -> 定時同步行程到指定試算表
透過表單登錄行程 -> 自動轉成 試算表 -> 定時將行程同步到 Calendar
在不知道其它背景的情況下,可以先考慮加速既有流程,也就是 1. 所有人登錄行程到 Calendar -> 定時同步行程到指定試算表。
這種同步其實不難,可以使用 Google Apps Script 或一些第三方工具如 MAKE。不過,第三方工具通常是訂閱制,每月都需要額外付一筆錢。用 Google Apps Script 其實就能輕鬆達成。
首先在指定試算表中,找到 工具列的擴充功能 (Extensions) > Apps Script ,點擊後進入 Apps Script 的專案編輯器。

你能看到 Apps Script 的編輯畫面

將下面程式碼貼上
程式碼
function syncCalendarToSheet() {
// 自定義參數
const config = {
calendarId: '你的日曆ID',
sheetName: 'CalendarEvents', // 試算表的工作表名稱
timeRange: {
startDaysAgo: 0, // 從當前時間往前多少天
endDaysFromNow: 7 // 從當前時間往後多少天
},
fields: ['標題', '開始時間', '結束時間', '描述', '位置', '建立者'] // 自定義需要的欄位
};
// 取得目前的試算表
const spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
let sheet = spreadsheet.getSheetByName(config.sheetName);
// 如果指定的工作表不存在,則建立一個
if (!sheet) {
sheet = spreadsheet.insertSheet(config.sheetName);
Logger.log(`工作表 '${config.sheetName}' 不存在,已自動建立。`);
} else {
// 如果工作表存在,先清空所有內容
sheet.clear();
}
// 計算要同步的時間範圍
const startTime = new Date();
startTime.setDate(startTime.getDate() - config.timeRange.startDaysAgo); // 從設定的天數前開始
const endTime = new Date();
endTime.setDate(endTime.getDate() + config.timeRange.endDaysFromNow); // 從設定的天數後結束
// 取得指定日曆範圍內的活動
const events = CalendarApp.getCalendarById(config.calendarId).getEvents(startTime, endTime);
// 寫入標題列
sheet.appendRow(config.fields);
// 寫入每個活動的資訊
events.forEach(event => {
const row = [];
// 根據 config.fields 順序動態生成行資料
config.fields.forEach(field => {
switch (field) {
case '標題':
row.push(event.getTitle());
break;
case '開始時間':
row.push(event.getStartTime());
break;
case '結束時間':
row.push(event.getEndTime());
break;
case '描述':
row.push(event.getDescription());
break;
case '位置':
row.push(event.getLocation());
break;
case '建立者':
row.push(event.getCreators().join(', ')); // 如果有多個建立者
break;
default:
row.push('N/A');
}
});
sheet.appendRow(row);
});
Logger.log(`已成功同步 ${events.length} 個活動到試算表 '${config.sheetName}'。`);
}
執行之前,請調整 config 參數區塊:
calendarId: 可以使用 'primary' 來代表主要日曆,也可以填入其他日曆的 ID。怎麼找到日曆 ID
sheetName: 要同步的工作表名稱。
timeRange: startDaysAgo 定義開始時間為幾個天前,endDaysFromNow 定義結束時間為幾個月後。預設值是從今天往後一週。
fields: 定義需要同步到試算表的欄位。你可以根據需求調整,如不需要某些欄位,刪除即可。
完成後,儲存並執行一次 syncCalendarToSheet(),就可以看到指定的日曆事件已經同步到指定的試算表 了,你便可以用這個試算表 去製作報告或是進一步的分析。

如果執行結果沒有問題,那就可以讓它定時執行。步驟如下:
回到 Apps Script 添加一個時間觸發器,週期為每日 凌晨一點執行。
點選左邊選單第四項的鬧鐘圖示,到觸發條件設定。

新增觸發條件:
執行功能:syncCalendarToSheet
活動來源:時間驅動
條件類型:日計時器
選取時段:每日上午 1 點執行
儲存後, Apps Script 就會在每天的凌晨 1 點,自動將所有行程搬運到指定的試算表。
댓글