[英]Exceeded maximum execution time
这是我的代码:
当我在第 3 步部分获取 pubHTML 并将其放入我的配置文件时,我得到了超出的最大执行时间。
我的代码按预期工作。 我想避免执行错误的最大限制。
function replicateCards() {
var ss = SpreadsheetApp.openById('configfile--xxxx');
var copyCard = SpreadsheetApp.openById('replicateCard-xxxx');
var getID = DriveApp.getFileById(copyCard.getId())
var card = copyCard.getSheetByName("Card");
var mastersheet = ss.getSheetByName("Mastersheet");
var getLastRow = mastersheet.getLastRow();
var destinationFolder = DriveApp.getFolderById('gdrivefolder-xxxx');
var changeColorToGrayList = card.getRangeList(['C7', 'E7', 'G7', 'I7', 'K7', 'M7', 'O7', 'Q7',
'C9', 'E9', 'G9', 'I9', 'K9', 'M9', 'O9', 'Q9',
'C11', 'E11', 'G11', 'I11', 'K11', 'M11', 'O11', 'Q11']);
var setValueToZero = card.getRangeList(['C8', 'E8', 'G8', 'I8', 'K8', 'M8', 'O8', 'Q8',
'C10', 'E10', 'G10', 'I10', 'K10', 'M10', 'O10', 'Q10',
'C12', 'E12', 'G12', 'I12', 'K12', 'M12', 'O12', 'Q12']);
for (i = 1; i < getLastRow; i++) {
var badgeStatus = mastersheet.getRange(i + 1, 5).getValue();
if (badgeStatus == "") {
var employeeNumber = mastersheet.getRange(i + 1, 1).getValue();
var employeeName = mastersheet.getRange(i + 1, 2).getValue();
copyCard.getRange("H3").setValue(employeeNumber);
copyCard.getRange("C3").setValue(employeeName);
SpreadsheetApp.flush();
if(mastersheet.getRange(1 + i, 5).getValue() != "completed"){
getID.makeCopy(employeeNumber, destinationFolder);
mastersheet.getRange(1 + i, 5).setValue("completed");
}
// Logger.log(i);
SpreadsheetApp.flush();
}
}
var files = DriveApp.getFolderById(SpreadsheetApp.openById("configFile-xxxx").getSheetByName("Config Sheet").getRange("B1").getValue()).getFiles();
//var fileIter = 1;
var employeeNumbers = mastersheet.getRange("A2:A").getValues();
var employeeNumbersTrunc = []
for(var i = 0; i < employeeNumbers.length; i++){
if(employeeNumbers[i][0] != "")
employeeNumbersTrunc.push("" + employeeNumbers[i][0]);
}
Logger.log(employeeNumbersTrunc);
while (files.hasNext()) {
var file = files.next();
/*var Found = false;
for (var j = 0; j < ; fileIter++) {
if (employeeNumber2[j][0] == file.getName()) {
Found = true;
}
}//*/
if (employeeNumbersTrunc.indexOf(file.getName())==-1) {
continue;
}else if(mastersheet.getRange(2 + (employeeNumbersTrunc.indexOf(file.getName())), 9).getValue() != ""){
continue;
}
try {
var fileId = file.getId();
var fileName = file.getName();
var revisions = Drive.Revisions.list(fileId);
var lastRevisionId = revisions.items[revisions.items.length - 1].id;
// get the resource and set the publish parameters
var resource = Drive.Revisions.get(fileId, lastRevisionId);
// Logger.log(resource);
resource.published = true;
resource.publishAuto = true;
resource.publishedOutsideDomain = true;
// publish to the web
Drive.Revisions.update(resource, fileId, lastRevisionId);
SpreadsheetApp.flush();
var openByID = SpreadsheetApp.openById(fileId);
SpreadsheetApp.flush();
var googleDriveSheet = openByID.getUrl().replace("edit", "pubhtml"); // or replace("edit", "pub");
SpreadsheetApp.flush();
Logger.log(file.getName());
Logger.log(employeeNumbersTrunc.indexOf(file.getName()));
mastersheet.getRange(2 + (employeeNumbersTrunc.indexOf(file.getName())), 9).setValue(googleDriveSheet);
SpreadsheetApp.flush();
} catch (err) {
Logger.log(err);
}
}
}
只运行一次代码,不会出现超出最大执行时间的错误。 有什么建议么?
下面的代码是根据我以前使用的代码修改的。 像这样的方法允许您完全执行一个单独无法在执行时间限制内完成的批处理。 通过了解批处理中的单个操作需要多长时间,您可以在达到该限制之前将进度保存在属性中,并以编程方式创建触发器以恢复处理。
您需要做一些事情才能使其工作:
getEmployees_()
function 以准确地从您的配置文件中获取员工。replicateForEmployee_()
function 中为 go。determineTimes()
function 以查看获取员工和文件复制需要多长时间。replicate()
function 中插入determineTimes()
的结果。 determineTimes()
的 output 将在“执行”页面(查看 > 执行)中可见。 展开执行行,您将看到如图所示的持续时间。
/**
* Get all of the employees in the sheet. Assumes row in the sheet is one employee. Adjust the range as needed.
* @returns {Object[][]}
*/
function getEmployees_() {
var source = SpreadsheetApp.openById("configfile--xxxx");
var sheet = source.getSheetByName("Mastersheet");
return sheet.getRange(1, 1, sheet.getLastRow(), sheet.getLastColumn()).getValues();
}
/**
* Refactor your current code so that this function will replicate all necessary files for a single
* employee. The function will be called for every single employee.
* @param {Object[]} employee - The row representing the employee in your config file
*/
function replicateForEmployee_(employee) {
// Execute your replication process for a SINGLE employee here
}
/**
* Run this, and then examine your script executions (View > Executions) to see how long each
* function takes. The resulting durations should replace the corresponding values in the replicate()
* function (I would recommend rounding up, so 458 --> 500ms).
*/
function determineTimes() {
console.time("timeToGetEmployees");
var employees = getEmployees_(); // Get all of the employees
console.timeEnd("timeToGetEmployees");
console.time("replicationDuration");
replicateForEmployee_(employees[0]); // Execute replication once
console.timeEnd("replicationDuration");
}
/**
* Replicates the files. When approaching the time limit, will save location and set a trigger to
* continue from stopping point. Emails user upon completion.
* @param {Boolean} isFromTrigger
* @returns {undefined}
*/
function replicate(isFromTrigger) {
var employees = getEmployees(); // Get all of the employees
var timeToGetEmployees = 1000; // Assume 1 second to execute getEmployees()
var replicationDuration = 500; // Number of milliseconds it takes to execute replication for one employee.
var maxExecutionTime = 360000 - timeToGetEmployees; // 6 mins - time already used to get employees
var continueFrom = 0; // If first execution, will be zero. Otherwise, get the index to start from.
if (isFromTrigger === true) {
continueFrom = parseInt(PropertiesService.getScriptProperties().getProperty("continueFrom"), 10);
}
var lapsedTime = 0; // ESTIMATED amount of time that has lapsed since the replication started
for (var i = continueFrom; i < employees.length; i++) {
// Replicate files for the employee
replicateForEmployee_(employees[i]);
// Checks how much time you have left
lapsedTime += replicationDuration;
if (lapsedTime >= (maxExecutionTime - replicationDuration)) { // warn just before timing out
PropertiesService.getScriptProperties().setProperty("continueFrom", i + 1); // save the last iterator value + 1
createAfterTrigger("replicateFromTrigger", 60000); // Start again in one minute
console.info("About to time out. Last iterator: " + i);
return;
}
}
deleteAllTriggers(); // Cleanup any lingering triggers
PropertiesService.getScriptProperties().deleteProperty("continueFrom"); // Clean up properties
// Send completion email
MailApp.sendEmail(Session.getEffectiveUser().getEmail(), "Replication Complete", "");
}
/**
* Should ONLY ever be called from a clock trigger.
* @returns {undefined}
*/
function replicateFromTrigger() {
replicate(true);
}
/**
* Create a new trigger to execute the specified function after a certain amount of time.
* @param {String} functionName - The name of the function to execute
* @param {Number} milliseconds - The duration (in milliseconds) after the current time when the trigger should run
* @returns {undefined}
*/
function createAfterTrigger(functionName, milliseconds) {
ScriptApp.newTrigger(functionName)
.timeBased()
.after(milliseconds)
.create();
}
/**
* Deletes all triggers in the current project.
* @returns {undefined}
*/
function deleteAllTriggers() {
var triggers = ScriptApp.getProjectTriggers();
for (var i = 0; i < triggers.length; i++) {
ScriptApp.deleteTrigger(triggers[i]);
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.