Advertisement
cedroid

Google Appscript format batchs of tabs within a Google Sheet

Jan 18th, 2024
1,205
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
JavaScript 7.42 KB | Software | 0 0
  1. /*
  2. The success of the entire script, especially the formatting, hinges on the correct setup of the getColumnFormats() function. It's essential that the column names and their corresponding formats in this function accurately reflect the actual data structure in your sheets for the script to work effectively.
  3.  
  4. The script below is based on a google sheet that contains hotel reservations data but the column order and the cell formatting was not correct, the issue was happening with hundreds of tabs within the same sheet, modify the script according to your needs:
  5.  
  6. 1. processSheets()
  7. This is the main function that initiates the processing of all sheets in the active spreadsheet. It performs several key tasks:
  8.  
  9. - Retrieves all the sheets in the spreadsheet.
  10. - Creates or accesses the 'Formatting Logs' sheet for tracking progress.
  11. - Processes each sheet (up to 30 at a time for resource management).
  12. - Logs the processing status (success or error) for each sheet.
  13. - Displays a notification summarizing the number of sheets successfully processed and those with errors.
  14.  
  15. 2. processSingleSheet(sheet, columnFormats)
  16. Processes an individual sheet by:
  17.  
  18. - Checking if the sheet has any columns and rows.
  19. - Sorting the columns alphabetically based on headers.
  20. - Writing the sorted data back to the sheet.
  21. - Applying formatting to each column based on predefined rules.
  22. - Returning the status of processing (success or error with notes).
  23.  
  24. 3. applyFormat(range, formatInfo)
  25. - Applies formatting to a given range in a sheet. It uses the format information specified in the formatInfo parameter. The function switches between different types of data (date, text, number, currency) and applies the corresponding format.
  26.  
  27. 4. logStatus(logSheet, sheet, status)
  28. - Logs the processing status of each sheet in the 'Formatting Logs' sheet. It records the sheet name, a hyperlink to the sheet, the timestamp of processing, and notes on the status (success or error).
  29.  
  30. 5. setupLogSheet(logSheet)
  31. - Sets up the initial headers in the 'Formatting Logs' sheet for tracking. Headers include "Sheet Name", "Hyperlink", "Timestamp", "Status", and "Status Notes".
  32.  
  33. 6. isSheetProcessed(logSheet, sheetName)
  34. - Checks if a sheet has already been processed successfully. It prevents reprocessing of sheets that are already formatted.
  35.  
  36. 7. getColumnFormats()
  37. - Crucial for the entire script, this function returns a hardcoded object mapping column names to their respective data types and formats. It is essential that the user manually matches these names and formats with the actual column names present in the sheets. Failure to correctly match these will result in improper or failed formatting. The formats for each type of data (like date, text, number, currency) need to be predefined here.
  38.  
  39. If you need a test spreadsheet you can generate one using the script that I have written here: https://pastebin.com/nbhP4WxB
  40.  
  41.  
  42. */
  43.  
  44. function processSheets() {
  45.   var ss = SpreadsheetApp.getActiveSpreadsheet();
  46.   var sheets = ss.getSheets();
  47.   var columnFormats = getColumnFormats();
  48.  
  49.   // Create or get the 'Formatting Logs' sheet
  50.   var logSheet = ss.getSheetByName("Formatting Logs") || ss.insertSheet("Formatting Logs");
  51.   // Set up log sheet headers
  52.   setupLogSheet(logSheet);
  53.  
  54.   var processedCount = 0;
  55.   var errorCount = 0;
  56.   var successCount = 0;
  57.  
  58.   // Process each sheet
  59.   sheets.forEach(function(sheet) {
  60.     if (sheet.getName() !== "Formatting Logs" && !isSheetProcessed(logSheet, sheet.getName())) {
  61.       var status = processSingleSheet(sheet, columnFormats);
  62.       logStatus(logSheet, sheet, status);
  63.  
  64.       if (status.error) {
  65.         errorCount++;
  66.       } else {
  67.         successCount++;
  68.       }
  69.  
  70.       processedCount++;
  71.       if (processedCount >= 30) {
  72.         // Stop processing after 30 sheets
  73.         return;
  74.       }
  75.     }
  76.   });
  77.  
  78.   // Show notification after processing
  79.   SpreadsheetApp.getUi().alert(
  80.     'Processing completed. ' +
  81.     'Success: ' + successCount + ', ' +
  82.     'Errors: ' + errorCount
  83.   );
  84. }
  85.  
  86. function processSingleSheet(sheet, columnFormats) {
  87.   var status = { error: false, notes: [] };
  88.   var lastColumn = sheet.getLastColumn();
  89.   var lastRow = sheet.getLastRow();
  90.  
  91.   // Check if the sheet has columns and rows
  92.   if (lastColumn === 0 || lastRow === 0) {
  93.     status.error = true;
  94.     status.notes.push("No columns or rows found in sheet.");
  95.     return status;
  96.   }
  97.  
  98.   // Get headers and sort them along with their data
  99.   var headers = sheet.getRange(1, 1, 1, lastColumn).getValues()[0];
  100.   var data = sheet.getRange(2, 1, lastRow - 1, lastColumn).getValues();
  101.  
  102.   // Create a combined array of headers and data for sorting
  103.   var combined = headers.map(function(header, index) {
  104.     return [header].concat(data.map(function(row) {
  105.       return row[index];
  106.     }));
  107.   });
  108.  
  109.   // Sort the combined array alphabetically based on headers
  110.   combined.sort(function(a, b) {
  111.     return a[0].localeCompare(b[0]);
  112.   });
  113.  
  114.   // Write the sorted data back to the sheet
  115.   for (var col = 0; col < combined.length; col++) {
  116.     sheet.getRange(1, col + 1, lastRow).setValues(combined[col].map(function(cell, index) {
  117.       return [cell];
  118.     }));
  119.   }
  120.  
  121.   // Apply formats to the sorted columns and check for errors
  122.   combined.forEach(function(column, index) {
  123.     var header = column[0];
  124.     if (columnFormats[header]) {
  125.       try {
  126.         var range = sheet.getRange(2, index + 1, lastRow - 1);
  127.         applyFormat(range, columnFormats[header]);
  128.       } catch (e) {
  129.         status.error = true;
  130.         status.notes.push("Error in column: " + header + " - " + e.message);
  131.       }
  132.     }
  133.   });
  134.  
  135.   // Return processing status
  136.   return status;
  137. }
  138.  
  139. function applyFormat(range, formatInfo) {
  140.   // Apply format based on type and specific format rules
  141.   switch (formatInfo.type) {
  142.     case "date":
  143.       range.setNumberFormat(formatInfo.format);
  144.       break;
  145.     case "text":
  146.       // Text formatting can be added here
  147.       break;
  148.     case "number":
  149.       range.setNumberFormat(formatInfo.format);
  150.       break;
  151.     case "currency":
  152.       range.setNumberFormat(formatInfo.format);
  153.       break;
  154.     // Add more cases as needed
  155.   }
  156. }
  157.  
  158. function logStatus(logSheet, sheet, status) {
  159.   var timeStamp = new Date();
  160.   var sheetUrl = sheet.getParent().getUrl() + "#gid=" + sheet.getSheetId();
  161.   var statusText = status.error ? "Error" : "Success";
  162.   var notesText = status.notes.join("\n");
  163.  
  164.   // Append log entry
  165.   logSheet.appendRow([sheet.getName(), sheetUrl, timeStamp, statusText, notesText]);
  166. }
  167.  
  168. function setupLogSheet(logSheet) {
  169.   // Setup headers for the log sheet
  170.   logSheet.getRange("A1:E1").setValues([["Sheet Name", "Hyperlink", "Timestamp", "Status", "Status Notes"]]);
  171. }
  172.  
  173. function isSheetProcessed(logSheet, sheetName) {
  174.   // Check if the sheet is already processed
  175.   var data = logSheet.getDataRange().getValues();
  176.   for (var i = 1; i < data.length; i++) {
  177.     if (data[i][0] === sheetName && data[i][3] === "Success") {
  178.       return true;
  179.     }
  180.   }
  181.   return false;
  182. }
  183.  
  184. function getColumnFormats() {
  185.   // Hardcoded column names and their formats
  186.   return {
  187.     "Date": { type: "date", format: "MM/dd/yyyy" },
  188.     "Name": { type: "text", format: "none" },
  189.     "Room": { type: "number", format: "0" },
  190.     "Price": { type: "currency", format: "$#,##0.00" },
  191.     "Check-in": { type: "date", format: "MM/dd/yyyy" },
  192.     "Check-out": { type: "date", format: "MM/dd/yyyy" },
  193.     // Add more column formats as needed
  194.   };
  195. }
  196.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement