简体   繁体   English

通过Google Apps脚本比较日期的烦人问题

[英]Tedious issue with comparing dates through Google Apps Script

Today I faced with the problem of comparing two dates using GAS: currentDate contains todays date and scheduledDate contains dates put in the column which is determined as row[3] . 今天,我面临着使用GAS比较两个日期的问题: currentDate包含今天的日期, scheduledDate包含放入确定为row[3]的列中的日期。

I've already spent on it 5 hours (hope that I was unlucky) and before we start the first thing to describe here is how cells in scheduledDate are filled: using custom function (code is put below) =SubtractDaysFromDate('2016'!A54, 8) , it subtracts 8 days from date located in '2016'!A54 and shows an outcome in a cell as 08/07/2016 or 08.07.2016 (depends on how you set up viewing format). 我已经花了5个小时(希望我很幸运),然后在我们开始描述之前,首先要描述scheduledDate中的单元格是如何填充的:使用自定义函数(代码放在下面) =SubtractDaysFromDate('2016'!A54, 8) ,它从位于'2016'!A54日期中减去8天,并在单元格中将结果显示为08/07/201608.07.2016 (取决于您如何设置查看格式)。

Here is the =SubtractDaysFromDate() source code: 这是=SubtractDaysFromDate()源代码:

function SubtractDaysFromDate(date, d) {
  var output = new Date(date.getTime()-d*(24*3600*1000)); // d — количество вычитаемых дней, date — дата или ячейка с датой, из которой вычитается данное количество дней.
  return output;
}

Here is the source code of my script: 这是我的脚本的源代码:

function SendElectronicMailing() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheetName = "Рассылка"; // Здесь указывается название листа в таблице.
var sheet = ss.getSheetByName(sheetName);
var startRow = 2; // Здесь первая строка для отправки рассылки.
var numRows = sheet.getLastRow()-1; // Здесь количество строк, которые необходимо обработать для отправки рассылки.
var dataRange = sheet.getRange(startRow, 1, numRows, 6);
var data = dataRange.getValues();
/* Здесь переменные с тематическими рассылками. */
var mailingChildrenHealth = "Здоровье детей перед отдыхом";
var mailingNonPersonalized = "–";
/* Здесь переменные со статусами электропочтовых рассылок. */
var statusMailingAwaiting = "Рассылка ожидает отправки";
var statusMailingSent = "Рассылка отправлена";
var statusMailingNotRequired = "Рассылка не требуется";
  for (var i = 0; i < data.length; ++i) {
    var row = data[i];
    var currentDate = new Date();
    var scheduledDate = new Date(row[3]); // Здесь указывается столбец с назначенной датой для отправки электропочтовой рассылки.
    var formattedCurrentDate = Utilities.formatDate(currentDate, "GMT+0300", "dd.MM.yyyy");
    Logger.log(currentDate);
    var formattedScheduledDate = Utilities.formatDate(scheduledDate, "GMT+0300", "dd.MM.yyyy");
    Logger.log("Getting new Date(): " + scheduledDate);
    Logger.log("Getting plain row[3]: " + row[3]);
    Logger.log("Using toString() and after replace(): " + row[3].toString().replace(/\./g, "/"));
    Logger.log("Using valueOf() of row[3]: " + scheduledDate.valueOf());
    var bookingNumber = [i+2];
    var contactFullName = row[0];
    var contactGivenName = contactFullName.split(" ").slice(0, -1).join(" ");
    var contactEmail = row[1];
    var mailingTopic = row[2];
    var cheapTicketsFinderLink = "http://go.ruslanchik.ru/";
    var mailingStatus = row[4]; // Столбец, в котором выставляется статус отправки/неотправки писем электропочтовой рассылки.
    var senderName = "Наталья Селецкая (Мини-гостиница Бердянская 56)";
    var replyTo = "natalya@berdyanskaya56.ru";
    Logger.log(formattedCurrentDate + " ==? " + formattedScheduledDate);


        /* Выставление статуса «Рассылка не требуется» для бронирований, по которым ввиду своего скудоумия не смог настроить отправку рассылки. */
        if (currentDate.valueOf() > scheduledDate.valueOf() && mailingStatus == statusMailingAwaiting) {
        sheet.getRange(startRow + i, 5).setValue(statusMailingNotRequired);
        Logger.log("Выставлен статус " + "«" + statusMailingNotRequired + "»" + " электропочтовой рассылки для бронирования № " + bookingNumber + " (" + contactFullName + ")" + " по причине несвоевременности её отправки гостю.");
        }

        /* Тематическая рассылка для гостей с детьми («забота о здоровье детей») с общей рассылкой о дешёвых билетах в Ейск и обратно. */
        if (formattedCurrentDate == formattedScheduledDate && mailingTopic == mailingChildrenHealth && mailingStatus == statusMailingAwaiting) {
        /* Здесь рассылка о здоровье детей перед отдыхом. */
        var subject_children_health = "Email subject";
        var message_children_health = "Email body.";
        MailApp.sendEmail(contactEmail, subject_children_health, message_children_health, {name: senderName, replyTo: replyTo});
        /* Здесь рассылка о дешёвых билетах в Ейск и обратно для гостей с детьми. */
        var subject_cheap_tickets = "Email subject";
        var message_cheap_tickets = "Email body";
        MailApp.sendEmail(contactEmail, subject_cheap_tickets, message_cheap_tickets, {name: senderName, replyTo: replyTo});
        /* А здесь уже проставление статуса отправки. */
        sheet.getRange(startRow + i, 5).setValue(statusMailingSent);
        Logger.log("Отправлены тематическая и общая электропочтовые рассылки для бронирования № " + bookingNumber + " (" + contactFullName + ")" + " гостю на " + contactEmail + ".");
        }
        SpreadsheetApp.flush(); // Здесь завершается обновление ячеек 5-го столбца, в котором проставляется статус отправки электропочтовых рассылок гостям.
  }
}

To check inputs , going to the link above you can check sheets named as 2016 (from this sheet =SubtractDatesFromDate() gets dates to subtract from) as well as Рассылка (on this sheet my script is run). 要检查输入 ,请转到上面的链接,您可以检查名为2016 (从此工作表=SubtractDatesFromDate()获取要减去的日期)以及Рассылка (在此工作表上运行我的脚本)。

To continue with, my script goes through all cells with these subtracted dates ( =SubtractDaysFromDate() ) on the sheet called Рассылка and checks whether current date is equal to the scheduledDate (ie, a column containing all cells with =SubtractDaysFromDate() on this sheet) and then sends emails. 要继续,我的脚本将遍历所有被减去日期( =SubtractDaysFromDate() )的工作表Рассылка所有单元格,并检查当前日期是否等于scheduledDate (即,此列包含所有带有=SubtractDaysFromDate()单元格的列工作表),然后发送电子邮件。

The problem is that while a small part of dates in scheduledDate (resulted by =SubtractDaysFromDate() ) is correctly recognised, another part of them stays to be not recognised and retrieved as 01.01.1970 . 问题在于,虽然正确识别了scheduledDate一小部分日期(由=SubtractDaysFromDate()导致=SubtractDaysFromDate() ,但其中的另一部分仍未被识别并检索为01.01.1970

To illustrate the problem, here is the script log: 为了说明问题,这是脚本日志:

[16-07-08 14:31:40:171 EAT] 08.07.2016 ==? 01.01.1970
[16-07-08 14:31:40:172 EAT] Fri Jul 08 14:31:40 GMT+03:00 2016
[16-07-08 14:31:40:173 EAT] Getting new Date(): Fri Jun 03 2016 00:00:00 GMT+0300 (MSK)
[16-07-08 14:31:40:173 EAT] Getting plain row[3]: Fri Jun 03 2016 00:00:00 GMT+0300 (MSK)
[16-07-08 14:31:40:174 EAT] Using toString() and after replace(): Fri Jun 03 2016 00:00:00 GMT+0300 (MSK)
[16-07-08 14:31:40:175 EAT] Using valueOf() of row[3]: 1464901200000
[16-07-08 14:31:40:175 EAT] 08.07.2016 ==? 03.06.2016
[16-07-08 14:31:40:176 EAT] Fri Jul 08 14:31:40 GMT+03:00 2016
[16-07-08 14:31:40:177 EAT] Getting new Date(): Wed Aug 03 2016 00:00:00 GMT+0300 (MSK)
[16-07-08 14:31:40:178 EAT] Getting plain row[3]: Wed Aug 03 2016 00:00:00 GMT+0300 (MSK)
[16-07-08 14:31:40:178 EAT] Using toString() and after replace(): Wed Aug 03 2016 00:00:00 GMT+0300 (MSK)
[16-07-08 14:31:40:179 EAT] Using valueOf() of row[3]: 1470171600000
[16-07-08 14:31:40:179 EAT] 08.07.2016 ==? 03.08.2016
[16-07-08 14:31:40:181 EAT] Fri Jul 08 14:31:40 GMT+03:00 2016
[16-07-08 14:31:40:181 EAT] Getting new Date(): Invalid Date
[16-07-08 14:31:40:182 EAT] Getting plain row[3]: #ERROR!
[16-07-08 14:31:40:182 EAT] Using toString() and after replace(): #ERROR!
[16-07-08 14:31:40:183 EAT] Using valueOf() of row[3]: NaN
[16-07-08 14:31:40:183 EAT] 08.07.2016 ==? 01.01.1970

If you look through the code above, it is clear that while for some dates comparison works perfectly: 如果您仔细阅读上面的代码,很明显,在某些日期进行比较比较完美:

[16-07-08 14:31:40:176 EAT] Fri Jul 08 14:31:40 GMT+03:00 2016 (note: this a current date)
[16-07-08 14:31:40:177 EAT] Getting new Date(): Wed Aug 03 2016 00:00:00 GMT+0300 (MSK)
[16-07-08 14:31:40:178 EAT] Getting plain row[3]: Wed Aug 03 2016 00:00:00 GMT+0300 (MSK)
[16-07-08 14:31:40:178 EAT] Using toString() and after replace(): Wed Aug 03 2016 00:00:00 GMT+0300 (MSK)
[16-07-08 14:31:40:179 EAT] Using valueOf() of row[3]: 1470171600000
[16-07-08 14:31:40:179 EAT] 08.07.2016 ==? 03.08.2016

For other part of them it doesn't: 对于它们的其他部分则不是:

[16-07-08 14:31:40:181 EAT] Fri Jul 08 14:31:40 GMT+03:00 2016 (note: this a current date)
[16-07-08 14:31:40:181 EAT] Getting new Date(): Invalid Date
[16-07-08 14:31:40:182 EAT] Getting plain row[3]: #ERROR!
[16-07-08 14:31:40:182 EAT] Using toString() and after replace(): #ERROR!
[16-07-08 14:31:40:183 EAT] Using valueOf() of row[3]: NaN
[16-07-08 14:31:40:183 EAT] 08.07.2016 ==? 01.01.1970

For better undestanding here is a link to my GS sheet: https://docs.google.com/spreadsheets/d/1azDfWZWDSVTVVKLaJZlsRDbW21-Cps8Hx8M2kbclw-g/edit?pli=1#gid=2147296153 . 为了更好地理解,这里是指向我的GS表的链接: https : //docs.google.com/spreadsheets/d/1azDfWZWDSVTVVKLaJZlsRDbW21-Cps8Hx8M2kbclw-g/edit?pli =1 #gid=2147296153

Please, could you check if I miss anything important to make it work properly? 请,您能检查一下我是否有任何重要事项要使其正常工作? Why one part of dates calculated by =SubtractDatesFromDate() is recognised correctly by my script, another and the biggest part of them is not? 为什么我的脚本可以正确识别由=SubtractDatesFromDate()计算的日期的一部分,而另一部分却不能被大多数人正确识别呢?

How can I fix it? 我该如何解决? All result-oriented attempts to solve this issue are strongly appreciated. 强烈赞赏所有以结果为导向的解决方案。


Edited. 编辑。 It is a part of my code that I've already edited: 这是我已经编辑的代码的一部分:

 function SendElectronicMailing1() { var ss = SpreadsheetApp.getActiveSpreadsheet(); var bookingsSheetName = "2016"; // Здесь указывается название листа откуда брать даты заезда по бронированиям. var mailingSheetName = "M1"; // Здесь указывается название листа где обновлять статусы отправки электропочтовой рассылки. var bookingsTableSheet = ss.getSheetByName(bookingsSheetName); var mailingListSheet = ss.getSheetByName(mailingSheetName); var startRow = 2; // Здесь первая строка для отправки рассылки. var bookingsNumRows = bookingsTableSheet.getLastRow()-1; // Здесь количество строк, которые необходимо обработать для отправки рассылки. var mailingNumRows = mailingListSheet.getLastRow()-1; var bookingsDataRange = bookingsTableSheet.getRange(startRow, 1, bookingsNumRows, 2); var mailingDataRange = mailingListSheet.getRange(startRow, 1, mailingNumRows, 6); var bookingsData = bookingsDataRange.getValues(); var mailingData = mailingDataRange.getValues(); /* Здесь переменные с тематическими рассылками. */ var mailingChildrenHealth = "Здоровье детей перед отдыхом"; var mailingNonPersonalized = "–"; /* Здесь переменные со статусами электропочтовых рассылок. */ var statusMailingAwaiting = "Рассылка ожидает отправки"; var statusMailingSent = "Рассылка отправлена"; var statusMailingNotRequired = "Рассылка не требуется"; for (var i = 0; i < bookingsData.length; ++i) { var row = bookingsData[i]; var currentDate = new Date(); var scheduledDate = new Date(row[0]).setHours(0,0,0,0)+(-10*24*3600*1000); // Здесь указывается столбец с назначенной датой для отправки электропочтовой рассылки. Её еще можно считать через new Date().setHours(0,0,0,0)+(-10*24*3600*1000). var formattedCurrentDate = Utilities.formatDate(currentDate, "GMT+0300", "dd.MM.yyyy"); Logger.log("It is a current date: " + currentDate); var formattedScheduledDate = Utilities.formatDate(scheduledDate, "GMT+0300", "dd.MM.yyyy"); Logger.log("Getting new Date() of row " + [i+2] + ": " + scheduledDate); Logger.log("Getting clear value of row " + [i+2] + ": " + row[3]); Logger.log("Using toString() and after replace(): " + [i+2] + ": " + row[3].toString().replace(/\\./g, "/")); Logger.log("Using valueOf() of row " + [i+2] + ": " + scheduledDate.valueOf()); var bookingNumber = [i+2]; var contactFullName = row[0]; var contactGivenName = contactFullName.split(" ").slice(0, -1).join(" "); var contactEmail = row[1]; var mailingTopic = mailingData.row[2]; var cheapTicketsFinderLink = "http://go.ruslanchik.ru/"; var mailingStatus = row[4]; // Столбец, в котором выставляется статус отправки/неотправки писем электропочтовой рассылки. var senderName = "Наталья Селецкая (Мини-гостиница Бердянская 56)"; var replyTo = "natalya@berdyanskaya56.ru"; Logger.log(formattedCurrentDate + " ==? " + formattedScheduledDate); } } 

Mu question is how to get the values of row[2] in the sheet Рассылка and write it to variable placed in for (var i = 0; i < bookingsData.length; ++i) { linking to 2016 ? 穆的问题是如何获取表格Рассылкаrow[2]的值并将其写入for (var i = 0; i < bookingsData.length; ++i) {链接到2016 Will it be a proper way to use var mailingTopic = mailingData.row[2]; 这是使用var mailingTopic = mailingData.row[2];的正确方法var mailingTopic = mailingData.row[2]; ?

This is pretty dumb, and may not fix the problem, however, I found that GAS is sometimes very finicky. 这是非常愚蠢的,可能无法解决问题,但是,我发现GAS有时非常挑剔。 It's normally something I would do just as a throwaway, but since I can't edit the script myself... 通常,这是我会做的事情,但是由于我自己无法编辑脚本...

Try moving the left '(' so it is around the d. I know order of operations SHOULD handle this, but it may not, then you would be having a serious issue. And I can't think of what else would cause the problem on only some dates, unless the dates in the spreadsheet were incorrectly formatted, which they don't seem to be. So, instead of this: 尝试向左移动'(',使它围绕d。我知道操作顺序应该可以处理此问题,但可能不行,那么您将遇到一个严重的问题。我无法想到还有什么会导致问题仅在某些日期,除非电子表格中的日期格式不正确(看起来好像不是),所以,请改用:

var output = new Date(date.getTime()-d*(24*3600*1000));

try: 尝试:

var output = new Date(date.getTime()-(d*24*3600*1000));

EDIT: 编辑:

This obviously is not EXACTLY what your after, but it shows transferring cells between two sheets on the same SS. 这显然不完全是您的追求,但是它显示了在同一SS的两张纸之间传输单元。

function example() {

  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var sheet1 = ss.getActiveSheet();
  var sheet2 = ss.getSheetByName('sheet2');

  var startRow = 1;
  var numRows = sheet1.getLastRow()-1; 
  var dataRange = sheet1.getRange(startRow, 1, numRows, 6);
  var data = dataRange.getValues();

  var row = []

  for (var i in data) {
    row.push(data[i] + 10);
  }

  sheet2.appendRow(row);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM