Javascript 谷歌应用程序脚本,从外部电子表格检索数据的最快方式
我试图将多个电子表格(~100)中的数据加载到一个电子表格中,但是当我尝试这样做时,我的脚本超时了。打开每个电子表格似乎需要很长时间。有没有什么办法可以让我加快速度或解决问题 下面是我用来打开每个电子表格的内容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
// 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);
勾选()