根据日期删除单元格

时间:2018-10-02 21:05:53

标签: google-apps-script google-sheets

我需要有关单元格删除脚本的帮助。通常,我想运行一个重置脚本,以清除直到运行它之前的所有数据。因为我正在向与过滤器中的信息匹配的单元格中静态输入值,所以我相信我需要删除那些单元格,以便在我从导出页面删除过期的行后正确地将输入与过滤器信息的位置对齐

这是我要在脚本中执行的操作:如果Column F值<今天的日期,则删除I,J和K中的单元格,并将其下方的单元格向上移动。我想我找到了执行此操作的代码,但是运行该程序需要花费很长时间,以至于该程序无法通过多行才超时。我将使用for循环在73页上运行它,因此,如果它滞后于一个页面...是的,我需要帮助!

def gc_g1xye(self):
    self.data.append(
        {'Xc': float(self.tlist[1][1:]), 'Yc': float(self.tlist[2][1:]), 'Zc': self.gc_z,
         'E': float(self.tlist[3][1:]),
         'F': None, 'FT': self.ft_var, 'EW': self.tc_ew, 'LH': self.tc_lh, 'Layer': self.cmt_layer})

...

# Once the parsing is done:
self.newdataframe = pd.DataFrame(self.data)

1 个答案:

答案 0 :(得分:2)

根据Apps脚本"best practices",您将希望限制电子表格服务的使用以缩短执行时间。可以考虑两种“即时”优化:

  1. 连续删除多个单元格 为此,只需选择一个1行x 3列范围:ss.getRange(i-1, 8, 1, 3)而不是选择(i-1, 8)(i-1, 9)(i-1, 10)并在每个字段上调用deleteCells三个Ranges中的一个。
  2. 在删除表格之前先对其进行排序,以便仅需要1个删除电话(例如C++ stdlib "erase-remove" idiom)。如果您的数据是根据F列排序的,则所有应删除的数据都在末尾,那么您只需要迭代内存数组(非常快速过程)来查找应该删除的第一个日期,然后删除以下(包括它)的所有数据。

选项2的实现如下所示(我假设您使用的是冻结的标头,因为在对工作表或范围进行排序时它们不会移动。)

function sortDescAndGetValuesBack_(s, col) {
  return s.getDataRange().sort({column: col, ascending: false}).getValues();
}
function deleteAllOldData() {
  const sheets = SpreadsheetApp.getActive().getSheets()
      .filter(function (sheet) { /** some logic to remove sheets that this shouldn't happen on */});
  const now = new Date();
  const dim = SpreadsheetApp.Dimension.ROWS;

  sheets.forEach(function (sheet) {
    var values = sortDescAndGetValuesBack_(sheet, 6); // Col 6 = Column F
    for (var i = sheet.getFrozenRows(), len = values.length; i < len; ++i) {
      var fVal = values[i][5]; // Array index 5 = Column 6
      if (fVal && fVal < now) { // if equality checked, .getTime() is needed
        console.log({message: "Found first Col F value less than current time",
                     index: i, num2del: len - i, firstDelRow: values[i],
                     currentTime: now, sheet: sheet.getName()});
        var delRange = sheet.getRange(1 + i, 8, sheet.getLastRow() - i, 3);
        console.log({message: "Deleting range '" + sheet.getName() + "!" + delRange.getA1Notation() + "'"});
        delRange.deleteCells(dim);
        break; // nothing left to do on this sheet.
      }
    }
    console.log("Processed sheet '" + sheet.getName() + "'");
  });
}

参考文献: