Скрипт листов Google - убирает лишние данные из второй строки и добавляет их в первую строку - PullRequest
0 голосов
/ 17 октября 2018

Я пытаюсь создать скрипт в скрипте листов Google, который будет перебирать лист, строка за строкой, и если в первой ячейке этой строки встречается идентификационный номер, идентичный указанному выше, онизвлекает данные из каждой ячейки, кроме столбцов A и B, и добавляет их к строке выше.В идеале это будет работать с неопределенным числом дубликатов идентификаторов строк, может быть 2, может быть 3, может быть 4.

После удаления данных, которые я хочу сохранить (например, столбцы C и далее), язатем хочу удалить все содержимое обработанной строки идентификатора-дубликата, но я просто не включил это в свой скрипт до тех пор, пока он не скопирует данные правильно.

В этом примере строки листа 6, 7 и 8имеют идентичные идентификационные номера (столбец A)

enter image description here

Вот результат, который я пытаюсь получить:

enter image description here

И вот результат, который я получаю:

enter image description here

Я пробовал несколько различныхпути, и разорвали и перестроили мой сценарий пару раз, не получив желаемого результата:

function stripMiner() {
  var ss = SpreadsheetApp.openById("1WDPoTICQvdruxfhAwHLtA51fz05DqyZ-NhNfpAyPO6Y");
  var mainSheet = ss.getSheetByName("Main");
  var startRow = 5;
  var numRows = mainSheet.getLastRow();//obtains the last row in the sheet
  var setrgh = mainSheet
  var dataRange = mainSheet.getRange(startRow, 1,4,120); //rowStart, columnStart, row count, column count, the columncount needs to be large enough to encompass all your ancillary data
  var data = dataRange.getValues();
  var iter = 0;
  var maxItRow = 4;
  var prevIdNum = 0;
  var dupCount = 1;
  var cc1 = "P5"; //Cells to dump check values into
  var cc2 = "P6";
  var dumpRow = startRow;
  //if (numRows >= maxItRow){var maxIter = maxItRow;}

  for (i in data){
    if (iter != maxItRow){ //making sure we haven't gone over the iteration limit
      var row = data[i];
      var idNum = (row[0]);
      var jCount = 0; //resets icount if the id number is different icount is used to skip some cells in a row

      if (idNum == prevIdNum){//only proceed if we've hit another line with the same ID number
        dupCount = +1; //increment the dupcount value
        mainSheet.getRange(cc2).setValue("dupCount"+dupCount); //dupcount check value
        var rowIterStart = 5; //RowIterStart is used to add to rowiter, EG if your data is 20 columns wide, and you start transposing from column 4, then this will want to be about 17
        var rowIter = 1;
        for (j in row){
          if (jCount >= 2){ //the integer here is the column where it will begin to transpose data
            mainSheet.getRange(dumpRow-1,(rowIterStart*dupCount)+(rowIter)).setValue(row[j]); //startRow+(iter-dupCount)

            mainSheet.getRange(cc1).setValue("dumprow"+dumpRow);
          }
          rowIter+=1;
          jCount +=1;
        }
      }
      else{
        var dupCount = 1;

        dumpRow +=1;
      }
      prevIdNum = (row[0]); //sets the most recently processed rows ID number 
    }
    iter +=1;
  }
}

Я не совсем уверен, где я иду не так.У кого-нибудь есть предложения?Спасибо!

(Кроме того, я еще новичок в этом вопросе, поэтому, если я упустил что-то очевидное или выбрал неправильный подход, прошу прощения!)

Ответы [ 2 ]

0 голосов
/ 10 декабря 2018

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

enter image description here

и превратить их в нечто вроде этого:

enter image description here

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

function stripMiner() {
  var ss = SpreadsheetApp.openById("1WDPoTICQvdruxfhAwHLtA51fz05DqyZ-NhNfpAyPO6Y");
  var mainSheet = ss.getSheetByName("Main");
  var startRow = 5;
  var numRows = mainSheet.getLastRow();//obtains the last row in the sheet
  var setrgh = mainSheet
  var dataRange = mainSheet.getRange(startRow, 1,3,120); //rowStart, columnStart, row count, column count, the columncount needs to be large enough to encompass all your ancillary data
  var data = dataRange.getValues();
  var iter = 0;
  var maxItRow = 4;
  var prevIdNum = 0;
  var dupCount = 1;
  var cc1 = "P5"; //Cells to dump check values into
  var cc2 = "P6";
  var dumpRow = startRow;
  //if (numRows >= maxItRow){var maxIter = maxItRow;}

  for (i in data){
    if (iter != maxItRow){ //making sure we haven't gone over the iteration limit
      var row = data[i];
      var idNum = (row[0]);
      var jCount = 0; //resets icount if the id number is different icount is used to skip some cells in a row

      if (idNum == prevIdNum){//only proceed if we've hit another line with the same ID number
        dupCount = +1; //increment the dupcount value
        mainSheet.getRange(cc2).setValue("dupCount"+dupCount); //dupcount check value
        var rowIterStart = 5; //RowIterStart is used to add to rowiter, EG if your data is 20 columns wide, and you start transposing from column 4, then this will want to be about 17
        var rowIter = 1;
        for (j in row){
          if (jCount >= 2){ //the integer here is the column where it will begin to transpose data
            mainSheet.getRange(dumpRow-2,(rowIterStart*dupCount)+(rowIter)).setValue(row[j]); //startRow+(iter-dupCount)

            mainSheet.getRange(cc1).setValue("dumprow"+dumpRow);
          }
          rowIter+=1;
          jCount +=1;
        }
      }
      else{
        var dupCount = 1;

        dumpRow +=1;
      }
      prevIdNum = (row[0]); //sets the most recently processed rows ID number 
    }
    iter +=1;
  }
}

Надеюсь, кто-то еще, кто хочет сделать подобное, может использовать это тоже.

0 голосов
/ 21 октября 2018

Результаты для кода спрашивающего в случае скопированных данных возникают из-за извилистой петли.По сути, несмотря на то, что дубликаты были идентифицированы, произошел неправильный подсчет для назначения скопированных данных правильному rowID.Что касается очистки данных, то никаких резервов не было.

Следующий код работает для достижения целей спрашивающего, хотя и далек от совершенства.

В настоящее время пересчет «последнего столбца» после копирования каждого дубликата является абсолютным, а не основанным на строках числом.Таким образом, если будет обнаружен дубликат, скажем, для ID = 3, данные будут скопированы в столбец 12, а не в столбец 6. Для этого требуется добавить простой счетчик строк dupID.

Второй фактор - этовычисление последнего столбца в электронной таблице.
var dataRange = mainSheet.getRange(startRow, 1,Rowlast+1,120);
Опрашивающий использовал 120 столбцов;и я сохранил это число просто ради последовательности.Спрашивающий должен повторно оценить, является ли это чрезмерным.


function ejb_so_5284922701() {

    var ss = SpreadsheetApp.openById("<<  insert questioners spreadsheet ID>>");
    var mainSheet = ss.getSheetByName("<< insert questioner's sheet name >>");

    var startRow = 5;

    // calculate the last row containing data
    var Rowvals = ss.getRange("A5:A").getValues();
    var Rowlast = Rowvals.filter(String).length; //6
    Logger.log("last row = " + Rowlast); // DEBUG


    // calculate the last column containing data
    var cell = mainSheet.getRange("A5"); //or however you determine "cell"
    var drCol = mainSheet.getDataRange().getLastColumn();
    Logger.log('getLastColumn = ' + drCol); //DEBUG
    for (var i = drCol; i >= 1; i--) {
        if (mainSheet.getRange(cell.getRow(), i).getValue() != "") {
            break;
        }
    }
    var lastColumn = i;
    Logger.log("Last column  with data = " + lastColumn); //DEBUG



    var setrgh = mainSheet

    // numColumns neds to be reviewed 
    var dataRange = mainSheet.getRange(startRow, 1, Rowlast + 1, 120); //rowStart, columnStart, row count, column count, the column count needs to be large enough to encompass all your ancillary data
    // start row = 5, 1= column A, 4, rows, 120, columns
    Logger.log("startRow = " + startRow + ", and the datarange = " + dataRange.getA1Notation()); //DEBUG

    var data = dataRange.getValues();
    Logger.log("length of data =" + data.length); //DEBUG


    var lastid = 0;

    for (i = 0; i < data.length; i++) {
        if (i == 0) {
            // if this is the first row, then assign anything but zero to last id
            lastid = 100;
            Logger.log(" this is the first row; set last id to 100");
        }

        var thisid = data[i][0];

        // evaluate whether this is a duplicate ID
        if (thisid == lastid) {

            // this is a dup
            Logger.log("i=" + i + ". This is a dup" + ", name is " + data[i][2]); //DEBUG
            var stufftocopyrange = mainSheet.getRange(startRow + i, 3, 1, 3);
            var stufftocopy = stufftocopyrange.getValues();
            Logger.log("the range to copy is " + stufftocopyrange.getA1Notation()); //DEBUG
            var targetrange = mainSheet.getRange(startRow + lastid - 1, lastColumn + 1, 1, 3);
            targetrange.setValues(stufftocopy);
            lastColumn = lastColumn + 3;
            var duprange = mainSheet.getRange(startRow + i, 1, 1, 5);
            Logger.log("the range to clear is " + duprange.getA1Notation()); //DEBUG
            duprange.clearContent();

        } else {
            // no dup

            //assign lastid value
            var lastid = thisid;
            Logger.log("i=" + i + ". No dup. Last id set to " + lastid); // DEBUG

        } // if

    } // end for loop

}

ДО
enter image description here


ПОСЛЕ

enter image description here

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...