0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

ファイル名をもとに勝手にフォルダ分けするGAS

Last updated at Posted at 2023-02-27

使用方法

ファイル名を、パスのようにしておく。
image.png
すると、ファイル名で指定したフォルダに勝手に移動される。
image.png
(又、移動後にrenameする)

ソースコード

コピペして、fileManagement関数にトリガーをセットしてください。 トリガーの間隔はなんでもいいです。(私は1時間に一度にしています。)
/**
 * ファイル名をもとに、特定のフォルダへそのファイルを移動する。
 * /test/test1/filename の場合、filenameという名前のファイルを、test>test1フォルダへ移動。
 * 振り分け後、ファイル名はpathではなくfilenameのみになる。
 * 注 : ルートフォルダのファイルにしか反応しない。
 * 注 : 同一フォルダ名で複数ある場合、後ろが優先。
 */

function fileManagement() {

  //最終更新が今日のファイルのみを対象にすることで、処理を軽くする。
  const today = Utilities.formatDate(new Date(),"JST","yyyy-MM-dd");
  const files = rootFolder.searchFiles(`modifiedDate >= "${today}"`);/**@type {DriveApp.FileIterator} */

  while(files.hasNext()){
    try{

      const file = files.next(); /**@type {DriveApp.File} */

      if(!file.getName().startsWith("/")) continue;

      //ファイル名を解析
      const fileInfo = file.getName().split("/"); //["",...path,filename]
      const filename = fileInfo[fileInfo.length-1]; /**@type {string} */
      const path = fileInfo.slice(1,fileInfo.length-1);

      // ファイル名でフォルダ指定がない場合、fileInfoは["",filename]
      if(!path.length) continue;

      //移動先の取得
      const directory = getDirectoryByPath(path);

      //移動
      file.moveTo(directory).setName(filename);

    }catch(e){

      console.log(e);

    }

  }
  
}


/**
 * @param {array} path [foldername1,foldername2,foldername3,...]
 */
function getDirectoryByPath(path){

  let directory;

  //対象フォルダの取得
  for(let i=0,l=path.length;i<l;i++){

    /**
     * @type {FolderMangerClass} directory
     */
    //初回はFolderManger.getFolder(),2回目以降はdirectory.getFolder()
    directory = (directory || FolderManager).getFolder(path[i]);

  }

  //directory: 
  //FolderMangerClass{
  //   currentFolder : DriveApp.Folder
  // } 
  return directory.currentFolder;/**@type {DriveApp.Folder} */

}


/**
 * 一度取得したフォルダを内部的にキャッシュすることで、パフォーマスの向上を期待
 */
class FolderManagerClass{

  /**
   * @param {DriveApp.Folder} 
   */
  constructor(currentFolder){

    this.currentFolder = currentFolder;
    return this;

  }

  /**
   * 指定のフォルダ名と一致するフォルダを取得。
   * @param {string} foldername
   * @return {FolderManagerClass} 同一ディレクトリに同一名のフォルダが複数ある場合、一番最後のフォルダを返す。
   */
  getFolder(foldername){

    //既に取得済みのフォルダはそのまま返す(処理の簡素化)
    if(this[foldername]) return this[foldername];

    //以降、新しく取得する際の処理際の処理
    
    //合致するフォルダの取得
    const folders = this.currentFolder.getFoldersByName(foldername);/**@type {DriveApp.FolderIterator} */
    let folder;
    while(folders.hasNext()) folder = folders.next();/**@type {DriveApp.Folder} */

    //内部的にキャッシュ => 次以降はガード節で引っかかる
    this[foldername] = new FolderManagerClass(folder);

    return this[foldername];

  }

}

const rootFolder = DriveApp.getRootFolder();
const FolderManager = new FolderManagerClass(rootFolder);



仕様

・ファイル名の先頭をスラッシュ(/)にしないと反応しません。
・同じフォルダの中に、同じ名前のフォルダが複数ある場合、一番後ろのフォルダが優先されます。
・ルートフォルダのファイルにしか反応しません。
・日付をyyyy/MM/ddで書くと、フォルダとして認識されてしまいます。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?