简体   繁体   English

Google表脚本超时错误

[英]Google sheet script timeout error

I'm trying to get file names and IDs from images and there are more than 3000 images and the number will just keep adding. 我正在尝试从图像中获取文件名和ID,并且有超过3000个图像,这个数字将继续添加。

I have this piece of code online that works pretty well. 我在网上有这段代码很好用。 However the problem is that the script will always timeout before it can finish getting all the images. 但问题是脚本在完成获取所有图像之前总是会超时。

So I'm wondering if there's a way to continue from where from the last session. 所以我想知道是否有一种方法可以从上一次会议继续。 I know there are many answers addressing session timeout problems but my javascript isn't proficient enough to figure out how to write them. 我知道有许多解决会话超时问题的答案,但我的javascript不够精通,无法弄清楚如何编写它们。

Thanks 谢谢

Here's the code I have 这是我的代码

function listFilesInFolder(folderName) {

   var sheet = SpreadsheetApp.getActiveSheet();
   sheet.appendRow(["Name", "File-Id"]);


//change the folder ID below to reflect your folder's ID (look in the URL when you're in your folder)
    var folder = DriveApp.getFolderById("ID");
    var contents = folder.getFiles();

    var cnt = 0;
    var file;

    while (contents.hasNext()) {
        var file = contents.next();
        cnt++;
            data = [
                file.getName(),
                file.getId(),
            ];
            sheet.appendRow(data);
    };
};

When I saw your question, I imaged 2 patterns. 当我看到你的问题时,我想象了2个模式。 But I think that there are several answers for your situation. 但我认为你的情况有几个答案。 So please think of this as two of them. 所以请把它想象成两个。

Pattern 1 : 模式1:

  • Use setValues() instead of appendRow() . 使用setValues()而不是appendRow()
    • The data is created in the while loop. 数据在while循环中创建。 And put the data to Spreadsheet using setValues() . 并使用setValues()将数据放入Spreadsheet。

Modified script : 修改后的脚本

function listFilesInFolder(folderName) {
  var data = [["Name", "File-Id"]];
  var folder = DriveApp.getFolderById("ID"); // Please set this.
  var contents = folder.getFiles();
  while (contents.hasNext()) {
    var file = contents.next();
    data.push([file.getName(), file.getId()]);
  };
  var sheet = SpreadsheetApp.getActiveSheet();
  sheet.getRange(sheet.getLastRow() + 1, 1, data.length, data[0].length).setValues(data); // Modified
};

Pattern 2 : 模式2:

  • Use Drive API. 使用Drive API。
    • Retrieve the data using Drive API. 使用Drive API检索数据。 And put the data to Spreadsheet using setValues() . 并使用setValues()将数据放入Spreadsheet。

In order to use this sample script, please enable Drive API at Advanced Google Services and API console. 要使用此示例脚本,请在高级Google服务和API控制台中启用Drive API。 You can see the flow of this at here . 你可以在这里看到这个流程。

Modified script : 修改后的脚本

function listFilesInFolder2(folderName) {
  var folderId = "ID"; // Please set this.
  var data = [["Name", "File-Id"]];
  var params = {
    'pageSize': 1000,
    'q': "'" + folderId + "' in parents and mimeType!='" + MimeType.FOLDER + "'",
    'fields': "nextPageToken,items(id,title)"
  };
  do {
    var r = Drive.Files.list(params);
    params["pageToken"] = r.nextPageToken;
    r.items.forEach(function(e) {data.push([e.title, e.id])});
  } while(r.nextPageToken);
  var sheet = SpreadsheetApp.getActiveSheet();
  sheet.getRange(sheet.getLastRow() + 1, 1, data.length, data[0].length).setValues(data); // Modified
};

References : 参考文献:

If these were not what you want, I'm sorry. 如果这些不是你想要的,我很抱歉。

Added : 添加 :

By the comment of @Steve Gon why do you think SetValue is better than AppendRow? 通过@Steve Gon的评论why do you think SetValue is better than AppendRow? , I added the reason I propose setValues() instead of appendRow() . ,我添加了我提出setValues()而不是appendRow()

In this issue, when many files (more than 3000) in a folder are retrieved and put to the spreadsheet, the process time is over 6 minutes which is the limitation. 在此问题中,当检索文件夹中的许多文件(超过3000个)并将其放入电子表格时,处理时间超过6分钟,这是限制。 If my understanding is correct, I think that OP wants to solve this issue. 如果我的理解是正确的,我认为OP希望解决这个问题。 Although I proposes to use "setValues()" because I had known that the values of 10000 rows with the 2 columns can be put to a sheet without errors using it, I had not shown about the difference of the process time in my answer. 虽然我建议使用“setValues()”,因为我已经知道可以将带有2列的10000行的值放到工作表中而没有使用它的错误,我没有在我的答案中显示处理时间的差异。 I'm really sorry for this. 我真的很抱歉。 So I added this. 所以我加了这个。

I prepared 2 sample scripts for this situation. 我为这种情况准备了2个示例脚本。 The main work is to put 10,000 rows with 2 columns to a sheet. 主要工作是将10,000行与2列放在一张纸上。 This is larger than 3,000 of the issue. 这大于3,000的问题。 At that time, it measures the process time of setValues() and appendRow() . 那时,它测量setValues()appendRow()的处理时间。

Sample script using setValues() 使用setValues()的示例脚本

var label = "sampleLabel"
console.time(label);
var rows = 10000;
var values = [];
for (var i = 0; i < rows; i++){
  values.push(["Name", "File-Id"]);
}
var ss = SpreadsheetApp.getActiveSheet();
ss.getRange(ss.getLastRow() + 1, 1, values.length, values[0].length).setValues(values);
console.timeEnd(label);

Sample script using appendRow() 使用appendRow()的示例脚本

var label = "sampleLabel"
console.time(label);
var rows = 10000;
var ss = SpreadsheetApp.getActiveSheet();
for (var i = 0; i < rows; i++){
  ss.appendRow(["Name", "File-Id"]);
}
console.timeEnd(label);

Result : 结果:

  • When setValues() was used, the process time was 2 s - 3 s. 当使用setValues()时,处理时间为2秒-3秒。 And there are no errors. 而且没有错误。
  • When appendRow() was used, when the value was put to 1400 - 1500 rows, the execution time was over 6 minutes. 当使用appendRow()时,当值被设置为appendRow()行时,执行时间超过6分钟。 Although I had tried several times, 3000 rows couldn't be put. 虽然我曾多次尝试过,但却无法放置3000行。

This is the reason I proposed setValues() . 这就是我提出setValues()的原因。

Try adding this: if (cnt % 500 ===0){SpreadsheetApp.flush();} 尝试添加:if(cnt%500 === 0){SpreadsheetApp.flush();}

function listFilesInFolder(folderName) {

   var sheet = SpreadsheetApp.getActiveSheet();
   sheet.appendRow(["Name", "File-Id"]);


//change the folder ID below to reflect your folder's ID (look in the URL when you're in your folder)
    var folder = DriveApp.getFolderById("ID");
    var contents = folder.getFiles();

    var cnt = 0;
    var file;

    while (contents.hasNext()) {
        var file = contents.next();
        cnt++;
            data = [
                file.getName(),
                file.getId(),
            ];
            sheet.appendRow(data);
            if (cnt % 500 ===0){
              SpreadsheetApp.flush();
            }

    };
};

I have noticed lots of problems when working with large spreadsheets. 在处理大型电子表格时,我注意到了很多问题。 I am working on a project right now at Google and I hear they are re-writing the way the interpreter/compiler runs. 我现在正在Google上开展一个项目,我听说他们正在重写解释器/编译器的运行方式。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM