根据单元格值格式化行颜色
Posted
技术标签:
【中文标题】根据单元格值格式化行颜色【英文标题】:Format row color based on cell value 【发布时间】:2013-06-10 22:19:39 【问题描述】:我正在尝试从this 以前的相关问题改编示例脚本。对于 K 列中的单元格值为零的行,我想将该行设为黄色。
这是我目前改编的代码:
function colorAll()
var sheet = SpreadsheetApp.getActiveSheet();
var startRow = 3;
var endRow = sheet.getLastRow();
for (var r = startRow; r <= endRow; r++)
colorRow(r);
function colorRow(r)
var sheet = SpreadsheetApp.getActiveSheet();
var c = sheet.getLastColumn();
var dataRange = sheet.getRange(r, 1, 1, c);
var data = dataRange.getValue();
var row = data[0];
if(row[0] === "0")
dataRange.setBackground("white");
else
dataRange.setBackground("yellow");
SpreadsheetApp.flush();
function onEdit(event)
var r = event.source.getActiveRange().getRowIndex();
if (r >= 3)
colorRow(r);
function onOpen()
colorAll();
我的问题是,我不知道如何引用 K 列。在上面的链接答案中,脚本的创建者声称,“[h]ere 是更改背景颜色的 Google Apps 脚本示例基于 A 列中的值的整行。“首先,最重要的是,我无法弄清楚他在哪里引用 A 列。我想改变“var dataRange = sheet.getRange(r, 1, 1 , C);”到“var dataRange = sheet.getRange(r, 11, 1, c);”会这样做,但这只是在我的工作表末尾添加了 10 个空白列,然后脚本崩溃了。我不明白为什么。
其次,但更重要的是,他声称脚本影响整个行的说法是不准确的,因为他原来的“var dataRange = sheet.getRange(r, 1, 1, 3);”只为前三列着色 - 这就是我添加“var c”并将“3”更改为“c”的原因。
此外,当我播放/调试脚本或从电子表格脚本管理器运行“onEdit”时,我收到“TypeError: Cannot read property “source” from undefined。”我可以看到“来源”是未定义的——我一开始错误地认为它是一种方法——但我也不确定如何解决这个问题。
最后,K 列并不总是参考列,因为我的意思是在它的左侧添加更多列。我假设每次添加列时我都必须更新脚本,但是第 2 行中有一个永远不会改变的列标题,所以如果有人可以帮助我设计一些代码来查找行中的特定字符串2,然后获取该列引用以在函数 colorRow() 中使用,我将不胜感激。
我无法判断此脚本的结构是否有效,但理想情况下,我希望我的电子表格具有反应性 - 我不想在编辑驱动单元格后或打开时重新运行此脚本;它看起来应该这样做(如果它没有错误的话),但这是我第一次尝试使用 Google Apps 脚本,我不确定任何事情。
我不擅长编写脚本,但早在 2006 年,我就在研究生院学习了编程基础/Python 课程,之后不久就使用 Excel 和 Access 工作了 4 年,经常创建和调整宏。我不能真正从头开始设计,但我了解基本原理和概念,即使我无法翻译所有内容(例如,我不明白“for”中第三个参数中的“++”是什么意思我正在使用的语句:“for (var r = startRow; r r++)。”我认为我在寓言上相当于一个有文化的西班牙语使用者试图阅读意大利语。
我们将不胜感激帮助和教育解释/示例。感谢您阅读/略读/跳到这句话。
【问题讨论】:
【参考方案1】:我不会重写你已经得到一些帮助的代码,我会尝试解释你提出的具体问题。我看到您已经有了一些答案,但我将其完全投入其中,因为它有助于理解。
My problem is, I can't figure out how to reference column K.
A 列 = 1,B = 2,... K = 10。
I can't figure out where he's referencing column A.
当您更改 .getRange 时,您已经很接近了。 .getRange 会根据 () 中的参数数量做不同的事情。有 4 个参数,它是 getRange(row, column, numRows, numColumns)。
sheet.getRange(r, 1, 1, c) // the first '1' references column A
从 row(r) 开始,最初是 row(3) 和 column(1)。所以这是单元格(A3)。该范围扩展到 1 行和 (c) 列。由于 c = sheet.getLastColumn(),这意味着您已将范围设为 1 行和所有列。
当您将其更改为
var dataRange = sheet.getRange(r, 11, 1, c) // the '11' references column L
您有一个从第 (3) 列 (L) 开始的范围,因为 11 = L。这将运行到第 (3) 列 (getLastColumn())。 如果您超出范围,这将做一些奇怪的事情。 您可能已将其推入无限 for 循环,这会导致脚本崩溃
其次,但更重要的是,他声称脚本影响整个行的说法是不准确的,因为他原来的“var dataRange = sheet.getRange(r, 1, 1, 3);” 只为前三列着色 - 这就是我添加“var c”并将“3”更改为“c”的原因。
你是对的。 (3) 表示范围扩展为 3 列。
"TypeError: Cannot read property "source" from undefined."
这里发生的事情并不直观。您无法从电子表格脚本管理器运行 onEdit(event) 函数,因为它需要一个“事件”。
onEdit 是一个特殊的 google 触发器,每当编辑电子表格时都会运行。 它被传递了激活它的(事件)并且 事件源。指的是事件发生的工作表 var r = event.source.getActiveRange().getRowIndex();获取发生编辑的行号,即要改变颜色的行。如果您在管理器中运行它,则没有事件可供读取,因此未定义。出于同样的原因,您也无法对其进行调试。
最后,K 列并不总是参考列,我的意思是 在其左侧添加更多列。我想我必须更新 每次我添加列时的脚本,但行中有一个列标题 2这永远不会改变,所以如果有人可以帮助我设计一点 将在第 2 行中查找特定字符串的代码,然后得到它 在函数 colorRow() 中使用的列参考,我将不胜感激 它。
在我给你代码帮助她之前,我有一个替代建议,因为你也在谈论效率,在电子表格中运行函数通常比使用脚本更快。您可以尝试将 A 列作为索引列,其中 ColumnA(Row#) = ColumnK(Row#)。如果将以下内容放入单元格(A1)中,则 ColumnA 将与 Column K 完全匹配。
=ArrayFormula(K:K)
更好的是,如果您在 A 和 K 之间添加/删除列,公式将更改其引用而无需您执行任何操作。现在只需隐藏 columnA,您的工作表就会恢复其原始外观。
这是您的代码帮助,使用了您自己的一些代码。
function findSearchColumn ()
var colNo; // This is what we are looking for.
var sheet = SpreadsheetApp.getActiveSheet();
var c = sheet.getLastColumn();
// gets the values form the 2nd row in array format
var values = sheet.getRange(2, 1, 1, c).getValues();
// Returns a two-dimensional array of values, indexed by row, then by column.
// we are going to search through values[0][col] as there is only one row
for (var col = 0; col < data[0].length; col++) // data[0].length should = c
if (data[0][col] == value)
colNo = col;
break; // we don't need to do any more here.
return(colNo);
如果 break 给您带来问题,只需将其删除并让外观完整或替换为 col = data[0].length;
我不知道这个脚本的结构是否有效,但理想情况下,我 希望我的电子表格具有反应性 - 我不想重新运行 此脚本在编辑驱动单元后或打开时;它读到 就像它应该那样做(如果它不是越野车的话),但这是我的 第一次尝试使用 Google Apps 脚本,但我不确定 任何东西。
没关系,效率的微调取决于电子表格。编辑功能(事件) 每次编辑工作表时都会运行,对此您无能为力。然而,它应该做的第一件事是检查相关范围是否已被编辑。 if (r >= 3) 行似乎正在这样做。您可以根据需要使其具体化。 我对隐藏索引列的建议旨在提高效率并且更易于实施。
I'm not great with scripting,
你做得很好,但可以做一些背景阅读,只需查找诸如 for 循环之类的内容。不幸的是,Python 在语法上与许多其他语言不同。 google 脚本中的 for 循环与 VBA、C、JAVA 等相同。所以阅读这些基本操作实际上是在教你很多语言。
I don't understand what the "++" means in the third argument in the "for" statement
这就是 C++ 语言得名的原因,就像一个程序员的笑话。
r++ 等于说 r = r+1
r-- 表示 r = r-1
r+2 表示 r = r+2
所以
for (var r = startRow; r <= endRow; r++)
表示 r 以 startRow 开头,在本例中为 3。
循环将一直运行到 r
循环每次运行后 r 递增 1,因此如果 endRow == 10,则循环将从 r = 3 运行到 r = 10 => 8 次
【讨论】:
【参考方案2】:1.onEdit
是一个特殊函数,在您编辑电子表格时会自动调用。如果您手动运行它,则所需的参数将不可用。
2.要在K列为0时改变整行的颜色,你需要对脚本进行简单的修改。见下文
function colorRow(r)
var sheet = SpreadsheetApp.getActiveSheet();
var c = sheet.getLastColumn();
var dataRange = sheet.getRange(r, 1, 1, c);
var data = dataRange.getValues();
if(data[0][10].toString() == "0") //Important because based on the formatting in the spreadsheet, this can be a String or an integer
dataRange.setBackground("white");
else
dataRange.setBackground("yellow");
SpreadsheetApp.flush();
【讨论】:
这几乎奏效了。正确的行变为黄色,但仅从 K 列开始,脚本仍在工作表的右端创建额外的 10 列。感谢您的改进,希望我能尽快解决这个问题......我对为什么会发生这种情况有一些想法/猜测。但也许你肯定知道? 查看编辑后的代码。它为整行着色。你只需要改变你选择的范围。 我看到您编辑的内容,我认为更改会修复它,但我收到此错误:“TypeError:无法调用未定义的方法“toString”。”我们是否需要定义另一个 var 来设置 data[0][11],然后将该 var 放在 .toString() 之前?嗯......我真的很感谢你的所有帮助! 对不起,我的错误。对于第 K 列,它应该是 data[0][10] - 它是一个数组索引,而不是绝对列号。以上是关于根据单元格值格式化行颜色的主要内容,如果未能解决你的问题,请参考以下文章