问题
I've built a spreadsheet that has 7 sheets, each of which is filled with many rows of data. I got tired of manually scrolling down to the last row of each sheet, so I constructed a simple script function to programmatically find and go to a sheet's last row. This function works, for the most part, when run manually. However, when I tried to execute this function with a "From Spreadsheet, On Open" installed event trigger, it doesn't fire properly.
Here's the function:
function LastRowOnOpen() {
var ss = SpreadsheetApp.getActive();
var sheet = SpreadsheetApp.setActiveSheet(ss.getSheetByName('302 Ashfrd'));
var lastRow = sheet.getLastRow();
lastRow = lastRow + 5;
sheet.getRange(lastRow, 1).activate();
sheet.showSheet();
var sheet = SpreadsheetApp.setActiveSheet(ss.getSheetByName('3220 Blmnt'));
var lastRow = sheet.getLastRow();
lastRow = lastRow + 5;
sheet.getRange(lastRow, 1).activate();
sheet.showSheet();
var sheet = SpreadsheetApp.setActiveSheet(ss.getSheetByName('3302 Blmnt'));
var lastRow = sheet.getLastRow();
lastRow = lastRow + 5;
sheet.getRange(lastRow, 1).activate();
sheet.showSheet();
var sheet = SpreadsheetApp.setActiveSheet(ss.getSheetByName('1035 Bnhm'));
var lastRow = sheet.getLastRow();
lastRow = lastRow + 5;
sheet.getRange(lastRow, 1).activate();
sheet.showSheet();
var sheet = SpreadsheetApp.setActiveSheet(ss.getSheetByName('Deer Park'));
var lastRow = sheet.getLastRow();
lastRow = lastRow + 5;
sheet.getRange(lastRow, 1).activate();
sheet.showSheet();
var sheet = SpreadsheetApp.setActiveSheet(ss.getSheetByName('3000-102 Lrn'));
var lastRow = sheet.getLastRow();
lastRow = lastRow + 5;
sheet.getRange(lastRow, 1).activate();
sheet.showSheet();
var sheet = SpreadsheetApp.setActiveSheet(ss.getSheetByName('2249 Wht'));
var lastRow = sheet.getLastRow();
lastRow = lastRow + 5;
sheet.getRange(lastRow, 1).activate();
sheet.showSheet();
P.S.
I also tried using a for loop containing:
var sheet = SreadsheetApp.setActiveSheet(ss.getSheetByName('2249 Wht'));
var lastRow = sheet.getLastRow();
lastRow = lastRow + 5;
sheet.getRange(lastRow, 1).activate();
sheet.showSheet(); `
varying the sheet = getSheetByname
method to reduce lines of code, however all but the last iteration of the loop was ignored.
回答1:
There isn't a good answer (that I could find) that addresses this topic in full:
The issue with your current script "ignoring" "all but the last iteration of the loop" stems from Google's own internal optimizations of the Spreadsheet Service:
Scripts commonly need to read in data from a spreadsheet, perform calculations, and then write out the results of the data to a spreadsheet. Google Apps Script already has some built-in optimization, such as using look-ahead caching to retrieve what a script is likely to get and write caching to save what is likely to be set.
In other words, your script is analyzed and effectively only the last activate
call is determined to be needed. To counter this, we use SpreadsheetApp.flush() and Utilities.sleep, as done here.
function onOpen(e) { // "Simple Trigger" from reserved function name.
// https://developers.google.com/apps-script/guides/triggers/events#open
scrollAll(e.source);
}
function scrollAll(wb) {
(wb ? wb : SpreadsheetApp.getActive()).getSheets().forEach(
function (sheet) {
wb.setActiveSheet(sheet).setActiveSelection("A" + sheet.getLastRow());
SpreadsheetApp.flush();
Utilities.sleep(1000); // may need to be adjusted
});
}
function scrollActive() { // Macro target
const s = SpreadsheetApp.getActiveSheet();
s.setActiveSelection("A" + s.getLastRow());
}
To have a keyboard shortcut to re-scroll the current sheet to the bottom, you would include the following in your project's manifest file to bind the scrollActive
function as a macro with a keyboard shortcut:
"sheets": {
"macros": [{
"menuName": "Scroll To Last Row",
"functionName": "scrollActive",
"defaultShortcut": "Ctrl+Alt+Shift+N" // N= 1, 2, 3, 4, 5, 6, 7, 8, 9, or 0
}]
}
来源:https://stackoverflow.com/questions/52632780/scroll-all-worksheets-to-last-row-on-open