想一次掌握一個活頁簿裡「所有分頁」?getSheets() 就是入口。它會回傳目前試算表中的 所有工作表(含隱藏),讓你能批量讀寫、命名、排序、顯示/隱藏,甚至產生「分頁目錄」。官方文件明確說明:Spreadsheet.getSheets() 會取得此活頁簿中的 Sheet 陣列。
管理一個 Google 試算表還好,但當分頁越長越像火車編號時,要找資料、重排順序、產出月報就開始卡。其實關鍵只差一個入口:getSheets()。
它一次把整本活頁簿的所有分頁抓到手上(包含被你藏起來的),之後要列清單、批次改名、依規則排序、建立「分頁目錄」、甚至快速隱藏不相干頁,都能一次到位。希望本篇文章可以幫助到需要的您。
目錄
{tocify} $title={目錄}
getSheets() 是什麼、為何好用
在 Apps Script 裡,活頁簿(Spreadsheet)底下有多個分頁(Sheet)。getSheets() 讓你一次抓到 所有 Sheet 物件,之後就能對每個分頁做事(例如改名、排序、合併、同步格式、彙總資料)。官方參考明載:回傳 Sheet[]。
幾個常見情境:
每月自動複製模板 → 批次改名並重排分頁順序。
整本活頁簿做稽核 → 列出分頁名稱、ID、是否隱藏。
產生「分頁目錄」表 → 點一下就跳到指定工作表。
清理專案 → 依規則(前綴、正則)批次隱藏/刪除。
基本觀念與回傳型別
三層結構:Spreadsheet(整本) → Sheet(分頁) → Range(儲存格範圍)。
回傳型別:
getSheets() → Sheet[](陣列)。陣列是 0 起算;而 Sheet.getIndex() 是「在活頁簿中的位置」,1 起算。別混淆。
分頁 ID:
每個 Sheet 都有唯一的 sheetId(整數),可用 getSheetId() 取得,很多 API/進階操作會用到這個 ID。
可見性:
分頁可能被隱藏。你可以用 sheet.isSheetHidden() 檢查;用 hideSheet() 隱藏、showSheet() 顯示。
3 分鐘上手:建立範例專案與第一支腳本
1. 打開任一 Google 試算表 → 擴充功能 ▸ Apps Script。
2. 在 Code.gs 貼上以下最小示例,儲存後執行一次並授權:
function listAllSheets() {
const ss = SpreadsheetApp.getActiveSpreadsheet(); // 取得目前活頁簿
const sheets = ss.getSheets(); // 取得所有分頁(含隱藏)
const summary = sheets.map(sh => ({
name: sh.getName(),
id: sh.getSheetId(),
index1Based: sh.getIndex(),
hidden: sh.isSheetHidden()
}));
Logger.log(JSON.stringify(summary, null, 2));
}
小提醒:getActiveSpreadsheet()/getActiveSheet() 等常用入口都在 SpreadsheetApp,官方說明可查。
核心用法範例
列出所有分頁名稱與 ID(附輸出到新表)
function exportSheetCatalog() {
const ss = SpreadsheetApp.getActiveSpreadsheet();
const sheets = ss.getSheets();
const out = [['Name', 'Sheet ID', 'Index(1-based)', 'Hidden?']];
for (const sh of sheets) {
out.push([sh.getName(), sh.getSheetId(), sh.getIndex(), sh.isSheetHidden()]);
}
const toc = ss.getSheetByName('目錄') || ss.insertSheet('目錄'); // 若無則建立
toc.clear();
toc.getRange(1, 1, out.length, out[0].length).setValues(out);
toc.autoResizeColumns(1, out[0].length);
}
只挑「可見」分頁
function getVisibleSheets() {
const sheets = SpreadsheetApp.getActive().getSheets();
return sheets.filter(sh => !sh.isSheetHidden()); // true=隱藏
}
判斷可見性靠 isSheetHidden()
依名稱排序/依索引排序
function sortSheetsByNameAsc() {
const ss = SpreadsheetApp.getActive();
const sheets = ss.getSheets().slice().sort((a, b) => a.getName().localeCompare(b.getName()));
// 依新順序搬動:注意 getIndex() 是 1 起算
sheets.forEach((sh, i) => ss.setActiveSheet(sh).moveActiveSheet(i + 1));
}
批次隱藏/顯示(避免把唯一可見分頁也隱藏)
function hideSheetsByPrefix(prefix) {
const ss = SpreadsheetApp.getActive();
const sheets = ss.getSheets();
const visible = sheets.filter(s => !s.isSheetHidden());
for (const sh of sheets) {
if (sh.getName().startsWith(prefix) && visible.length > 1) {
sh.hideSheet(); // 唯一可見分頁不可被隱藏,否則會拋錯
}
}
}
function showAllSheets() {
SpreadsheetApp.getActive().getSheets().forEach(sh => sh.showSheet());
}
跨檔案抓分頁
function listOtherFileSheets(fileId) {
const ss = SpreadsheetApp.openById(fileId);
return ss.getSheets().map(s => ({ name: s.getName(), id: s.getSheetId() }));
}
常見錯誤與雷點
1. 0/1 索引混淆
ss.getSheets() 回傳 陣列 → 0 起算;sheet.getIndex() 是在活頁簿中位置 → 1 起算。排序或搬移時特別容易犯錯。
2. 隱藏分頁也會被撈到
getSheets() 包含隱藏分頁。若只想處理可見頁,請先 !sheet.isSheetHidden() 過濾。
3. 把唯一可見分頁也隱藏
hideSheet() 對活頁簿的最後可見分頁呼叫會丟例外。先確認目前仍有其他可見分頁再隱藏。
4. 授權與身分
初次執行會跳授權。裝設的觸發器「以建立者的身分」執行,跟當下開啟文件的人不同,注意權限與可存取範圍。
5. 配額/逾時
Apps Script 有每日配額與觸發器總執行時間等限制;若遇到「Service invoked too many times」等錯誤,請參考配額與疑難排解頁面。
若你改採 Sheets API 操作,還有每分鐘的讀/寫速率限制,需實作退避(exponential backoff)。
6. 沒呼叫 flush()
多步驟 UI 效果(像即時看到格式/欄寬變動)需要 SpreadsheetApp.flush() 強制套用。
問題集
Q1:getSheets() 的順序是什麼?
通常與分頁在活頁簿的排列一致;若要保險,請用 getIndex()(1 起算)確認並搭配 moveActiveSheet() 調整。
Q2:要只取「可見分頁」?
先 const visibles = ss.getSheets().filter(s => !s.isSheetHidden())。
Q3:如何避免把最後一張可見分頁隱藏?
先計算目前可見分頁數量,確保至少留一張。hideSheet() 對唯一可見分頁會丟例外。
Q4:長任務會不會逾時?
會。Apps Script 有配額與執行時間限制,建議分批、減少往返呼叫,必要時改用時間驅動觸發器分段處理;遇到錯誤請參考官方配額與疑難排解。
Q5:為什麼我在 UI 看不到剛做的變更?
可能變更還在緩存,呼叫 SpreadsheetApp.flush() 強制套用即可。
結語
getSheets() 看似只是「抓全部分頁」,但它其實是 多分頁自動化的關鍵門戶。有了它,你能:
清點與稽核整本文件(名稱、ID、可見性、排序);
用 ID 精準定位要同步/複製/匯出的一頁;
結合觸發器與選單,把日常維運(建目錄、重排、清理)做成一鍵工具。
上面每段程式都能直接複用或延伸。先從「列出清單」開始,逐步加上可見性判斷、排序與導覽。當分頁一多,這些小步驟就會省下你每天的時間。
延伸閱讀推薦:
