2014-09-12 2 views
1

Используя этот отличный ответ, мне удалось изменить его, чтобы создать сценарий для экспорта событий из Google Таблицы в Календарь Google.Сценарий Google, который создает события Календаря Google из таблицы Google - «Превышено максимальное время выполнения»

Create Google Calendar Events from Spreadsheet but prevent duplicates

Затем я получил некоторые большой совет, и работал, что он не был заселение столбца EVENTID из-за ошибки я получал - «превышен максимальное время выполнения» - из-за большое количество строк (до 1000).

Create Google Calendar events from a Google Spreadsheet - script is creating duplicates

Я просматривал ответы, чтобы попытаться выработать способ обойти это, но не могу показаться, чтобы выработать ответ! Извинения - я совершенно новичок в этом.

Может ли кто-нибудь указать мне в правильном направлении, как я могу заставить скрипт обрабатывать более 5 минут или что-то еще?

function onOpen() { 
    var sheet = SpreadsheetApp.getActiveSpreadsheet(); 
    var entries = [{ 
    name : "Export Events", 
    functionName : "exportEvents" 
    }]; 
    sheet.addMenu("Calendar Actions", entries); 
}; 

/** 
* Export events from spreadsheet to calendar 
*/ 
function exportEvents() { 
    var sheet = SpreadsheetApp.getActiveSheet(); 
    var headerRows = 2; // Number of rows of header info (to skip) 
    var range = sheet.getDataRange(); 
    var data = range.getValues(); 
    var calId = "[email protected]";// use default claendar for tests 
    var cal = CalendarApp.getCalendarById(calId); 
    for (i in data) { 
    if (i < headerRows) continue; // Skip header row(s) 
    var row = data[i]; 
    var date = new Date(row[12]); // WHC 
    var title = row[18];   // WHC Title 
    var tstart = setTimeToDate(date,row[15]);// start time 
    var tstop = setTimeToDate(date,row[16]);// end time 
    Logger.log('date = '+date+'tstart = '+tstart+' tstop = '+tstop); 
    var id = row[17]; //EventID WHC 
    // Check if event already exists, update it if it does 
    try { 
     var event = cal.getEventSeriesById(id); 
     event.setTitle('got you');// this is to "force error" if the event does not exist, il will never show for real ;-) 
    }catch(e){ 
     var newEvent = cal.createEvent(title, tstart, tstop); // create a "normal" event 
     row[17] = newEvent.getId(); // Update the data array with event ID 
     Logger.log('event created');// while debugging 
     var event = cal.getEventSeriesById(row[17]);// make it an event Serie 
    } 
    event.setTitle(title); 
    } 
    // Record all event IDs to spreadsheet 
    range.setValues(data); 
} 

function setTimeToDate(date,time){ 
    var t = new Date(time); 
    var hour = t.getHours(); 
    var min = t.getMinutes(); 
    var sec = t.getSeconds(); 
    var dateMod = new Date(date.setHours(hour,min,sec,0)) 
    return dateMod; 
} 

ответ

0

Идея состоит в том, чтобы подсчитать время, в течение которого сценарий принимает внутри основной функции, и прерывать его, когда мы достигаем предела.

Нам нужно сохранить номер строки, где мы прерываем сценарий и продолжаем оттуда в следующем прогоне.

Поскольку мы не хотим делать это вручную (как мы ленивы :-), мы создадим триггер, чтобы запускать его каждые 5 минут.

Ниже приведен полный сценарий. Он отправит вам электронное письмо по каждому прогону, чтобы сообщить вам о прогрессе ... вам нужно будет удалить эту строку после вашего теста (если вы не хотите получать электронные письма каждые 5 минут от себя!)

Вы будете необходимо изменить идентификатор календаря, распределение строк (я проверил его на листе с меньшим количеством столбцов, чем ваш), но это будет довольно легко.

function createEventsWithBatch() { 
    // check if the script runs for the first time or not, 
    // if so, create the trigger and PropertiesService.getScriptProperties() the script will use 
    // a start index and a total counter for processed items 
    // else continue the task 
    if(PropertiesService.getScriptProperties().getKeys().length==0){ 
    PropertiesService.getScriptProperties().setProperties({'itemsprocessed':0}); 
    ScriptApp.newTrigger('createEventsWithBatch').timeBased().everyMinutes(5).create(); 
    } 
    // initialize all variables when we start a new task, "notFinished" is the main loop condition 
    var itemsProcessed = Number(PropertiesService.getScriptProperties().getProperty('itemsprocessed')); 
    var startTime = new Date().getTime(); 
    var sheet = SpreadsheetApp.getActiveSheet(); 
    var headerRows = 1; // Number of rows of header info (to skip) 
    var range = sheet.getDataRange(); 
    var data = range.getValues(); 
    var calId = "[email protected]"; 
    var cal = CalendarApp.getCalendarById(calId); 
    for (var i = itemsProcessed ; i < data.length ; i++){ 
    if (i < headerRows) continue; // Skip header row(s) 
    var row = data[i]; 
    var date = new Date(row[0]); // First column 
    var title = row[1];   // Second column 
    var tstart = setTimeToDate(date,row[2]); 
    var tstop = setTimeToDate(date,row[3]); 
// Logger.log('date = '+date+'tstart = '+tstart+' tstop = '+tstop); 
    var loc = row[4]; 
    var desc = row[5]; 
    var type = row[6]; 
    var times = row[7] 
    var id = row[8]; 
    // Check if event already exists, update it if it does 
    try { 
     var event = cal.getEventSeriesById(id); 
     event.setTitle('got you'); 
    }catch(e){ 
     var newEvent = cal.createEvent(title, tstart, tstop, {description:desc,location:loc}); 
     row[8] = newEvent.getId(); // Update the data array with event ID 
//  Logger.log('event created'); 
     var event = cal.getEventSeriesById(row[8]); 
    } 
    event.setTitle(title); 
    event.setDescription(desc); 
    event.setLocation(loc); 
    if(type=='PM'){ 
     var recurrence = CalendarApp.newRecurrence().addMonthlyRule().times(times); 
     event.setRecurrence(recurrence, tstart, tstop); 
    }else if(type=='PW'){ 
     var recurrence = CalendarApp.newRecurrence().addWeeklyRule().times(times) 
     event.setRecurrence(recurrence, tstart, tstop); 
    } 
    data[i] = row ; 
    Logger.log(i+' '+new Date().getTime()-startTime) 
    if(new Date().getTime()-startTime > 240000){ // if > 4 minutes 
     var processed = i+1;// save usefull variable 
     PropertiesService.getScriptProperties().setProperties({'itemsprocessed':processed}); 
     range.setValues(data); 
     MailApp.sendEmail(Session.getEffectiveUser().getEmail(),'progress sheet to cal','item processed : '+processed); 
     return; 
    } 
    } 
    range.setValues(data);// this time we are done ! 
    killTrigger();// delete the trigger 
    PropertiesService.getScriptProperties().deleteAllProperties(); // clean up properties 
} 

function setTimeToDate(date,time){ 
    var t = new Date(time); 
    var hour = t.getHours(); 
    var min = t.getMinutes(); 
    var sec = t.getSeconds(); 
    var dateMod = new Date(date.setHours(hour,min,sec,0)) 
    return dateMod; 
} 

function killTrigger(){ 
    var trigger = ScriptApp.getProjectTriggers()[0]; 
    ScriptApp.deleteTrigger(trigger); 
} 
+0

Спасибо Серж! Поэтому из того, что он посоветовал, я бы предположил, что заставить его прервать себя каждые 125 строк, было бы безопасно ... и извинить мою путаницу, но где я буду использовать/ставить эту информацию, чтобы исправить эту проблему? – Ingrid

+0

Этот код не подсчитывает строки, он подсчитывает время, потраченное ... это безопаснее. Это полный код, просто используйте его как есть или скопируйте соответствующие части в свои. –

+0

Многие, огромное спасибо! – Ingrid

1

Существуют различные библиотеки GAS, которые помогут вам пройти мимо 5 минут ожидания выполнения, используя ту же самую идею, как предложил @Serge. Я лично использую Continuous Batch Library.

Смежные вопросы