通过 ID 同步 Google Sheet 和 Google 日历以防止重复

Sync Google Sheet and Google Calendar by ID preventing duplicates

使用此代码我可以将事件从 google 传播到 sheet 到 google 日历,但现在我想通过一个唯一的 ID 在两个平台之间同步这些事件我可以存储在 spreadsheet.

首先,我尝试每5分钟触发一次,但我不知道这是不是最好的解决方案,同时考虑到sheet上的事件超过300(它们可能会增加,但每天有 5 或 6 个新事件)所以我会避免错误 错误:“您在短时间内创建或删除了太多日历或日历事件。”

我想做的第二件事是从 google 日历调用 id 到 sheet 的列 A 但没有成功。

我该如何继续?

function sendToCal() {
  var spreadsheet = SpreadsheetApp.getActive().getSheetByName('XCALENDAR')
  let eventCal = CalendarApp.getCalendarById("xxx");
  var signups = spreadsheet.getRange("A2:M").getValues();

  for (x = 0; x < signups.length; x++) {
    var shift = signups[x];

    let d = shift[3]
    let e = shift[4].split(":")
    let f = shift[5]
    let g = shift[6].split(":")

    var startTime = new Date(d.getFullYear(),d.getMonth(),d.getDate(),parseInt(e[0]),parseInt(e[1]),0);
    var endTime   = new Date(f.getFullYear(),f.getMonth(),f.getDate(),parseInt(g[0]),parseInt(g[1]),0);
    var nameevent = shift[1];
    var desc = shift[11];
    var color = shift[12];
    var event = eventCal.createEvent(nameevent, startTime, endTime, { description: desc });

    if (color) {
      event.setColor(CalendarApp.EventColor[color]);
    }
  }
}

嗯,

如果我的理解正确,您希望有 sheet 个事件,每个事件都有自己的标识符,并确保它们始终同步。

如果这是正确的,我的建议是仅使用事件 ID 作为 sheet 上的标识符,当 运行 您的脚本时,仅针对 sheet 中的事件没有标识符。

获取事件ID,简单如:

// var event = eventCal.createEvent(nameevent, startTime, endTime, { description: desc });
const eventID = eventCal.createEvent(nameevent, startTime, endTime, { description: desc }).getId();

您可以将其附加到您想要的位置,但我认为第一列或第二列最好。

尝试:

function sendToCal() {

  const spreadsheet = SpreadsheetApp.getActive().getSheetByName('XCALENDAR')
  const eventCal = CalendarApp.getCalendarById("xxx");
  const signups = spreadsheet.getRange("A2:M").getValues();

  const targetEvents = signups.filter(i => i[0] === ``);

  for (let newEvent of targetEvents) {

    const rowIndex = signups.findIndex(i => i === newEvent);

    const [d, e, f, g] = [newEvent[3], newEvent[4].split(":"), newEvent[5], newEvent[6].split(":")];
    const [nameevent, desc, color] = [newEvent[1], newEvent[11], newEvent[12]];

    const startTime = new Date(d.getFullYear(),d.getMonth(),d.getDate(),parseInt(e[0]),parseInt(e[1]),0);
    const endTime   = new Date(f.getFullYear(),f.getMonth(),f.getDate(),parseInt(g[0]),parseInt(g[1]),0);
    
    const eventID = eventCal.createEvent(nameevent, startTime, endTime, { description: desc }).getId();

    const updatedRow = [eventID, ...newEvent];
    spreadsheet.getRange(rowIndex+2, 1, 1, updatedRow.length).setValues([updatedRow])

    if (color) {
      event.setColor(CalendarApp.EventColor[color]);
    }

  }

}

主要变化是:

  • 增加原来的 signups 范围。
  • 仅针对没有 ID 的事件 (targetEvents)。
  • 由于新的 ID 列,所有索引值都增加 1。
  • 创建事件后更新行以包含 ID。

如果您有任何问题,请告诉我!

尝试使用有限的注册(使用 getLastRow())和 getDisplayValues() 来防止格式出现任何问题(假设您的日期是 dd/MM/yyyy)

function sendToCal() {
  var spreadsheet = SpreadsheetApp.getActive().getSheetByName('XCALENDAR')
  let eventCal = CalendarApp.getCalendarById("xxx");
  var signups = spreadsheet.getRange("A2:M" + spreadsheet.getLastRow()).getDisplayValues();

  for (x = 0; x < signups.length; x++) { 
    var shift = signups[x];
    if (shift[0]==''){
    let d = shift[3].split("/")
    let e = shift[4].split(":")
    let f = shift[5].split("/")
    let g = shift[6].split(":")

    var startTime = new Date(parseInt(d[2]), parseInt(d[1])-1, parseInt(d[0]), parseInt(e[0]), parseInt(e[1]), 0)
    var endTime = new Date(parseInt(f[2]), parseInt(f[1])-1, parseInt(f[0]), parseInt(g[0]), parseInt(g[1]), 0)
    var nameevent = shift[1];
    var desc = shift[11];
    var color = shift[12];
    var event = eventCal.createEvent(nameevent, startTime, endTime, { description: desc });
    spreadsheet.getRange('A' + (+x + 2)).setValue(event.getId())
    if (color) {
      event.setColor(CalendarApp.EventColor[color]);
    }
    }
  }
}