|
| 1 | +/** |
| 2 | + * Google Apps Script for updating inventory columns based on Lesson Name. |
| 3 | + * |
| 4 | + * INSTRUCTIONS: |
| 5 | + * 1. Open your Google Sheet. |
| 6 | + * 2. Go to Extensions > Apps Script. |
| 7 | + * 3. Delete any code in the editor and paste this code. |
| 8 | + * 4. Click the Save icon and name it "Inventory Updater". |
| 9 | + * 5. Refresh your Google Sheet. You will see a new menu: "Inventory Tools". |
| 10 | + */ |
| 11 | + |
| 12 | +function onOpen() { |
| 13 | + const ui = SpreadsheetApp.getUi(); |
| 14 | + ui.createMenu('Inventory Tools') |
| 15 | + .addItem('Update Enhanced Columns', 'showUpdateDialog') |
| 16 | + .addToUi(); |
| 17 | +} |
| 18 | + |
| 19 | +/** |
| 20 | + * Shows a dialog to paste CSV data. |
| 21 | + */ |
| 22 | +function showUpdateDialog() { |
| 23 | + const html = HtmlService.createHtmlOutput( |
| 24 | + '<p>Paste the content of your MERGED-enhanced-metadata CSV file below:</p>' + |
| 25 | + '<textarea id="csvData" style="width: 100%; height: 300px; font-family: monospace;"></textarea>' + |
| 26 | + '<br><br>' + |
| 27 | + '<button onclick="runUpdate()" style="padding: 10px 20px; background: #1a73e8; color: white; border: none; border-radius: 4px; cursor: pointer;">Update Sheet</button>' + |
| 28 | + '<script>' + |
| 29 | + ' function runUpdate() {' + |
| 30 | + ' const data = document.getElementById("csvData").value;' + |
| 31 | + ' google.script.run.withSuccessHandler(closeDialog).processCsv(data);' + |
| 32 | + ' }' + |
| 33 | + ' function closeDialog() {' + |
| 34 | + ' google.script.host.close();' + |
| 35 | + ' }' + |
| 36 | + '</script>' |
| 37 | + ).setWidth(600).setHeight(450); |
| 38 | + |
| 39 | + SpreadsheetApp.getUi().showModalDialog(html, 'Update Inventory Data'); |
| 40 | +} |
| 41 | + |
| 42 | +/** |
| 43 | + * Processes the CSV data and updates the sheet. |
| 44 | + */ |
| 45 | +function processCsv(csvString) { |
| 46 | + const sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet(); |
| 47 | + const data = Utilities.parseCsv(csvString); |
| 48 | + |
| 49 | + if (data.length < 2) { |
| 50 | + SpreadsheetApp.getUi().alert('Invalid CSV data.'); |
| 51 | + return; |
| 52 | + } |
| 53 | + |
| 54 | + const headers = data[0]; |
| 55 | + const csvRows = data.slice(1); |
| 56 | + |
| 57 | + // Get sheet data |
| 58 | + const sheetData = sheet.getDataRange().getValues(); |
| 59 | + const sheetHeaders = sheetData[0]; |
| 60 | + const sheetRows = sheetData.slice(1); |
| 61 | + |
| 62 | + // Find column indices in CSV |
| 63 | + const colMap = { |
| 64 | + name: headers.indexOf('name'), |
| 65 | + author: headers.indexOf('author'), |
| 66 | + license: headers.indexOf('license'), |
| 67 | + contributor: headers.indexOf('contributor'), |
| 68 | + dateCreated: headers.indexOf('dateCreated'), |
| 69 | + dateModified: headers.indexOf('dateModified'), |
| 70 | + datePublished: headers.indexOf('datePublished'), |
| 71 | + inLanguage: headers.indexOf('inLanguage'), |
| 72 | + timeRequired: headers.indexOf('timeRequired'), |
| 73 | + identifier: headers.indexOf('identifier'), |
| 74 | + slug: headers.indexOf('slug'), |
| 75 | + '@id': headers.indexOf('@id'), |
| 76 | + Topic: headers.indexOf('Topic'), |
| 77 | + about: headers.indexOf('about'), |
| 78 | + abstract: headers.indexOf('abstract'), |
| 79 | + accessibilitySummary: headers.indexOf('accessibilitySummary') |
| 80 | + }; |
| 81 | + |
| 82 | + // Find column indices in Sheet |
| 83 | + const sheetColMap = {}; |
| 84 | + Object.keys(colMap).forEach(key => { |
| 85 | + sheetColMap[key] = sheetHeaders.indexOf(key); |
| 86 | + }); |
| 87 | + |
| 88 | + if (sheetColMap.name === -1) { |
| 89 | + SpreadsheetApp.getUi().alert('Error: "name" column not found in Google Sheet.'); |
| 90 | + return; |
| 91 | + } |
| 92 | + |
| 93 | + let updateCount = 0; |
| 94 | + let skipCount = 0; |
| 95 | + |
| 96 | + // Create a map for CSV data for fast lookup |
| 97 | + const csvDataMap = {}; |
| 98 | + csvRows.forEach(row => { |
| 99 | + const name = row[colMap.name]; |
| 100 | + if (name) csvDataMap[name] = row; |
| 101 | + }); |
| 102 | + |
| 103 | + // Iterate through sheet rows and update |
| 104 | + for (let i = 0; i < sheetRows.length; i++) { |
| 105 | + const sheetName = sheetRows[i][sheetColMap.name]; |
| 106 | + const csvRow = csvDataMap[sheetName]; |
| 107 | + |
| 108 | + if (csvRow) { |
| 109 | + const rowNum = i + 2; // 1-indexed + header |
| 110 | + |
| 111 | + Object.keys(colMap).forEach(key => { |
| 112 | + if (key === 'name') return; // Don't update name |
| 113 | + |
| 114 | + const sheetCol = sheetColMap[key]; |
| 115 | + const csvCol = colMap[key]; |
| 116 | + |
| 117 | + if (sheetCol !== -1 && csvCol !== -1) { |
| 118 | + const newValue = csvRow[csvCol]; |
| 119 | + const oldValue = sheetRows[i][sheetCol]; |
| 120 | + |
| 121 | + if (newValue && newValue !== String(oldValue)) { |
| 122 | + sheet.getRange(rowNum, sheetCol + 1).setValue(newValue); |
| 123 | + updateCount++; |
| 124 | + } |
| 125 | + } |
| 126 | + }); |
| 127 | + } else { |
| 128 | + skipCount++; |
| 129 | + } |
| 130 | + } |
| 131 | + |
| 132 | + SpreadsheetApp.getUi().alert('Update Complete!\nUpdated cells: ' + updateCount + '\nLessons not found in CSV: ' + skipCount); |
| 133 | +} |
0 commit comments