有没有办法循环所有文件夹和子文件夹,从所有工作簿中获取特定工作表并复制到我在 GAS 中的主工作表?

问题描述 投票:0回答:2

所以,我有一个名为“Evaluation”的文件夹,该文件夹有 2 个名为“N1”和“N2”的子文件夹。每个都有 5 个子文件夹,称为“A”、“B”、“C”、“D”和“E”。

现在,在文件夹 A、B、C、D、E 中,我有几个谷歌表格:它们都具有相同的结构。每本练习册中,都有一张名为“摘要”的表格。

我想从此摘要表中将 A1:C32 范围复制到主表,但我不知道如何操作。我在这里找到了一个代码,但是如果我更改文件夹的特定路径(我链接到一个单元格),它就会起作用;它在子文件夹中不起作用,所以每次我想提取信息时都必须更改它。

有没有一种方法可以从所有文件夹和子文件夹循环更新我的代码,而无需我与代码交互?这是我目前所拥有的。

function getdata() {
  //múltiples variables
   var destinationSpreadsheet,destinationSS_ID,destsheet,destrange,file,files,
      sourcerange,sourceSS,sourcesheet,srcSheetName,sourcevalues;
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var FolderDestino = ss.getSheetByName("SetUp").getRange('C1').getValue();
  srcSheetName = "Resumen";
  destinationSS_ID = "1v2Ga6SLgDBVzC4rxTt0dO6P3FGMPDM9MVf6-1r4Z4XQ";
  files = DriveApp.getFolderById(FolderDestino).getFiles(); //t01
  //files = DriveApp.getFolderById("11nqc2K_J4zKjBBIFYj2qvwrCIxf1o7aJ").getFiles(); //t02
  //files = DriveApp.getFolderById("1UaQkdZeYj_OQkiBPlgjZOnIGqWb7xk3r").getFiles(); //t03
  //files = DriveApp.getFolderById("1E6uW66LVr6nNM3fT77iuIquuEW5UyIxj").getFiles(); //t04
  //files = DriveApp.getFolderById("1nEaKpb7YkCWG6LhYdjn3lQDPyQM0ILtu").getFiles(); //t05
  
  destinationSpreadsheet = SpreadsheetApp.openById(destinationSS_ID);
  destsheet = destinationSpreadsheet.getSheetByName('Base');  

  while (files.hasNext()) {
    file = files.next();
    if (file.getMimeType() !== "application/vnd.google-apps.spreadsheet") {
      continue;
    };
    sourceSS = SpreadsheetApp.openById(file.getId());
    sourcesheet = sourceSS.getSheetByName(srcSheetName);
    //sourcesheet.getRange(start row, start column, numRows, number of Columns)
    sourcerange = sourcesheet.getRange(8,1,sourcesheet.getLastRow()-1,3);
    sourcevalues = sourcerange.getValues();

    //Write all the new data to the end of this data
    destrange = destinationSpreadsheet.getSheetByName("Base")
        .getRange(destsheet.getLastRow()+1,1,sourcevalues.length,sourcevalues[0].length);

    destrange.setValues(sourcevalues);         
  };
};

如有任何帮助,我们将不胜感激。

loops google-apps-script google-sheets merge
2个回答
0
投票

这是递归执行某些操作的基本示例,我希望与您的要求类似。

需要的事情之一是遍历树的函数访问外部静态内存的方法,以便我们可以在必须退出或递归到另一个级别时保存数据,我通常使用cacheService或PropertiesService。在微处理器的早期,我在 CPU 周围开发自己的高速缓存来满足这种需求,如果你有这种内存访问,递归循环可以比大多数其他类型的结构化编程运行得快得多。尽管如此,对于那些不熟悉它们的人来说调试它们可能相当困难。我必须承认我认为这是一个巨大的优势。

第一个函数通过找到起始文件夹并调用随后遍历树的函数来开始工作。

function getFileIds() {
  const evalFolder = DriveApp.getFolderById(gobj.globals.testfolderid);
  let fid = [];
  PropertiesService.getScriptProperties().setProperty("fid",JSON.stringify(fid));
  getff(evalFolder);
  fid = JSON.parse(PropertiesService.getScriptProperties().getProperty("fid"));
  const ss = SpreadsheetApp.getActive();
  const sh = ss.getSheetByName("Sheet0");
  sh.clearContents();
  let o = fid.map(id => [id]);
  o.unshift(['IDs']);
  sh.getRange(1,1,o.length,o[0].length).setValues(o);//now you have a list of all of these spreadsheet id's in your folders and you can now easily access them sequentially for building your report.
}

function getff(folder) {
  let fid = JSON.parse(PropertiesService.getScriptProperties().getProperty("fid"));
  let files = folder.getFilesByType(MimeType.GOOGLE_SHEETS);
  while(files.hasNext()) {
    let file = files.next();
    let ss = SpreadsheetApp.openById(file.getId());
    if(ss.getSheets().filter(sh => sh.getName() == "Summary").length == 1) {
      fid.push(file.getId());
      PropertiesService.getScriptProperties().setProperty("fid",JSON.stringify(fid));
    }
  }
  let subfolders = folder.getFolders();
  while(subfolders.hasNext()) {
    let subfolder = subfolders.next();
    getff(subfolder);
  }
}

复制粘贴所有数据到master中

function copyPaste() {
  const ss = SpreadsheetApp.getActive();
  const msh = ss.getSheetByName("Master");
  const idsh = ss.getSheetByName("Sheet0");
  const ids = idsh.getRange(2,1,idsh.getLastRow() - 1).getValues().flat();
  ids.forEach(id => {
    let ss = SpreadsheetApp.openById(id);
    let sh = ss.getSheetByName("Summary");
    let vs = sh.getRange(A1:C32).getValues()
    msh.getRange(msh.getLastRow() + 1, 1,vs.length,vs[0].length).setValues(vs);
  })
}

0
投票

我尝试执行相同的代码,它获取文件的所有 id,但是,我无法从该文件获取信息,我是否需要将脚本的第二部分放在不同的选项卡上?

© www.soinside.com 2019 - 2024. All rights reserved.