Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/364.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 谷歌应用程序脚本,从外部电子表格检索数据的最快方式_Javascript_Google Apps Script_Google Sheets - Fatal编程技术网

Javascript 谷歌应用程序脚本,从外部电子表格检索数据的最快方式

Javascript 谷歌应用程序脚本,从外部电子表格检索数据的最快方式,javascript,google-apps-script,google-sheets,Javascript,Google Apps Script,Google Sheets,我试图将多个电子表格(~100)中的数据加载到一个电子表格中,但是当我尝试这样做时,我的脚本超时了。打开每个电子表格似乎需要很长时间。有没有什么办法可以让我加快速度或解决问题 下面是我用来打开每个电子表格的内容 // We set the current spreadsheet to master and get the current date. var master = SpreadsheetApp.getActive(); var masterSheet = master.getSheet

我试图将多个电子表格(~100)中的数据加载到一个电子表格中,但是当我尝试这样做时,我的脚本超时了。打开每个电子表格似乎需要很长时间。有没有什么办法可以让我加快速度或解决问题

下面是我用来打开每个电子表格的内容

// We set the current spreadsheet to master and get the current date.
var master = SpreadsheetApp.getActive();
var masterSheet = master.getSheetByName('Master');
var users = master.getEditors();
var today = new Date();

// Adds the menu to the spreadsheet
function onOpen() {
  var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
  var entries = [{
    name : "Update Data",
    functionName : "retrievePartnerData"
  }];
  spreadsheet.addMenu("Submissions Menu", entries);
};


// First we get all data from the partner sheets
function retrievePartnerData() {

  masterSheet.getRange(2, 1, masterSheet.getLastRow(), masterSheet.getLastColumn()).clear(); //Clear our master sheet aka Sheet All
  masterSheet.hideSheet();

  //Get's Promo Outline from the internal sheet and store it's values in the promoRange array
  var promoRange = master.getSheetByName("Promotional Outline").getRange("A1:Z100").getValues();

  var sheetPartnerArray = [];

  // Row is an array that contaings the url's to the external spreadsheets
  var row = master.getSheetByName('Partner Sheet Collection').getRange("B:B").getValues();

  row.map(function(e){
    if(e[0] != "" && e[0] != "Url"){
      var ss = SpreadsheetApp.openByUrl(e[0]);

      var studioName = ss.getSheets()[0].getRange("A1").getValue();

      //Updates the Promotional Outline sheet in the partner sheet
      var promoSheet = ss.getSheetByName("Promotional Outline");   
      promoSheet.getRange("A1:Z100").setValues(promoRange);

      //Hide columns K to Z
      promoSheet.hideColumns(11,4);

      var sheet = ss.getSheets();

      sheet.map(function(f){
        var sheetName = f.getSheetName(); // Retrieves the sheetname of each sheet

        var lastRow = 0;
        if(f.getLastRow() == 1) {
          lastRow = 1;
        } else {
          lastRow = f.getLastRow() - 1;
        }
        var dataRange = f.getRange(2, 1, lastRow, f.getLastColumn());
        var data = dataRange.getValues();

        for (var j = 0; j < data.length; j++) {
          if (data[j][0].length != 0 && (data[j][5] > today || data[j][5] == "[Please Enter]")) { // We check if the promo end date is after the current day
            var sheetRow = data[j];
            sheetRow[1] = studioName;
            sheetRow.unshift(sheetName); //Adds the Country to the beginning of the row using the sheet name from spreadsheets 
            sheetPartnerArray.push(sheetRow);
          }
        }
      })
    }
  })
  masterSheet.getRange(2, 1, sheetPartnerArray.length , sheetPartnerArray[0].length ).setValues(sheetPartnerArray);
};
//我们将当前电子表格设置为master并获取当前日期。
var master=SpreadsheetApp.getActive();
var masterSheet=master.getSheetByName(“master”);
var users=master.getEditors();
var today=新日期();
//将菜单添加到电子表格中
函数onOpen(){
var电子表格=SpreadsheetApp.getActiveSpreadsheet();
变量项=[{
名称:“更新数据”,
函数名:“retrievePartnerData”
}];
电子表格。添加菜单(“提交菜单”,条目);
};
//首先,我们从合作伙伴表中获取所有数据
函数retrievePartnerData(){
masterSheet.getRange(2,1,masterSheet.getLastRow(),masterSheet.getLastColumn()).clear();//清除我们的masterSheet又称为sheet All
母版纸;
//从内部工作表获取的Promo大纲,并将其值存储在promoRange数组中
var promoRange=master.getSheetByName(“促销大纲”).getRange(“A1:Z100”).getValues();
var数组=[];
//行是一个数组,包含指向外部电子表格的url
var row=master.getSheetByName(“合作伙伴工作表集合”).getRange(“B:B”).getValues();
行映射(函数(e){
如果(e[0]!=”&&e[0]!=“Url”){
var ss=SpreadsheetApp.openByUrl(e[0]);
var studioName=ss.getSheets()[0].getRange(“A1”).getValue();
//更新合作伙伴表中的促销提纲表
var promotsheet=ss.getSheetByName(“促销大纲”);
promoSheet.getRange(“A1:Z100”).setValue(promoRange);
//隐藏K到Z列
hideColumns(11,4);
var sheet=ss.getSheets();
图纸.地图(功能(f){
var sheetName=f.getSheetName();//检索每个工作表的sheetName
var lastRow=0;
如果(f.getLastRow()==1){
lastRow=1;
}否则{
lastRow=f.getLastRow()-1;
}
var dataRange=f.getRange(2,1,lastRow,f.getLastColumn());
var data=dataRange.getValues();
对于(var j=0;jtoday | | |数据[j][5]==“[请输入]”){//我们检查促销结束日期是否在当天之后
var sheetRow=数据[j];
sheetRow[1]=研究名称;
sheetRow.unshift(sheetName);//使用电子表格中的工作表名称将国家/地区添加到行的开头
sheetPartnerArray.push(sheetRow);
}
}
})
}
})
masterSheet.getRange(2,1,sheetPartnerArray.length,sheetPartnerArray[0].length).setValues(sheetPartnerArray);
};

谢谢

一种常见的方法是设置触发器,以便在将来某个时间(刚好超过最大执行时间)重新启动大作业。然后你的大任务尽可能多地完成(或者在某个逻辑点上很好地停止),要么被杀,要么悄悄地退出。不管是哪种方式,它都会很快重新启动,然后继续工作

Patt0将这个想法完美地结束了,您可以将其添加到脚本中。通过一些调整,您应该能够将
retrievePartnerData()
转换为批处理作业

由于您已经有了一个菜单,
retrievePartnerData()
涉及到对许多电子表格的迭代,因此您有机会以另一种方式打破障碍,在单独的服务器脚本实例中完成每个迭代(或者更好地说,完成一组迭代)

这项技术出现在

在这方面也有相似之处。在这个答案中,UI客户端使用计时器重复执行服务器功能。然而,在这里,迭代将是基于工作的,而不是基于时间的。在浏览器中运行的此客户端函数将一直调用服务器,直到没有更多工作要做:

  /**
   * Call the server-side 'serverProcess' function until there's no more work.
   */
  function dispatchWork(){
    if (window.runningProcess) {
    }
    google.script.run
     .withSuccessHandler(                //<<<< if last call was good
       // After each interval, decide what to do next
       function(workis) {
         if (!workis.done) {             //<<<<< check if we're done
           // There's more work to do, keep going.
           dispatchWork();
         }
         else {
           // All done. Stop timer
           stopTimer();
           $('#start-process').hide();
           $("#final").html(' <h2>Processing complete!</h2>');
         }
       })
     .withFailureHandler(
       function(msg, element) {         //<<<<<< do this if error
         showError(msg, $('#button-bar'));
         element.disabled = false;
       })
     .serverProcess();                  //<<<<< call server function
  };
Conductor.html

开始处理
已用处理时间:-:--:--
/**
*加载文档时,将单击处理程序分配给按钮“添加”
*应开始隐藏的元素(避免“闪烁”),以及
*开始轮询文档选择。
*/
$(函数(){
//分配单击处理程序
$(“#启动流程”)。单击(启动流程);
});
/**
*调用服务器端的“serverProcess”函数,直到没有更多工作。
*/
功能分派工作(){
if(window.runningProcess){
}
google.script.run
.withSuccessHandler(
//每次休息后,决定下一步做什么
功能(工作){
如果(!工作完成){
//还有更多的工作要做,继续。
调度工作();
}
否则{
//全部完成,停止计时
停止计时器();
$(“#启动进程”).hide();
$(“#final”).html('Processing complete!');
}
})
.withFailureHandler(
函数(消息,元素){
淋浴器(味精,$(“#按钮栏”);
element.disabled=false;
})
.serverProcess();
};
/**
*运行服务器端函数以检索当前
*选定的文本。
*/
函数startProcess(){
this.disabled=true;//禁用按钮
$(“#错误”).remove();//清除以前的错误消息(如果有)
startTimer();//启动工作计时器,以便向用户显示
window.runningProcess=true;
dispatchWork();//在服务器上开始我们的工作
}
//定时器根据http://codingforums.com/javascript-programming/159873-displaying-elapsed-time.html
/**
*启动tick函数。
*/
函数startTimer()
{
window.seconds=null;
window.ticker=null;
window.seconds=-1;
window.ticker=setInterval(勾号,1000);
勾选()