Google表格脚本-从第二行中删除多余的数据,然后将其添加到第一行

时间:2018-10-17 07:15:43

标签: javascript google-apps-script google-sheets

我正在尝试在Google表格脚本中构建一个脚本,该脚本将逐行向下迭代一个工作表,如果该行的第一个单元格中的ID编号与该行上方的ID相同,则该脚本会从除列A和B之外的每个单元格中删除数据,并将其附加到上面的行。理想情况下,此方法适用于不确定数量的重复行ID,可能为2,可能为3,可能为4。

除去要保留的数据(例如,C列及以后的列)后,然后我想删除已处理的重复ID行的全部内容,但是直到复制后我才将其放入脚本中数据正确。

在此示例中,工作表第6、7和8行具有相同的ID号(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 :(得分:0)

在复制数据的情况下,发问者代码的结果来自复杂的循环。从本质上讲,尽管识别出重复项,但存在计数错误,无法将复制的数据分配给正确的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

答案 1 :(得分:0)

先前发布的解决方案并没有完全达到我需要的结果,但是我设法将一些对我有用的东西拼凑在一起。它希望以以下格式查看数据:

enter image description here

将其变成这样:

enter image description here

在使用重复ID号(重复次数不确定)的情况下,仅从重复行中提取某些数据列并将其追加到第一行。

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;
  }
}

希望其他人也可以做类似的事情。