如何获取共享链接列表?

时间:2020-02-26 15:21:31

标签: google-apps-script

对于以下内容,所有文件均为 Google表格格式

我的问题: 我的工作环境的结构如下(文件夹/子文件夹):

RACINE:
-> ID4522
-> ID7852
-> ID5864
-> ....

跟踪文件“ FOLLOW_UP”位于RACINE文件夹中。 ID4522,ID7852和ID5864文件夹是RACINE文件夹的子文件夹。

我们在ID4522子文件夹中找到以下Google工作表文件“ Entry_Form_ID4522”,在ID7852子文件夹中找到以下Google工作表文件“ Entry_Form_ID7852”,…

重要说明:子文件(“ IDxxxx”格式)的数量可以随时更改,而不会发出警告。

我的愿望

很可能是通过javascript中的宏,从单元格B3以及向下的跟踪文件(“ FOLLOW_UP”)中检索每个文件“ Entry_Form_IDxxxx”的共享链接列表。子文件夹列表可以随时更改(例如,当我的客户添加带有关联的“ Entry_Form_IDxxxx”文件的文件夹时)。

先谢谢您。

关于。 杰罗姆(Jérôme)

2 个答案:

答案 0 :(得分:1)

递归文件URL的文件夹

我假设您只有一个名为RACINE的文件夹,并且其中只有一个名为“ FOLLOW UP”的文件,并且数据所在的工作表是最左侧的工作表。假设这是真的,那么此函数将从B列的= HYPERLINK()单元格中提取URL,从第3行一直到工作表末尾。

最初我跳到一个结论,即B列中有链接,并且您需要URL列表,因此此功能可能是您不想要的。请让我知道,我将其删除。

function getLinks() {
  const folder=DriveApp.getFoldersByName("RACINE").next();//assumes only one folder with that name
  const file=folder.getFilesByName("FOLLOW UP").next();//assumes only one file by that name
  const ss=SpreadsheetApp.openById(file.getId());
  const sh=ss.getSheets()[0];//the most left sheet in the spreadsheet
  const vs=sh.getRange(3,2,sh.getLastRow()-2,1).getFormulas();
  var links=[];
  vs.forEach(function(r,i){
    let v=r[0].match(/([^"]+)/g);
    links.push(v[1]);  
  })
  var ui=HtmlService.createHtmlOutput(links.join('<br />'));
  SpreadsheetApp.getUi().showModelessDialog(ui, "URLS");
  return links;//as an array
}

得出结论后

我认为这是您真正想要的,这是工作子目录中符合特定命名格式的文件的URL列表,如以下段落所述。我在此答案中使用后两个函数生成的一些数据上对此进行了测试。修正了几次输入错误后,它在正确的位置运行了非常漂亮的网址。

第一个功能基本上是启动器。它假定您在Google驱动器上只有一个名为“ RACINE”的文件夹。它调用一个递归函数,该函数本质上搜寻所有RACINE的子文件夹,以查找格式为“ Entry_Form_IDxxxx”的文件,其中xxxx均为0-9之间的数字。当找到类似的文件名时,它将把该URL加载到“ FOLLOW UP”的sheet [0]中columnB底部的下一个空单元格中。它还搜索格式为“ IDxxxx”的子目录,其中xxxx均为0到9的数字。当它通过从getFnF()内部调用getFnF()来递归找到这些子文件夹时。遵循这个过程可能会很困难,因此,如果您是新手,您可能会想雇用一些人来帮助您。

function getFileUrlsIntoB3() {
  const folder=DriveApp.getFoldersByName("RACINE").next();//assumes only one folder with that name
  getFnF(folder);  
}

以下函数将后续文件的ID放入递归函数中,以便可以将数据写入文件“ FOLLOW UP”的最左侧。它使用缓存服务,因此在第一次调用之后的所有调用都可以更快地进行,因为文件ID是直接从缓存获取的。缓存将最多保留此值3分钟,但您可以根据需要进行调整。

function getFollowUpId() {
  const cs=CacheService.getScriptCache();
  const cached=cs.get('FOLLOW UP ID');
  if(cached) {
    return cached;
  }else{
    let folder=DriveApp.getFoldersByName("RACINE").next();
    let file=folder.getFilesByName("FOLLOW UP").next();
    cs.put('FOLLOW UP ID',file.getId(),180);//3 minute cache time
    return file.getId();
  }
}

这是递归函数。这只是意味着它是一个自我调用的函数。

function getFnF(folder) {
  const ss=SpreadsheetApp.openById(getFollowUpId());
  var sh=ss.getSheets()[0];
  var files=folder.getFiles();
  while(files.hasNext()) {
    var file=files.next();
    if(file.getName().match(/^Entry_Form_ID\d{4}/)) {
      sh.getRange(getColumnHeight(2,sh,ss)+1,2).setValue(file.getUrl());
    }
  }
  var subfolders=folder.getFolders() 
  while(subfolders.hasNext()) {
    var subfolder=subfolders.next();
    if(subfolder.getName().match(/^ID\d{4}/)) {
      getFnF(subfolder);
    }
  }
}

最后是计算电子表格“ FOLLOW UP”的Sheet [0]中B列的当前高度的函数

function getColumnHeight(col,sh,ss){
  var ss=ss||SpreadsheetApp.getActive();
  var sh=sh||ss.getActiveSheet();
  var col=col||sh.getActiveCell().getColumn();
  var v=sh.getRange(1,col,sh.getLastRow(),1).getValues().map(function(r){return r[0];});
  var s=0;
  var h=0;
  v.forEach(function(e,i){if(e==''){s++;}else{s=0;}h++;});
  return (h-s);
}

测试

我使用以下两个功能创建了一些文件夹和文件,并发现测试代码很容易。它只有3个错字类型错误,然后就可以正常运行了。它只是创建ascii文本文件而不是电子表格,但它们仍然是文件。

function generateFoldersAndFiles() {
  const folder=DriveApp.getFolderById('RACINE FolderId');
  for(let i=0;i<4;i++) {
    let subfldr=folder.createFolder(getStrings("ID",4));
    for(let j=0;j<4;j++) {
      subfldr.createFile(getStrings("Entry_Form_ID",4),"Text Content");
    }
  }
}

function getStrings(prefix,length) {
  const nA=[0,1,2,3,4,5,6,7,8,9];
  var s=prefix;
  for(let i=0;i<length;i++) {
    s+=nA[Math.floor(Math.random()*nA.length)];
  }
  return s;
}

文件结构:

enter image description here

答案 1 :(得分:0)

是的,只有一个名为RACINE的文件夹和一个名为“ FOLLOW_UP”的文件。我不明白可以有多个文件夹和多个同名文件吗?我提醒您,我不是开发人员。

子文件夹(IDxxxx类型)的名称也是唯一的。我指定子文件夹的名称也可以采用IDxxxx_x的形式(例如ID4522_1)。

IDxxxx和IDxxxx_x子文件夹都位于RACINE文件夹中。

每个IDxxxx(和IDxxxx_x)子文件夹中都有一个Entry_Form_IDxxxx(或Entry_Form_IDxxxx_x)文件。只有一个Entry_Form_IDxxxx和Entry_Form_IDxxxx_x文件。

例如,在ID4522子文件夹中,存在文件“ Entry_Form_ID4522”(只有一个文件“ Entry_Form_ID4522”)。 例如,在ID4522_1子文件夹中,存在文件“ Entry_Form_ID4522_1”(只有一个文件“ Entry_Form_ID4522_1”)。

在每个IDxxxx或IDxxxx_x文件夹中,只有一个Entry_Form _...文件。

我想截图以更好地说明我的问题,但我不知道该怎么办?

我要在其中检索结果的文件(即“ Entry_Form_IDxxxx”文件的可共享链接)称为“ FOLLOW_UP”(“ feuille 1”选项卡)。

在“ FOLLOW_UP”文件(“ feuile 1”选项卡)中,这是我想要获得的:

例如,在单元格B3中: https://docs.google.com/spreadsheets/d/1VUf_t1gkv2lddfgsfgds7UhJeunrNzo2-QGcRe24/edit?usp=sharing

此链接将对应于找到的第一个文件的链接,例如“ Entry_Form_ID4522”

在单元格B4中: https://docs.google.com/spreadsheets/d/1VUf_jkghkdxjfghgjgjzo2-QGcRe24/edit?usp=sharing

此链接将对应于找到的第二个文件的链接,例如“ Entry_Form_ID7852”