Google 試算表:設定工作表名稱 setName()


如果你常在試算表裡新增分頁、做月報或日報,應該遇過「命名一團亂、連結對不上」的慘劇。

其實只要用到一個方法——setName()——就能把改名這件事變得可預測、可複用。

本篇文章用白話步驟帶你上手:怎麼安全改名、什麼時候要先比對再改、要不要幫名字做清洗,以及批次改名該注意哪些節點。也會示範幾個日常情境:從 A1 取名、複製模板自動加日期、避免撞名加尾碼。文末整理雷點清單與最佳實務,讓你少走彎路,交出去的表格可讀又耐看。希望能幫助到需要的您。


目錄

{tocify} $title={目錄} 


為什麼要在程式裡改「工作表名稱」?

把工作表(Sheet)命名這件事自動化,有幾個直接好處:

        資料管控更穩:自動命名可避免手動拼錯、漏改,報表鏈結(查詢、驗證、保護、命名範圍…)就不會亂。

        排程&版本化:例如每天複製模板 → 以日期命名,舊表自動封存或鎖權限。

        大規模作業:一次處理數十/上百張分頁,靠程式比手改可靠太多。

在 Google Apps Script 中,工作表物件 Sheet 提供 setName(name),可以把分頁名稱改成你指定的字串,方法本身也支援鏈式呼叫(回傳 Sheet)。官方參考文件白紙黑字寫得很清楚,還附範例程式碼與授權範圍說明。


核心概念 3 行搞懂

const ss = SpreadsheetApp.getActiveSpreadsheet();
const sheet = ss.getSheetByName('原本名稱');
sheet.setName('新的名稱');  // 回傳 Sheet,可繼續鏈式呼叫


setName(name: string)

         把分頁改名,回傳同一張 Sheet(便於鏈式寫法)。

權限/授權範圍:需要 spreadsheets 或 spreadsheets.currentonly。

getName() 可讀取目前名稱,常見於比對「舊名 ≠ 新名才改」。


快速上手:4 個最常見情境

直接把目前分頁改名

function renameActive() {
  const sheet = SpreadsheetApp.getActiveSheet();
  sheet.setName('報表v2');
}


省話重點:改名動作是立即的,不用 flush()


先確認不同再改,避免不必要動作

function renameIfNeeded() {
  const sheet = SpreadsheetApp.getActiveSheet();
  const want = '銷售月報';
  if (sheet.getName() !== want) sheet.setName(want);
}


這招能避開一些觸發器(例如 onEdit)被重複觸發的意外。


批次把一串分頁依照清單改名

function batchRenameByList() {
  const ss = SpreadsheetApp.getActiveSpreadsheet();
  const map = [
    ['Sheet1', '概況'],
    ['Sheet2', '訂單'],
    ['Sheet3', '庫存']
  ];
  map.forEach(([from, to]) => {
    const sh = ss.getSheetByName(from);
    if (sh && sh.getName() !== to) sh.setName(to);
  });
}


複製模板 → 依日期(或欄位值)命名

function duplicateTemplateWithDateName() {
  const ss = SpreadsheetApp.getActiveSpreadsheet();
  const tpl = ss.getSheetByName('TEMPLATE');
  const ymd = Utilities.formatDate(new Date(), Session.getScriptTimeZone(), 'yyyy-MM-dd');
  const copy = tpl.copyTo(ss).setName(`日報_${ymd}`); // 鏈式改名
}


這種流程常見在「每日產生工作表」的排程腳本。遇到「名稱已存在」要先處理(下面雷點有解)。官方文件也示範 copyTo() 的用法;setName() 的鏈式呼叫是被支援的。


進階:從儲存格動態命名

從 A1 讀值當作新名稱,並做一點清洗(去頭尾空白、換行、過長截斷):

function renameByCellA1() {
  const sh = SpreadsheetApp.getActiveSheet();
  const raw = String(sh.getRange('A1').getValue() || '');
  let name = raw.trim().replace(/\s+/g, ' ');
  if (name.length === 0) throw new Error('A1 為空,無法命名');
  if (name.length > 100) name = name.slice(0, 100); // 和 UI 體感一致,保守截斷
  if (name !== sh.getName()) sh.setName(name);
}


備註:官方 setName() 文件沒有硬性「長度上限」說明,但實務上工作表分頁在 UI 呈現過長會難讀,建議自訂上限(例如 60–100 字元)。setName() 本身的使用與授權屬性以官方文件為準。


命名規範&限制:哪些要注意?

名稱必須在同一份試算表中唯一:

        同名會失敗(實務上常見於「先複製、後改名」但同名已存在)。工作流程或第三方工具也會拋出「name already exists」之類的錯誤。


字元:

        Google Sheets 分頁名相對寬鬆(包含空白、中文、Emoji 通常可用)。遇到跨系統對接(例如把分頁名拿去當檔名或資料表鍵)才需要限制字元集。


觸發器:

        onEdit、onChange 之類事件可能因為改名而連鎖觸發其它流程,要小心迴圈或重複執行。

官方對 Sheet.setName() 的定義與授權需求請以參考文件為準;若你同時在 Drive 端改檔名(DriveApp.File.setName()),是另一個不同層級,別混淆。


常見錯誤與雷點

1. 同名衝突(名字已被用)

    症狀:複製模板後馬上改名,偶發失敗;或報「名稱已存在」。

    處理:

function safeSetName(sh, want) {
  const ss = sh.getParent();
  const exists = ss.getSheets().some(s => s.getName() === want);
  if (exists) {
    const ts = Utilities.formatDate(new Date(), Session.getScriptTimeZone(), 'HHmmss');
    want = `${want}_${ts}`; // 或加流水號
  }
  return sh.setName(want);
}


    在某些整合工具/流程裡,確實會看到「name already exists」的錯誤訊息,需要先做重名檢查。


2. onEdit/onChange 觸發「雙重複製」

    症狀:用 onEdit 搭 copyTo(),有時產生兩張副本(其中一張留著「Copy of …」)。

    原因:同一事件被多次觸發(例如多儲存格編輯、保護規則、外掛同步),或你的邏輯在改名前後又被呼叫一次。

    對策:

            用「旗標欄位」或「鎖」機制(PropertiesService)保證單次執行。

            嚴格限定觸發條件(只在特定欄/列變動時執行)。

            把「複製→改名」封成一個函式並加上重入保護。

    社群討論曾提到 .copyTo() 在事件環境下偶見雙生,實務要做好防呆。


3. 從儲存格取名含不適合字元

    症狀:名稱包含過多空白、換行、看起來像公式片段,之後難以搜尋或外部系統不吃。

    對策:前面「清洗字元」的範例直接收斂成單一空白、刪除控制字元,必要時自訂白名單(例如只留中英數、空白、底線)。


4. 誤把「命名範圍」的 setName() 當「工作表改名」

    NamedRange.setName() 是命名範圍用,不是改分頁名;兩者 API 不同、行為不同。官方也各自有文件。


5. 改名後公式「找不到分頁」

    症狀:跨表參照或 Apps Script 程式碼還在使用舊名稱,導致 #REF! / 未解析的工作表名稱。

    對策:

            在改名前列出受影響的範圍(用 TextFinder 找 '舊名'! 片段),改名後一起更新。

            程式碼端盡量用 sheet.getSheetId()(數字 ID)當索引,名稱只用於呈現;需要時用 ID 反查 Sheet 再 .setName()。官方文件提供 getSheetId() 與 getSheets() 等存取方式。


與「檔案命名」的區別(Drive File.setName())

工作表分頁名:

        Sheet.setName()(變的是分頁標籤)。

試算表檔名:

        DriveApp.getFileById(id).setName('新檔名')(變的是雲端硬碟檔案)。

兩者常一起用:先把分頁標籤標準化,再把整份檔案依專案規則改名(例如 專案-客戶-日期)


問題集

Q1. 可以用 setName() 把分頁名設成空字串嗎?

不行。名稱必須有內容(實務上請先驗證字串長度),否則會拋錯或在 UI 上直接拒絕。官方文件雖未逐條列出這種驗證,但以實務與 UI 規則須避免空名;方法定義照官方。

Q2. 可以用斜線、冒號、Emoji 嗎?

多數情況可行(Sheets 不像 Excel 那麼嚴格)。但若要把分頁名拿去當檔名/外部系統鍵值,建議自行限制字元集並做清洗。

Q3. 批次改名會不會很慢?

setName() 是改結構的操作,批量數十張一般無感;大量(數百張)建議分批或減少事件觸發。必要時可先 SpreadsheetApp.flush() 讓 UI 盡快同步(非必須)。

Q4. 改名後公式壞掉(未解析工作表名)怎麼辦?

先用 TextFinder 搜 '<舊名>'!,改完名再批次替換;或設計上改用 sheetId 追蹤對應關係,減少對名稱的硬繫結。


延伸閱讀推薦:

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