首页 > 解决方案 > GAS:将 Google Drive 中多个 Google Sheets 文档(工作簿)中的数据合并到一个工作簿中

问题描述

我有多个工作表存储在一个文件夹中,我想做的是通读每张工作表(特别是每张工作表的 D 和 H 列),并通过将列映射到行来将数据附加到主文件(与谷歌相同的方式表单与谷歌表格上的回复一起使用)。

下一步是在读取文件后将读取的文件移动到另一个文件夹中。我做了一些挖掘并想出了下面的代码,但遇到了一些挑战,希望能得到以下帮助:

(a) 将列数据(D 和 H)获取到主文件的单行。(b) 读取后将复制的文件移动到不同的文件夹中。

function combinesheets() {
  const folder = DriveApp.getFolderById(Copy_Folder_id)
  const filesIterator = folder.getFiles();
  const ws = SpreadsheetApp.openById(Stage_sheet_id);
  const ss = ws.getSheetByName("Project List");
  let combinedata = [];
  while(filesIterator.hasNext()){
    file = filesIterator.next();
    fileType = file.getMimeType();
    if(fileType === "application/vnd.google-apps.spreadsheet"){
      ssID = file.getId();
      const data = getDataFromSpreadsheet(ssID);
      combinedata.concat(data);
    }
  }
  ss.getRange(2,1,1,combinedata.length).setValues([combinedata]);
}

function getDataFromSpreadsheet(){
  var ss =  SpreadsheetApp.openById(ssID);
  var ws = ss.getSheets()[0]
  var data =  ws.getRange("A1:I" + ws.getLastRow()).getValues();
  data = data.reduce((acc,row) => acc.concat([row[3], row[7]]), []);
  return data;
}

标签: javascriptarraysgoogle-apps-scriptgoogle-sheetsmapping

解决方案


获取特定列:

您可以使用reduce将某些列中的值获取到单个数组中,然后可以将其添加到电子表格行中:

function getDataFromSpreadsheet(ssID){
  var ss =  SpreadsheetApp.openById(ssID);
  var ws = ss.getSheets()[0]
  var data =  ws.getRange("A1:I" + ws.getLastRow()).getValues();// how do I get the columns I want here (D & H)
  data = data.reduce((acc,row) => acc.concat([row[3], row[7]]), []);
  return data;
}

然后,您需要将此数据添加到主工作表中。考虑到data来自不同电子表格的数据可能具有不同的长度,我建议在循环内调用appendRow而不是在外部调用setValues一次(因为,如果所有源列的长度不同,则必须修改生成的数组以使它们大小相同;虽然可以这样做并且可以提高效率,但我不确定这是否值得,特别是如果您没有很多电子表格):

function combinesheets() {
  const folder = DriveApp.getFolderById(Copy_Folder_id)
  const filesIterator = folder.getFiles();
  const ws = SpreadsheetApp.openById(Stage_sheet_id);
  const ss = ws.getSheetByName("Project List");
  while(filesIterator.hasNext()){
    file = filesIterator.next();
    fileType = file.getMimeType();
    if(fileType === "application/vnd.google-apps.spreadsheet"){
      ssID = file.getId();
      const data = getDataFromSpreadsheet(ssID);
      ss.appendRow(data);
    }
  }
}

如果所有列的长度都相同,则可以改为:

function combinesheets() {
  const folder = DriveApp.getFolderById(Copy_Folder_id)
  const filesIterator = folder.getFiles();
  const ws = SpreadsheetApp.openById(Stage_sheet_id);
  const ss = ws.getSheetByName("Project List");
  let combinedata = [];
  while(filesIterator.hasNext()){
    file = filesIterator.next();
    fileType = file.getMimeType();
    if(fileType === "application/vnd.google-apps.spreadsheet"){
      ssID = file.getId();
      const data = getDataFromSpreadsheet(ssID);
      combinedata.push(data);
    }
  }
  ss.getRange(2,1,combinedata.length, combinedata[0].length).setValues(combinedata);
}

最后,如果来自不同工作表的所有数据都应该在同一行中,您可以这样做:

function combinesheets() {
  const folder = DriveApp.getFolderById(Copy_Folder_id)
  const filesIterator = folder.getFiles();
  const ws = SpreadsheetApp.openById(Stage_sheet_id);
  const ss = ws.getSheetByName("Project List");
  let combinedata = [];
  while(filesIterator.hasNext()){
    file = filesIterator.next();
    fileType = file.getMimeType();
    if(fileType === "application/vnd.google-apps.spreadsheet"){
      ssID = file.getId();
      const data = getDataFromSpreadsheet(ssID);
      combinedata.concat(data);
    }
  }
  ss.getRange(2,1,1,combinedata.length).setValues([combinedata]);
}

移动文件:

要将文件移动到另一个文件夹,您只需通过DriveApp检索文件和目标文件夹,然后调用:

const file = DriveApp.getFileById("FILE_ID");
const folder = DriveApp.getFolderById("FOLDER_ID");
file.moveTo(folder);

推荐阅读