如果你經常用 Google 試算表做報表,應該遇過這種情況:頁籤越長越多,命名亂成一團,腳本插錯位置、重複新增,最後只好手動救火。其實很多問題,在一開始先把「張數」數清楚就能避開。
getNumSheets() 就是這把小扳手:回傳整本活頁簿目前有幾張工作表,給你一個可靠的數字去控制流程。
本篇文章會用淺白的步驟跟範例,示範如何用它安排插入順序、做每月自動補分頁、寫儀表板統計,以及在門檻超過時自動停手。不多說專有名詞,重點放在可複製的寫法、錯誤排查的方法和幾個常見地雷。把這招放進你的腳本,報表流程會安靜很多。希望本篇文章可以幫助到需要的您。
目錄
{tocify} $title={目錄}
為什麼要數「工作表」這件小事?
很多人寫報表自動化時,只盯著儲存格的值,忽略「工作表的數量」這個關鍵狀態。實務上你常會遇到:每天自動建立一張新頁籤做日誌、以「月份」當分頁整理數據、或在匯入資料後要把新分頁排到指定順序。這些都離不開先知道目前到底有幾張工作表。
在 Google Apps Script 裡,Spreadsheet 類別提供的 getNumSheets() 就是最俐落的解法:回傳整份活頁簿的分頁數量(整數)。這個方法穩、簡單、可讀性高,拿來做索引邏輯、排版、迴圈控制都很合適(官方參考頁清楚載明此方法會回傳分頁數量)。
getNumSheets() 是什麼?
定義:回傳目前活頁簿(Spreadsheet)裡工作表的總數(整數)。
所屬類別:Spreadsheet(從 SpreadsheetApp.getActiveSpreadsheet() 或 SpreadsheetApp.openById() 等取得)。
什麼情境會用到?
1. 動態插入新分頁到最後:插入新表時需要用「目前表數」當作插入位置索引。
2. 批次巡覽/稽核:跑 for 迴圈時決定上限,避免硬編寫死值。
3. 自動命名/自動編號:例如建立 Report-#,# 以現有張數+1 產生。
4. 資料清理:檢查是否超過允許的分頁上限,超過就合併或封存。
5. 報表健檢:理應只有固定分頁數,異常增加代表流程有問題。
6. 備援策略:搬移或重建分頁前確認數量,降低誤刪與漏刪風險。
快速上手:3 個步驟
1. 打開 Apps Script 編輯器
在你的試算表中:擴充功能 → Apps Script,新建專案。
2. 取得活頁簿物件
const ss = SpreadsheetApp.getActiveSpreadsheet();
2. 取得活頁簿物件
const count = ss.getNumSheets(); // 例如回傳 7
Logger.log(`目前有 ${count} 張工作表`);
官方 Spreadsheet 類別文件載明 getNumSheets() 回傳整數。
十個實戰範例
1. 取得分頁數並寫到儀表板
function writeSheetCount() {
const ss = SpreadsheetApp.getActiveSpreadsheet();
const dashboard = ss.getSheetByName('Dashboard') || ss.insertSheet('Dashboard');
const count = ss.getNumSheets();
dashboard.getRange('B2').setValue(count);
}
2. 插入新分頁到最後(以目前張數為索引)
function insertAtEnd(name) {
const ss = SpreadsheetApp.getActiveSpreadsheet();
const index = ss.getNumSheets(); // 最後一個之後的位置
ss.insertSheet(name, index);
}
社群範例中常見把 getNumSheets() 用來決定 insertSheet 的插入位置。
3. 建立流水命名的分頁(Report-001…)
function createSequentialReport() {
const ss = SpreadsheetApp.getActiveSpreadsheet();
const n = ss.getNumSheets() + 1;
const name = `Report-${String(n).padStart(3, '0')}`;
ss.insertSheet(name, ss.getNumSheets());
}
4. 以檔案 ID 讀取(非目前活頁簿)
function countSheetsById(fileId) {
const ss = SpreadsheetApp.openById(fileId);
return ss.getNumSheets();
}
SpreadsheetApp 提供 openById() / openByUrl() 讀取其他檔案,再呼叫 getNumSheets()。
5. 每月自動補一張分頁:只在需要時建立
function ensureMonthlySheet() {
const ss = SpreadsheetApp.getActiveSpreadsheet();
const ym = Utilities.formatDate(new Date(), Session.getScriptTimeZone(), 'yyyy-MM');
if (!ss.getSheetByName(ym)) {
ss.insertSheet(ym, ss.getNumSheets());
}
}
6. 巡覽全部分頁:以張數當上限(示範健檢)
function auditAllSheets() {
const ss = SpreadsheetApp.getActiveSpreadsheet();
const total = ss.getNumSheets();
const sheets = ss.getSheets(); // 也可以直接用陣列長度
for (let i = 0; i < total; i++) {
const sh = sheets[i];
// 你的檢查邏輯...
}
}
7. 超過上限就封存:避免失控增生
function capSheetCount(limit = 24) {
const ss = SpreadsheetApp.getActiveSpreadsheet();
let total = ss.getNumSheets();
if (total <= limit) return;
const archive = ss.getSheetByName('_archive') || ss.insertSheet('_archive', ss.getNumSheets());
const sheets = ss.getSheets();
// 把最舊的幾張移到封存(示意:從前面開始)
while (total > limit) {
const victim = sheets[0];
if (victim.getName() === '_archive') break;
victim.copyTo(archive).setName(`backup_${victim.getName()}`);
ss.deleteSheet(victim);
total--;
}
}
8. 產生目錄頁:列出總數與清單
function buildTOC() {
const ss = SpreadsheetApp.getActiveSpreadsheet();
const toc = ss.getSheetByName('TOC') || ss.insertSheet('TOC');
toc.clear();
const sheets = ss.getSheets();
toc.getRange(1,1).setValue(`Total: ${ss.getNumSheets()}`);
for (let i = 0; i < sheets.length; i++) {
toc.getRange(i+2, 1).setValue(sheets[i].getName());
}
}
9. 自訂函數:在儲存格裡顯示分頁數
/**
* 在儲存格輸入 =COUNT_SHEETS() 顯示分頁數
*/
function COUNT_SHEETS() {
return SpreadsheetApp.getActiveSpreadsheet().getNumSheets();
}
10. 與流程控制結合(門檻判斷)
function guardBeforeImport(limit = 50) {
const ss = SpreadsheetApp.getActiveSpreadsheet();
const total = ss.getNumSheets();
if (total >= limit) {
throw new Error(`分頁已達 ${total} 張,超過上限 ${limit},停止新增。`);
}
// 繼續你的匯入流程...
}
常見錯誤與雷點
const ss = SpreadsheetApp.getActiveSpreadsheet(); // 正確
// const sh = ss.getActiveSheet(); // 這是 Sheet,不是 Spreadsheet
ss.getNumSheets(); // 只能在 Spreadsheet 上呼叫
文件對象:Spreadsheet、Sheet 類別分別定義於 Spreadsheet 服務。
