取引先から届く請求書や納品書をGoogleドライブの受領フォルダに集めているものの、種類別・年月別への振り分けを手作業で続けている場合、ファイル数が増えるほど整理が後回しになりがちです。
Google Apps Scriptを使うと、受領フォルダのファイルを種類と年月ごとのフォルダへ自動で振り分ける仕組みを作れます。
以下では、その具体的な作り方を、誤って別の場所へ移動しないためのテスト手順まで整理しています。
完成イメージと仕組み
完成すると、受領フォルダに置いたファイルが定期実行のたびに読み取られ、種類ごとのフォルダへ、さらにその中の作成年月ごとのフォルダへ自動で移動する状態です。
内部では、DriveApp が受領フォルダ内のファイルを1件ずつ取り出し、種類に応じたフォルダ名と作成日から求めた年月フォルダ名を組み立て、moveTo() で該当フォルダへ移します。
フォルダが存在しなければスクリプト側で自動作成するため、新しい種類のファイルが届いても振り分け先を事前に用意しておく必要はありません。
Google Apps Scriptでどの業務から自動化すべきか迷う場合は、判断基準を別記事で整理しています。

手順
準備からトリガー設定まで、4つのステップで完成します。
Step1. フォルダとログ用シートを準備する
整理対象にする受領フォルダと、振り分け先の格納先ルートフォルダをGoogleドライブ上にそれぞれ作成し、URLに含まれるフォルダIDを控えます。
続けて移動履歴を記録するログ用に、新規のスプレッドシートも1つ用意しておきましょう。
後から「いつ・どのファイルが・どこへ移動したか」を追跡できるようになります。
Step2. コードを貼り付ける(コード全文)
格納先ルートフォルダに紐づくどのスプレッドシートでもよいので、拡張機能からApps Scriptを開き、次のコードを貼り付けます。
const CONFIG = {
sourceFolderId: 'YOUR_SOURCE_FOLDER_ID', // ★ここを変える: 整理対象の受領フォルダID
destinationRootId: 'YOUR_DESTINATION_ROOT_ID', // ★ここを変える: 振り分け先ルートフォルダID
logSheetId: 'YOUR_LOG_SHEET_ID', // ★ここを変える: 移動履歴を記録するスプレッドシートID
isDryRun: true, // ★ここを変える: true=移動せずログのみ記録、false=実際に移動
};
function organizeDriveFiles() {
const sourceFolder = DriveApp.getFolderById(CONFIG.sourceFolderId);
const destinationRoot = DriveApp.getFolderById(CONFIG.destinationRootId);
const logSheet = SpreadsheetApp.openById(CONFIG.logSheetId).getActiveSheet();
// 移動中に受領フォルダの中身が変わって取りこぼさないよう、先に全ファイルを取得しておく
const fileIterator = sourceFolder.getFiles();
const files = [];
while (fileIterator.hasNext()) {
files.push(fileIterator.next());
}
for (const file of files) {
moveFileByTypeAndDate(file, destinationRoot, logSheet);
}
}
function moveFileByTypeAndDate(file, destinationRoot, logSheet) {
const typeFolderName = getTypeFolderName(file);
const dateFolderName = Utilities.formatDate(file.getDateCreated(), Session.getScriptTimeZone(), 'yyyy-MM');
const typeFolder = getOrCreateFolder(destinationRoot, typeFolderName);
const dateFolder = getOrCreateFolder(typeFolder, dateFolderName);
if (!CONFIG.isDryRun) {
file.moveTo(dateFolder);
}
logSheet.appendRow([
new Date(),
file.getName(),
file.getId(),
`${typeFolderName}/${dateFolderName}`,
CONFIG.isDryRun ? 'テストのみ(未移動)' : '移動済み',
]);
}
function getTypeFolderName(file) {
const mimeType = file.getMimeType();
if (mimeType === MimeType.PDF) {
return 'PDF';
}
if (mimeType === MimeType.GOOGLE_SHEETS || mimeType === MimeType.MICROSOFT_EXCEL) {
return 'スプレッドシート';
}
if (mimeType === MimeType.GOOGLE_DOCS || mimeType === MimeType.MICROSOFT_WORD) {
return 'ドキュメント';
}
if (mimeType === MimeType.JPEG || mimeType === MimeType.PNG) {
return '画像';
}
return 'その他';
}
function getOrCreateFolder(parentFolder, folderName) {
const existingFolders = parentFolder.getFoldersByName(folderName);
if (existingFolders.hasNext()) {
return existingFolders.next();
}
return parentFolder.createFolder(folderName);
} ファイルの種類は getTypeFolderName が判定する部分です。
getOrCreateFolder は振り分け先フォルダを名前で探し、見つからなければ新規に作ります。
CONFIG.isDryRun が true の間は moveTo() が実行されず、ログの記録だけが行われる点が誤移動を防ぐ土台になります。
Step3. 振り分け条件を自社の運用に合わせる
getTypeFolderName の判定条件と格納先フォルダ名の対応は、次の表のとおりです。
| ファイルの種類 | 判定に使うMimeType | 格納先フォルダ名 |
|---|---|---|
| PDFファイル |
| |
| 表計算ファイル |
| スプレッドシート |
| 文書ファイル |
| ドキュメント |
| 画像ファイル |
| 画像 |
| 上記に該当しないファイル | 条件なし(既定値) | その他 |
分類を増やしたい場合は、getTypeFolderName の中に if 文を1つ追加し、対応する MimeType と戻り値のフォルダ名を書くだけで対応できます。
年月フォルダの単位を変えたい場合は、Utilities.formatDate に渡している 'yyyy-MM' の書式を 'yyyy'(年のみ)などに変更してください。
Step4. テストモードで実行し、時間トリガーを設定する
CONFIG.isDryRun を true にしたまま organizeDriveFiles を一度実行し、ログ用シートに想定どおりの移動先が記録されるか確認します。
問題がなければ isDryRun を false に変更し、少数のファイルで実際に移動されることを確認したうえで、スクリプトエディタの時計マークから時間主導型のトリガーを追加します。
実行する関数には organizeDriveFiles を選び、種類は日付ベースまたは時間ベースのタイマーを選んで保存してください。
これで、受領フォルダに新しいファイルが届くたびに自動で振り分けられる状態になります。
整理したファイルの内容をスプレッドシートで管理したい場合は、受信メールの転記方法も参考になります。

誤移動を防ぐテスト手順
moveTo() はファイルの中身を変えず親フォルダの参照だけを書き換える処理なので、万が一違うフォルダへ移動しても、移動先フォルダを開けばファイルはそのまま見つかります。
とはいえ振り分け先が数十にもなると、目視で探し出す手間はばかになりません。
本番実行の前に、次の順番でテストしておくと安心です。
まず isDryRun: true のまま一度実行し、ログ用シートに記録された「想定される移動先」の列をひとつずつ目で確認します。
このとき、想定と違うフォルダ名が並んでいたら、それはgetTypeFolderNameの判定条件がファイルの実態と合っていないサインです。
次に、受領フォルダの中身を一時的に数件だけ残した状態で isDryRun: false にして実行し、実際の移動結果と格納先ルートフォルダのフォルダ構成を照合します。
ここまで問題がなければ、受領フォルダを元の件数に戻してから時間トリガーを有効にします。
トリガーを有効化した後も、しばらくはログ用シートの「移動済み」の行数と実際に振り分けられたファイル数を突き合わせておいてください。
その習慣があれば、想定外の分類が紛れ込んでもすぐに気づけます。
Google Apps Scriptでのドライブ整理について相談してみませんか?
「振り分け条件をどう設計すれば自社のファイル運用に合うか分からない」「誤って移動したときの復旧手順まで含めて設計してほしい」「社内にGoogle Apps Scriptを設計できる人材がいない」
少しでもお心当たりがあれば、お気軽にご相談ください。
現在、Google Apps Scriptを使った業務自動化のお悩みをお伺いする 無料の個別相談 を実施しています。
よくある質問
Q. サブフォルダの中にあるファイルも整理の対象にできますか?
コードのままでは受領フォルダ直下のファイルだけが対象です。
サブフォルダの中まで対象にしたい場合は、sourceFolder.getFolders() でサブフォルダを取得し、それぞれに対して同じ処理を再帰的に呼び出す形に書き換える必要があります。
Q. 同じ名前のファイルが移動先に既にある場合はどうなりますか?
Googleドライブは同じフォルダ内に同名ファイルが複数あることを許容する仕様のため、上書きされず両方のファイルが残ります。
ファイル名の重複を避けたい場合は、移動前にファイル名を書き換える処理を追加してください。
Q. スプレッドシートやドキュメント以外のGoogle独自形式にも対応できますか?
getTypeFolderName に判定条件を追加すれば対応できます。
Googleスライドであれば MimeType.GOOGLE_SLIDES、Googleフォームであれば MimeType.GOOGLE_FORMS を条件に加えてください。
Q. 実行間隔はどれくらいにすればよいですか?
受領フォルダにファイルが届く頻度に合わせるのが基本です。
1日に数件程度であれば1時間おき、まとまった件数が一度に届く運用であれば1日1回の実行でも整理漏れは起きません。