【问题标题】:Docslist.find executing very slowlyDocslist.find 执行非常缓慢
【发布时间】:2014-05-11 17:23:30
【问题描述】:

我正在使用 DocsList.find() 并且我的代码中的所有内容都运行良好。唯一的问题是,即使文件夹中只有两个文件,在指定的文件夹中查找文件也可能需要长达 90 秒!

我希望有人能提出一种加快执行速度的方法。或者,可能是我误解了 DocsList 的文件夹元素。任何帮助将不胜感激!

谢谢,

奥利

示例代码:

function myFunction() {
var folder = DocsList.getFolderById("MYFOLDERID");
var lastrow = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Form Responses 1').getLastRow();
var thissheet = SpreadsheetApp.openById(SpreadsheetApp.getActiveSpreadsheet().getId());

var i = 3;
while (i<= lastrow)
if(SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Add scores to sheets').getRange(i,6).getValue() < 1){

 var getfile = folder.find(thissheet.getSheetByName('Add scores to sheets').getRange(i,3).getValue())[0].getId();
  var cell = SpreadsheetApp.openById(getfile).getSheetByName('Sheet1').getRange(thissheet.getSheetByName('Add scores to sheets').getRange(i,5).getValue());

  if(cell.getValue() < thissheet.getSheetByName('Add scores to sheets').getRange(i,4).getValue()){
  cell.setValue(thissheet.getSheetByName('Add scores to sheets').getRange(i,4).getValue());
  }


  thissheet.getSheetByName('Add scores to sheets').getRange(i,6).setValue(1);
   i++ 
}

else {i++}

}

代码从工作表“将分数添加到工作表”中获取分数,找到 C 列中命名的文件(电子邮件地址),定位命名范围并设置值,前提是当前值小于新值.我是一名数学老师 - 这一切都来自 Google 表单测验。

【问题讨论】:

  • 您是否计算了脚本的哪些部分执行缓慢,因为它可能不是DocsList 调用? (例如,您多次为同一张工作表调用getSheetByName,这些调用中的每一个都有成本,您最好在脚本开头将“向工作表添加分数”表指定为变量以节省一些执行时间)
  • 谢谢,山姆。我仍然不确定这是否是问题所在。看看我在下面对迈克尔的回答的回复。

标签: google-apps-script google-drive-api google-docs


【解决方案1】:

我们遇到了同样的问题,Folder.find() 扫描单个文件夹并只返回一个文件需要大约 40 秒。

一种更快的解决方案是使用Folder.getFiles() 并在结果集上循环以获得您需要的内容..

例如,如果您需要删除文件名中包含“DELETED”字符串的所有文件:

[SLOW] folder.find()

var files = folder.find("DELETE");
for(var x = 0; x < files.length; x++){
  files[x].removeFromFolder(folder)
}

[FAST] folder.getFiles()

var files = folder.getFiles();
for(var x = 0; x < files .length; x++){
  var fileName = files[x].getName();
  if(fileName.indexOf("DELETE") > - 1){
    files[x].removeFromFolder(folder)
  }
}

第二个版本,在我们的特定情况下,只需要 3 秒即可完成。

【讨论】:

  • 好主意!不敢相信我以前没想过要索引!感谢您的精彩回复!
  • 总之发现行为很奇怪.. 扫描一个文件夹怎么会花这么多时间?!?!
【解决方案2】:

正如上面的评论所说,您可能希望首先限制对 getSheetByName 的调用。如果你声明一个变量,像这样:

var addScoresToSheetsSheet = 
    SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Add scores to sheets')

然后在您的 while 循环中使用该变量名,如下所示:

if(addScoresToSheetsSheet.getRange(i,6).getValue() < 1){

 var getfile = folder.find(addScoresToSheetsSheet.getRange(i,3).getValue())[0].getId();
  var cell = SpreadsheetApp.openById(getfile).getSheetByName('Sheet1').getRange(addScoresToSheetsSheet).getRange(i,5).getValue());

  if(cell.getValue() < addScoresToSheetsSheet.getRange(i,4).getValue()){
  cell.setValue(addScoresToSheetsSheet).getRange(i,4).getValue());
  }


  addScoresToSheetsSheet.getRange(i,6).setValue(1);
   i++ 
}

它不仅使代码更具可读性,而且还使它执行得更快。如果这还不够,那么您可能需要将整个工作表读入一个数组,然后在该数组上执行您的代码,如此处所述:

https://developers.google.com/apps-script/best_practices#batchOperations

【讨论】:

  • 感谢您的宝贵时间和重要提示。我当然会将工作表称为变量,尽管这似乎不是问题。根据执行记录,getSheetByName 每次花费 0 秒。花费时间的是 folder.find() 元素。这是成绩单的副本:snag.gy/xRHFA.jpg
猜你喜欢
  • 2016-08-22
  • 1970-01-01
  • 1970-01-01
  • 2010-10-10
  • 1970-01-01
  • 1970-01-01
  • 2010-10-24
  • 2014-05-25
  • 1970-01-01
相关资源
最近更新 更多