我目前正在写一个google脚本,不幸的是运行太慢了。(超过6分钟限制)。该脚本打开一个文档,替换两个字符串(在google工作表中设置),将其保存为PDF。没什么花哨的。
我大约有200个这样的文档要运行这个脚本,但在6分钟的限制内,它只能运行6个。谷歌脚本就是这么慢吗,还是我无意中写出了效率最低的谷歌脚本?
function createAllPDF() {
var sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
var range = SpreadsheetApp.getActiveSheet().getActiveRange()
var numRows = SpreadsheetApp.getActiveSpreadsheet().getLastRow() - 1;
for(var i = 9; i <= numRows; i++) {
var thisRange = sheet.getRange("A" + n + ":C" + n);
var fond = thisRange.getCell(1, 1).getValue();
var adresse = thisRange.getCell(1, 3).getValue();
thisRange.setBackground('#cfe2f3');
genDoc(fond, adresse);
}
}
//// CREATE PDF ////////////////// FUNCTION FOR GENERATING THE PDF /////////////////////////////////
function genDoc(fond, adresse) {
// Finds the template and duplicate it into a new file.
var template = ("xxxxxxxxxxxx");
var docId = DriveApp.getFileById(template).makeCopy().getId();
// Opens the newly created Document for editing
var doc = DocumentApp.openById(docId);
var body = doc.getActiveSection();
// Renames the newly generated document
var newName = doc.setName(fond);
// Replaces each with the parsed variables.
body.replaceText("%FOND%", fond);
body.replaceText("%ADRESSE%", adresse);
doc.saveAndClose();
//Adds the PDF ID to the invoice_input sheet
var conv = DriveApp.getFileById(docId);
var pdf = conv.getAs("application/pdf");
var fileId = DriveApp.createFile(pdf).getId();
// Gets the PDF file by ID
var thisPDF = DriveApp.getFileById(fileId);
// The ID of the folder I'd like to put the PDF into.
var folderId = "xxxxxxxxxxx";
// Gets the folder by ID
var targetFolder = DriveApp.getFolderById(folderId);
// Adds the PDF to the Folder
targetFolder.addFile(thisPDF);
// Removes the PDF from the root.
var root = DriveApp.getRootFolder().removeFile(thisPDF);
// Deletes the duplicated document
DriveApp.getFileById(docId).setTrashed(true)
return fileId;
}任何关于如何优化的指点都将非常感谢。我是谷歌脚本和编程的新手,所以不用大惊小怪,哈哈。如果我没有正确地使用这块板子,我道歉。请告诉我,我会改正的。
发布于 2016-08-31 06:27:46
我立即注意到您有一个未定义的变量n。它在队列中:
var thisRange = sheet.getRange("A" + n + ":C" + n);
这应该会使代码完全不可用。将这些变量更改为i后,我能够成功地运行代码整整6分钟。在此期间,它能够循环大约41.5次。它创建了第9-53行的文件,但在能够将最后一个文件添加到正确的文件夹之前停止。
查看执行记录,您最长的操作是创建、移动和删除文件的几次调用。
您还定义了range,然后再也不使用这个变量,这样就没有必要使用它了。
我在我自己多次使用的结构和方法中重写了代码。我能够完全处理第9-59行。该方法能够将其扩展6行。我建议添加一个超时触发器,每隔5分55秒停止一次功能,然后在5秒后再次重新启动。关于javascript时间的指南可以在here上找到。我还使用了一种不同的匹配方法;使用RegEx。关于RegEx以及如何最小化处理时间,有大量的指南。我在这方面一点也不精通。
function PDFCreator() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName("Test Sheet");
var lastRow = sheet.getLastRow();
var checkRange = sheet.getRange(9, 1, (lastRow - 8), 3);
var check = checkRange.getBackgrounds();
var lightBlue = "#cfe2f3";
var template = DriveApp.getFileById("1RslWGntAwfLTSytOv_IoOv2_iBhSmsK0ZtEVWaq3ezM");
var folder = DriveApp.getFolderById("0BwZ6LWJudkOHaTFiQjd5cFA5OG8");
for (i = 0; i < check.length; i++) {
if (check[i] == lightBlue) {
continue;
} else {
var dataRow = sheet.getRange((i + 9), 1, 1, 3);
var fond = sheet.getRange((i + 9), 1, 1, 1).getValue();
var adresse = sheet.getRange((i + 9), 3, 1, 1).getValue();
var docName = fond + ".pdf";
var docCopy = template.makeCopy(docName, folder);
var docId = docCopy.getId();
var docToEdit = DocumentApp.openById(docId);
var docBody = docToEdit.getBody();
docBody.replaceText(/\%{1}[F][O][N][D]\%{1}/g, fond);
docBody.replaceText(/\%{1}[A][D][R][E][S][S][E]\%{1}/g, adresse);
docToEdit.saveAndClose();
var fileToPDF = DriveApp.getFileById(docId);
var pdfBlob = fileToPDF.getAs(MimeType.PDF);
var pdfRoot = DriveApp.createFile(pdfBlob).setName(docName);
var pdf = pdfRoot.makeCopy(folder);
pdfRoot.setTrashed(true);
fileToPDF.setTrashed(true);
dataRow.setBackground(lightBlue);
}
}
}您会注意到,我在main函数中嵌套了for()和if()。这样,您就不会在函数之间来回传递信息。通常,您可以在循环外部定义的越多,您需要进行的调用就越少。我可以在for循环之外设置更多的变量,以进一步扩展它的运行。
基本上,这是一个很长的过程,它不可能在6分钟内运行200次。您可以以完美的效率将其扩展到总共55/60行,但在这一点上,您只需要再次运行它。
发布于 2016-08-31 05:11:31
(注意:我还没有测试过这个,但应该可以让你开始)
一些想法:
”和“
所以就像这样:
function createAllPDF() {
var sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
var numRows = sheet.getLastRow() - 1;
var range = sheet.getActiveRange();
var values = range.getValues();
var templateId = ("xxxxxxxxxxxx");
var template = DriveApp.getFileById(templateId);
// The ID of the folder I'd like to put the PDF into.
var folderId = "xxxxxxxxxxx";
// Gets the folder by ID
var targetFolder = DriveApp.getFolderById(folderId);
var rootFolder = DriveApp.getRootFolder();
for(var i = 9; i <= numRows; i++) {
var fond = values[i][1]; // TODO: check syntax.
var adresse = values[i][3];
genDoc(fond, adresse, template, targetFolder, rootFolder);
}
range.setBackground('#cfe2f3'); // TODO: only first 3 columns
}
//// CREATE PDF ////////////////// FUNCTION FOR GENERATING THE PDF /////////////////////////////////
function genDoc(fond, adresse, template, targetFolder, rootFolder) {
// Finds the template and duplicate it into a new file.
var conv = template.makeCopy();
var docId = conv.getId();
// Opens the newly created Document for editing
var doc = DocumentApp.openById(docId);
var body = doc.getActiveSection();
// Renames the newly generated document
var newName = doc.setName(fond);
// Replaces each with the parsed variables.
body.replaceText("%FOND%", fond);
body.replaceText("%ADRESSE%", adresse);
doc.saveAndClose();
//Adds the PDF ID to the invoice_input sheet
var pdf = conv.getAs("application/pdf");
var fileId = DriveApp.createFile(pdf).getId();
// Gets the PDF file by ID
var thisPDF = DriveApp.getFileById(fileId);
// Adds the PDF to the Folder
targetFolder.addFile(thisPDF);
// Removes the PDF from the root.
rootFolder.removeFile(thisPDF);
// Deletes the duplicated document
conv.setTrashed(true);
}发布于 2021-09-15 07:09:13
如果您的代码已得到改进,请考虑使用触发器,但请记住,代码在完成后需要删除触发器,因为您可以创建的数量是有限制的。
初始代码应该在需要创建的文档工作表中设置一个列表,然后设置一个触发器来运行create document。
create document代码然后可以检查是否有更多的文档要从列表中创建,如果有,则创建文档并设置下一个触发器,删除旧触发器。
这样一来,一个文档就会成功运行,如果还有更多的事情要做,那么很快就会触发下一个文档。
记住,除了6分钟的限制之外,还有总的时间限制。
https://stackoverflow.com/questions/39233844
复制相似问题