简体   繁体   中英

Google-Script GetRange Multiplying instead of Adding?

I have a code which should input a calendar event then insert a note into the cell saying "Inputted". This part works, but only to an extent.

If I have more than one event (on separate lines), it will say "Input" as I want on the first one. But for others, it then creates a note 10 rows down instead of 1. Looking at my code, I can't see anything that would cause it to do this - as the calendar events are created perfectly. I believe it lies in the var Comment section - but there's no multiplication there!

Can anyone see where I'm going wrong?!

  function CalendarInput() {

      var sheet = SpreadsheetApp.getActiveSheet();

       var startRow = 2;  // First row of data to process
      var numRows = 3;   // Number of rows to process
      var dataRange = sheet.getRange(startRow, 1, numRows, 26); //What data will be used
      var data = dataRange.getValues();
      var cal = CalendarApp.getDefaultCalendar(); //Gets the correct calendar
    for (i in data) {
      var row = data[i];
      var title = row[2];  // Column with Title
      var desc = row[8];       // Column with Description
      var date = row[3];   //Column with Date
      var edate = row[4] //Column with end date
      var loc = row[9];    //Column with Location
      var invite = row[11] //Column with Invite List
      var sent = row[12] //Check Sent
      var check = row[7]
      var Comment = sheet.getRange(i+startRow, 7).setNote("Inputted")


              cal.createAllDayEventSeries(title, new Date(date), CalendarApp.newRecurrence().addDailyRule().until(new Date(edate)), {description:desc,location:loc,guests:invite})

There are documented warnings about the use of for..in to loop over Arrays, see this Description on MDN for example.

The problem you're seeing is being caused by the way for..in works in apps-script.

Demo Code

This test function will demonstrate what's going on when you .setComment() on row i + startRow :

function test() {
  var data = [ [2,3,4,5],[5,4,3,2],[6,7,8,9],[9,8,7,6] ];
  var startRow = 2;
  var i;

  Logger.log("for (var i in data)");
  for (i in data) {
    Logger.log( i + startRow );
  }
  Logger.log(typeof i);

  Logger.log("for (var i = 0; i < data.length ; i++)");
  for (i = 0; i < data.length ; i++) {
    Logger.log( i + startRow );
  }
  Logger.log(typeof i);
}

Logging Output

[13-06-01 22:41:10:046 EDT] for (var i in data)
[13-06-01 22:41:10:046 EDT] 02
[13-06-01 22:41:10:046 EDT] 12
[13-06-01 22:41:10:046 EDT] 22
[13-06-01 22:41:10:046 EDT] 32
[13-06-01 22:41:10:047 EDT] string

[13-06-01 22:41:10:047 EDT] for (var i = 0; i < data.length ; i++)
[13-06-01 22:41:10:047 EDT] 2.0
[13-06-01 22:41:10:047 EDT] 3.0
[13-06-01 22:41:10:047 EDT] 4.0
[13-06-01 22:41:10:047 EDT] 5.0
[13-06-01 22:41:10:047 EDT] number

What's happening?!

When the for..in loop is used, the looping variable i is a string - The looping variable i is of type String - and so you get string behavior for operators like + . When i + startRow is executed, startRow is coerced to a string, then is concatenated to i , which was already a string.

On the other hand, in the for loop, the same statement results in a mathematical operation, since both operands are of type number.

Don't use for..in for Array operations

It's short, it often works, but break the habit.

Use this instead:

for (var i = 0; i < data.length ; i++) {
  ...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM