Невозможно скопировать более одного значения при сравнении двух столбцов на двух листах из-за различий в скрипте Google Apps - PullRequest
0 голосов
/ 10 июня 2019

Я создаю сценарий в Google Apps Script, который сравнивает два листа в электронной таблице строка за строкой в ​​определенном столбце, содержащем уникальные идентификаторы. Если A [i] в ​​листе (1) отличается от A [i] в ​​листе (2), я хочу, чтобы вся строка с этой ячейкой была скопирована на новый лист. Листы действительно большие, несколько тысяч рядов.

До сих пор я дошел до того, что сценарий копирует значение один раз, а затем продолжает цикл без дальнейших результатов. Кроме того, это занимает много времени, и я подозреваю, что это может быть очень неоптимальным. Мне очень сложно отлаживать в Google Apps Script, и я в конце концов. Вот что у меня есть и мои комментарии.

function compareSheetDrop(input) {

    var ss = SpreadsheetApp.getActiveSpreadsheet();

    //create a new blank sheet where the output will be stored
    ss.insertSheet(5);

    /*create references to sheets used by the script. 
    dropSheet is the sheet used as a basis, 
    compareSheet is a sheet possibly containing new values, 
    resultSheet is the blank sheet that will store new values
     */
    var dropSheet = ss.getSheetByName("Drop (2)");
    var compareSheet = ss.getSheets()[4];
    var resultSheet = ss.getSheets()[5];

    /*loop over the entire dropSheet and look for differences. 
The sheets have header rows*/
    for (var i = 2; i <= dropSheet.getLastRow(); i++) {

        /*variable j will represent the row number 
        where the difference will be pasted to 
        resultsSheet.A[j] etc.*/
        var j = 1;

        /*establish references to the cells 
        that will be used for comparison 
        (i.e. A[i] in dropSheet, A[i] in compareRange)*/
        var dropRange = dropSheet.getRange(i, 1);
        var compareRange = compareSheet.getRange(i, 1);

        /*establish references to the row 
        that will be copied from compareSheet 
        and to the row that 
        will be the destination in resultsSheet*/
        var resultRange = resultSheet.getRange(j, 1);
        var entireRow = compareSheet.getRange(i, 1);

        /*check if the unique value of 
        cell dropSheet.A[i] is different from 
        compareSheet.A[i] and whether they are not blanks. 
        If they are different, 
        copy entire row from compareSheet to the resultsSheet*/
        if (dropRange.getValues()[0] !== compareRange.getValues()[0] && dropSheet.getRange(i, 1).isBlank() == false && compareSheet.getRange(i, 1).isBlank() == false) {
            j++;
            entireRow.copyTo(resultRange, SpreadsheetApp.CopyPasteType.PASTE_NORMAL, false);
        }
    }
}

Я ожидаю, что resultSheets будет полон строк из CompareSheet, которых нет в dropSheet, но вместо строки я заполняю одну ячейку A1, и тогда ничего не происходит, пока скрипт еще работает. Я подозреваю, что проблема может быть в самом цикле и в copyTo, но я не могу найти причину.

Ответы [ 2 ]

0 голосов
/ 10 июня 2019

Попробуйте это:

function copyRowWhenAsDontMatch() {
  var ss=SpreadsheetApp.getActive();
  var sh1=ss.getSheetByName('Sheet1');
  var rg1=sh1.getRange(2,1,sh1.getLastRow()-1,sh1.getLastColumn());
  var vA1=rg1.getValues();
  var sh2=ss.getSheetByName('Sheet2');
  var rg2=sh2.getRange(2,1,sh2.getLastRow()-1,sh2.getLastColumn());
  var vA2=rg2.getValues();
  var sh3=ss.getSheetByName('Sheet3');//rows that dont match in sheet1
  sh3.clear();
  var sh4=ss.getSheetByName('Sheet4');//rows that dont match in sheet2
  sh4.clear();
  for(var i=0;i<vA1.length;i++) {
    if(vA1[i][0]!=vA2[i][0]) {
      sh3.appendRow(vA1[i]);
      sh4.appendRow(vA2[i]);
    }
  }
}
0 голосов
/ 10 июня 2019

Если вы сравниваете только первые столбцы каждого листа, вы можете использовать метод getSheetValues(startRow, startColumn, numRows, numColumns), чтобы получить значения, не проверяя каждую ячейку относительно друг друга. Когда вы получите листы, вы должны получить их так:

var dropSheet = ss.getSheetByName("Drop (2)").getSheetValues(1,1,x,1);
var compareSheet = ss.getSheets()[4].getSheetValues(1,1,x,1);

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

Этот вопрос имеет хороший пример того, как получить диапазон строк: Сценарий Google выбирает всю строку в таблице Google

Ссылка на документацию электронной таблицы на случай, если есть какие-либо сомнения относительно методов: https://developers.google.com/apps-script/reference/spreadsheet/spreadsheet#getsheets

...