我正在尝试制定一个公式来为特定行的不同工作表总结值,如下所示:
Sheet 1
A | B
---------
bob | 3
foo | 14
bar | 7
Sheet 2
A | B
---------
bob | 2
foo | 1
bar | 9
但是需要注意的是一张新的'表3'可以添加相关数据,并自动获取。
在处理新的(正确命名的)工作表时,如何获取每张工作表中每行的求和值?
Results
-------
bob | 5
foo | 15
bar | 16
我们可以假设行值完全相同,例如在命名范围内,People = {bob,foo,bar}。
我的尝试类似于:
={People,ARRAYFORMULA('Sheet 1'!B1:B3+'Sheet 2'!B1:B3)}
但是对于新工作表,我必须通过添加
来手动更新公式+'Sheet 3'!B1:B3
我尝试使用INDIRECT
动态生成工作表名称,但它没有采用数组。我猜我可能不得不使用
SpreadsheetApp.getActiveSpreadsheet().getSheets()
在脚本中,但如果我可以像公式那样做,那么向继承电子表格的人员解释会更容易。
由于
答案 0 :(得分:2)
我使用稍微不同的方法来解决您的问题。 我建议将所有数据拉到一个结果页面并在那里总结。那么你不需要大量的“总和”功能或脚本。
使用indirect
,您可以从每张工作表中提取信息,前提是数据位于每张工作表的相同单元格位置。如果那不可能,您也可以使用vlookup
来提取数据。我已经分享了一个如何用你的数字做这个的例子。
Sheet1 =iferror(indirect("'"&C$2&"'!"&"b3"),"")
上'bob'值的语法
其中C$2
是工作表名称(在本例中为Sheet1
),而B3
是Sheet1
上bob的值。然后,您可以在列中复制此公式,并更新表格顶部的工作表名称。
https://docs.google.com/spreadsheets/d/15pB5CclseUetl5zSRPDOR9YA4u6_7TK8RB8CpSxqhnk/edit?usp=sharing
答案 1 :(得分:0)
解决方法是使用自定义函数:
警告!该功能不会自动刷新。如果您添加然后删除其上方的行,它将刷新。
语法:
function test_sumBySheets()
{
var sheet1 = 'Sheet1';
var sheet2 = 'Sheet2';
var range = 'b1:b3';
Logger.log(sumBySheets(sheet1, sheet2, range));
}
function sumBySheets(sheet1, sheet2, address)
{
var file = SpreadsheetApp.getActive();
var s1 = file.getSheetByName(sheet1);
var s2 = file.getSheetByName(sheet2);
var i1 = s1.getIndex() - 1; //get sheet indexes
var i2 = s2.getIndex() - 1;
var sheets = file.getSheets();
var result = [];
var arrays = [];
// remember all the data
for (var i = i1; i <=i2; i++)
{
var s = sheets[i];
var range = s.getRange(address);
arrays.push(range.getValues());
}
return sumByArrays_(arrays);
}
function sumByArrays_(arrays)
{
// take array #1
var arr = arrays[0];
l = arr.length;
ll = arr[0].length
// plus all arrays
for (var x = 1, xx = arrays.length; x < xx; x++) // loop arrays
{
for (var i = 0; i < l; i++) { // loop rows
for(var ii = 0; ii < ll; ii++) { // loop cells
arr[i][ii] += arrays[x][i][ii];
}
}
}
return arr;
}
Sheet1和Sheet2之间可能有更多工作表:
代码:
test_sumBySheets
注意:
FROM nginx:latest
COPY docker-entrypoint.sh /usr/local/bin/
RUN chmod 777 /usr/local/bin/docker-entrypoint.sh
ENTRYPOINT ["docker-entrypoint.sh"]
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
函数并获取权限。答案 2 :(得分:0)
过了一段时间,但这是我最终获得解决方案的地方。
以下代码动态加载与电子表格相关的所有工作表(请注意,我对其进行了一些编辑,以提高SO的可读性,可能是一些错字):
// These vars indicate what sheet, column and rows to start
// the list of sheets.
var main_sheet = 'Sheet1';
var sheet_col = 'A';
var sheet_row_start = 1;
function onEdit(e) {
// The onEdit trigger is the most useful as it fires most often.
// Therefore it is more likely to update the list of sheets relatively
// quickly.
_set_sheet_cells();
}
function _clear_sheet_cells(num_sheets, sheets_length) {
// Clear sheet cells, in case number of sheets has dropped.
var sheet_ctr = Number(num_sheets);
var stats = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(main_sheet);
if (sheet_ctr) {
if (sheet_ctr >= sheets_length) {
for (var i=0 ; i<sheet_ctr ; i++) {
stats_sheet.getRange(sheet_col+(sheet_row_start+i)).clearContent();
}
}
}
}
function _get_sheets() {
// Gather our sheets, can be combined with a regex to prune sheets.
var out = new Array();
var sheets = SpreadsheetApp.getActiveSpreadsheet().getSheets();
for (var i=0 ; i<sheets.length ; i++) {
out.push( sheets[i].getName() );
}
}
return out
}
function _set_sheet_cells() {
var userProperties = PropertiesService.getUserProperties();
var num_sheets = Number(userProperties.getProperty('sheet_names'));
var sheets = _get_sheets();
if (num_sheets == sheets.length) {
// Do nothing, no changes, remove if concerned about renaming sheets.
return;
}
_clear_sheet_cells(num_sheets, sheets.length);
var stats = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(main_sheet);
for (var j=0 ; j<sheets.length ; j++) {
// Put one sheet name per row.
stats_sheet.getRange(sheet_col+(sheet_row_start+j)).setValue(sheets[j]);
}
userProperties.setProperty('num_sheets', sheets.length)
}
一旦我动态加载了所有工作表,我就使用@ cgm990的答案,好处是,如果我向电子表格中添加另一个工作表,它会自动更新我的所有金额。