google-apps-scriptarray-combine

How do I combine two rows with a the same identity?


I'm trying to combine 2 rows with the same identity. I've been looking for a solution, but somehow can't find a working solution. I'm trying to make a tracker for my stocks, but I want it to combine the information if I add the same asset. I made a form with which trades can be added to the portfolio. So if there is a duplicate asset, the new duplicate will always be on the last row.

I'm neither an expert in programming or google sheets, but here's the pseudo code:

Here is an example sheet: https://docs.google.com/spreadsheets/d/1AEdljHtXUOnRJ1kxbziqKAjYo5EqGZjjnWOx1mbeTI0/edit#gid=0

I tried several things but I got stuck. I have made a code to go through the data, find the duplicate and add it to a list. But after that I just don't know how to go about it.

You're probably going to laugh at my code, but from a certain point it was just like going round in circles.


function readData() {
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var formSS = ss.getSheetByName("Portfolio");
  var rangeArray = formSS.getRange("B2:B" + formSS.getLastRow()).getValues(); //makes an array of values from column B, but each item  is in array in itself.
  rangeArray = [].concat.apply([],rangeArray);//takes the elements outside their own array;
  var sortedRangeArray = rangeArray.sort();//sort the items to a new array
  duplicates=[];//make a list of duplicates to identify
  for (var i =0; i < 1;sortedRangeArray.length, i++)//iterate through sortedArray
    if(sortedRangeArray[i+1] === sortedRangeArray[i]){
      duplicates.push(sortedRangeArray[i]);//if a duplicate is found, push it to the duplicates list
    }
  var str = duplicates[0];//identify the duplicate, there is only one anyway.
  for (var k = 0; k < sortedRangeArray.length; k++) {
    var row = sortedRangeArray[k];
    if(row[SEARCH_COL_IDX] == str) {
      var index = rangeArray.findIndex(str);//I thought it might help defining the position
}}}``` 


Solution

  • It could be something like this:

    function main() {
      var table = SpreadsheetApp.getActiveSheet().getDataRange().getValues();
    
      var ids = table.map(x => x[1]);     // get array of IDs (column B)
      var row = ids.indexOf(ids.pop());   // find ID from last row in the array
      if (row == -1) return;              // if not found do nothing
    
      var value = table[row][2];          // get value of 3rd cell
      table[row] = table.pop();           // move the last row in current row
      table[row][2] += value;             // add the value to 3rd cell
      table.push(Array(table[0].length)); // add empty row to the table
    
      SpreadsheetApp.getActiveSheet().getDataRange().setValues(table); // put the table back on the sheet
    }
    

    Update

    Since your table contains formulas it needs a slightly another implementation:

    function main() {
      var sheet = SpreadsheetApp.getActiveSheet();
      var table = sheet.getDataRange().getValues();
    
      var ids = table.map(x => x[1]);     // get array of IDs (column B)
      var row = ids.indexOf(ids.pop());   // find ID from last row in the array
      if (row == -1) return;              // if not found do nothing
      
      var last_row = table.pop();
    
      var date  = last_row[0];
      var id    = last_row[1];
      var value = last_row[2] + table[row][2];
    
      sheet.getRange(row+1,1,1,3).setValues([[date,id,value]]);
    
      sheet.getRange(sheet.getLastRow(),1,1,8).clearContent();
    }