indexOf () не находит значение в массиве - PullRequest
0 голосов
/ 16 января 2020

Исходя из этой публикации , я работаю над проверкой концепции, чтобы захватить запрос товара через форму Google, отправить его по электронной почте для одобрения, и результат одобрения был отправлен обратно в соответствующую строку в листе Google. Строка ищется из массива, используя метку времени в качестве ключа.

Я столкнулся с двумя проблемами: во-первых, метка времени в массиве имеет другой формат и иногда отличается на 1 секунду. Я настроил это, настроив формат в соответствии с тем, как выглядят значения массива, и запустил второй поиск, если поиск по первой временной метке не удался. Я надеюсь, что это надежно, но дайте мне знать, если есть лучший способ. Я не мог понять, почему иногда есть разница в 1 секунду.

Я застрял на второй задаче : я не могу успешно найти метку времени в массиве, indexOf () всегда возвращает значение -1. ​​

Буду признателен за любую помощь. Пожалуйста, будьте подробны, если нужно, я новичок ie.

Вот мой код:

function sendEmail(e) {
  // Response columns: Timestamp    Requester Email Item    Cost
  var email = e.namedValues["Requester Email"];
  var item = e.namedValues["Item"];
  var cost = e.namedValues["Cost"];
  var timestamp = e.namedValues["Timestamp"];

  var url = ScriptApp.getService().getUrl();

  // Enhancement: include timestamp to coordinate response  
  var options = '?approval=%APPROVE%&timestamp=%TIMESTAMP%&reply=%EMAIL%'
         .replace("%TIMESTAMP%",encodeURIComponent(e.namedValues["Timestamp"]))
         .replace("%EMAIL%",e.namedValues["Requester Email"])         
  var approve = url+options.replace("%APPROVE%","Approved"); 
  var reject = url+options.replace("%APPROVE%","Rejected");

  var html = "<body>"+
                "<h2>Please review</h2><br />"+
                "Request from: " + email + "<br />"+
                "For: "+item +", at a cost of: $" + cost + "<br /><br />"+ 
                "<a href="+ approve +">Approve</a><br />"+
                "<a href="+ reject +">Reject</a><br />"+
             "</body>";

  MailApp.sendEmail(Session.getEffectiveUser().getEmail(),
                    "Approval Request", 
                    "Requires html",
                    {htmlBody: html});  
}


function doGet(e) {

  var answer = (e.parameter.approval === 'Approved') ? 'Buy it!' : 'Not this time, Keep saving'; 
  var timestamp = e.parameter.timestamp;
  var newtimestamp = Utilities.formatDate(new Date(timestamp), "GMT+8", "EEE MMM dd yyyy HH:mm:ss 'GMT+0800 (SGT)'");  //reformat timestamp to match the ones in the data array
  var approvalCol = 5;

  MailApp.sendEmail(e.parameter.reply, "Purchase Request", 
                    "Your manager said: "+ answer);   

  // Update approval status back to the sheet
  var wsID = "<myworksheetID>";
  var sheet = SpreadsheetApp.openById(wsID).getSheetByName("Requests");
  var data = sheet.getDataRange().getValues();

  var oneColArray = new Array();
  for(i=0;i<data.length;++i){
     oneColArray.push(data[i][0]); // taking index 0 means I'll get column A of each row and put it in the new array
  }

  var row = oneColArray.indexOf(newtimestamp);

  Logger.log("\ntimestamp: " + timestamp + "\n\n" + "newtimestamp: " + newtimestamp + "\n\n" + "oneColArray: \n" + oneColArray);

  if (row < 0) {                                     //not found
    //Lower timestamp by 1 second. Sometimes there is a 1-second difference than the one in the array. I don't know why
    var dateString = Utilities.formatDate(new Date(timestamp), "GMT+8",'EEE, d MMM yyyy HH:mm:ss');
    var date = new Date(dateString);
    var revisedtimestamp = new Date((date.getTime() - (1/(24*60*60)*1000)));

    // now search again using the adjusted timestamp
    var row = oneColArray.indexOf(revisedtimestamp); 

    if (row < 0) {
       Logger.log("\ntimestamp: " + timestamp + "\n\n" + "newtimestamp: " + newtimestamp + "\n\n" + "oneColArray: \n" + oneColArray + "\n\n" + "revisedtimestamp: " + revisedtimestamp);
       throw new Error ("Request not found in list.");
    } else {
    sheet.getRange(row + 1, approvalCol).setValue(e.parameter.approval);
    }
  } else {
    sheet.getRange(row + 1, approvalCol).setValue(e.parameter.approval);
    }
}



1 Ответ

0 голосов
/ 18 января 2020

Я нашел решение на основе этой записи .

Я изменил эту строку:

var row = oneColArray.indexOf(newtimestamp); 

на эту, чтобы преобразовать массив в строку, и indexOf ( ) возвращает начальную точку, где он находит первое вхождение отметки времени. Из возвращаемого значения я только что подсчитал, какая строка находится на листе:

var row = oneColArray.join().indexOf(newtimestamp); 

Еще один вариант, который я предпочел больше, - это циклический переход по столбцу меток времени массива данных, в каждом l oop значение преобразуется в строка перед выполнением indexOf (). Мне просто нужно добавить 1 к [i], чтобы получить фактическую строку на листе.

for (var i = 0; i < data.length; ++i) {
       var row = data[i][0].toString().indexOf(newtimestamp);
    if (row > -1) {
      var a = i;
      break;
    }
  }
...