試算表、文件、簡報與表單
這四個服務對應 Google 的四種「檔案」:試算表、文件、簡報、表單。它們都是先開啟一個檔案,再對檔案裡的內容做事。總表與星等說明見 內建服務。
SpreadsheetApp
常用度:★★★★★ 常搭配的觸發:onOpen、onEdit、變更、時間驅動、選單、自訂函式(唯讀)
操作試算表的入口,也是 GAS 最常用的服務。結構是四層:SpreadsheetApp → Spreadsheet(整本)→ Sheet(一張工作表)→ Range(一格或一塊)。日常讀寫幾乎都是 getValues() 與 setValues() 一次處理整塊二維陣列。完整用法見 SpreadsheetApp 與 Range。
範例:在「待辦」工作表,C 欄改成「完成」時,自動在 D 欄填上完成時間(簡易觸發 onEdit)
function onEdit(e) {
const range = e.range;
const sheet = range.getSheet();
if (sheet.getName() !== "待辦" || range.getColumn() !== 3) return; // 只管 C 欄
if (range.getValue() === "完成") {
sheet.getRange(range.getRow(), 4).setValue(new Date()); // D 欄寫入時間
}
}
第一行先過濾工作表與欄位,其他儲存格被改就立刻離開。注意:一次貼上多格時,e.range 是整塊範圍,getValue() 只會取到左上角那格。
DocumentApp
常用度:★★★☆☆ 常搭配的觸發:onOpen(加選單)、選單、時間驅動。Google 文件沒有 onEdit 觸發
操作 Google 文件:Document → Body(內文)→ 段落、表格、圖片。最常見的用途是套版:先做一份含 {{姓名}} 這種佔位字的範本,程式複製它再把佔位字換成真實資料,用來產生合約、邀請函、證書。
範例:從試算表第 2 列的資料,產生一份邀請函
function createLetter() {
const TEMPLATE_ID = "範本文件ID";
const [name, company, date] = SpreadsheetApp.getActiveSheet()
.getRange("A2:C2")
.getValues()[0];
const copy = DriveApp.getFileById(TEMPLATE_ID).makeCopy("邀請函-" + name);
const doc = DocumentApp.openById(copy.getId());
const body = doc.getBody();
body.replaceText("{{姓名}}", name);
body.replaceText("{{公司}}", company);
body.replaceText("{{日期}}", Utilities.formatDate(new Date(date), "Asia/Taipei", "yyyy/MM/dd"));
doc.saveAndClose(); // 存檔,避免後續讀到舊內容
Logger.log(copy.getUrl());
}
replaceText 的搜尋字串是正規表示式,{{姓名}} 這種寫法可以直接用;若佔位字含 .、(、* 等符號,要加反斜線跳脫。
SlidesApp
常用度:★★☆☆☆ 常搭配的觸發:onOpen、選單、時間驅動
操作 Google 簡報:Presentation → Slide → 形狀、文字、圖片。用途和文件類似,多半是把試算表的數字定期填進簡報範本,做成週報或月報。
範例:把彙總表的本月營收填進簡報
function updateMonthlyDeck() {
const total = SpreadsheetApp.getActive()
.getSheetByName("彙總")
.getRange("B1")
.getValue();
const deck = SlidesApp.openById("簡報ID");
deck.replaceAllText("{{本月營收}}", String(total)); // 全部投影片一次換掉
}
搭配每月 1 號的時間驅動觸發,就是全自動月報。
FormApp
常用度:★★★☆☆ 常搭配的觸發:表單提交(可安裝)、onOpen(表單編輯器)、時間驅動
表單有兩個方向:建立或修改表單(FormApp.create()、addTextItem() 等),以及收到回應之後做事,後者靠可安裝的「提交表單時」觸發,而不是 FormApp 本身。
範例一:用程式建立報名表單
function buildForm() {
const form = FormApp.create("課程報名");
form.addTextItem().setTitle("姓名").setRequired(true);
form.addMultipleChoiceItem()
.setTitle("想參加哪一場?")
.setChoiceValues(["週六上午", "週六下午"]);
Logger.log("編輯網址:" + form.getEditUrl());
Logger.log("填寫網址:" + form.getPublishedUrl());
}
範例二:有人送出表單時,把整份回答寄給自己(在「表單」上建立可安裝的提交觸發)
function onFormSubmit(e) {
const lines = e.response.getItemResponses().map(
(r) => r.getItem().getTitle() + ":" + r.getResponse()
);
MailApp.sendEmail(Session.getEffectiveUser().getEmail(), "新的表單回覆", lines.join("\n"));
}
觸發是建在表單上時,e.response 是整份回應;建在試算表上時,事件物件改成 e.namedValues、e.values,兩者的資料結構不同,見 Gmail、Drive、日曆、表單。
下一步:Gmail、Drive 與日曆。