优化Google表格.appendRow()

时间:2017-08-31 15:22:25

标签: google-apps-script google-sheets

我一直在创建一个脚本来迭代文件夹结构并将特定数据复制到Google表格中的行。文件夹结构与此

类似
  • 根文件夹
    1. 街道名称1
      • 102
      • 104
    2. 街道名称2
      • 98-110

经过一番工作,我想出了这段代码

        // GetFolders function goes through first and second level subfolder 
using while loop
// Requires folderID string, an array for storage, and an active sheet to be 
passed as arguments
    function GetFolders(folderID, dataArray, sheet)
    {
      var rootFolder = DriveApp.getFolderById(folderID).getFolders();

      while (rootFolder.hasNext()) 
  {
var subFolder = rootFolder.next();
var subFolderName = subFolder.getName();
var subFolderID = subFolder.getId();

//append first subfolder name to array
dataArray[0] = subFolderName;

var subFolderIterator = DriveApp.getFolderById(subFolderID).getFolders();

while (subFolderIterator.hasNext())
{
  var subFolder2 = subFolderIterator.next();
  var subFolder2Name = subFolder2.getName();

  //append second subfolder name to array
  dataArray[1] = subFolder2Name;

  //append second subfolder hyperlink to array
  dataArray[2] = subFolder2.getUrl();

  //default flag column to blank string
  dataArray[3] = '';

  //check subFolder2 for hyphen in name
  if (subFolder2Name.indexOf('-') > -1) //if a hyphen is present in foldername
  {
    //append flag to dataArray
    dataArray[3] = 'X'; 
  } //end if      

  //write array contents to next empty row in spreadsheet
  sheet.appendRow(dataArray);        

    } //end while
  } //end while
} //end GetFolders()

起初,这看起来非常有效,在达到超时限制之前写了大约3,500行。但是,我需要编写超过12,000行(最好只执行一次)。看看谷歌的“最佳实践”页面告诉我这可能更有效率,但我对如何去做这件事感到茫然。根据我的研究,似乎批处理是我最好的选择。有谁知道在我的脚本中实现这个的好方法?

1 个答案:

答案 0 :(得分:0)

您可以通过使用PropertiesService保存FileIterator的延续令牌来保持状态。下面的脚本检查脚本是否接近5分钟时间配额限制,保存延续令牌并创建触发器,使该功能在设定时间后再次运行:

function processFiles() {


  var files, continuationToken;

  var sheet = SpreadsheetApp.openById(SHEET_ID)
                            .getSheets()[0];

  var startTimeInMillisec = new Date().getTime();

  var triggers = ScriptApp.getProjectTriggers();

  for (var i=0; i < triggers.length; i++) { //delete previously created triggers for this project to avoid clutter

       ScriptApp.deleteTrigger(triggers[i]);


}

if (!PropertiesService.getScriptProperties().getProperty("continuationToken")) { //if no token was saved, start from the beginning 

 files = DriveApp.getFiles();


} else {


continuationToken = PropertiesService.getScriptProperties()
                                     .getProperty("continuationToken");
files = DriveApp.continueFileIterator(continuationToken); //pass continuation token to DriveApp to continue iterating where we left off


}


while (files.hasNext()) {

  var file = file.next();

  // process file here

  var elapsedTimeInMillisec = new Date().getTime() - startTimeInMillisec;

  if (elapsedTimeInMillisec > 290000) { //check if we are nearing the 5 minute time limit

    continuationToken = files.getContinuationToken();

    PropertiesService.getScriptProperties()
                     .setProperty("continuationToken", continuationToken);

    ScriptApp.newTrigger("processFiles") //set the function to execute again after 5 minutes
             .timeBased()
             .after(300000)
             .create();
    return;

  }

}

}