本当に必要なスクリプトを見つけました( link ):
function getTotalSum(cell) {
var sheets = SpreadsheetApp.getActiveSpreadsheet().getSheets();
var sum = 0;
for (var i = 0; i < sheets.length ; i++ ) {
var sheet = sheets[i];
var val = sheet.getRange(cell).getValue();
if (typeof(val) == 'number') {
sum += val;
}
}
return sum;
}
ただし、通常はエラー(最大実行時間を超過)が発生します。
このエラーを解決するにはどうすればよいですか?
次のカスタム関数を最大170枚まで正常に試しました。
function getTotalSum(startrow, startcol) {
var ss = SpreadsheetApp.getActive();
var start = new Date();
var numSheets = ss.getNumSheets(), sum=0;
for(var k=1; k<numSheets; k++) {
var data = ss.getSheets()[k].getDataRange().getValues();
var value = data[startrow-1][startcol-1];
if(typeof(value) == 'number') {
sum += value;
}
}
return sum;
}
170を超えると、問題が生じます。
そのため、少なくとも750枚のシートに使用できる(ただし、カスタム関数としては使用しない)コードを作成しました。
// global
var ss = SpreadsheetApp.getActive();
function onOpen() {
ss.addMenu("Sum", [{name: "Go !!", functionName: "getSum"}]);
}
function getSum() {
// get user input
var cell = Browser.inputBox('Enter A1 notation', 'like B21',
Browser.Buttons.OK_CANCEL);
// retrieve cell reference from a sheet and get row and col index
var aCell = ss.getActiveSheet().getRange(cell.toString());
var row = aCell.getRow()-1, col = aCell.getColumn()-1;
// get number of sheets and set sum to zero
var numSheets = ss.getNumSheets(), sum=0;
// iterate through sheets, starting from second sheet
for(var k=1; k<numSheets; k++) {
// bulk load sheet at once
var data = ss.getSheets()[k].getDataRange().getValues();
// get value from array
var value = data[row][col];
// valid value
if(typeof(value) == 'number') {
sum += value;
}
}
// return value to active cell
ss.getActiveCell().setValue(sum);
}
カスタム関数は、実際にこれを広範囲に使用するためのものではありません。奇妙なことに、カスタム関数は170枚のシート(30秒)の実行時間の5分以内にうまく動作します。 .getDataRange().getValues()
の使用は、.getValue()
(750枚で約30秒)よりもわずかに有利です。
サンプルファイルを作成しました:750枚
コピーを作成し、追加したコードの余分な部分を探します。