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

时间:2018-02-07 22:13:16

标签: google-apps-script google-sheets

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

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

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

由于

3 个答案:

答案 0 :(得分:2)

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

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

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

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

答案 1 :(得分:0)

Sample File

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

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; }

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

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

enter image description here

代码:

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