Google 試算表:藉由名稱取得工作表getSheetByName()

 


做 Google 試算表自動化,第一步常卡在「到底要改哪個分頁?」getSheetByName() 就是那把鑰匙:用分頁名稱,準確拿到要動手的頁籤。

本篇文章會盡可能說明內容,內容涵蓋最小可用的範例、怎麼避免找不到分頁、名稱改了怎麼辦。也會補上常見坑點(例如大小寫、空白字元、綁定腳本 vs. 獨立腳本)和實用的可複用函式。

希望讀完你不只會用,還能寫出耐改名、耐擴充、可交接的腳本。


目錄

{tocify} $title={目錄} 


為什麼一定要會 getSheetByName()

        在自動化報表、資料清洗或產生月報時,你幾乎都會「按工作表名稱」去定位資料頁籤。getSheetByName(name) 就是拿到指定分頁(Sheet)的最快方式:給它一個精準的分頁名稱,回傳對應的 Sheet 物件,沒有就回傳 null。這是官方行為定義,不是鄉野傳說。


快速上手:基本語法與最小可用範例

基本語法

const ss = SpreadsheetApp.getActiveSpreadsheet();
const sheet = ss.getSheetByName('原始資料'); // 找不到會回傳 null
if (!sheet) throw new Error('找不到「原始資料」工作表');


getSheetByName() 精準比對名稱,大小寫、空白、全形半形都算數;找不到只會回傳 null,不會直接丟例外。


讀寫範例:把 A1 寫進時間戳記

function writeTimestamp() {
  const ss = SpreadsheetApp.getActiveSpreadsheet();
  const sheet = ss.getSheetByName('原始資料');
  if (!sheet) throw new Error('找不到「原始資料」工作表');

  sheet.getRange('A1').setValue(new Date());
}


建立後再取用:不存在就新建

function getOrCreateSheetByName(name) {
  const ss = SpreadsheetApp.getActiveSpreadsheet();
  let sheet = ss.getSheetByName(name);
  if (!sheet) sheet = ss.insertSheet(name);
  return sheet;
}


insertSheet(name) 可以直接用名稱建立分頁


正確的專案開檔方式(超重要)

綁定腳本(從試算表 → 擴充功能 → Apps Script 進入)時,用 SpreadsheetApp.getActiveSpreadsheet() 才有「作用中的檔案」。如果你在獨立腳本環境跑它,getActiveSpreadsheet() 可能是 null,任何串接方法都會變成 Cannot read properties of null 這類錯。

若腳本必須跨檔案操作,改用 openByUrl() 或 openById() 自行指向目標檔案,而不要期待「作用中」檔案。


進階:用 Sheet ID 穩固指向,避免「被改名就爆」

名字會被改,但 Sheet ID 幾乎不會變。Apps Script 現在提供:

    sheet.getSheetId() 取得分頁的唯一 ID

    ss.getSheetById(id) 直接以 ID 取回分頁

這對「月度複製樣板後重新命名」這類流程很重要:先抓到 ID,之後就算名稱被改寫,仍能穩定取到同一個分頁。

示例:寫入時盯 ID 而非名稱

function safeWriteById(sheetId, a1, value) {
  const ss = SpreadsheetApp.getActiveSpreadsheet();
  const sheet = ss.getSheetById(sheetId);
  if (!sheet) throw new Error(`找不到 ID=${sheetId} 的工作表`);
  sheet.getRange(a1).setValue(value);
}


樣板複製:先以樣板建立,再改名

你可以用 insertSheet(newName, index, { template: templateSheet }) 直接以某分頁為模板,產生新分頁並命名。這招在建置週/月度報表超好用。


function createFromTemplate(newName, templateName = 'TEMPLATE') {
  const ss = SpreadsheetApp.getActiveSpreadsheet();
  const tpl = ss.getSheetByName(templateName);
  if (!tpl) throw new Error('找不到樣板分頁');

  // 在第 1 個位置插入,並以樣板複製內容/格式
  ss.insertSheet(newName, 1, { template: tpl });
}


常見錯誤與雷點

1.    TypeError: Cannot read properties of null (...)

    成因:

        getActiveSpreadsheet() 在獨立腳本或特定執行環境拿不到作用中檔案 → 變 null。

    解法:

        改用 openByUrl() / openById() 明確指定;或把腳本綁回試算表再跑。


2.    getSheetByName() 回傳 null(名稱對不起來)

    成因:

        名稱打錯、含多餘空白(特別是全形空白)、大小寫不同、或分頁真的不存在。

    排查:

        直接在 UI 檢查分頁名稱;也可以在程式中列出 ss.getSheets().map(s => s.getName()) 幫自己核對。

公式世界裡,工作表名稱與儲存格引用用 ! 分隔,若名稱內有空白或特殊字元,公式需要單引號包起來('表名 with space'!A1),這常導致你以為「名字沒問題」,其實程式碼與 UI 名稱仍不一致。


3.    「未解析的工作表名稱」(Unresolved sheet name)

情境:你改了分頁名稱,但一堆公式或外掛、串接工具仍指向舊名,報錯。

解法:

先建立新分頁,再把資料搬過去、最後才刪舊分頁;或改以 Sheet ID 綁定資料流程。


4.    名稱衝突

    情境:複製分頁或改名時,系統回你「名稱已存在」。

    說明:工作表內部名稱通常必須唯一;若你用 API/自動化做批次複製,流程設計不良會撞名而失敗。先建立再延後改名,或以時間戳記附尾避免衝突。


5.   你以為抓到「工作表」,其實抓到「作用中的分頁」

    常見錯把 getActiveSheet()(回傳 Sheet)當成 Spreadsheet,接著又呼叫 getSheetByName() 就爆「XXX 不是函式」。

記得:getSheetByName() 是 Spreadsheet 的方法,不是 Sheet 的。


6.    執行逾時 / 偶發卡住

    偶爾社群回報 getSheetByName() 在特定檔案卡住的案例(大量分頁、外部資料源、權限異常)。建議用重試或降頻處理,並先確認檔案本身沒有資料來源執行中的衝突。


問題集

Q1. 我需要跨檔案操作特定分頁,還能用 getSheetByName() 嗎?

        A:可以,但你得先用 openByUrl()/openById() 打開「那一份檔案」後再呼叫 getSheetByName()。不要用 getActiveSpreadsheet(),因為那是「眼前作用中」的檔案。

Q2. 改名會不會讓程式掛掉?

        A:會。如果你是用名稱取分頁,改名就取不到。把關鍵流程改成 sheetId 方式最穩。

Q3. 為什麼我用 getActiveSpreadsheet() 會拿到 null?

        A:大多是因為你不是在綁定腳本環境跑,或用到了不會產生「作用中試算表」的執行路徑。

Q4. 表內可以有兩個同名分頁嗎?

        A:一般 UI 流程不會讓你重名;若自動化流程撞名,API 會回錯。請在複製/改名的流程上設計避重邏輯。


延伸閱讀推薦:

張貼留言 (0)
較新的 較舊