5

我正在尝试创建一个 Google Apps 脚本,以使 Google 日历和云端硬盘上的“主电子表格”保持同步——这可能吗?我找到了这两个帖子:

我很确定这可以使用大量 if 语句和逻辑来完成,但也许有更简单的方法?

我最终只提供了以下简单的脚本。真正需要的只是添加基于两列的事件,而这将花费太长时间来开发。

function onOpen() {
  //spawns a menu with a button that triggers AddToCal
  var sheet = SpreadsheetApp.getActiveSpreadsheet();
  var entries = [{
    name : "Add event to calendar",
    functionName : "AddToCal"
  }];
  sheet.addMenu("Data To Calendar Plugin", entries);
};

function AddToCal(){

  //get the current row
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var cell = ss.getActiveCell();
  var R = cell.getRow();

  //grab values for current row to pass to calendar event
  var date_of_event = ss.getRange('G'+R).getValue();
  var date = new Date(date_of_event);
  var event_title = ss.getRange('A'+R).getValue();
  //access the calendar
  var cal = CalendarApp.getCalendarById('[IDREMOVED]');
  cal.createAllDayEvent(event_title,date);

  ss.toast("Event added to " + cal.getName());
  }
4

4 回答 4

6

是的,可以编写双向事件同步脚本,但这并不简单。您引用的那两个帖子具有可以重复使用的部分,但与您在实际同步中将面临的挑战相比,它们是非常基本的。您可能需要阅读使用 Google Apps 脚本来创建基于电子表格的日历条目(但不进行持续同步)的活动预订系统。我过去曾对该脚本进行过一些调试。

同步需要支持:

  • 在任一位置创建事件
  • 在任一位置修改事件详细信息(尽管您可以选择仅考虑事件详细信息的子集以进行简化)
  • 删除任一位置的事件
  • 复发,例如CalendarEvent.getEventSeries()处理(或选择避免)

这是您可以开始的伪代码:

Open Calendar, Read Calendar events into calArray (will all attributes you care for)
Open Spreadsheet, Read Spreadsheet events into sheetArray

For each event in calArray:
  Search for calEvent in sheetArray.
  If found, compare lastUpdated values.
    If equal, do nothing
    Otherwise copy most recently updated to least recently updated
    Continue with next event
  If not found then copy calEvent to new sheetEvent, including lastUpdated value.
  Continue with next event

For each event in the sheetArray (...that hasn't been handled yet)
  Similar logic above.

Write updated sheetArray to spreadsheet.
Write updated calEvents to calendar API (see note 1 below)

笔记:

  1. 对 calEvents 的所有更新都可以立即写入数组并写入日历 API,作为批量更新的替代方案。这将消除在本地跟踪更改的需要,尽管触摸 lastUpdated 值是一个好主意。

  2. 您在读取 ​​calEvents 时会想要使用CalendarEvent.getLastUpdated(),并将类似的值存储在电子表格中(与onEdit触发器相关联)以方便比较。

  3. 它将简化比较以记录CalendarEvent.getId()电子表格中的事件。您还CalendarEvent.setTag(key,value)可以将自定义元数据记录到日历中,例如指示源自电子表格或已与电子表格同步的事件。(这些标签无法通过 GCal UI 访问,因此只能通过脚本访问。)

  4. 您应该考虑要处理的日期范围或事件数量,并限制脚本的范围。如果不这样做,您肯定会在实际操作中遇到执行时间限制。

  5. 某些日历事件特征不适合在电子表格中轻松表达,例如:

    • 嘉宾名单
    • 提醒清单
于 2013-04-01T15:19:19.257 回答
4

正如在另一篇文章中提到的(感谢 Henrique),我花了一些时间——实际上正是它把我带到了 GAS——电子表格和日历之间的数据交换,主要是因为与我一起工作的人过去常常组织他们的时间安排(对于高中)在电子表格中,我必须照顾到谷歌日历的过渡。

一段时间后,尽管在线日历界面似乎更有效地创建事件,因此他们不再使用工作表到日历脚本!

另一方面,GCal 中的打印和演示选项非常有限,因此另一个方向仍然非常有用,我们一直在使用它!

我知道这似乎与原始问题无关,而且可能太荒谬了,但我只是想指出,在重新发明轮子之前,您应该彻底考虑您真正需要的东西......正如 Mogsdad 提到的,一些事件参数是在电子表格逻辑中不容易描述,最后它可能会变得比原始工具更复杂。

当我需要删除或编辑大量类似事件时,我使用双向数据传输开发的唯一真正有用的工具是“批量修改工具”。

例如,如果我们全年都需要更改老师的姓名,我会导入一些班级的所有活动,替换电子表格中的姓名并更新课程日历......这需要我 5 分钟,并且是很容易,但这些是非常具体的用例,我不确定它是否很常见。

无论如何,我不会称其为“同步”,因为它只需要一些时间并更改它们......我从未尝试使用日历来更新电子表格,根据我的经验,日历非常可靠,我认为它们作为原始数据源。正如我已经说过的,我们每周都会在电子表格中导入数据,仅用于打印和本地存档。

很抱歉这么长而且有点含糊的评论(那太长了,不适合正常的 500 chrs 评论;-)

于 2013-04-01T18:18:40.163 回答
2

不,没有。尽管关于 Apps Script Calendar Service 的许多问题已经解决(时区、全天事件、查询等),但它仍然是一项相当复杂的任务。

我知道 Serge,在#google-apps-script 标签上的 SO 中的最高贡献者,已经开发了相当多的涉及日历服务的脚本。

但是我不知道在日历和电子表格之间进行了双向更新。这应该是一个艰难的过程。如果你曾经这样做,请善意分享:)

于 2013-04-01T14:29:28.657 回答
2

我编写了一个在 GCalendar 和 GSheet 之间同步的脚本。您可以按原样使用它,或者当然可以从中借用想法。每种方式都有用于复制事件的单独命令:https ://github.com/Davepar/gcalendarsync

于 2019-06-26T22:26:38.610 回答