【问题标题】:how to stop script from duplicating events in calendar?如何阻止脚本在日历中复制事件?
【发布时间】:2019-09-03 18:33:07
【问题描述】:

我正在使用谷歌表单来自动填写谷歌表格。有了这个表格,客户可以在他们想要预订的时候告诉我。我使用一些代码将我的谷歌表同步到谷歌日历。

我有 2 个问题。

(1) 每次我运行脚本时,它都会复制事件。 (2) 当添加更多行时,它不会同步新事件,因为我预先选择了范围。 (这是我知道的唯一方法)我不能每次添加新行时都修改我的代码!

这是目前为止的代码:

function scheduleShifts() {

var spreadsheet = SpreadsheetApp.getActiveSheet();
var calendarId = spreadsheet.getRange("P1").getValue();
var eventCal = CalendarApp.getCalendarById(calendarId);

var signups = spreadsheet.getRange("J2:L4").getValues();

for (x=0; x<signups.length; x++) {

var shift = signups [x];

var startTime = shift[0];
var endTime = shift[1];
var inspector = shift[2];


eventCal.createEvent(inspector, startTime, endTime);
}
}

function onOpen() {
var ui = SpreadsheetApp.getUi();
ui.createMenu('Synchroniser au calendrier')
   .addItem('Sync now', 'scheduleShifts')
   .addToUi();

}

【问题讨论】:

  • 当您在日历中创建活动时,为什么不直接删除电子表格中的行。
  • @Cooper 没想到...它可以工作..
  • 如果我们能看到一个示例电子表格,我会很有帮助。
  • 我什至会考虑不将事件添加到电子表格中。只需使用对话框创建事件。您始终可以直接从日历中获取某个日期范围内的事件列表。
  • ibb.co/984dKwB@Cooper 示例

标签: google-apps-script google-sheets google-calendar-api


【解决方案1】:

这是一个可能与您可以使用的对话框接近的示例。

文件名:aq4.html

<!DOCTYPE html>
<html>
  <head>
    <base target="_top">
    <link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
    <script>
    $(function() {
      google.script.run
      .withSuccessHandler(function(vA){
        var id='sel1';
        var select = document.getElementById(id);
        select.options.length = 0; 
        for(var i=0;i<vA.length;i++) {
          select.options[i] = new Option(vA[i],vA[i]);
        }
      })
      .getInspectors();
    });
      function submitForm(frmData) {
        google.script.run
        .withSuccessHandler(function(hl){
          document.getElementById('status').style.display ='inline';
          document.getElementById('status').innerHTML=hl;
        })
        .createEvent(frmData)
      }
      console.log('My Code');
    </script>
  </head>
   <body>
    <h1 id="main-heading">Event Dialog</h1>
    <div id="formDiv">
      <form id="myForm">
        <br /><input type="text" name="title" value=""/> Title
        <br /><input type="datetime-local" name="start" id="dt"/> Start
        <br /><input type="datetime-local" name="end" /> End
        <br /><select id="sel1" name="inspector"></select> Inspector
        <br /><input type="button" value="Submit" onclick="submitForm(this.parentNode)" />
      </form>
    </div>
  <div id="status" style="display: none"></div>  
</body>
</html>

文件名:aq1.gs

function createEvent(frmData) {
  //Logger.log('title: %s, start: %s, end: %s, inspector: %s ',frmData.title,frmData.start,frmData.end,frmData.inspector);
  var rv='Event Not Created';
  var cal=CalendarApp.getCalendarById("calendar id");//insert your calendar id
  var event=cal.createEvent(frmData.title,new Date(frmData.start),new Date(frmData.end));
  if(event) {
    event.setDescription(Utilities.formatString('Inspector: %s', frmData.inspector))
    rv="Event Created";
  }
  return rv;
}


//The following function gets the data in column one of the Inspectors sheet or tab in the script container spreadsheet.  You can create your own list that way and then you wont have to type them in 
function getInspectors() {
  var ss=SpreadsheetApp.getActive();
  var sh=ss.getSheetByName('Inspectors');
  var rg=sh.getRange(1,1,sh.getLastRow()-1,1);
  var vA=rg.getValues();
  return vA;
}

function launchDialog() {
  var userInterface=HtmlService.createHtmlOutputFromFile('aq4');
  SpreadsheetApp.getUi().showModelessDialog(userInterface, "Event Creation Dialog");
}

这是一个免费赠品,您可以使用它来显示您的日历 ID:

function displayCalendarInfo()
{
  var cals=CalendarApp.getAllCalendars();
  var s='Calendar Information';
  for(var i=0;i<cals.length;i++)
  {
    s+=Utilities.formatString('<br />Name: %s Id: %s', cals[i].getName(),cals[i].getId());
  }
  s+='<br /><input type="button" value="Close" onClick="google.script.host.close();" />';
  var ui=HtmlService.createHtmlOutput(s).setWidth(1200).setHeight(450);
  SpreadsheetApp.getUi().showModelessDialog(ui, 'Calendar Data');
}

这也是一个简单的对话框。

对话框如下所示:

警告:不要尝试使用 google.script.run 将 Date() 从客户端传递到服务器。阅读this,直到你明白它在告诉你什么。

【讨论】:

  • 非常感谢您的回答。我希望我知道如何阅读并知道在哪里粘贴此代码以查看结果。我会尝试用它做点什么。非常感谢。
  • 哇。非常感谢@Cooper !!!给你:docs.google.com/spreadsheets/d/…
  • 我的意思是,如果您共享电子表格,我会为您设置此示例,但我不想将其集成到您当前的电子表格中,因为这不会变得复杂并且需要比我更多的时间现在。
  • 是的,完全可以理解!您可以使用我发送给您的电子表格,它不是我现在使用的电子表格,它只是一个测试!随心所欲!
  • 此链接https://docs.google.com/spreadsheets/d/1_V2kU_YfkuqylcFhRHpSOvCtwXir8l5yC8F4mX3Zrmk/edit?usp=sharing仅供查看。
【解决方案2】:

基于您的代码的简单解决方案如下:

  1. 避免重复事件
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');
    }
  }

使用前请务必enable高级日历服务

  1. 要动态检测电子表格中的所有行,请使用方法getLastRow() 并将您的范围定义为getRange(row, column, numRows, numColumns)
var startRow=2;
var startColumn=10; //column J
var rowNumber=spreadsheet.getLastRow()-startRow+1;
var columnNumber=3;
var signups = spreadsheet.getRange(startRow,startColumn,rowNumber,columnNumber).getValues();

【讨论】:

    猜你喜欢
    • 2021-10-19
    • 2022-12-06
    • 2020-10-05
    • 2020-02-02
    • 1970-01-01
    • 2011-05-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多