-1

I am trying to randomise a set of increments over a large number of variables.

So for example, I have 5,000 people, each of these people has a base value of 1, but adding 1 has a variable affect to each of these people. Example adding 1 to Person A, means there base number increments by 1.1. Adding 1 to person b increments their base by 1.4 and so on.

I have figured out how to do the different values assigned to each +1 action with vlookups, but I now need to loop the +1 increments through the range.

I have base values setup in column B:B but can't figure out how to loop the script. This is what I have so far:


    function increment(){
   var ss = SpreadsheetApp.getActiveSpreadsheet();
   var sheet = ss.getSheets()[1];
  
  

  var range = sheet.getRange("b1");
   var value = range.getValue(); 

  for (var i = 1; i >= range; i++);
  
   range.setValue(value + 1);
  
}

But this only increments 1 to "b1". How do I loop it so it runs continously, say every second through b1, b2, b3, b4 etc adding +1 each time?

TheMaster
  • 45,448
  • 6
  • 62
  • 85

1 Answers1

1

Simply by adding range name using "b" + i in getRange() function, and move it into for loop.
Or you can use offset() function instead.

the code

for (var i = 1; i >= range; i++);
    range.setValue(value + 1);

is loop without running the command range.setValue(value + 1); because first line was ending with semi-colon.

Finally, the code should be as below.

function increment()
{
    var ss = SpreadsheetApp.getActiveSpreadsheet(); 
    var sheet = ss.getSheets()[1];
    //var range = sheet.getRange("b1"); 
    //var value = range.getValue();

    // change 5000 to amount of you need
    for (var i = 1; i <= 5000; i++)
    {
        var range = sheet.getRange("b" + i); 
        var value = range.getValue();
        range.setValue(value + 1);
    }
}

if using offset function code would be as below.

function increment()
{
    var ss = SpreadsheetApp.getActiveSpreadsheet(); 
    var sheet = ss.getSheets()[1];
    var range = sheet.getRange("b1"); 
    //var value = range.getValue();

    // change 5000 to amount of you need
    for (var i = 1; i <= 5000; i++)
    {
        var value = range.offset(i, 0).getValue();
        range.offset(i, 0).setValue(value + 1);
    }
}

Edit for improve execute time

function increment()
{
    var ss = SpreadsheetApp.getActiveSpreadsheet(); 
    var sheet = ss.getSheets()[1];

    // change 5000 to amount of you need
    var formulas = new Array(5000);

    for (var i = 0; i < 5000; i++)
    {
        formulas[i] = "=R[0]C[-1]+1";
    }

    // Assume that column C is not used
    var ranges = sheet.getRange("C1:C5000");
    ranges.setFormulasR1C1(formulas)
    ranges.copyValuesToRange(sheet, 2, 2, 1, 5000);
    ranges.clearContent();
}
  • Hey Adisak. Firstly massive thanks for your help with this. Your script looks great and runs well for the most part. There are a couple of problems though. 1, when it reaches 4,401, Apps script throws up an error saying "reached maximum execution time." and stops the script. Not sure how to get around this? – Paul Allen Oct 10 '15 at 11:41
  • Second part is just probably to do with my lack of knowledge. I tried to reduce the number to 4000 so I at least get a good chunk done. But when it reaches the end of this execution, it just stops. How do I get it to start again? Thanks again for your help. You're a star! – Paul Allen Oct 10 '15 at 11:49
  • Hmm. Think I might have resolved it. Can run it to 4390. (This takes about 5 mins) and then add trigger set to 5mins. :) Testing... – Paul Allen Oct 10 '15 at 11:58
  • Take a look at this link http://stackoverflow.com/questions/7854573/exceeded-maximum-execution-time-in-google-apps-script but it is more complicated. – Adisak Anusornsrirung Oct 10 '15 at 12:01
  • Hmm. Ok, that doesn't seem to be the most stable as the triggers run at different times. I looked up similar issues and this code seems to address it, but I can't seem to get to work. Ideas? – Paul Allen Oct 10 '15 at 12:10
  • var startRow = ScriptProperties.getProperty("start_row"); for(var ii = startRow; ii <= size; ii++) { var currTime = (new Date()).getTime(); if(currTime - startTime >= MAX_RUNNING_TIME) { ScriptProperties.setProperty("start_row", ii) ScriptApp.newTrigger("runMe") .timeBased() .at(new Date(currTime+REASONABLE_TIME_TO_WAIT)) .create(); – Paul Allen Oct 10 '15 at 12:10
  • Ok, not to worry. My previous idea works, I just had to use trigger only. There is a small bit of overlap, but not much and it works for what I need it for. Thanks for your help on this. :) – Paul Allen Oct 10 '15 at 12:29
  • Ya tried the edit there now. I am getting an error with it: Cannot convert Array to Object[][]. (line 16, file "") – Paul Allen Oct 10 '15 at 15:59
  • I was running into issues with the offset code too. Seems it affects the triggers after a while. Have switched back to your first code using the 5 minute trigger and seems to be working perfectly now. – Paul Allen Oct 10 '15 at 16:08