单元格格式仅适用于可见(未过滤)的行

时间:2015-02-19 11:44:43

标签: google-apps-script formatting google-sheets

我正在使用GDrive Spreadsheets和Google App Script。我需要更改所有单元格的格式和背景颜色,我需要以编程方式进行。以下代码非常有用:

ss.getRange(1, 1, ss.getLastRow(), ss.getLastColumn()).setNumberFormat("@STRING@").setBackground("cyan");

唯一的问题是它在可见行/列上仅 - 即如果您在特定列值上过滤工作表,则上面的代码仅适用于当前显示的行。< / p>

例如,我有以下电子表格

enter image description here

我继续在第二列添加过滤器:

enter image description here

如您所见,我选择过滤 zxc 值的第二列。现在我需要使用谷歌应用程序脚本格式化具有青色背景的电子表格单元格。这是代码:

function testFormat(){
  var id = "theIdOfMySpreadsheet";
  var sheet = SpreadsheetApp.openById(id);
  var ss = sheet.getSheets()[0];
  ss.getRange(2, 1, ss.getLastRow() - 1, ss.getLastColumn()).setBackground("cyan");
}

以及电子表格中的结果:

enter image description here

一切似乎都很好。但是看看如果我删除过滤器会发生什么:

enter image description here

5个中只有2行具有正确的背景颜色,即使我已将其设置在整个范围内。我已经测试了返回范围的长度,它可以正常工作,因为它返回5行和3列。

你们有没有遇到过这个问题?如何强制它在已过滤的行上也改变背景?

4 个答案:

答案 0 :(得分:0)

如果有相当于数据的应用脚本方法 - 关闭过滤器,则可以清除隐藏的行。但截至目前,这种可能性并不存在。

一个选项是在应用任何过滤器之前,使用所有数据突出显示整个范围第一个。当范围过滤到较小的列表时,颜色格式将仅在较小的列表上。当它被放回时,它将返回到整个列表。

您先过滤,然后应用背景。首先尝试应用背景颜色。

如果您不能这样做,那么您可以使用可安装的onChange触发器来监视OTHER事件类型。 OTHER事件类型由数据过滤器和其他事件触发。

但是你需要知道过滤器之前和之后的状态。因此,您需要以某种方式记录原始状态,然后检查更改,例如显示的行数。

答案 1 :(得分:0)

如果您想要所有行的背景颜色,为什么不首先更改颜色然后应用过滤器? (注意:我的声誉不允许我发表评论,因此我将其作为答案发布)

答案 2 :(得分:0)

这是我编写的用于解决此问题的函数。 它检查工作表上的过滤器,并停用列上存在的所有过滤器条件,将背景色设置在指定范围内,然后重新激活过滤器条件。

// Globals
var SS = SpreadsheetApp.getActive();
var SH = SS.getSheetByName('Data');

var COLOR = {
  draft: '#d9ead3', // light green
  published: '#93c47d' // dark green
};

function colorBg_(sheet, a1Notations, color) {
  // color must be null to reset
  // calling the .setBackground method with undefined does nothing 
  // and with no argument throws an error
  color = color? color: null;

  // calling .getRangeList with wrapping a1Notation strings in an array throws an error
  a1Notations = !Array.isArray(a1Notations)? [a1Notations]: a1Notations;

  const filter = sheet.getFilter(); // returns null if there is no filter present (does not throw error)
  if (!filter) { // no filter, no problems

    // this works fine even with a single range in the list
    sheet.getRangeList(a1Notations).setBackground(COLOR.published);

  } else { // temporary remove filters so color will be applied to all visible rows

    const headerColumns = filter.getRange().getValues()[0];

    const filterCriterias = headerColumns.reduce(function(criterias, column, index) {
      const columnPosition = index + 1;
      const criteria = filter.getColumnFilterCriteria(columnPosition);
      if (criteria) {
        criterias[columnPosition] = criteria;
      }
      return criterias;
    }, {});

    const filteredColumnPositions = Object.keys(filterCriterias);

    filteredColumnPositions.forEach(function(columnPosition) {
    // const columnPosition = parseInt(key, 10); // this step is unnecessary, 
    // columnPosition can be a number or a string
      filter.removeColumnFilterCriteria(columnPosition);
    });

    // now that filters are inactive and all rows are visible, set the color
    sheet.getRangeList(a1Notations).setBackground(color);

    // replace filter criteria on columns
    filteredColumnPositions.forEach(function(columnPosition) {
      filter.setColumnFilterCriteria(columnPosition, filterCriterias[columnPosition]);
    });
  }
}

function colorDefault (color) {
  const a1Notation = 'E2:F';
  colorBg_(SH, a1Notation) // colorBg_ function will default color argument to null
}

function colorPublished () {
  var a1Notations = [
    'E3:F6',
    'F8',
    'E10'
  ];
  colorBg_(SH, a1Notations, COLOR.published);
}

答案 3 :(得分:-1)

//Enter your sheet name in getSheetByName function.

function clearFilter() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var ssId = ss.getId();
var sheetId = ss.getSheetByName("SheetName");
var filter =sheetId.getFilter();

for(var i=1;i<=column.length;i++)//colunm.length means number of columns.
{
    filter.removeColumnFilterCriteria(i);
}
}