setActiveCell on all sheets within a spreadsheet.

2020-04-19 07:59发布

问题:

I have a Google spreadsheet with multiple sheets. I would like the cursor to be set to a particular cell onOpen for all tabs. Each cell of the first row represents a week of the year, start to finish, for the whole year. I've written some code to have that particular column (week of the year) preselected on row 5 when opening.

Currently, only the last sheet has the cell selected that I want. This is because setActiveCell can only be used for one cell at a time I guess. I have also tried setActiveRange and setActiveSelection to no avail.

I found a question from years ago Here, but the solution does not work for me. Perhaps something has changed since then.

Here is my code:

function onOpen() {
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  Date.prototype.getWeek = function() {
    var onejan = new Date(this.getFullYear(),0,1);
    return Math.ceil((((this - onejan) / 86400000) + onejan.getDay()+1)/7);
  }
  var now = new Date();
  var weekNum = now.getWeek(); 
  var sheets = ss.getSheets();
  for(var i = 0; i < sheets.length; i++) {
    var newRange = sheets[i].getRange(5,weekNum + 1);      
    sheets[i].setActiveCell(newRange);
  }
}

Within the link I provided above, I've tried variances of all of the given solutions, but my code was never exactly the same because I wasn't looking for the exact same things as the OP. For example, using Jacob Jan Tuistra's latest code solution, I came up with:

function setCursor() {
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  Date.prototype.getWeek = function() {
    var onejan = new Date(this.getFullYear(),0,1);
    return Math.ceil((((this - onejan) / 86400000) + onejan.getDay()+1)/7);
  }
  var now = new Date();
  var weekNum = now.getWeek(); 
  ss.getSheets().forEach(function (sheet, weekNum) {
  Logger.log(weekNum);
      sheet.setActiveRange(sheet.getRange(5,weekNum+1));
    });
}

Which also only set the last sheet

回答1:

Looks like you need to make a call to SpreadsheetApp.flush() when you loop over the sheets collection:

function onOpen() {
  SpreadsheetApp.getActive().getSheets().forEach(function (s) {
    s.setActiveSelection("B4");
    SpreadsheetApp.flush(); // Force this update to happen
  });
}

My guess is Apps Script's execution engine optimizes the writes to a single call, and in that single call only one active selection can be made. Calling flush forces 1 call per sheet to be updated.