【问题标题】:Use formula inside script在脚本中使用公式
【发布时间】:2021-06-29 11:52:42
【问题描述】:

我想在自定义函数中使用公式,例如:

function myFunction(range, value) {
    var countNumber = COUNTIF(range; value); // COUNTIF is a formula that can be used in the spreadsheet
    if (countNumber > 0) {
        return "RESULT";
    } else {
        return "OTHER RESULT";
    }
}

然后:

=MYFUNCTION(A1:A5,"VALUETOTEST")


我想简化一个庞大的公式:

类似:

=IF(SUM(COUNTIFS(G182:G186;"ERROR";H182:H186;"62");COUNTIFS(G182:G186;"ERROR";H182:H186;"ALL"))>0;"ERRO";IF(SUM(COUNTIFS(G182:G186;"RETEST";H182:H186;"62");COUNTIFS(G182:G186;"RETEST";H182:H186;"TODOS"))>0;"RETEST";IF(COUNTIF(G182:G186;"UNIMPLEMENTED")>0;"UNIMPLEMENTED";"SOLVED")))

【问题讨论】:

  • 如果它解决了您的问题或提供了进一步的见解,请不要忘记接受答案。这有助于其他人找到您的问题以及由此产生的解决方案。

标签: google-apps-script google-sheets


【解决方案1】:

您可以通过三种方式执行这些操作。

  1. 在您需要的范围内将工作表公式添加到工作表本身。然后使用 GAS 函数从结果单元格中读取数据(无论您将其设置为写入何处)。然后,您可以使用结果进行进一步处理。

  2. 使用您的 GAS 函数将工作表公式写入工作表。然后使用更多的 GAS 来读取该结果并处理数据。这个方法可以在这里找到:https://developers.google.com/apps-script/reference/spreadsheet/range#setFormula(String)

  3. 您可以使用 GAS 创建自定义工作表公式,然后在工作表中使用。然后 GAS 可以读取该结果并处理信息。这需要对整个 JS 进行一些研究,以了解如何重新创建、组合和执行您需要工作表中的数据执行的操作。

您可以在此处找到制作自定义公式的指南:https://developers.google.com/apps-script/guides/sheets/functions

这里还有 JS 指南:http://www.w3schools.com/js/default.asp

W3 Schools 有一个相当全面的 JS 指南。 GAS 使用所有原生 JS 方法,因为它是一个 JS 编码环境。查看 GAS 参考,了解更多有关可能执行您需要的 GAS 特定方法的信息。

如果您需要检查条件和/或遍历行,请尝试以下操作:

function myFunction() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getActiveSheet();
var range = sheet.getRange(startRow, startColumn, numRows, numColumns);
var values = range.getValues(); //This is a 2D array; iterate appropriately
  for (i = 0; i < values.length; i++) {
    if (values[i] == conditionToCheck) {
      //perform code..OR
      //continue; <- This works to skip the row if the condition is met
    } else {
      //perform alternate code if condition is not met
    }
  }
}

正如我所提到的,.getValues() 创建了一个二维数组。如果您需要遍历列和行,则需要 2 个 for() 循环,如下所示:

for (i = 0; i < values.length; i++) { //iterates through the rows
  for(j = 0; j < values[i].length; j++) { //iterates through the columns in that current row

重要的是要提到 GAS 如何处理 2D 数组。 values[i][j] 表示有多少 i 行和 j 列。您可以像这样进行可视化:

values = [[A1, B1, C1],[A2, B2, C2],[A3, B3, C3]]

这是一个数组数组,其中外部数组是行数组,而内部是该行中按列排列的单元格值数组。

【讨论】:

  • 例如。我将不得不根据条件计算单元格。但为此,我将不得不阅读一系列单元格。我需要在单元格中进行 foreach 。有sheet.getRange(),但它如何切换到下一个单元格?我怎么知道它在范围的末尾?
  • 您正在寻找的是 for() { 循环以及 if() {} else { 语句。 for() { 循环允许在一个范围内迭代; if() 语句在每次迭代时检查条件。我将编辑我的答案以反映一个例子。如果此示例足够,请接受答案作为解决问题。
  • 此答案中的方式 #1 是从 Google Apps 脚本函数调用 Google 表格函数的方式。将 GS 函数放入一个单元格中,为其每个输入参数引用另一个单元格。例如。让 GAS 函数调用 GS 函数以添加两个值:将 =SUM(A1:B1) 放入单元格 C1。然后在 GAS 函数中放入 var sheet = SpreadsheetApp.getActiveSheet(); sheet.getRange("A1").setValue(firstVal); sheet.getRange("B1").setValue(secondVal); var sumVal = sheet.getRange("C1").getValue();您可以使用命名范围而不是文字单元格地址。
  • 此答案中的方式 #2 是 GAS 函数将标准 GS 函数插入工作表的方式,因此所有代码都在 GAS 脚本中,而不是手动配置工作表。
  • 此答案中的方式#3 是在 GAS 脚本中创建新 GS 函数的方式,而不依赖于标准 GS 函数。确实是GS sheet使用与GAS脚本相同的代码的一种方式,所以函数既可以用在GS sheet也可以用在GAS脚本中。
【解决方案2】:

谷歌应用脚​​本中的自定义函数无权访问电子表格函数。你可以试试这个=IF(COUNTIF(A1:A5,"VALUETOTEST")&gt;0,"RESULT","OTHER RESULT")

如果结果公式很大,请尝试为结果创建函数

function result1() {
     return "RESULT";
}

function result2() {
     return "OTHER RESULT";
}

那就用这个=IF(COUNTIF(A1:A5,"VALUETOTEST")&gt;0,RESULT1(),RESULT2())

试试这个 - 在应用程序脚本中复制以下函数,并将其用作公式 =myFunction("G182:G186","H182:H186") 记住用“"”包围范围,因为您将范围作为字符串传递,并注意两个范围都必须是长度相等。

function myFunction(aRange, bRange) {

    var cond_1 = "ERROR";
    var cond_2 = "62";
    var cond_3 = "ALL";
    var cond_4 = "RETEST";
    var cond_5 = "TODOS";
    var cond_6 = "UNIMPLEMENTED";


    var sheet = SpreadsheetApp.getActiveSpreadsheet();
    var aRange = sheet.getRange(aRange);
    var aValues = aRange.getValues();
    var bRange = sheet.getRange(bRange);
    var bValues = bRange.getValues();
    var count = 0;
    var tmplength = 0;

    if (aValues.length != bValues.length) {
        return "Range length does not Match";
    }

    for (i = 0; i < aValues.length; i++) {

        if (aValues[i] == cond_1 && bValues[i] == cond_2) {
            count += 1;
        }
        if (aValues[i] == cond_1 && bValues[i] == cond_3) {
            count += 1;
        }

        if (count > 0) {
            return "ERROR";
        } else {
            count = 0;

            if (aValues[i] == cond_4 && bValues[i] == cond_2) {
                count += 1;
            }
            if (aValues[i] == cond_4 && bValues[i] == cond_5) {
                count += 1;
            }

            if (count > 0) {
                return "RETEST";
            } else {
                count = 0;

                if (aValues[i] == cond_6) {
                    count += 1;
                }
                if (count > 0) {
                    return "UNIMPLEMENTED";
                } else {
                    return "SOLVED";
                }
            }
        }
    }
}

【讨论】:

  • 对,但那是因为我有一个庞大的公式。
  • 还有其他方法吗?
  • 您必须将公式重新创建为 GAS 中的函数
  • 是的,这就是我想做的,创建一个函数。你的意思是气体?
  • 这就是我想要的。但我会用我的函数替换一个 COUNTIFs 公式。
【解决方案3】:

这就是我解决问题的方法。我感谢帮助我达到这个结果的人!

// Like COUNTIFS
var countConditionals = function(cells, condition1, condition2) {

  var count = 0;

  for (i = 0; i < cells.length; i++) {

    if (cells[i][0] == condition1 && cells[i][1] == condition2) {
      count++;
    }

  }

  return count;
}

// Like COUNTIF
var countConditional = function(cells, condition) {

    var count = 0;

    for (i = 0; i < cells.length; i++) {

        if (cells[i][0] == condition) {
          count++;
        }

    }

  return count;
}

//Whole Formula
function verificaStatus(cells, db) {

  const ERROR  = "ERROR";
  const ALL    = "ALL";
  const RETEST = "RETEST";
  const NOTYET = "UNIMPLEMENTADED";
  const SOLVED = "SOLVED";

  var countErrors    = countConditionals(cells, ERROR, db);
  var countErrorsAll = countConditionals(cells, ERROR, ALL);
  var sumErrors      = countErrors + countErrorsAll;

  if (sumErrors > 0) {
    return ERROR;
  } else {

    var retest    = countConditionals(cells, RETEST, db);
    var retestAll = countConditionals(cells, RETEST, db);
    var sumRetest = retest + retestAll;

    if (sumRetest > 0) {
      return RETEST;
    } else {

      var countNonCreated = countConditional(cells, NOTYET);

      if (countNonCreated > 0) {
        return NOTYET;
      }

    }

  } 

  return SOLVED;

}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-17
    • 1970-01-01
    相关资源
    最近更新 更多