根据单元格值格式化行颜色

时间:2013-06-14 09:41:29

标签: google-apps-script google-sheets

我正在尝试调整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]是一个改变背景颜色的Google Apps脚本示例基于A列中的值的整行。“首先,最重要的是,我无法弄清楚他在哪里引用A列。我想改变”var dataRange = sheet.getRange(r,1,1) , C);” to“var dataRange = sheet.getRange(r, 11 ,1,c);”会这样做,但只是在我的工作表的末尾添加了10个空白列,然后脚本崩溃了。我不明白为什么。

其次,但更多的是,他声称脚本影响整行是不准确的,因为他原来的“var dataRange = sheet.getRange(r,1,1,3);”只有前三列的颜色 - 这就是我添加“var c”并将“3”改为“c”的原因。

此外,当我播放/调试脚本或从电子表格脚本管理器运行“onEdit”时,我从“未定义”获得“ TypeError:无法读取属性”源“。我可以看到“源”未定义 - 我错误地认为它最初是一个方法 - 但我不知道如何解决这个问题。

最后,列K并不总是参考列,因为我的意思是在其左侧添加更多列。我假设我每次添加列时都必须更新脚本,但第2行中的列标题永远不会改变,所以如果有人可以帮我设计一些代码来查找行中的特定字符串2,然后获取该列参考用于函数colorRow(),我将不胜感激。

我无法判断这个脚本是否有效构建,但理想情况下,我希望我的电子表格能够被动 - 我不想在编辑驱动单元后或打开时重新运行此脚本;它读起来就像是应该这样做的(它没有错误),但这是我第一次尝试使用Google Apps脚本,我感到不确定。

我在编写脚本方面不是很好,但是我在2006年在研究生院学习了编程基础/ Python课程,并且花了4年时间使用Excel&amp;在此之后不久访问,通常创建和调整宏。我不能真正从头开始设计,但我理解基本原理和概念,即使我无法翻译所有内容(例如,我不明白“++”在“for”中的第三个参数中意味着什么声明我正在使用:“for(var r = startRow; r&lt; = endRow; r ++ )。”我认为我在寓言上相当于一位有文化的西班牙语演讲者试图阅读意大利语。

将非常感谢帮助和教育解释/示例。感谢您阅读/略读/跳过这句话。

2 个答案:

答案 0 :(得分:2)

我会尝试向您解释您提出的具体问题,而不是重写您已经获得帮助的代码。我看到你已经有了一些答案,但我完全把事情放在一边,因为它有助于理解。

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

从行(r)开始,行(r)最初是行(3)和列(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循环,这将导致脚本崩溃

  

其次,但更多的是,他声称脚本影响整行是不准确的,因为他的原始&#34; var dataRange = sheet.getRange(r,1,1,3);&#34;    只有前三列的颜色 - 这就是为什么我添加&#34; var c&#34;并改变了#34; 3&#34;到&#34; c&#34;。

你是对的。 (3)表示范围扩展为3列。

"TypeError: Cannot read property "source" from undefined."

这里发生的事情并不直观。您无法从电子表格脚本管理器运行onEdit(event)函数,因为它期待&#34;事件&#34;。

  • onEdit是一个特殊的谷歌触发器,无论何时编辑电子表格都会运行。
  • 传递激活它的(事件)和
  • event.source。指事件发生的表格
  • var r = event.source.getActiveRange()。getRowIndex();获取编辑发生的行号,即要改变颜色的行。

如果在管理器中运行它,则没有事件要读取,因此未定义。您出于同样的原因无法对其进行调试。

  

最后,列K并不总是参考列,我的意思是   在其左侧添加更多列。我假设我必须更新   每次添加列时脚本,但行中都有一个列标题   2永远不会改变,所以如果有人可以帮我设计一点   将在第2行中查找特定字符串的代码,然后获取该代码   用于函数colorRow()的列引用,我将不胜感激   它

在我给你代码帮助她之前,我有另一个建议,因为你也在谈论效率,在电子表格中运行函数通常比使用脚本更快。您可以尝试将列A作为索引列,其中ColumnA(行#)= ColumnK(行#)。如果将以下内容放入单元格(A1)中,ColumnA将与列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脚本,我并不确定   任何东西。

没关系,效率的微调取决于电子表格。函数onEdit(事件)  每次编辑工作表时都要运行,没有什么可以做的。然而,它应该做的第一件事是检查相关范围是否已被编辑。 if(r> = 3)的行似乎正在这样做。您可以根据需要进行定制。 我对隐藏索引列的建议旨在提高效率,并且更容易实现。

I'm not great with scripting,

你做得很好,但可以做一些背景阅读,只需查看循环等内容。不幸的Python在语法上与许多其他语言不同。谷歌脚本中的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&lt; = endRow,在这种情况下是sheet.getLastRow()
  • 每次循环后r增加1,所以如果endRow == 10,则循环将从r = 3运行到r = 10 =&gt; 8次

答案 1 :(得分:0)

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(); 
}