如果它们不是粗体,则求和

时间:2016-06-22 10:04:15

标签: javascript google-apps-script

我对我的Google Apps脚本感到困惑,该脚本仅用于计算单元格总和粗体

以下是来源:

function SumIfNotBold(range, startcol, startrow){
  // convert from int to ALPHANUMERIC 
  // - thanks to Daniel at http://stackoverflow.com/a/3145054/2828136
  var start_col_id = String.fromCharCode(64 + startcol);
  var end_col_id = String.fromCharCode(64 + startcol + range[0].length -1);
  var endrow = startrow + range.length - 1

  // build the range string, then get the font weights
  var range_string = start_col_id + startrow + ":" + end_col_id + endrow
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var getWeights = ss.getRange(range_string).getFontWeights();

  var x = 0;
  var value;
  for(var i = 0; i < range.length; i++) {
    for(var j = 0; j < range[0].length; j++) {
      if(getWeights[i][j].toString() != "bold") {
        value = range[i][j];
        if (!isNaN(value)){
          x += value;
        }
      }
    }
  }
  return x;

这是公式:

=(SumIfNotBold(K2:K100,COLUMN(K2), ROW(K2)))*1

我有三个主要问题:

  1. 当我设置触发器以在任何编辑时启动此脚本时,我意外收到来自Google Apps的电子邮件,说明
  2.   

    TypeError:无法读取属性&#34;长度&#34;来自undefined。 (第7行,档案   &#34; SumIfNotBold&#34)

    因此,我该如何解决?有没有办法忽略这些自动发送的通知?

    1. 如果公式在另一个列表中,则公式不会计算单元格的总和。例如,如果我将公式放在B列表中但单元格位于A列表中,则此脚本在导出错误计算方面无法正常工作。

    2. 更新单元格值时,公式派生不是。在这种情况下,我会刷新公式本身(即,更改&#34; K2:K50&#34;到&#34; K3:K50&#34;以及一次返回)以获得更新的推导。

    3. 请帮我修复此脚本的问题。或者,如果最好使用新的计算非粗体单元格中的总和,那么我很乐意接受您的新解决方案。

1 个答案:

答案 0 :(得分:0)

以下是此脚本的一个版本,它解决了您提出的一些问题。如果使用其他工作表,则会将其简单地调用为=sumifnotbold(A3:C8)=sumifnotbold(Sheet2!A3:C8)

作为任何自定义函数,如果编辑其引用范围内的条目,则会自动重新计算该函数。 如果您将字体从粗体更改为正常或返回,则会自动重新计算。在这种情况下,您可以通过delete-undo在其求和范围内的任何非空单元格上快速刷新该函数。 (即删除一些数字,然后撤消删除。)

大多数函数通过解析活动单元格中的公式来获取对传递范围的引用。 警告:这是基于假设该函数单独使用=sumifnotbold(B2:C4)。它不会在=max(A1, sumifnotbold(B2:C4)之类的其他函数中起作用。

function sumifnotbold(reference) {
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var sheet = SpreadsheetApp.getActiveSheet();
  var formula = SpreadsheetApp.getActiveRange().getFormula();
  var args = formula.match(/=\w+\((.*)\)/i)[1].split('!');
  try {
    if (args.length == 1) {
      var range = sheet.getRange(args[0]);
    }
    else {
      sheet = ss.getSheetByName(args[0].replace(/'/g, ''));
      range = sheet.getRange(args[1]);
    }
  }
  catch(e) {
    throw new Error(args.join('!') + ' is not a valid range');
  }

  // everything above is range extraction from the formula
  // actual computation begins now

  var weights = range.getFontWeights();
  var numbers = range.getValues();  
  var x = 0;
  for (var i = 0; i < numbers.length; i++) {
    for (var j = 0; j < numbers[0].length; j++) {
      if (weights[i][j] != "bold" && typeof numbers[i][j] == 'number') {
        x += numbers[i][j];
      }
    }
  }
  return x;
}