使用 Apps 脚本在带有日期的 Google 电子表格中存档

Posted

技术标签:

【中文标题】使用 Apps 脚本在带有日期的 Google 电子表格中存档【英文标题】:Archiving in Google Spreadsheets with Date Using Apps Script 【发布时间】:2013-01-17 00:19:06 【问题描述】:

我有一个电子表格,其中包含附有日期和优先级的行动项目。如果项目是优先级 2 且一周或更长时间,我想创建一个归档行的函数。

这是我的脚本,但它正在发挥作用——有时它移动了错误的优先级,有时它移动了错误的日期,而且它从不移动它应该移动的所有日期。最糟糕的是,它在我的“Action Items”表底部添加了大量空行,并在“Archive”表中创建了空行。

显然有些地方出了问题,但我真的没有看到,即使经过一天的紧张调试。任何帮助都会有所启发和感激!

function Archiver() 
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Action Items'); // get the sheet
  var targetsheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Archive'); // get the target sheet
  var columnF = sheet.getRange(2, 6, sheet.getLastRow()-1, 1); // get all the rows with dates
  var fValues = columnF.getValues(); // get the values of dates
  var columnE = sheet.getRange(2, 5, sheet.getLastRow()-1, 1); // get all the rows with priorities
  var eValues = columnE.getValues(); // get the values of priorities
  var day = 24*3600*1000 // calculate ms in a day
  var today = parseInt((new Date().setHours(0,0,0,0))/day); // get date today
  for (var i = 0; i < fValues.length; i++)  // repeat loop
    var priority = eValues[i][0]; // set priority in loop
    var dataday = parseInt(fValues[i][0].getTime()/day); // convert date column into miliseconds
    Logger.log(dataday+" <= " + today-7 + " - " + priority) // my log isn't picking up day
    if (dataday <= today-7 && priority == "P2")  // if an item is more than 7 days old and Priority 2...
      targetsheet.insertRows(2,1)
      // move the entire source row to the second row of target sheet
    var rangeToMove = sheet.getRange(/*startRow*/ i + 2, /*startColumn*/ 1, /*numRows*/ 1, /*numColumns*/ sheet.getMaxColumns());
    rangeToMove.moveTo(targetsheet.getRange("A2"));
          // add date and time of when approved to target row in column E
    targetsheet.getRange("M2").setValue(Date());
    // delete row from source sheet
    sheet.deleteRows(i + 2,1);
    
  
        ss.toast("Move along.", "Archiving Complete.");

【问题讨论】:

【参考方案1】:

我没有调试您的代码,但我最初的想法是在迭代时删除行会扰乱数据的顺序并造成混乱,因此我对其进行了调整以复制行(而不是移动)并将行号存储到在数组中被删除,这样我们就可以在循环外删除它们。我做了一个快速测试,这似乎有效。

function Archiver() 
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Action Items'); // get the sheet
  var targetsheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Archive'); // get the target sheet
  var columnF = sheet.getRange(2, 6, sheet.getLastRow()-1, 1); // get all the rows with dates
  var fValues = columnF.getValues(); // get the values of dates
  var columnE = sheet.getRange(2, 5, sheet.getLastRow()-1, 1); // get all the rows with priorities
  var eValues = columnE.getValues(); // get the values of priorities
  var day = 24*3600*1000 // calculate ms in a day
  var today = parseInt((new Date().setHours(0,0,0,0))/day); // get date today
  var rowsToDelete = [];
  for (var i = 0; i < fValues.length; i++)  // repeat loop
    var priority = eValues[i][0]; // set priority in loop
    var dataday = parseInt(fValues[i][0].getTime()/day); // convert date column into miliseconds
    Logger.log(dataday+" <= " + (today-7) + " - " + priority) // my log isn't picking up day
    if (dataday <= today-7 && priority == "P2")  // if an item is more than 7 days old and Priority 2...
      targetsheet.insertRows(2,1)
      // move the entire source row to the second row of target sheet
    var rangeToMove = sheet.getRange(/*startRow*/ i + 2, /*startColumn*/ 1, /*numRows*/ 1, /*numColumns*/ sheet.getMaxColumns());
    rangeToMove.copyTo(targetsheet.getRange("A2"));
          // add date and time of when approved to target row in column E
    targetsheet.getRange("M2").setValue(Date());
    // delete row from source sheet
    rowsToDelete.push(i+2);
    
  
  rowsToDelete.reverse();
  for (var j = 0; j < rowsToDelete.length; j++)  sheet.deleteRow(rowsToDelete[j]); 
  ss.toast("Move along.", "Archiving Complete.");
 

【讨论】:

它有效。我看到您创建了一个循环来删除行,但我没有看到我解析日期的方式有任何变化。我想知道为什么在我调试时没有显示日期,但它们出现在您的代码中。仍然很困惑,但我非常感谢您的帮助! 对不起,我不够清楚。我的意思是删除存档的行需要在实际比较和移动发生的主循环之外;因为删除一行会更改工作表中尚未处理的数据的行号,但不会更改我们在函数开头读取的值。我只在今天 7 点左右在 Logger.log 调用中添加了 (),以防止将字符串与导致 NaN 错误的数字混合。 哦,我明白了!非常感谢您的澄清。

以上是关于使用 Apps 脚本在带有日期的 Google 电子表格中存档的主要内容,如果未能解决你的问题,请参考以下文章

带有 GraphQL 解析错误的 Google Apps 脚本 API 请求

如何在 Google Apps 脚本中将 BigQuery TIMESTAMP 转换为日期?

Google Apps 脚本 - 将 n 小时添加到当前时间和日期

如何在 Google Apps 脚本中为 DateTimePicker 获取正确的 DateTime?

使用 Google Apps Script、Google Cloud SQL 和 JDBC 存储日期

Google Apps 脚本 setTimestamp 到 mysql 数据库