4

如果我有以下用户定义的函数,我可以返回文本“foo”...

function myFunction(input){
   return "You wrote: "+ input;
}

如何通过代码为单元格分配红色背景?尽管这是一个简单的示例,但我的脚本更复杂,我想通过代码分配格式(我不想使用格式 > 条件格式...选项;我需要在单个脚本中配置所有内容。

有什么可以起作用的吗?

function myFunction(input){
   setBackground('red');
   return "You wrote: "+ input;
}

getActiveCell对我不起作用,因为这会触发单击(或激活)的单元格,而不一定是包含公式的单元格。

4

2 回答 2

5

如果我没听错,您就是在使用公式语法调用应用程序脚本函数,方法是=myFunction()在工作表中放入一个单元格。

在这种情况下,没有基于脚本的方法将格式应用于包含公式的单元格。您不仅不会自动引用函数中的父单元格,而且您也无权从单元格公式内的自定义函数调用中调用set方法(例如)。Range.setBackground()

这在使用 Apps 脚本服务标题下的文档中有所说明:

电子表格:只读(可以使用大多数 get*() 方法,但不能使用 set*())。无法打开其他电子表格(SpreadsheetApp.openById() 或 SpreadsheetApp.openByUrl())。

https://developers.google.com/apps-script/guides/sheets/functions#advanced

您的自定义函数(当作为自动执行的公式放置在单元格中时)唯一可以做的就是返回一个字符串或数组,然后将其显示在工作表中。

于 2018-01-10T20:43:38.883 回答
1

如果您有一个用户触发的脚本,您可以通过代码指定单元格的颜色,同时将所有内容保留在脚本中。

如何通过 Google 表格中的代码格式化单元格

第一:正如@Cameron Roberts 所说,作为单元格中的公式自动执行的自定义函数没有访问权限来更改任何单元格(包括它自己的)的格式,或者访问工作表以更改条件格式,这是正确的规则(因为工作表处于更高级别)。

我专注于回答这里突出显示的部分:

如何通过代码为单元格分配红色背景?尽管这是一个简单的示例,但我的脚本更复杂,我想通过代码分配格式(我不想使用 Format > Conditional Formatting... 选项;我需要在单个脚本中配置所有内容

您可以通过脚本设置条件格式规则,这将允许您在单个脚本中配置所有内容:https ://developers.google.com/apps-script/reference/spreadsheet/conditional-format-rule

如果您有一个复杂的脚本,那么用户很可能必须以某种方式启动它。依靠它,您可以执行类似的操作,通过代码更改单元格的格式。

选项 1 - 在电子表格打开时自动:

// This does not set the color of a user-selected cell like using getActiveCell does,
// but it necessarily relies on getActiveSheet(), since ranges are defined as referencing cells within sheets.
function setBackgroundOfScriptDeclaredCell() {
  var sheet = SpreadsheetApp.getActiveSheet();
  var range = sheet.getRange("A1");
  range.setBackground("red");
}

// Will run when user opens/refreshes spreadsheet.
function onOpen() {
  setBackgroundOfScriptDeclaredCell();
}

您可以执行上述操作,但不能将单元格设置为=setBackgroundOfScriptDeclaredCell()从单元格内调用该自定义函数。它将给出“例外:您无权调用 setBackground”。由于对单元格中允许访问的自定义函数的合理限制(仅 getter,而不是 setter)。请参阅:https ://developers.google.com/apps-script/guides/sheets/functions#advanced

选项 2 — 当用户启动您的脚本时

// Add custom menu to spreadsheet
function onOpen() {
  var ui = SpreadsheetApp.getUi();
  ui.createMenu('Run custom script')
      .addItem('Set background of a script-declared cell (A1)', 'setBackgroundOfScriptDeclaredCell')
      .addToUi();
}

// This does not set the color of a user-selected cell like using getActiveCell does, but it necessarily relies on getActiveSheet(), since ranges are defined as referencing cells within sheets.
function setBackgroundOfScriptDeclaredCell() {
  var sheet = SpreadsheetApp.getActiveSheet();
  var range = sheet.getRange("A1");
  range.setBackground("red");
}

选项 3 — 通过脚本设置条件格式规则

您可以通过脚本设置条件格式规则,这将允许您在单个脚本中配置所有内容:https ://developers.google.com/apps-script/reference/spreadsheet/conditional-format-rule 此脚本可能是当电子表格打开或用户启动您的脚本(例如通过菜单选项)时自动执行。

function yourScript() {
  // ...
  var cellsInA1Notation = "A1"; // could also have been e.g. "C3:D4"
  setRangeToRedBackground(cellsInA1Notation);
  // ...
}

// This is a custom convenience function I made which is not provided directly by the Google Sheets API.
function addConditionalFormatRule(sheet, rule) {
  var rules = sheet.getConditionalFormatRules();
  rules.push(rule);
  sheet.setConditionalFormatRules(rules)
}

// Adds a conditional format rule to a sheet that causes a cell to have red background color if it contains a 1.
// To illustrate that conditional formatting rules do not need to be spread out across (and hidden) in the spreadsheet GUI,
// but can be manipulated entirely in your script.
function setRangeToRedBackground(cellsInA1Notation) {
  var sheet = SpreadsheetApp.getActiveSheet();
  var range = sheet.getRange(cellsInA1Notation);
  var customFormulaString = "=A1=1";
  var rule = SpreadsheetApp.newConditionalFormatRule()
    .whenFormulaSatisfied(customFormulaString) 
    .setBackground("red")
    .setRanges([range])
    .build();
  addConditionalFormatRule(sheet, rule);
}

这样做,然后你可以做一个像这样的功能:

function foo() {
  return 1;
}

并将其放入A1。然后当 foo() 在 A1 中执行并返回 1 时,A1 会将其背景颜色更改为红色。这当然假设您知道 foo() 将输出的结果。当用户打开电子表格时,脚本已经设置了 A1 的条件格式规则。

这样做的好处是,这表明您可以通过脚本控制单元格的格式,甚至是条件格式规则(其中最先进的称为“自定义公式”)。如果您想在脚本中包含所有相当复杂的代码(包括复杂的自定义公式),这将是有利的。也许您希望能够轻松地重新分发您的脚本。或者,也许你只是想把所有东西都放在一个地方。您还可以避免在 Google 表格 GUI 中分散和隐藏复杂的逻辑。

如果您使用 GUI 来管理用于条件格式的自定义公式,那么要查看和管理该逻辑,您必须找到并选择正确的单元格,或者选择整个电子表格,然后右键单击并选择“条件格式” ”,或转到菜单并选择“格式 -> 条件格式”,以实际查看和编辑该逻辑。这有时会很不方便。

我还在一篇博文中写了这篇文章,其中我更详细地讨论了两点:

  • 如果使用更通用的SpreadsheetApp.newConditionalFormatRule().withCriteria函数而不是仅使用特殊情况来实现 setRangeToRedBackground 会怎样.whenFormulaSatisfied
  • 是否可以“在用于条件格式的自定义公式中执行自定义函数,就像在单元格中一样?”

在这里:https ://medium.com/@magne/how-to-format-cells-through-code-in-google-sheets-9d727ecc6053

我希望这个答案可以帮助其他可能遇到这个挑战的人。

这个答案的灵感来源,除了我自己有大致相同的问题:https ://developers.google.com/apps-script/reference/spreadsheet/conditional-format-rule-builder

于 2020-04-30T17:24:01.097 回答