如何在不重复更新单个事件的情况下更新其他事件?

问题描述 投票:1回答:1

我目前正在使用应用程序脚本来同步我的谷歌表到谷歌日历。这个过程是相当简单的,我的脚本只需要一个日期和标题从电子表格,并创建一个整天的事件在该日期与标题。

我面临的问题是,如果我不小心键入了错误的日期,或者我必须更新电子表格中的一个日期,在运行scheduleShifts函数时,所有的事件都会被再次创建,这导致了许多重复的事件,而我并不打算在那里。我试图找到一个解决方案,帮助更新事件的标题或删除事件,并在电子表格中的日期是错误的情况下创建一个新的事件。

更新电子表格中的数据然后更新日历也不是很有效,因为如果有很多日期或标题需要更改,那么在日历中更改所有的日期或标题会花费很多时间。此外,删除当前的日历,创建一个新的日历,将该id复制到电子表格中,然后再更新所有的东西,也会非常麻烦。

这就是我目前的代码样子。

function scheduleShifts() 
{
  /*Identify calendar*/
  var spreadsheet = SpreadsheetApp.getActiveSheet();
  var calendarId = spreadsheet.getRange("C1").getValue();
  var eventCal = CalendarApp.getCalendarById(calendarId);

  /*Import data from the spreadsheet*/
  var signups = spreadsheet.getRange("C4:F73").getValues();

  /*Create events*/
  for (x=0; x<signups.length; x++)
  {
    var shift = signups[x];
    var title = shift[0];
    var date = shift[3];

    eventCal.createAllDayEvent(title, date);
  } 
}

/*Make the script shareable for others to use*/
function onOpen() 
{
  var ui = SpreadsheetApp.getUi();
  ui.createMenu('Sync to Calendar')
      .addItem('Schedule shifts', 'scheduleShifts')
      .addToUi();
}

我试着用高级日历服务检索所有的事件,把它们的标题推到一个数组中,然后用IndexOf验证,以避免重复事件。然而,我不确定如果事件的日期有更新时标题保持不变,这种方法是否有效。

我所引用的代码就是这样做的。

var existingEvents=Calendar.Events.list(calendarId);
var eventArray=[]; 
existingEvents.items.forEach(function(e){eventArray.push(e.summary)});                                                    
for (x=0; x<signups.length; x++) {
  var shift = signups [x];
  var startTime = shift[0];
  var endTime = shift[1];
  var inspector = shift[2];
    if(eventArray.indexOf(inspector)==-1){ 
      eventCal.createEvent(inspector, startTime, endTime);
    }else{
      Logger.log('event exists already');
    }
  }

如果有人需要更多的信息,请在评论中提问,我们将非常感谢您的帮助。

google-apps-script google-sheets duplicates google-calendar-api
1个回答
0
投票
  • 你已经开发了一个脚本来创建事件使用数据从一个表。
  • 您希望能够更新以前创建的事件,同时避免创建重复的事件。

第1步:避免创建重复的事件 避免创建重复的事件。

为了避免创建重复的事件,你可以让脚本写出相应的内容。eventId 当每一个事件被创建后,它就会出现。这样,下一次脚本运行时,就可以检查是否有 eventId 被填充(在这种情况下,事件已经存在),只有在事件不存在时才创建事件。它可以是这样的(在这个示例中,这个 eventIds 被写入G列)。)

function scheduleShifts() {
  const spreadsheet = SpreadsheetApp.getActiveSheet();
  const calendarId = spreadsheet.getRange("C1").getValue();
  const eventCal = CalendarApp.getCalendarById(calendarId);
  const signups = spreadsheet.getRange("C4:G7").getValues();
  for (let x = 0; x < signups.length; x++) {
    const shift = signups[x];
    const title = shift[0];
    const date = shift[3];
    const eventId = shift[4];
    if (eventId == "") { // Check the event doesn't exist
      const newEvent = eventCal.createAllDayEvent(title, date);
      const newEventId = newEvent.getId();
      spreadsheet.getRange(4 + x, 7).setValue(newEventId); // Write new eventId to col G  
    }
  }
}

第2步: 更新事件。

关于更新过程,我建议你: -- 安装一个onEdit触发器,要么 手动程序上. 这个动作需要授权,一个简单的 onEdit 触发器在这里不能工作(见 限制条件).

这样,你就可以使用 事件对象 只更新与被编辑的行相对应的事件,这样就避免了每次都要更新所有的事件,这将使这个过程的效率非常低。更新过程本身包括调用 setTitlesetAllDayDate.

该功能由 onEdit 触发器可以是这样的。

function updateEvent(e) {
  var editedRow = e.range.getRow();
  var editedData = e.source.getActiveSheet().getRange(editedRow, 3, 1, 5).getValues()[0];
  var eventId = editedData[4];
  try {
    var event = CalendarApp.getEventById(eventId);
    event.setTitle(editedData[0]);
    event.setAllDayDate(editedData[3]);
  } catch(err) {
    console.log("There was a problem updating the event. This event might not exist yet.");
  }
}

注意:

  • 你可能不想手动设置范围 (C4:G73),如果事件的数量可能有所不同。你可以使用像 getLastRow() 根据电子表格的内容,不使这个范围成为动态的。
  • eventId 这里使用的,对应于 类 CalendarEvent,与API不完全相同 活动资源. 在您使用 高级服务.
© www.soinside.com 2019 - 2024. All rights reserved.