【问题标题】:Google Script - function comparing if date is older than todayGoogle Script - 比较日期是否早于今天的函数
【发布时间】:2023-03-11 06:05:01
【问题描述】:

一列中有日期,如果其他列的状态发生变化,该日期会自动更新。如果从“打开”更改为“进行中”,则会设置今天的日期。

如果日期早于今天,我需要一个自动执行“某事”的功能。

到目前为止有这个代码,但它不起作用,我不知道为什么。 谢谢

function backgroundformate() {
  var odpovediSheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Odpovědi formuláře");
  var lastRow = odpovediSheet.getLastRow();
  var columnH = odpovediSheet.getRange(2, 8, odpovediSheet.getLastRow(), 1).getValues();
  var day = 24*3600*1000
  var today = parseInt((new Date().setHours(0,0,0,0))/day);

  for (var i=1; i < columnH.length; i++) {
    var dataday = parseInt(new Date(columnH[i][8]).getTime()/day);
    if (dataday < today) {odpovediSheet.getRange(i+1, 8, lastRow, 1).setBackground("red")}
    else {odpovediSheet.getRange(i+1, 8, lastRow, 1).setBackground("yellow")}
  }
}

【问题讨论】:

    标签: google-apps-script google-sheets date-comparison


    【解决方案1】:

    您实际上不需要解析日期来比较它们,JavaScript 可以原生地做到这一点。 这是你的工作代码:

    function backgroundformate() {
      var odpovediSheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Odpovědi formuláře");
      SpreadsheetApp.getActiveSpreadsheet().getActiveSheet()
      var lastRow = odpovediSheet.getLastRow();
      var columnH = odpovediSheet.getRange(2, 8, odpovediSheet.getLastRow(), 1).getValues();
      var today = new Date(new Date().setHours(23,59,59,0,0));// I set the hour to near midnight so you can get the right result today until 23:59:59 
    
      for (var i=1; i < columnH.length; i++) {
        var dataday =columnH[i][0];
        if (dataday < today) {odpovediSheet.getRange(i+1, 8, lastRow, 1).setBackground("red")}
        else {odpovediSheet.getRange(i+1, 8, lastRow, 1).setBackground("yellow")}
      }
    }
    

    另外,你确实在这段代码中犯了一个错误:

    var dataday = parseInt(new Date(columnH[i][8]).getTime()/day);
    

    您要查找的值位于索引 0 处,因为您仅在定义范围时才从该列获取数据。 代码应该是

    var dataday = parseInt(new Date(columnH[i][0]).getTime()/day);
    

    但无论如何,解析是不必要的。

    也就是说,在循环中调用 ss 服务并不是一个好习惯,您可以使用数组和单个 SS 调用更有效地做到这一点。 代码是这样的,请尝试比较执行速度。

      function backgroundformate() {
          var odpovediSheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Odpovědi formuláře");
          SpreadsheetApp.getActiveSpreadsheet().getActiveSheet()
          var columnH = odpovediSheet.getRange(2, 8, odpovediSheet.getLastRow()-1, 1).getValues();
          var columnHBG = odpovediSheet.getRange(2, 8, odpovediSheet.getLastRow()-1, 1).getBackgrounds();
          var today = new Date(new Date().setHours(23,59,59,0,0));
    
          for (var i=0; i < columnH.length; i++) {
            var dataday =columnH[i][0];
            if (dataday < today) {
              columnHBG[i][0]='#F00';
            }else{
              columnHBG[i][0]='#FF0';
            }
          }
          odpovediSheet.getRange(2, 8, odpovediSheet.getLastRow()-1, 1).setBackgrounds(columnHBG);
        }
    

    【讨论】:

      【解决方案2】:

      此脚本仅在用户此时提示时才起作用。

      您有两个选择,或者在其上放置一个触发器,例如让脚本每 5 分钟运行一次,请参阅here

      或者将函数作为 onEdit(e) 启动,当工作表中的任何内容发生更改时,它会自动触发脚本。但是,这可能会减慢在工作表中的工作速度,请参阅 here

      我不确定您是说您的脚本没有正常工作还是没有被触发。如果您希望我查看您的脚本,请提供指向 Google 表格的链接。

      function backgroundformate() {
        var odpovediSheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Odpovědi formuláře");
        var lastRow = odpovediSheet.getLastRow();
        var columnH = odpovediSheet.getRange(2, 8, odpovediSheet.getLastRow(), 1).getValues();
        var day = 24*3600*1000
        var today = parseInt((new Date().setHours(0,0,0,0))/day);
      
        for (var i=1; i < columnH.length; i++) {
          var value = columnH[i][8].getValue();
          var dataday = parseInt(value/day);
          if (dataday < today) {odpovediSheet.getRange(i+1, 8, lastRow, 1).setBackground("red")}
          else {odpovediSheet.getRange(i+1, 8, lastRow, 1).setBackground("yellow")}
        }
      }
      

      【讨论】:

      • 我明白了。我认为我需要设置一个触发器。我的功能本身有问题。脚本不工作。这是:docs.google.com/spreadsheets/d/…
      • 我没有编辑权限,所以看不到您的脚本。我认为脚本中的日期与工作表中的格式不同。在 var today ( Logger.log(today) ) 和 var dataday ( Logger.log(dataday) ) 后面放置一个记录器,然后比较两个日志。
      • 尝试添加这些日志并告诉我是否有任何不同。
      • [17-08-01 17:08:53:195 CEST] 17378.0 [17-08-01 17:08:53:196 CEST] NaN [17-08-01 17:08: 53:199 CEST] NaN [17-08-01 17:08:53:201 CEST] NaN 今天是 17378.0 数据日 NaN,那么糟糕的格式?
      • 是的,您不能像在可变数据日中那样定义日期。您获得的值已经是一个日期。只需 parseInt 特定列并将其除以您的 day 变量。如果您不确定 H 列中的日期格式是否正确,您可以在开始循环之前先使用 Utilities.formatDate(new Date(), "GMT", "yyyy-MM-dd'T'HH 格式化该列:mm:ss'Z'")。但是,由于您正在使用我认为不必要的解析。
      猜你喜欢
      • 1970-01-01
      • 2018-04-05
      • 1970-01-01
      • 2015-07-24
      • 1970-01-01
      • 2014-04-20
      • 1970-01-01
      • 2018-06-17
      相关资源
      最近更新 更多