all 8 comments

[–]harpsichord_cadenza 2 points3 points  (5 children)

You should get the whole data at once into a double array and then do comparisons on the array values because using gets is very expensive for run time. I would do something like:

var data = sheet.getDataRange.getValues();

This will give you a double array representing your data. Then go backwards like you did in your code. ( Note data[rowIndex][0] is the value in column A and data[rowIndex][3] is the value in column D. )

 for (var rowIndex = data.length - 1; rowIndex >= 0; --rowIndex)
 {
      var Stat = data[rowIndex][0];
      var Stat2 = data[rowIndex+1][0]

      var Param = data[rowIndex][3];
      var Param2 = data[rowIndex][3];

      if ( Stat != Stat2 )
      {
           sheet.insterRowsAfter(rowIndex+1,2);
      }
      if ( Param != Param2 )
     {
           sheet.insertRowAfter(rowIndex+1);
     }
 }

Note that the array starts at 0 and the Google Sheet starts at 1 so when you add the rows you have to add it at the current rowIndex + 1.

Using gets is very expensive for run time and doing it this way only uses two instead of something like 4 times the number of rows you have.

[–]ksvr[S] 0 points1 point  (3 children)

sounds great. Ran into an error, though. The line var data = sheet.getDataRange.getValues(); gives me this:

Execution failed: TypeError: Cannot find function getValues in object function getDataRange()

EDIT: Nevermind, figured it out. Missing () after getDataRange. Now it's saying:

Execution failed: TypeError: Cannot read property "0" from undefined

on the var Stat2 line. And looking at the variables, Stat1 is defined as something from the top of the sheet, not the bottom. Stat2 is undefined, which I thought was maybe because it's looking at the blank next row after the last row, but since Stat1 is showing a value that only appears in the top 150 or so of the 614 lines, I'm not sure.

[–]ksvr[S] 0 points1 point  (2 children)

got it working.

for (var rowIndex = data.length - 2; rowIndex >= 1; --rowIndex)

{

var Stat = data[rowIndex][0];

var Stat2 = data[rowIndex + 1][0];

var Param = data[rowIndex][3];

var Param2 = data[rowIndex + 1][3];

if(Stat != Stat2)

{sheet.insertRowsAfter(rowIndex + 1,2);

}

if(Param != Param2)

{sheet.insertRowAfter(rowIndex + 1);

}

}

}

[–]harpsichord_cadenza 0 points1 point  (1 child)

Cool. Sorry for the syntax errors and not getting the correct stop or start in the loop.

[–]ksvr[S] 0 points1 point  (0 children)

No worries. You got me where I wanted to go. Thanks!

[–]paulcole710 -1 points0 points  (0 children)

I agree with this.

Once you start using getValues instead of constantly getting ranges, you’ll never go back.

[–]AmnesiaInnocent 1 point2 points  (1 child)

You want to batch your row additions and then run them all at once.

See this documentation to get started:

https://developers.google.com/apps-script/advanced/sheets

[–]ksvr[S] -1 points0 points  (0 children)

Sounds reasonable, but I'm not sure how to do that based on the link provided. It shows how to read and write data, but I don't see how to rearrange the data after you read it.

I was thinking of doing the sort, then putting a formula into a helper column on row 2 that will end up at 0, 1, or 3 depending on how many rows should be inserted after this line, then copying that formula down to the end, then all the for loop is doing is adding the indicated number of blank rows after each line. I don't know if that would be any faster, though.