我在google工作表上有一个不断增长的数据集,我需要在其上运行一些复杂的过滤器/查询/ vlookups。但是,我只需要在新数据到达时每天这样做。复杂公式的数量开始减慢电子表格的速度,特别是在我们糟糕的宽带连接的情况下。!
因此,我提出了一种解决方法,使用GAS在单元格中设置公式,然后获取值,然后设置值,因为知道GAS本身不运行电子表格函数(根据VBA) )。因为我已经在我需要的工作表上编写过滤器和vlookups,所以我没有编写公式脚本来实现同样的目的。
以下是代码的简化版本:
function myFunction() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sh = ss.getSheetByName('Sheet1');
var rng = sh.getRange('B11');
rng.setFormula('=sum(filter(C2:E5,A2:A5="Bob"))');
var val = rng.getValue();
rng.setValue(val);
}
在我的生产电子表格中,我可以在30张纸张上分别使用@ 300个公式,所以如果这些都在数据集中ping,我会得到灰色进度条的长时间段。 (本质上,公式是过滤/求和或将每日数据计算到每周数据)上面的例子显示了一张纸上发生的所有事情。
想知道是否有更好/不同的做法?
由于
添
答案 0 :(得分:1)
好吧,我还没有想出更好的东西,所以我会发布我的解决方案。两个脚本。第一个检查用户是否确实想要更新他们的值,如果他们说是,则再次检查用户并向他们显示它将更新的日期范围。然后运行第二个脚本,简单地说就是将公式应用于单元格然后复制生成的值并粘贴该值。在使用完整数据加载进行测试时,电子表格没有"等待/进展灰色框"完全解决了我的问题。
function runWriteBehavs() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sy = ss.getSheetByName("summary");
//gets last row in column B - data is contigious
var BVals = sy.getRange("B1:B").getValues();
var BLast = BVals.filter(String).length;
var rowBeh = BLast + 1;
var lastDate = sy.getRange("A" + rowBeh).getValue();
var lastEndDate = new Date(lastDate.getTime()+6*3600000*24);;
//formats dates
lastDate = Utilities.formatDate(new Date(lastDate), "GB", "dd/MM/yyyy");
lastEndDate = Utilities.formatDate(new Date(lastEndDate), "GB", "dd/MM/yyyy");
//message box for confirmation
var output = Browser.msgBox("This script will run the summaries for the week:\\n" + lastDate + " - " + lastEndDate + "\\n Are you really sure you want to continue?",Browser.Buttons.YES_NO);
if ( output == "yes" ) {
//calls main update script
writeBehavs();
}
}
//Needs to be run once all data is entered
function writeBehavs() {
//get variables
var ss = SpreadsheetApp.getActiveSpreadsheet();
var db = ss.getSheetByName("database");
var sy = ss.getSheetByName("summary");
var sL = ss.getSheetByName("lists");
//gets number of behaviours, a counta() of list on sheet
var bCount = sL.getRange("H1").getValue();
//gets column listing hard coded on sheet
var bCol = sL.getRange("H2:H30").getValues();
//gets last row in column B - data is contigious
var BVals = sy.getRange("B1:B").getValues();
var BLast = BVals.filter(String).length;
//for each number on behaviour count
for (var i=0; i<bCount; ++i) {
//set the column
var colBeh = [bCol[i]];
//set the correct row for data entry and start date check
var rowBeh = BLast + 1;
//sets correct row for end date check
var rowBeh2 = rowBeh + 1;
//gets first empty row in Column from iteration
var rng = sy.getRange(colBeh+rowBeh);
//enters the formula in the cell
rng.setFormula('=iferror(sum(filter(database!$E$2:$E,database!$D$2:$D='+ colBeh + '$1,database!$A$2:$A=lists!$G$2,database!$B$2:$B>=$A' + rowBeh + ',database!$B$2:$B<$A' + rowBeh2 + ')),"0")');
//captures the value generated by the formula
var val = rng.getValue();
//pastes the formula to the cell
rng.setValue(val);
//Job Done!
}
}