さまざまなフォルダにあるファイルのIDを取得します

Nov 20 2020

これは、このスレッドのフォローアップの質問です。

別のフォルダにあるファイルのIDを取得する方法はありますか?以下は私が取り組んでいるもののディレクトリです。

そして、これは私が使用しているコードです。

function myFunction() {
  const ss = SpreadsheetApp.getActive();
  
  var SSID =  ss.getId(); //sheet id
  var spreadsheetFile =  DriveApp.getFileById(SSID);
  var folderId = spreadsheetFile.getParents().next().getId();
  
  const sh = ss.getSheetByName('Sheet4'); // change that to the name of your sheet
  const filenames = sh.getRange('B3:B').getValues().flat().filter(r=>r!='');
  const IDs = [];
  const Folder = DriveApp.getFolderById(folderId);
  
  filenames.forEach(fn=>{
      let Files = Folder.getFilesByName(fn);
      while(Files.hasNext()){
          let file = Files.next();
          IDs.push([file.getId()]);
      }
  });
  sh.getRange(3,3,IDs.length,1).setValues(IDs);
}

このコードは、ファイルがフォルダーにある場合は正常に機能しますが、サブフォルダーまたは別のフォルダーでは機能しません。

以下は私が取り組んでいるシートです。

回答

1 Tanaike Nov 21 2020 at 02:10

この場合、目標を達成するために、次のフローはどうですか?

  1. 内のすべてのファイルのファイルリストを取得しますfolderId
  2. Spreadsheetに値を入力するための配列を作成します。

スクリプトを変更すると、次のようになります。

変更されたスクリプト:

から:
const IDs = [];
const Folder = DriveApp.getFolderById(folderId);

filenames.forEach(fn=>{
    let Files = Folder.getFilesByName(fn);
    while(Files.hasNext()){
        let file = Files.next();
        IDs.push([file.getId()]);
    }
});
に:
const Folder = DriveApp.getFolderById(folderId);

// 1. Retrieve the file list of all files in `folderId`.
const getFileList = (f, folders = [], fileList = {}) => {
  const fs = f.getFiles();
  while (fs.hasNext()) {
    const file = fs.next()
    fileList[file.getName()] = file.getId();
  }
  const fols = f.getFolders();
  const folderObjs = [];
  while (fols.hasNext()) folderObjs.push(fols.next());
  if (folderObjs.length > 0) {
    folders.push(folderObjs);
    folderObjs.forEach(fol => getFileList(fol, folders, fileList));
  }
  return fileList;
};
const fileList = getFileList(Folder);

// 2. Create an array for putting values to Spreadsheet.
const IDs = filenames.map(fn => [fileList[fn] || ""]);

注意:

  • この場合、スプレッドシートの「B」列に同じファイル名が存在しないと想定しています。これに注意してください。
1 puffin Nov 21 2020 at 02:15

ここにはいくつかのオプションがあります。まずDriveApp.getFoldersByName(name)、指定された名前に一致するドライブ内のすべてのフォルダのリストを返すメソッドがあります。もちろん、実行前にフォルダの名前を知っている必要があり、同じ名前の他のフォルダを持つことはできません。そうしないと、リスクがあります。間違ったフォルダのIDを取得しています。

フォルダツリーの上位にあるフォルダのIDがわかっている場合(上記の例に示されているスクリプトの直接の親など、を参照File.getParents())、を使用して上記の方法の影響を制限できますFolder.getFoldersByName(name)。ここでは上記と同じ制限が適用されますが、より高速になります(反復するファイルが少なくなります)が、親フォルダーのIDが必要です。

アクセスするファイルがわかっていて、スクリプトの実行全体で一定のままである場合は、URLからフォルダーIDをコピーして、定数変数として保存することもできます。もちろん、この方法は、実行前にファイルを作成する必要があるため、より厳密です。ただし、ディレクトリツリーを反復処理する必要がないため、高速になります。