└── Code.gs /Code.gs: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * Author: Nick Young - @techupover | techupover.com 4 | * 5 | * 6 | * CREDITS 7 | * Kudos to https://www.pbainbridge.co.uk/2020/06/bulk-create-google-drive-folders-20.html 8 | * and various stackoverflow threads for filling in some gaps about how things work 9 | */ 10 | 11 | /** 12 | * 13 | * CHANGE THESE VARIABLES PER YOUR PREFERENCES 14 | * 15 | */ 16 | 17 | const CUSTOM_MENU_NAME = 'Neat Features'; // the name of the new menu in your google sheet 18 | const CUSTOM_MENU_ITEM = 'Generate Folders Now'; // the menu item you'll click to run the script 19 | const DATA_TAB_NAME = 'folder_data'; // name for the sheet tab that contains the folder info that will be created/processed 20 | const LOG_TAB_NAME = 'log'; // name of the sheet tab that will store the log messages from this script 21 | const DATE_FORMAT = 'yyyy-MM-dd HH:mm:ss'; // date format to use for the log entries. Probably dont change this unless you really really want to. 22 | 23 | /** 24 | * 25 | * DO NOT CHANGE ANYTHING UNDER THIS LINE 26 | * 27 | * ONLY CHANGE THINGS IN THE CONFIG.GS FILE 28 | * 29 | */ 30 | 31 | /** 32 | * When the spreadsheet is open, add a custom menu 33 | */ 34 | function onOpen() { 35 | var spreadsheet = SpreadsheetApp.getActive(); 36 | var customMenuItems = [ 37 | {name: CUSTOM_MENU_ITEM, functionName: 'processGoogleSheetData_'} 38 | ]; 39 | spreadsheet.addMenu(CUSTOM_MENU_NAME, customMenuItems); 40 | } 41 | 42 | /** 43 | * Bulk create Google Folders from data within a Google Sheet. 44 | * This is the function to call from the custom menu item. 45 | * Others are referenced by this one. 46 | */ 47 | function processGoogleSheetData_() { 48 | 49 | // get current spreadsheet 50 | var ss = SpreadsheetApp.getActiveSpreadsheet(); 51 | 52 | // Log starting of the script 53 | logEventToGoogleSheet('Script has started'); 54 | 55 | // display Toast notification 56 | ss.toast('Starting!!!', 'Yep, we are starting...now.'); 57 | 58 | // get TimeZone 59 | var timeZone = ss.getSpreadsheetTimeZone(); 60 | 61 | // get Data sheet 62 | var dataSheet = ss.getSheetByName(DATA_TAB_NAME); 63 | 64 | // get all data as a 2-D array 65 | var data = dataSheet.getDataRange().getValues(); 66 | 67 | // create a name:value pair array to send the data to the next Function 68 | var spreadsheetData = {ss:ss, timeZone:timeZone, dataSheet:dataSheet, data:data}; 69 | 70 | // run Function to create Google Folders 71 | var doCreateFolders = createFolders(spreadsheetData); 72 | 73 | // check success status 74 | if (doCreateFolders) { 75 | // display Toast notification 76 | ss.toast('Script complete', 'Finished'); 77 | } 78 | else { 79 | // script completed with error 80 | // display Toast notification 81 | ss.toast('Got some errors. Check the logs', 'Finished'); 82 | } 83 | 84 | // Log starting of the script 85 | logEventToGoogleSheet('Script finished'); 86 | 87 | 88 | } 89 | 90 | 91 | /** 92 | * Loop through each row and create folders, set permissions 93 | */ 94 | function createFolders(spreadsheetData) { 95 | 96 | // extract data from name:value pair array 97 | var ss = spreadsheetData['ss']; 98 | var timeZone = spreadsheetData['timeZone']; 99 | var dataSheet = spreadsheetData['dataSheet']; 100 | var data = spreadsheetData['data']; 101 | 102 | // get last row number so we know when to end the loop 103 | var lastRow = dataSheet.getLastRow(); 104 | 105 | var folderIdMap = new Object(); 106 | 107 | // start of loop to go through each row iteratively 108 | for (var i=1; i