要怎麽简单快速地做出客制化地文件?今天,我们会教用 GAS 搭配 Goolge Doc。那因为在 Google Slide 中的 Element 也是相同的,所以这边就会讲细一点,之後就可以一起服用。换句话说,今天会教说怎麽透过 GAS 调整 Google Doc 和 Google Slide 里面的元素。那今天的问题可以有以下的排列组合——
虽然总共有 4x4 共 16 种的排列组合,我们会用案例一个个来说明。基本上前天讲了讲新增与读取,昨天专注於删除,今天终於可以讲到「更新」了,就让我们开始吧!
答案在今天的文章当中!
考虑到有些夥伴不一定会都看过前面的文章,就捞叨一点把基本步骤再次附上,如果会的夥伴可以直接跳到 Q1。
我们已经知道大致上,每一个 Google 文件都会有 Element (元件),且每一个 Element 都会有 Attribute (属性)。今天我们主要会介绍蓝色的 Element 的部分。
那我们把 Element 展开来看,里面有很多小的物件,这边抓出其中最常用的四种。分别是段落、照片、表格与清单。
那我们的目标就是透过读取、写入、更新与删除(对的,参照 CRUD 的 format)来带大家让是怎麽操作这些表格。这边就节录一本书中的「段落、照片、表格与清单」,来作为今天我们的范例。
这一集我们有个重要的的观念,也就是我们可以透过 getParent()
和 getChildren()
来取得上下层关系的物件。如果这个关系不懂,一定要回到前一天看,因为今天会大量用到。完整的上下层概念,可以参考 Google 的官方文件。
好,那我们就开始吧!
那这次我们不会用 Google Sheet,而是直接用 Google Doc 进入,借一下 D16 的影片。
一样第一次会有存取验证需要大家按一下。这边仍是借用一下 D2 的影片。
getBody()
我们先用 getActiveDocument()
抓出正在绑定的文件;那假设我们都是针对主要内文(Body)的部分,所以我们先设定好 getbody()
。
let doc_body = DocumentApp.getActiveDocument().getBody();
因为更新有比较复杂的细节,我们就先来讲讲删除。
那不管是删除还是更新,我们都要先取得目标的物件。所以先让我们取得清单,为此我们先做出三份清单。
接着,我们要读取清单,并进行更动。
getListItems()
读取清单接下来,我们试着用 getListItems()
来读取清单的内容。
function readLists(){
let doc_body = DocumentApp.getActiveDocument().getBody();
let list_items = doc_body.getListItems();
for (let i=0; i < list_items.length; i++){
Logger.log(list_items[i].getText())
}
}
理论上跑起来会是清单含有的所有文字,但这是理论上。来确认一下跑起来如何——
看起来没抓到范围,是怎麽回事?原因是getListItems()
要抓的是「Google Doc」认可的清单。而我只是打上点点或数字,并不代已经是它认可的清单格式,这个时候就会出问题。换句话说,我们要重新确认一下自己的文本。以下示范如何调整成正确的格式——
好,那实际运作的 getListItems()
会跑出什麽样子呢?(注意,影片中的清单为了说明,有再微调)
可以得知:
也附上小测验第一题的答案。
getListId()
和 setListId()
设定清单项目的归属要注意 getListItems()
得到的不会是「有几份清单」,而是有几个清单的子项目。截稿的目前 GAS 未开放可以直接操作的 List Item。那,我们要怎麽知道这些项目属於相同的 List 呢?这时要用到 getListId()
来核对。
function getListItemsParentTable(){
let doc_body = DocumentApp.getActiveDocument().getBody();
let list_items = doc_body.getListItems();
for (let i=0; i < list_items.length; i++){
Logger.log(list_items[i].getText() +" "+list_items[i].getListId())
}
}
这边我们直接用图解,说明执行後的结果。
可以看出,只要中间有隔出一行,就会被视为不同的表单。那我们要如何让就算有空一行,仍被视为同样的表单呢?这时就要用到 setListId()
了。假如我想用一段程序码,让图中的所有合格清单项目,都归属於同一个清单。
function setListItemsSameList(){
let doc_body = DocumentApp.getActiveDocument().getBody();
let list_items = doc_body.getListItems();
let item_1 = list_items[0];
for (let i=0; i < list_items.length; i++){
list_items[i].setListId(item_1).setGlyphType(DocumentApp.GlyphType.NUMBER);
}
}
跑起来长这样——
可以发现,被认为是清单的物件数字全部变成连贯的了!(原本蓝色的 1 2 3 变为 5 6 7)那这边有两点要注意。
setListId()
後面要放的 不是 ID,而是你想要设定跟它作为同一张表的 ListItem
,以上面的程序码来说,我就以第一个 item_1 作为归属处。.setGlyphType(DocumentApp.GlyphType.NUMBER)
来让 List 可以是数字为基底。有人问说为什麽红色的范例清单没有动,因为它不是 Google Doc 认可的清单,在上头的 Step 3 的有提到原因与改进方式。
好,那总算搞定清单的读取了,接着就让我们用来玩「更新内容」吧!
setNestingLevel(nestingLevel)
设定层级在清单中,我们很常用 Tab
键来调整层级,而这功能在 GAS 中即是 setNestingLevel(nestingLevel)
,预设的层级即为 0。那我们来看如何设置从 0 开始的层级。
function setListItemLevel(){
let doc_body = DocumentApp.getActiveDocument().getBody();
let list_items = doc_body.getListItems();
for (let i=0; i < list_items.length; i++){
Logger.log(i)
list_items[i].setNestingLevel(i);
}
}
跑起来长这样——
那为什麽还有一个蓝色的项目没有变成子项目呢?因为 nestingLevel
的最大值是 8,也就是我们最多只能创造九层(0 ~ 8)。
removeFromParent()
将单一 ListItem 拔除如果我们只想移除其中特定的 Item,不想影响其上或下阶层的内容,那我们可以用 removeFromParent()
。抓出想移除的 ListItems,将其移出。
function removeItemListFromParent(){
let doc_body = DocumentApp.getActiveDocument().getBody();
let list_items = doc_body.getListItems();
for (let i=0; i < list_items.length; i++){
if (i==7){
list_items[i].removeFromParent();
}
}
跑出来长这样——
merge()
将两个 ListItem 合并如果今天我们想将层级不同的清单(List)进行合并,要怎麽做?这时可以透过 Merge。这边我们试着合并范例清单二的第一项(区别技术性与调适性挑战,ListItemIndex = 7)和第三项(聆听选外之音,ListItemIndex = 9)
function mergeListItemss(){
let doc_body = DocumentApp.getActiveDocument().getBody();
let list_items = doc_body.getListItems();
for (let i=0; i < list_items.length; i++){
if (i==7){
list_items[i].merge();
}
}
}
跑起来长这样——
我这边示范了两组数字,分别是 i==7 & i==9 ,可以发现其合并的逻辑是:「与下面一项合并」,更细节来说,是
replaceText()
更改文字内容那总算到我们的文字部分拉, replaceText(parttern, replacement)
其实在前几章就有偷用到,这边完整讲述一下使用方式。
pattern
的部分是要用所谓的「正规表示法」,那部分我们再找时间细讲,我自己的建议是直接写上「要改的文字内容」;replacement
则要放你想换上的东西,可以理解成「另外的文字」。当然进阶版你要换成图片或其他物件其实是可以的。那我们来看看怎麽用,这边我就单纯示范将句号换成惊叹号的方式——
function replaceText(){
let doc_body = DocumentApp.getActiveDocument().getBody();
let list_items = doc_body.getListItems();
for (let i=0; i < list_items.length; i++){
list_items[i].replaceText("。","!");
}
}
跑起来长这样——
提醒的是,我这样的指令码,是针对 ListItem 进行更改,文中其他的段落或表格都不会被动到。
insertText()
插入文字内容那这边我们就实作一个用 insertText(childIndex, text)
在每个 ListItem 的之前,插入一个数字。
function readLists(){
let doc_body = DocumentApp.getActiveDocument().getBody();
let list_items = doc_body.getListItems();
for (let i=0; i < list_items.length; i++){
list_items[i].insertText(0, i)
}
}
跑起来长这样——
那可以发现:
那如果设定数字为 2 的话,各位客官可以自己跑一次看看,会出现错误。因为对 ListItem
来说,下面唯一的 Child ,就是列点内的内容。
今天学的大多都可以套用到「段落」与「表格」,不过要搭配前面两天一起消化。那如果是非文字部分像是照片、图表,基本上更新的方式建议直接删掉旧的,加上新的。其他的今天的内容应该都可以 Cover。
好,那今天就到这边。今天我们主要交代了 Element 的「如何更新」;如果还有问题,透过留言之外,也可以到 Facebook Group,想开很久这次铁人赛才真的开起来,欢迎来当 Founding Member。如果不想错过可以订阅按赞小铃铛(?),也欢迎留言跟我说你还想知道什麽做法/主题。我们明天见。
<<: [第四天]从0开始的UnityAR手机游戏开发-介绍Unity介面和常用快捷键
在这系列教学里,我们以撰写一个以购物车为主题的 Kotlin 函式库为例,经过一连串 TDD、语法风...
程序语言会有一些常见的资料组单位,例如 python 会有 list,C、C++ 有 array ...
昨天我们对更新资料库的资料进行了简单的操作, 我们对资料库已经可以新增、更新了 我们现在的情境是 i...
Netflix上的鱿鱼游戏正夯,雪伦也是一集接一集的看完了 上次看机智医生生活搭配辣炒年糕,那这次看...
计时器 TIMER 今天开始我们要来使用STM32强大的功能之一 TIMER! STM32F429Z...