Добавьте новые записи в последнюю пустую строку (вместо того, чтобы игнорировать последние пустые строки и добавлять новую строку в конце листа)

#google-apps-script #google-sheets #google-sheets-formula

#google-приложения-скрипт #google-таблицы #google-таблицы-формула

Вопрос:

У меня есть этот скрипт, он работает нормально. Но он игнорирует пустые строки после последней строки записи на листе. Вместо этого он добавляет совершенно новую строку в конец листа для новой добавляемой записи. Например: у меня есть лист с 1000 строками. В данном случае есть только записи до строки 25. Итак, что он делает… он добавляет / добавляет новую запись в строку 1001 вместо добавления ее в пустую строку после последней записи, т. е. строки 26.

Вот ссылка на фиктивный лист: https://docs.google.com/spreadsheets/d/1mt9G9PWdIvAQsQSWmRb14o8eeocCx9gkOWJT6KHAGa0/edit?usp=sharing

 function appendUniqueRows() {
      var ss = SpreadsheetApp.getActive();
      var sourceSheet = ss.getSheetByName('source');
      var destSheet = ss.getSheetByName('destination');
    
      var sourceData = sourceSheet.getRange("A:D").getValues();
      var destData = destSheet.getRange("E:H").getValues();
    
      //Check whether destination sheet is empty
    if (destData.length === 1 amp;amp; "" === destData[0].join('')) {
      // Empty, so ignore the phantom row
        destData = [];
      }
    
      // Generate hash for comparisons
      var destHash = {};
      destData.forEach(function(row) {
        destHash[row.join('')] = true; // could be anything
      });
    
      // Concatentate source rows to dest rows if they satisfy a uniqueness filter
      var mergedData = destData.concat(sourceData.filter(function (row) {
        var hashedRow = row.join('');
        if (!destHash.hasOwnProperty(hashedRow)) {
          // This row is unique
          destHash[hashedRow] = true;   // Add to hash for future comparisons
          return true;                  // filter -> true
        }
        return false;                   // not unique, filter -> false
      }));
    
      // // Check whether two data sets were the same width
      // var sourceWidth = (sourceData.length > 0) ? sourceData[0].length : 0;
      // var destWidth = (destData.length > 0) ? destData[0].length : 0;
      // if (sourceWidth !== destWidth) {
      //   // Pad out all columns for the new row
      //   var mergedWidth = Math.max(sourceWidth,destWidth);
      //   for (var row=0; row<mergedData.length; row  ) {
      //     for (var col=mergedData[row].length; col<mergedWidth; col  )
      //       mergedData[row].push('');
      //   }
      // }
    
      // Write merged data to destination sheet
      destSheet.getRange(1, 5, mergedData.length, mergedData[0].length)
               .setValues(mergedData);
    }
 

Ответ №1:

Я полагаю, что ваша цель заключается в следующем.

  • Вы хотите добавить отфильтрованные sourceData в следующую строку последней строки destData .

Я думаю, что причина вашей проблемы связана с var mergedData = destData.concat(sourceData.filter(function (row) { . В этом случае отфильтрованное sourceData добавляется в destData оф var destData = destSheet.getRange("E:H").getValues(); . destSheet.getRange("E:H").getValues() включает в себя пустые строки. Итак, в этом случае, как насчет следующей модификации?

От:

 var sourceData = sourceSheet.getRange("A:D").getValues();
var destData = destSheet.getRange("E:H").getValues();
 

Для:

 var sourceData = sourceSheet.getRange("A1:D"   sourceSheet.getLastRow()).getValues();
var destData = destSheet.getRange("E1:H"   destSheet.getLastRow()).getValues();
 

или

От:

 var mergedData = destData.concat(sourceData.filter(function (row) {
 

Для:

 var mergedData = destData.filter(row => row.join('')).concat(sourceData.filter(function (row) {
 

Примечание:

  • Когда учитывается стоимость процесса, я думаю, что 1-я модификация будет подходящей.