在动态添加的工作表中使用公式

问题描述 投票:3回答:3

我正在尝试制定一个公式来为特定行的不同工作表总结值,如下所示:

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()

在一个脚本中,但如果我可以像公式那样做,那么向继承电子表格的人解释会更容易。

谢谢

google-apps-script google-sheets
3个回答
2
投票

我使用稍微不同的方法来解决您的问题。我建议将所有数据拉到一个结果页面并在那里总结。那么你不需要大量的“求和”函数或脚本。

使用indirect,您可以从每张纸上提取信息,前提是数据位于每张纸上相同的单元格位置。如果那是不可能的,你也可以使用vlookup来提取数据。我已经分享了一个如何用你的数字做这个的例子。

Sheet1上的'bob'值的语法=iferror(indirect("'"&C$2&"'!"&"b3"),"")其中C$2是Sheet名称(在本例中为Sheet1),B3Sheet1上bob的值。然后,您可以跨列复制此公式,并更新表格顶部的工作表名称。

https://docs.google.com/spreadsheets/d/15pB5CclseUetl5zSRPDOR9YA4u6_7TK8RB8CpSxqhnk/edit?usp=sharing


0
投票

Sample File

解决方法是使用自定义函数:

enter image description here

警告!该功能不会自动刷新。如果您添加然后删除其上方的行,它将刷新。

语法:=sumBySheets("Sheet1", "Sheet2", "B1:B3")

  • “Sheet1” - 表格
  • “Sheet2” - 表单
  • “B1:B3” - 总和的范围地址。

Sheet1和Sheet2之间可能有更多工作表:

enter image description here

代码:

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;

}

注意:

  • 请先运行test_sumBySheets函数并获取权限。

0
投票

已经有一段时间了,但这是我最终为我的解决方案所取得的成果。

以下代码动态加载与电子表格关联的所有工作表(请注意,为了便于阅读,我编辑了一下,可能是一些错别字):

// 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的答案,这样做的好处是,如果我在电子表格中添加了另一张工作表,它会自动更新我的所有金额。

© www.soinside.com 2019 - 2024. All rights reserved.