来到了第九天。但一样先讲结论,如果你很急着用,可以直接使用这份 Add-On: Drive Explorer,功能还蛮强大的!自己写的好处是,如果你想结合其他功能会比较方便。对於想知道怎麽做的人,让我们开始吧!
现在几乎每天都会打开 Google Drive,但有时当档案一多,就会面临两个问题——权限设置不清,当一个人加入或离职时,要重复好几次开开关关。又或是要将不同的线上文件寄信并分享给不同人,这些都会需要知道档案 ID。有没有一个快速的方式,可以让我们抓出特定资料夹内的档案 ID,并用一个表格管理权限呢?
这次的主题我们会分成两天写。第一题会在今天跟大家分享,明天会针对第二题与第三题。那我们就开始吧!
因为我们要用到 Google Sheet ,所以一样用其作为开启的管道。借用一下 D8 的影片,来说明怎麽样开启一个有连结 GAS 的 Google Sheet。
一样执行时会有「需要验证」出现,让我借用一下 D2 的影片。
这边我们开一个资料夹,并且在里面设置一些档案,其中有一些是有子目录的。要注意里面有个「demo」资料夹
那这边要特别提一下「ID」的概念,每一个 Google 产品都有特定的 ID,位置可以参考这张图
这边提供两种取得方式——
一种是直接从网址上复制,另一种是按右键时会出现的。这边用影片解释。好,那当我们取得要抓的档案 ID 後,就是将其丢到 GAS 上,一样开一个 environment.gs
存放资料。这边示范完整的流程——
在 Google Drive 官方定义的 API 中,主要会将能操作的物件分成三种,分别是 Folder
、File
和User
。会用不同的 API 读取。
我们来拆解步骤——
getFolderById()
读取 Folder
。getFiles()
会读出 files
(实际上是 fileIterator
,但可以理解成「很多档案」就是)。files
(fileIterator
)会将这个资料夹内的档案一个个列出来,这边我列出它的档名(getName()
)和 ID(getId()
)。完整程序码在这——
function readFiles(){
let folder = DriveApp.getFolderById(drive_ID);
let files = folder.getFiles();
let file_arr = []
while (files.hasNext()) {
let file = files.next();
file_arr.push([file.getName(),file.getId()]);
};
Logger.log(file_arr);
}
跑起来长这样——
好那你会发现一个问题,是这边并没有列出「资料夹」。仔细一看会发现我们里面并没有我们在 Step 2 埋梗的「资料夹」 demo
,那请问我们要如何抓到 demo
与里面的小资料夹(还有资料)?
Step 3 我们是用 getFiles()
,这边我们就带大家来看看 getFolders()
怎麽样读取。
这边我们要用到的技巧叫做 DP (Dynamic Programming),简单来说就是(1)在根目录(或目标位置)执行 DP,去发现子目录,而(2)进到每个子目录後,一旦发现还有子子目录,就会再执行一次 DP,并且不断重复到找到全部的位置为止。
程序码长这样,是直接借用 rpm 在 Stakeholder 的回应:Google apps script - iterate folder and subfolder,觉得写得很好懂。其中的 getSubFolders(parent)
中还有 getSubFolders(child)
的写法,就是所谓的 DP。
function getSubFolders(parent) {
parent = parent.getId();
let childFolder = DriveApp.getFolderById(parent).getFolders();
while(childFolder.hasNext()) {
let child = childFolder.next();
Logger.log(child.getName());
getSubFolders(child);
}
return;
}
function listFolders() {
let parentFolder = DriveApp.getFolderById(drive_ID);
let childFolders = parentFolder.getFolders();
while(childFolders.hasNext()) {
let child = childFolders.next();
Logger.log(child.getName());
getSubFolders(child);
}
}
好,那执行起来会长什麽样子呢?(可以参考 Step 2 的架构图)——
但这样只有列出「目录」,又要怎麽样列出所有档案,包括子目录内的档案呢?让我们从 Step 5 来看看。
这边就要结合我们的 Step 3 和 Step 4 啦。我们先将 Step 3 改写成会读取输入的 Folder
Object 的 function。
function readFilesInFolder(folder){
let files = folder.getFiles();
while (files.hasNext()) {
let file = files.next();
Logger.log([file.getName(),file.getId()]);
};
}
接着,在将上面这段放入 Step 4 中。
function getSubFolders(parent) {
parent = parent.getId();
let childFolder = DriveApp.getFolderById(parent).getFolders();
while(childFolder.hasNext()) {
let child = childFolder.next();
Logger.log(child.getName());
readFilesInFolder(child)
getSubFolders(child);
}
return;
}
function listFolders() {
let parentFolder = DriveApp.getFolderById(drive_ID);
readFilesInFolder(parentFolder)
let childFolders = parentFolder.getFolders();
while(childFolders.hasNext()) {
let child = childFolders.next();
Logger.log(child.getName());
readFilesInFolder(child);
getSubFolders(child);
}
}
那接着我们执行看看——
补充的是,有人问说如果是在一进去 Google Drive 的根目录(没有 ID 的部分),要怎麽读?其实就是直接 getFiles()
就行了。这边是修改 官方范例的程序码 供大家参考。
function readAllFiles(){
// Log the name of every file in the user's Drive.
let files = DriveApp.getFiles();
while (files.hasNext()) {
let file = files.next();
Logger.log(file.getName());
}
}
一样按执行就好罗!好,那今天学了...
接着可以将结果参考 D8 写入 Google Sheet。好,那今天就是我们的 D9,明天 D10 会继续介绍结合读取档案後的操作模式。如果还有问题,透过留言之外,也可以到 Facebook Group,想开很久这次铁人赛才真的开起来哈哈哈,欢迎来当 Founding Member。如果不想错过可以订阅按赞小铃铛(?),也欢迎留言跟我说你还想知道什麽做法/主题。我们明天见。
09-14-2021 本章内容 子组件更新父组件的状态 设定组建间的状态 设定组建间事件处理的程序 ...
设定完成後,开启Django应用程序(APP)的views.py档案,这边就是撰写LINE Bot接...
从一开始的api流程到後面购物车以及订单, 今天我们终於又要将快要忘掉的金流给提起拉!! 首先让我们...
在写程序时,我们可能需要重复执行某些程序,总不可能每行程序一直复制贴上,这时候就会用到我们的回圈(l...
曾有一位与我合作的一线主管问过我一个问题:「我一直在学习观察,试着找出团队系统有没有问题,但我总觉得...