GAS:将 Google 中多个 Google 工作表文档(工作簿)的数据合并到一个工作簿中

GAS: Combine Data from Multiple Google Sheets Documents (Workbooks) in Google Drive into One Workbook

我有多个工作 sheet 存储在一个文件夹中,我想做的是通读每个 sheet(特别是每个 sheet 的 D 和 H 列)并通过将列映射到行来将数据附加到主文件(与 Google 表单处理 google sheet 上的响应的方式相同)。

下一步是将读取的文件移动到另一个文件夹中。我已经做了一些挖掘并提出了下面的代码,但我遇到了一些挑战,非常感谢帮助:

(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;
}

你有两个问题。

如何移动 Google 驱动器中的文件

您只需要移动到的文件 ID 和文件夹 ID。浏览 google 驱动器时,都可以在 URL 中看到。

这是一个执行它的函数:

function changeLocation(folderToMoveToID,fileID) {
  var destinationFolder = DriveApp.getFolderById(folderToMoveToID);
  var theFileToMove = DriveApp.getFileById(fileID);
  theFileToMove.moveTo(destinationFolder);
}

稍后我会尝试回答其他问题。

获取特定列:

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

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;
}

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

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);
}

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

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);