GASで企業のフォルダーをたくさん作る作業メモ
企業一覧のCSVから、グーグルドライブの企業のフォルダをたくさん作って、そのフォルダURLをCSVに追記するという作業をした時のメモです。
ディレクトリ構成
CompanyDirs ├ 企業A └ 商品画像 └ 企業B └ 商品画像 CreateCompanyDirsScript ├ CreateCompanyFolders.gs ├ CreateCompanyFoldersImport.csv ├ CreateCompanyFoldersExport.ss └ README
README
## インストール ### 1. Google Apps Script Install [Google Apps Script chorome拡張をインストールする](https://chrome.google.com/webstore/detail/google-apps-script/eoieeedlomnegifmaghhjnghhmcldobl?hl=ja) ### 2. CSVをアップロード マイドライブ > CreateCompanyFoldersScript に以下条件のCSVをアップロード。 - フォーマットは「得意先コード/企業名/店舗名」の3つに整形 - 文字コードは、UTF-8(SJISはサポート外) ### 3. スクリプトを実行 マイドライブ > CreateCompanyFoldersScript > CreateCompanyFolders の設定を確認。 問題なければ再生ボタンでスクリプト実行。 ## スクリプトの仕様 既にある企業や店舗、店舗ごとのフォルダはそのまま、新規追加分だけ新しく追加される。 ## 店舗が増えて本店の名前が変わった場合 ### 1. ドライブでフォルダ名を変更 対象企業の「本店」->「〇〇店」 ### 2. CSVを作成 追加分の企業と店舗を入れたCSVを作成 ※注 空だったところに「〇〇店」を追記忘れずに ### 3. インポート インストール手順の2-3を実行
CreateCompanyFolders.gs
GASには5分の実行制限があるので、トリガー機能を使ってそれ以降の処理を出来るようにしました。 ただし、トリガーには厳しいAPI制限があるので、5000件中、4000件くらいしか出来ませんでした。 なので、残りの1000件は別の日に再実行しました。 最後の実行記録はストアに保存されているので、再実行すれば続きから実行出来ます。
var Lib = new function() { this.getItem = function (item) { return (item.hasNext())? item.next() : false; } this.deleteItem = function (item) { var file = this.getItem(item); if (file) { file.setTrashed(true); return true; } return false; } this.getCsv = function (targetDir, csvName) { var csvFile = this.getItem(targetDir.getFilesByName(csvName)); if (!csvFile) { return null; } return Utilities.parseCsv(csvFile.getBlob().getDataAsString("utf8")); } this.createDir = function (targetDir, dirName) { var dir = this.getItem(targetDir.getFoldersByName(dirName)); if (!dir) { dir = targetDir.createFolder(dirName); } return dir; } this.createDirList = function (targetDir, companyName, shopName, shopDefaultDirs) { var result = { companyDirUrl: "", shopDirUrl: "", }; var companyDir = this.createDir(targetDir, companyName); result.companyDirUrl = companyDir.getUrl(); var shopDir = this.createDir(companyDir, shopName); result.shopDirUrl = shopDir.getUrl(); for (var idx in shopDefaultDirs) { var dirName = shopDefaultDirs[idx]; var shopInDir = this.createDir(shopDir, dirName); } return result; } this.editSs = function (targetDir, sheetName) { var ssId; var file = this.getItem(targetDir.getFilesByName(sheetName)); if (!file) { ssId = SpreadsheetApp.create(sheetName).getId(); var tmpSs = DriveApp.getFileById(ssId); DriveApp.getRootFolder().removeFile(tmpSs); targetDir.addFile(tmpSs); } return (file)? SpreadsheetApp.open(file) : SpreadsheetApp.openById(ssId); } this.saveSsRow = function (ssInstance, targetLine, row) { Logger.log([targetLine, row]); ssInstance.getRange(targetLine, 1, 1, row.length).setNumberFormat('@').setValues([row]); } this.setTrigger = function (triggerKey, functionName) { this.deleteTrigger(triggerKey); var triggerId = ScriptApp.newTrigger(functionName).timeBased().after(10000).create().getUniqueId(); Logger.log(triggerId + "triggerId"); PropertiesService.getScriptProperties().setProperty(triggerKey, triggerId); } this.deleteTrigger = function (triggerKey) { var triggerId = PropertiesService.getScriptProperties().getProperty(triggerKey); if (!triggerId) return; ScriptApp.getProjectTriggers().filter(function(trigger){ return trigger.getUniqueId() == triggerId; }) .forEach(function (trigger) { ScriptApp.deleteTrigger(trigger); }); PropertiesService.getScriptProperties().deleteProperty(triggerKey); } }(); function myFunction() { var startTime = new Date(); var triggerKey = "CreateCompanyFolders"; var outputDir = Lib.getItem(DriveApp.getFoldersByName("CompanyFolders")); // 出力先のフォルダー名 var scriptDir = Lib.getItem(DriveApp.getFoldersByName("CreateCompanyFoldersScript")); // スクリプトがあるフォルダー名 var shopDefaultDirs = ["商品画像"]; // 店舗内に作成するフォルダー名 var headerList = ["企業ID","企業名","店舗名","店舗フォルダーURL"]; // 出力するSSのヘッダー名 var exportSs = Lib.editSs(scriptDir, "CreateCompanyFoldersExport").getActiveSheet(); // 出力するSS名 var rows = Lib.getCsv(scriptDir, "CreateCompanyFoldersImport.csv"); // インポーとするCSVファイル名 if (rows == null) { Logger.log("インポートデータ無し"); return; } // スタート行を設定 var properties = PropertiesService.getScriptProperties(); var startIdx = parseInt(properties.getProperty("startIdx")) || 1; // ヘッダー書き込み Lib.saveSsRow(exportSs, 1, headerList); for (var idx=0; idx<rows.length; idx++) { if (idx < startIdx) continue; // 4分経過すると新規トリガー if (parseInt((new Date() - startTime) / (1000 * 60)) >= 4) { properties.setProperty("startIdx", idx); Lib.setTrigger(triggerKey, "myFunction"); Logger.log(startIdx + '-' + idx + "Complete!"); return; } var companyId = rows[idx][0].trim(); var companyName = rows[idx][1].trim(); var shopName = rows[idx][2].trim(); if (!(companyId && companyName)) { Logger.log("不正なデータ" + idx + "行目"); continue; } if (!shopName) { shopName = "本店"; } var dirUrlList = Lib.createDirList(outputDir, companyName, shopName, shopDefaultDirs); Lib.saveSsRow(exportSs, idx + 1, [companyId, companyName, shopName, dirUrlList.shopDirUrl]); } Lib.deleteTrigger(triggerKey); properties.deleteProperty("startIdx"); Logger.log("完了!"); }