【问题标题】:Extraction of multiple calendars to Google sheet将多个日历提取到 Google 工作表
【发布时间】:2022-06-18 02:05:15
【问题描述】:

我很难创建一个循环来将多个日历提取到 Google 工作表中。日历的 ID 在单元格 P1 中,开始日期在 P7 中,结束日期在 P8 中。

代码适用于一个日历,但是当我尝试在更多日历上添加 j 循环时,我的提取为空。有人能弄清楚我做错了什么吗?

感谢您的帮助。

代码如下:


var sheet = SpreadsheetApp.getActiveSheet();

  // Set filters
var startDate = sheet.getRange('p7').getValue();
var endDate = sheet.getRange('p8').getValue();
var mycal = sheet.getRange('p1').getValue().toString(); 
var cal = CalendarApp.getCalendarById(mycal);

 

// Create a header record on the current spreadsheet in cells A1:N1 - Match the number of entries in the "header=" to the last parameter
// of the getRange entry below
var header = [["Calendar Address", "Event Title", "Event Description", "Event Location", "Event Start", "Event End", "Calculated Duration", "Visibility", "Date Created", "Last Updated", "MyStatus", "Created By", "All Day Event", "Recurring Event"]]
var range = sheet.getRange(1,1,1,14);
range.setValues(header);

var row=2

for (var j = 0; j< mycal.lengh; j++){
    //here we do the things we do once per calander
 var cal = CalendarApp.getCalendarById(mycal[j]);   
var events = cal.getEvents(startDate, endDate);

  
// Loop through all calendar events found and write them out starting on calulated ROW 2 (i+2)
          for (var i=0;i<events.length;i++) {
          var row=i+2;
          var myformula_placeholder = '';
         
          var details=[[mycal,events[i].getTitle(), events[i].getDescription(), events[i].getLocation(), events[i].getStartTime(), events[i].getEndTime(), myformula_placeholder, ('' + events[i].getVisibility()), events[i].    getDateCreated(), events[i].getLastUpdated(), events[i].getMyStatus(), events[i].getCreators(), events[i].isAllDayEvent(), events[i].isRecurringEvent()]];
        var range=sheet.getRange(row,1,1,14);
        range.setValues(details);

      
      var cell=sheet.getRange(row,7);
      cell.setFormula('=(HOUR(F' +row+ ')+(MINUTE(F' +row+ ')/60))-(HOUR(E' +row+ ')+(MINUTE(E' +row+ ')/60))');
      cell.setNumberFormat('.00');
      row++; 
           }
  }
}

【问题讨论】:

  • 我不明白为什么不是问题
  • @Cooper 是“有人能弄清楚我做错了什么吗?”更好?
  • mycal 未定义,lengh 不是数组的属性。

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


【解决方案1】:

正如@Cooper 提到的,lengh 不是一个属性。我对脚本进行了更正和其他更改。此外,我创建了另一个工作表,其中包含日历 ID 列表,startDateendDate。请参阅下面的脚本,我添加了一些 cmets 来解释我所做的更改。确保根据您拥有数据的位置更改范围。

function calendarFunction() {
  var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Sheet1");
  var sheet2 = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Sheet2"); //Sheet name where you will have the list of calendar ID's, startDate and endDate

  sheet.clear() // If you'll be runnning the script several times, the data will be duplicated so I added this line to clear the sheet before adding the data
  // other option would be to create a script to check if data already exists before adding it to the sheet

  // Set filters
  var startDate = sheet2.getRange('B1').getValue(); //Range for startDate
  var endDate = sheet2.getRange('B2').getValue(); //Range for endDate
  var users = sheet2.getRange('A1:A').getValues(); //Range where you have the calendar ID's

  // Create a header record on the current spreadsheet in cells A1:N1 - Match the number of entries in the "header=" to the last parameter
  // of the getRange entry below
  var header = [["Calendar Address", "Event Title", "Event Description", "Event Location", "Event Start", "Event End", "Calculated Duration", "Visibility", "Date Created", "Last Updated","MyStatus", "Created By", "All Day Event", "Recurring Event"]]
  var range = sheet.getRange(1,1,1,14);
  range.setValues(header);
  
  for (var j = 0; j< users.length; j++){
    //here we do the things we do once per calander
    if (users[j] == ""){
      break;
    }
    
    else{
      var cal = CalendarApp.getCalendarById(users[j]);
      var events = cal.getEvents(startDate, endDate);

      // Loop through all calendar events found and write them out starting on the next empty row
      for (var i=0;i<events.length;i++) {
        var myformula_placeholder = '';
        var details=[
          [users[j].toString(),events[i].getTitle(), events[i].getDescription(), events[i].getLocation(), events[i].getStartTime(), events[i].getEndTime(), 
          myformula_placeholder, ('' + events[i].getVisibility()), events[i].getDateCreated(), events[i].getLastUpdated(), events[i].getMyStatus(),
          events[i].getCreators().toString(), events[i].isAllDayEvent(), events[i].isRecurringEvent()]
        ];

        var lastRow = sheet.getLastRow()+1;
        var range=sheet.getRange(lastRow,1,1,14);
        range.setValues(details);
          
        var cell=sheet.getRange(lastRow,7);
        cell.setFormula('=(HOUR(F' +lastRow+ ')+(MINUTE(F' +lastRow+ ')/60))-(HOUR(E' +lastRow+ ')+(MINUTE(E' +lastRow+ ')/60))');
        cell.setNumberFormat('.00');
      }
    }
  }
}

【讨论】:

  • 感谢 @Lorena 提供此更新,也感谢 Cooper 的反馈,我会努力理解我所犯的错误。我能够实现代码。它按预期工作。如果日历 ID 是动态的,有没有办法制作列表?将来我会在列表中添加更多日历。每当我有新员工来时。贝斯特,j。
  • 我看到脚本的另一个问题,看起来如果我运行两次,下次运行时,这些行会写在第 926 行及以上。
  • @Julien 我已经更新了我的答案,您可以继续在 A 列中添加更多日历 ID,它会起作用。关于写在表格末尾的行,这是ARRAYFORMULA 的问题,我也已修复。
  • 谢谢,@Lorena 这正是我想要的!我在运行它时遇到了时间限制问题,可能是因为我提取了 10 个不同日历中的一年半。你知道有办法避免这种限制吗?
  • @Julien 很高兴知道脚本有效!关于时间限制,Apps Script 有一些limitations。对于 6 分钟的执行限制,有一些解决方法可能会有所帮助,您可以参考这些其他答案 12 并尝试将其应用于此脚本。
【解决方案2】:

感谢这个了不起的社区的帮助,我能够拥有一个运行速度如此之快的脚本。

  var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Extraction 8 - Calendrier");
  var sheet2 = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Id Calendriers - Dates Debut et Fin"); //Sheet name where you will have the list of calendar ID's, startDate and endDate

  sheet.clear() // If you'll be runnning the script several times, the data will be duplicated so I added this line to clear the sheet before adding the data
  // other option would be to create a script to check if data already exists before adding it to the sheet

  // Set filters
  var startDate = sheet2.getRange('k15').getValue(); //Range for startDate
  var endDate = sheet2.getRange('k16').getValue(); //Range for endDate
  var users = sheet2.getRange('b3:B').getValues(); //Range where you have the calendar ID's

  // Create a header record on the current spreadsheet in cells A1:N1 - Match the number of entries in the "header=" to the last parameter
  // of the getRange entry below
  const data = []
  const formulas = [];
  const headers = [["Titre", "Description", "Location", "Début", "Fin", "Heures effectives","Extraction 2","Extraction 3","Heures Planifiées", "Vacances", "Maladie","Congé légal", "Absence"]]

  
  for (var j = 0; j< users.length; j++){
    //here we do the things we do once per calander
    if (users[j] == ""){
      break;
    }
    
    else{
      var cal = CalendarApp.getCalendarById(users[j]);
      var events = cal.getEvents(startDate, endDate);
      var lastRow = sheet.getLastRow()+8;

      // Loop through all calendar events found and write them out starting on the next empty row
      for (var i = 0; i < events.length; i++) {
        var details=
        [
          events[i].getTitle(), 
          events[i].getDescription(), 
          events[i].getLocation(), 
          events[i].getStartTime(), 
          events[i].getEndTime()
        ];

        data.push(details);
        const rowFormulas = 
        [
          '=(HOUR(RIGHT(b' +lastRow+';5))+(MINUTE(RIGHT(b' +lastRow+ ';5))/60))-(HOUR(LEFT(b' +lastRow+ ';5))+(MINUTE(LEFT(b' +lastRow+ ';5))/60))',
          '=IFERROR(TEXT(INDEX(SPLIT(A'+lastRow+';" ");2);"hh:mm");"")',
          '=IFERROR(TEXT(INDEX(SPLIT(A'+lastRow+';" ");3);"hh:mm");"")',
          '=IF(OR(G'+lastRow+'="Maladie";G'+lastRow+'="Congé";G'+lastRow+'="Absence";G'+lastRow+'="00:00";G'+lastRow+'="Vacances");0;(HOUR(H'+lastRow+')+(MINUTE(H'+lastRow+')/60))-(HOUR(G'+lastRow+')+(MINUTE(G'+lastRow+')/60)))',
          '=IF(IFNA(VLOOKUP(D'+lastRow+'; feries;1;FALSE);1)<>1;0;IF(AND(G'+lastRow+'="00:00";H'+lastRow+'="Vacances");0.5;IF(G'+lastRow+'="Vacances";1;0)))',
          '=IF(G'+lastRow+'="Maladie";1;0)',
          '=IF(G'+lastRow+'="Congé";1;0)',
          '=IF(G'+lastRow+'="Absence";1;0)'
        ]
        
        formulas.push(rowFormulas)
        lastRow=lastRow+1
      }
    }
  }

  sheet.getRange(7,1,headers.length, headers[0].length).setValues(headers)
  sheet.getRange(8,1,data.length,data[0].length).setValues(data);
  sheet.getRange(8,data[0].length + 1,formulas.length, formulas[0].length).setFormulas(formulas);
  sheet.getRange(8,6,sheet.getLastRow()).setNumberFormat('.00');

}```

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-08-03
    • 1970-01-01
    • 1970-01-01
    • 2022-08-11
    • 2016-12-04
    • 1970-01-01
    • 1970-01-01
    • 2020-08-21
    相关资源
    最近更新 更多