top of page

自動同步 Google Calendar 到表格,告別手動搬移抄寫

作家相片: 駒米駒米

最近看到一個詢問,大意是:

他們團隊的行程都共同記錄在 Google Calendar 上,有一個共同的日曆。但主管要求所有人,要再把行程填寫到另一個他自製的表格。所有人在日曆上看,不是很清楚嗎?抄寫不難,但每個同事都會把時間耗在這種細碎、重複的事情上。主管需要的其實是一個秘書每天唸行程給他聽吧?

這問題挺有趣,我把它拆解成兩個部分

  1. 主管為何這樣要求?

  2. 有沒有更好的解決辦法?


主管為何要求再抄寫到另一個表格?

假設主管會用 Calendar,但他為何不用?

性子急的人可能會直接說: 「因為他就是固執,只用自己熟悉的工具。」


沒錯,每個人都會有工具使用的偏好。但如果往第二層思考,為何他不改用更好用的工具呢?有沒有可能這個工具才能夠滿足他的需求呢?


其實發問者提到了一些關鍵,主管堅持使用表格管理,通常是有其他考量。


日曆雖然可以很簡單的做到記錄、邀請、提醒、甚至整合地址、線上會議連結等資訊。但如果這些資訊需要再處理,就沒那麼容易。例如說,做成日報或週報、統計行程類型或時數、備份或印出(離線使用),等等需求。


因此,要求再抄寫一次,可能是基於某些工作流程的需求,必須用表格來管理行程資料。




有沒有更好的解決辦法?

既然從 Calendar 抄寫到 Sheets 是重複性的作業,在運作一段時間後流程也穩定的話,就蠻適合把它自動化進行同步作業。


以這題為例,它的資料方向可以是:

  1. 所有人登錄行程到 Calendar -> 定時同步行程到指定試算表

  2. 透過表單登錄行程 -> 自動轉成 試算表 -> 定時將行程同步到 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 點,自動將所有行程搬運到指定的試算表。



댓글


駒米 JUMI

部落格《JUMI》創辦人 / 系統開發顧問 / 獨立開發者 

時常分享數位工具、系統實務、及讀書心得。10 多年開發與管理經驗,最愛用 Google Workspace 進行團隊的流程優化。曾主持 Kensington、Johnson 等公司的產品開發,建置超過 50 個系統。

Mail-amico
​訂閱電子報 

取得最新的生產力文章及工具包

​感謝你的訂閱!

​追蹤駒米 JUMI
  • Portaly
  • Line
  • 線程

2025 駒米 JUMI | 圖片來源 Freepik, Storyset, Flaticon

bottom of page