如何更改运行函数的单元格格式

How to change format of cell that runs function

如果我有以下用户定义的函数,我可以 return 文本 "foo"...

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

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

这里面有什么可行的吗?

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

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

如果我没听错,你是在使用公式语法调用应用程序脚本函数,方法是将 =myFunction() 放入 sheet.

的单元格中

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

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

Spreadsheet: Read only (can use most get*() methods, but not set*()). Cannot open other spreadsheets (SpreadsheetApp.openById() or SpreadsheetApp.openByUrl()).

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

您的自定义函数(当作为自动执行的公式放置在单元格中时)唯一可以做的是 return 字符串或数组,然后将显示在 sheet .

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

如何通过 Google Sheets

中的代码格式化单元格

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

我在这里重点回答了突出显示的部分:

How can I assign a red background to the cell through code? Even though it's a simple example, my script is more complex and I want to assign formatting through code (I don't want to use the Format > Conditional Formatting... option; I need to have everything configured in a single script.

您可以通过脚本设置条件格式规则,这样您就可以将所有配置保存在一个脚本中: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 和 returns 1 中执行时,A1 会将其背景颜色更改为红色。这当然假定您知道 foo() 将输出的结果。当用户打开电子表格时,脚本已经设置了 A1 的条件格式规则。

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

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

我也在博客 post 中写了这篇文章,其中我对两点进行了更详细的介绍:

  • 如果使用更通用的 SpreadsheetApp.newConditionalFormatRule().withCriteria 函数而不是仅使用特殊情况 .whenFormulaSatisfied 来实现,setRangeToRedBackground 会是什么样子?
  • 是否可以"Execute custom functions in a custom formula used for conditional formatting, like you would in a cell?"

此处: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