Google apps script 将行添加到筛选范围

Google apps script 将行添加到筛选范围,google-apps-script,google-sheets,Google Apps Script,Google Sheets,我在google sheets中有一个待办事项列表应用程序。我有按注释类型和完成状态过滤的功能,用户可以在任何给定时刻使用这些功能 我还有一些函数可以轻松地添加任何给定类型的新注释。但是,当运行函数添加新便笺时,工作表已被过滤,我得到以下错误: 具有筛选出行的范围不支持此操作 关于如何将行添加到筛选范围,有什么建议吗 下面是我用来添加特定类型新注释的代码: function addNewCueNote() { if( sheet.getSheetName() == sheetName ) {

我在google sheets中有一个待办事项列表应用程序。我有按注释类型和完成状态过滤的功能,用户可以在任何给定时刻使用这些功能

我还有一些函数可以轻松地添加任何给定类型的新注释。但是,当运行函数添加新便笺时,工作表已被过滤,我得到以下错误:

具有筛选出行的范围不支持此操作

关于如何将行添加到筛选范围,有什么建议吗

下面是我用来添加特定类型新注释的代码:

function addNewCueNote() {
  if( sheet.getSheetName() == sheetName ) {
    var noteType = "CUE"

   //ADDS ROW AND COPIES FORMULA DOWN
  //SETS VARIABLES FOR LAST ROW AND LAST COLUMN
  var lRow = sheet.getLastRow(); 
  var lCol = sheet.getLastColumn();
  //INSERT LAST ROW  
  sheet.insertRowsAfter(lRow, 1);
  //COPY FORMULAS DOWN FOR SPECIFIED COLUMNS
  sheet.getRange(lRow,firstCopyCol,1,numColCopy).copyTo(sheet.getRange(lRow+1,firstCopyCol,1,numColCopy));

    //SETS NOTE TYPE    
    sheet.getRange(sheet.getLastRow(),noteTypeCol).setValue(noteType); 
}

抓取现有筛选器,将其从工作表中删除,添加新行,然后使用初始筛选器中的条件重新创建筛选器

function addNewCueNote() {
  var sheet = SpreadsheetApp.getActiveSheet();  // added to get code to run; not sure if you handle elsewhere

  if (sheet.getSheetName() === sheetName) {

    // Save state of existing filter before removing it
    var oldCriteria = [];
    var filter = sheet.getFilter();
    if (filter != null) {
      var oldNumColumns = filter.getRange().getNumColumns();
      for (var c = 1; c <= oldNumColumns; c++) {
        var criteria = filter.getColumnFilterCriteria(c);
        if (criteria != null) {
          oldCriteria.push([c, criteria.copy()]);
        }
      }
      filter.remove();
    }


    //*** PUT YOUR ROW INSERT LOGIC HERE ***


    // Recreate filter on new data range
    var dataRange = sheet.getDataRange();
    var newFilter = dataRange.createFilter();
    if (filter != null) {
      var newNumColumns = dataRange.getNumColumns();
      for (var i = 0; i < oldCriteria.length && oldCriteria[i][0] <= newNumColumns; i++) {
        newFilter.setColumnFilterCriteria(oldCriteria[i][0], oldCriteria[i][1]);
      }
    }
}

抓取现有筛选器,将其从工作表中删除,添加新行,然后使用初始筛选器中的条件重新创建筛选器

function addNewCueNote() {
  var sheet = SpreadsheetApp.getActiveSheet();  // added to get code to run; not sure if you handle elsewhere

  if (sheet.getSheetName() === sheetName) {

    // Save state of existing filter before removing it
    var oldCriteria = [];
    var filter = sheet.getFilter();
    if (filter != null) {
      var oldNumColumns = filter.getRange().getNumColumns();
      for (var c = 1; c <= oldNumColumns; c++) {
        var criteria = filter.getColumnFilterCriteria(c);
        if (criteria != null) {
          oldCriteria.push([c, criteria.copy()]);
        }
      }
      filter.remove();
    }


    //*** PUT YOUR ROW INSERT LOGIC HERE ***


    // Recreate filter on new data range
    var dataRange = sheet.getDataRange();
    var newFilter = dataRange.createFilter();
    if (filter != null) {
      var newNumColumns = dataRange.getNumColumns();
      for (var i = 0; i < oldCriteria.length && oldCriteria[i][0] <= newNumColumns; i++) {
        newFilter.setColumnFilterCriteria(oldCriteria[i][0], oldCriteria[i][1]);
      }
    }
}

@尼克,你的代码逻辑有问题。无论如何,这是一个有效的代码

// *** I have to add this for tests ***
var firstCopyCol = 3;
var numColCopy = 2;
var noteTypeCol = 2;
var sheet = SpreadsheetApp.getActiveSheet();
var sheetName = 'MatchImport';

// ************************************

function addNewCueNote() {
  if (sheet.getSheetName() === sheetName) {
    var filter = sheet.getFilter();
    if (filter) {
      var dataRange = sheet.getDataRange();
      var oldNumColumns = filter.getRange().getNumColumns();
      var newNumColumns = dataRange.getNumColumns();
      var criterias = {};
      for (var c = 1; c <= oldNumColumns && c <= newNumColumns; c++) {
        var criteria = filter.getColumnFilterCriteria(c);
        if (criteria) criterias['_' + c] = criteria;
      }
      filter.remove();
    }

    // START OF YOUR INSERT LOGIC
    var noteType = 'CUE';

    // ADDS ROW AND COPIES FORMULA DOWN
    // SETS VARIABLES FOR LAST ROW AND LAST COLUMN
    var lRow = sheet.getLastRow();
    var lCol = sheet.getLastColumn(); // This is never used
    // INSERT LAST ROW
    sheet.insertRowsAfter(lRow, 1);

    // COPY FORMULAS DOWN FOR SPECIFIED COLUMNS

    sheet
      .getRange(lRow, firstCopyCol, 1, numColCopy)
      .copyTo(sheet.getRange(lRow + 1, firstCopyCol, 1, numColCopy));

    // SETS NOTE TYPE
    sheet.getRange(sheet.getLastRow(), noteTypeCol).setValue(noteType);

    //* * END OF YOUR INSERT LOGIC

    if (!filter) return;
    dataRange = sheet.getDataRange();
    var newFilter = dataRange.createFilter();
    newNumColumns = dataRange.getNumColumns();
    for (c = 1; c <= oldNumColumns && c <= newNumColumns; c++) {
      if (criterias['_' + c])
        newFilter.setColumnFilterCriteria(c, criterias['_' + c]);
    }
  }
}

@尼克,你的代码逻辑有问题。无论如何,这是一个有效的代码

// *** I have to add this for tests ***
var firstCopyCol = 3;
var numColCopy = 2;
var noteTypeCol = 2;
var sheet = SpreadsheetApp.getActiveSheet();
var sheetName = 'MatchImport';

// ************************************

function addNewCueNote() {
  if (sheet.getSheetName() === sheetName) {
    var filter = sheet.getFilter();
    if (filter) {
      var dataRange = sheet.getDataRange();
      var oldNumColumns = filter.getRange().getNumColumns();
      var newNumColumns = dataRange.getNumColumns();
      var criterias = {};
      for (var c = 1; c <= oldNumColumns && c <= newNumColumns; c++) {
        var criteria = filter.getColumnFilterCriteria(c);
        if (criteria) criterias['_' + c] = criteria;
      }
      filter.remove();
    }

    // START OF YOUR INSERT LOGIC
    var noteType = 'CUE';

    // ADDS ROW AND COPIES FORMULA DOWN
    // SETS VARIABLES FOR LAST ROW AND LAST COLUMN
    var lRow = sheet.getLastRow();
    var lCol = sheet.getLastColumn(); // This is never used
    // INSERT LAST ROW
    sheet.insertRowsAfter(lRow, 1);

    // COPY FORMULAS DOWN FOR SPECIFIED COLUMNS

    sheet
      .getRange(lRow, firstCopyCol, 1, numColCopy)
      .copyTo(sheet.getRange(lRow + 1, firstCopyCol, 1, numColCopy));

    // SETS NOTE TYPE
    sheet.getRange(sheet.getLastRow(), noteTypeCol).setValue(noteType);

    //* * END OF YOUR INSERT LOGIC

    if (!filter) return;
    dataRange = sheet.getDataRange();
    var newFilter = dataRange.createFilter();
    newNumColumns = dataRange.getNumColumns();
    for (c = 1; c <= oldNumColumns && c <= newNumColumns; c++) {
      if (criterias['_' + c])
        newFilter.setColumnFilterCriteria(c, criterias['_' + c]);
    }
  }
}

谢谢Kate,我收到一个执行失败的错误。在创建变量的行上找不到筛选器oldNumColumns@NickSolyom发现问题,;再次更新,使解决方案更加清晰。这个解决方案只是保存、删除和重置过滤器,在我实现它时需要9-10秒。这仅仅是我的实现,还是你也得到了这样的结果?9-10秒似乎很长,但对电子表格进行几次修改会很快变得昂贵,例如:你对数据有很多现有的过滤器吗?。请尝试检查执行日志,或添加一些console.time和console.timeEnd调用,以查看大部分时间花在哪里?谢谢,凯特,我收到一个执行失败的错误。在创建变量的行上找不到筛选器oldNumColumns@NickSolyom发现问题,;再次更新,使解决方案更加清晰。这个解决方案只是保存、删除和重置过滤器,在我实现它时需要9-10秒。这仅仅是我的实现,还是你也得到了这样的结果?9-10秒似乎很长,但对电子表格进行几次修改会很快变得昂贵,例如:你对数据有很多现有的过滤器吗?。请尝试检查执行日志,或添加一些console.time和console.timeEnd调用,以查看大部分时间花在哪里?看见