Javascript: группировка данных CSV по месяцам, а не по дням перед вставкой в Google Sheets

1

Я очень новичок в Javascript, но недавно начал изменять скрипты, чтобы мы могли загружать различные отчеты csv в Google Таблицы, используя скрипт Google Apps. В текущем скрипте мы читаем файл csv, а затем вставляем все данные после 8-й строки (так как строки до этого просто содержат информацию, например, когда она была сгенерирована, имя отчета и т.д.).

Теперь проблема состоит в том, что нам нужен отчет за год, который делится по месяцам на листы (если мы разделить на день, мы достигнем 2-миллионного предела ячейки). Но поскольку инструмент отчетности в этом случае не позволяет сегментировать любую другую переменную даты, чем день, мы должны выполнить разделение внутри скрипта. Таким образом, у нас в основном будет отчет с начала года, который будет отправлен с данными на уровне объявлений, разделенными на день. Затем данные уровня объявления группируются по месяцам, а не в день внутри сценария, прежде чем данные будут вставлены в Таблицы. Другими словами, я хочу, например, данные о стоимости, показе и клике для объявления, которое будет суммироваться для всех ежедневных событий в течение одного месяца.

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

Для справки, пожалуйста, найдите два сценария ниже. Первый из них - рабочий скрипт, который мы в настоящее время имеем, который просто вставляет данные csv из 8-й строки (но не группирует):

 function importData() {
 var sheet_atlas = SpreadsheetApp.getActive().getSheetByName('sheet_name');
 sheet_atlas.getRange('A2:V10000').clearContent();
 var sheetName = "sheet_name"

 var threads = GmailApp.search("attachment_name")
 var msgs = GmailApp.getMessagesForThreads(threads);
 var newData = [];

  for (var i = 0 ; i < msgs.length; i++) {
   for (var j = 0; j < msgs[i].length; j++) {
     var attachments = msgs[i][j].getAttachments();
     var bodyEmail = msgs[0][0].getBody();

     var regExp = new RegExp('a href="(.*?)"', "gi");
     //var regExp = new RegExp('data-saferedirecturl="(.*?)"', "gi"); // "i" is for case insensitive
     var url = regExp.exec(bodyEmail)[1];
     Logger.log(url)
     var decode = new XML('<d>' + url + '</d>');
     var strDecoded = decode.toString()
     var response = UrlFetchApp.fetch(strDecoded).getContentText();
     var csvdata = Utilities.parseCsv(response)
     var newOrders = []
     //Logger.log(csvdata)
     for (var eachRow in csvdata){
       //for(var col1 in csvdata[8]){
         //if(csvdata[8][col1] == 'Campaign Name'){ var campaignCol = col1 }

         //else if(csvdata[8][col1] == 'Publisher Name'){ var publisherCol = col1 }

         //else if(csvdata[8][col1] == 'Statistics Date'){ var dateCol = col1 }

       //}
         //Logger.log(dateCol)
         //Logger.log(publisherCol)
         //Logger.log(campaignCol)

       if (eachRow>8)
       {
                 var theRow  = [] 
                 theRow.push(csvdata[eachRow][0])
                 theRow.push(csvdata[eachRow][1])
                 theRow.push(csvdata[eachRow][2])
                 theRow.push(csvdata[eachRow][3])
                 theRow.push(csvdata[eachRow][4])
                 theRow.push(csvdata[eachRow][5])
                 theRow.push(csvdata[eachRow][6])
                 theRow.push(csvdata[eachRow][7])
                 theRow.push(csvdata[eachRow][8])
                 theRow.push(csvdata[eachRow][9])
                 theRow.push(csvdata[eachRow][10])
                 theRow.push(csvdata[eachRow][11])
                 theRow.push(csvdata[eachRow][12])
                 theRow.push(csvdata[eachRow][13])
                 theRow.push(csvdata[eachRow][14])
                 theRow.push(csvdata[eachRow][15])
                 theRow.push(csvdata[eachRow][16])
                 theRow.push(csvdata[eachRow][17])
                 theRow.push(csvdata[eachRow][18])
                 theRow.push(csvdata[eachRow][19])
                 theRow.push(csvdata[eachRow][20])
                 theRow.push(csvdata[eachRow][21])
                 newOrders.push(theRow)
              }
        }
   }

  }
  Logger.log(newOrders)
    SpreadsheetApp.getActiveSpreadsheet().getSheetByName(sheetName).getRange(2,1, newOrders.length, newOrders[0].length).setValues(newOrders)

  }

Вторая - моя текущая попытка создания группировки. До сих пор мне удалось вырваться за месяц, но когда дело доходит до суммирующей части, все идет не так.

function importData() {
 var sheet_atlas = SpreadsheetApp.getActive().getSheetByName('sheet name');
 sheet_atlas.getRange('L2:AA60000').clearContent();
 var sheetName = "sheet name"

 var threads = GmailApp.search("attachment_name")
 var msgs = GmailApp.getMessagesForThreads(threads);
 var newData = [];

  for (var i = 0 ; i < msgs.length; i++) {
   for (var j = 0; j < msgs[i].length; j++) {
     var attachments = msgs[i][j].getAttachments();
     var bodyEmail = msgs[0][0].getBody();

     var regExp = new RegExp('a href="(.*?)"', "gi");
     var url = regExp.exec(bodyEmail)[1];
     Logger.log(url)
     var decode = new XML('<d>' + url + '</d>');
     var strDecoded = decode.toString()
     var response = UrlFetchApp.fetch(strDecoded).getContentText();
     var csvdata = Utilities.parseCsv(response)
     var newOrders = []
     //Logger.log(csvdata)
     var currMonth = "";
     var theRow = [];
     var columns = 11;
     var formattedMonth = "";
     for (var eachRow in csvdata){
       //for(var col1 in csvdata[8]){
         //if(csvdata[8][col1] == 'Campaign Name'){ var campaignCol = col1 }

         //else if(csvdata[8][col1] == 'Publisher Name'){ var publisherCol = col1 }

         //else if(csvdata[8][col1] == 'Statistics Date'){ var dateCol = col1 }

       //}
         //Logger.log(dateCol)
         //Logger.log(publisherCol)
         //Logger.log(campaignCol)

       if (eachRow>8)
       {
                var date = csvdata[eachRow][2].split("-")
                var month = date[0]
                if((currMonth != "") && (month.localeCompare(currMonth) != 0)) {
                    theRow[2] = formattedMonth
                    newOrders.push(theRow)
                    theRow = []
                    currMonth = month
                 for (var ci = 0; ci < columns; ci++){
                    // Reset data structure
                    theRow.push("0")
                  }
                }

                formattedMonth = date[0] + "-" + date[2]

                for(var cy = 0; cy < columns; cy++) {
                    if(cy != 2){
                        // Sum the columns
                        theRow[cy] = parseFloat(theRow[cy]) + parseFloat(csvdata[eachRow][cy])
                    }
                }
        }
   }
   // Pushing final row
   Logger.log(formattedMonth)  
   newOrders.push(theRow)

  }
  Logger.log(newOrders)
SpreadsheetApp.getActiveSpreadsheet().getSheetByName(sheetName).getRange(2,12, newOrders.length, newOrders[0].length).setValues(newOrders)

  }
}

Спасибо заранее и дайте мне знать, если что-то нужно уточнить!

  • 0
    Пожалуйста, смотрите Как создать минимальный, полный и проверяемый пример . Вы должны стремиться сократить свой код до максимально простого, чтобы продемонстрировать свою проблему - группировка дат по месяцам должна быть не более пары строк кода, независимо от того, рассматриваются ли они как строки или объекты Date. Вы также должны предоставить пример ввода с ожидаемым результатом.
Теги:
csv
date
google-apps-script
grouping

1 ответ

0

Не ответ, поскольку вы не предоставили достаточной информации, но некоторые намеки на то, где все может пойти не так.

Вы действительно должны использовать полуколонны для завершения выражений, кто бы ни оставил вам этот код для поддержания необходимости напоминать об их обязательствах перед другими.

Одна из проблем в вашем коде заключается в том, что currMonth является пустой строкой:

var currMonth = "";

...

   if (eachRow > 8)
   {
        var date = csvdata[eachRow][2].split("-")
        var month = date[0]

        // This expression must always return false since currMonth == ""
        if((currMonth != "") && (month.localeCompare(currMonth) != 0)) {
                theRow[2] = formattedMonth
                newOrders.push(theRow)
                theRow = []

                // this statement expression will never be executed,
                // so currMonth remains an empty string
                currMonth = month
             for (var ci = 0; ci < columns; ci++){
                // Reset data structure
                theRow.push("0")
              }
            }

Также смотрите:

for (var eachRow in csvdata){

    if (eachRow>8)

предположительно eachRow является строкой, сравнивая ее с номером с помощью > всегда будет возвращать false, если Number(eachRow) не возвращает число (например, он будет правильно оценивать, если eachRow - строка типа "12" или "6", но не строка как "2017-08-28").

Вам нужно предоставить образец для csvdata и вывод, который вы ожидаете от его обработки.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню