优化Google表格.appendRow() [英] Optimizing Google Sheets .appendRow()

查看:120
本文介绍了优化Google表格.appendRow()的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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




  • 根文件夹


    1. 街道姓名1


      • 102

      • 104

      • etc
      • $
        $ b

        • 街道名称2
          $ b

          • 98-110





经过一番努力,我想出了这个代码

  // GetFolders函数通过第一级和第二级子文件夹
使用while循环
//需要folderID字符串,存储数组,以及作为参数传递的
活动表
函数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();

//将第一个子文件夹名追加到数组
dataArray [0] = subFolderName;

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

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

//将第二个子文件夹名追加到数组
dataArray [1] = subFolder2Name;

//追加第二个子文件夹超链接到数组
dataArray [2] = subFolder2.getUrl();

//默认标志栏空白字符串
dataArray [3] ='';

//检查subFolder2中名称为
的连字符if(subFolder2Name.indexOf(' - ')> -1)//如果连字符存在于文件夹名称
{
//将标志附加到dataArray
dataArray [3] ='X';
} // end if

//将数组内容写入电子表格中的下一个空行
sheet.appendRow(dataArray);

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

起初,这看起来非常奏效,在达到超时限制之前写了大约3,500行。但是,我有超过12,000行需要写入(最好是一次执行)。查看谷歌的最佳实践页面告诉我,这可能会更有效率,但我不知道如何去做这件事。从我的研究看来,配料似乎是我最好的选择。有谁知道在我的脚本中实现这一点的好方法吗?

解决方案

您可以通过使用FileIterator的继续令牌来保存状态PropertiesService。下面的脚本检查脚本是否接近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 ++){//删除此项目的以前创建的触发器以避免混乱

ScriptApp.deleteTrigger(triggers [一世]); $!



if(!PropertiesService.getScriptProperties()。getProperty(continuationToken)){//如果没有保存标记,从头开始

files = DriveApp.getFiles();

$ b} else {


continuationToken = PropertiesService.getScriptProperties()
.getProperty(continuationToken);
文件= DriveApp.continueFileIterator(continuationToken); //将继续令牌传递给DriveApp以继续迭代我们离开的位置


}


while(files.hasNext()){

var file = file.next();

//在此处理文件

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

if(elapsedTimeInMillisec> 290000){//检查我们是否接近5分钟的时间限制

continuationToken = files.getContinuationToken();

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

ScriptApp.newTrigger(processFiles)//设置函数在5分钟后再次执行
.timeBased()
.after(300000)
.create ();
return;

}

}

}


I have been creating a script to iterate through a folder structure and copy specific data to rows in a Google Sheet. The folder structure is similar to this

  • Root folder

    1. Street Name 1
      • 102
      • 104
      • etc
    2. Street Name 2
      • 98-110

After some work, I came up with this code

        // 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()

At first, this appeared to work wonderfully, writing about 3,500 rows before hitting the timeout limit. However, I have over 12,000 rows that need to be written (preferrably with one single execution). Looking at Google's "Best Practices" page tells me that this can be more efficient, but I'm at a loss with how to go about doing this. From my research, it seems that batching would be my best option. Does anyone know a good way to implement this in my script?

解决方案

You can persist states by saving continuation token of the FileIterator using PropertiesService. The script below checks if the script is nearing the 5-minute time quota limit, saves the continuation token and creates a trigger for the function to run again after set time:

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;

  }

}

}

这篇关于优化Google表格.appendRow()的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆