# Een automatisch dashboard bouwen met Apps Script en Sheets [[TOC]] ## Waarom een Apps Script-dashboard? Google Sheets is een uitstekend platform voor dashboards: eenvoudig te begrijpen voor eindgebruikers, krachtig genoeg voor complexe berekeningen en gemakkelijk te delen. Met Apps Script voeg je automatisering toe, zodat data automatisch wordt opgehaald en verwerkt zonder dat iemand handmatig iets hoeft te doen. Typische toepassingen: - Verkoopdashboard dat elke ochtend wordt bijgewerkt - Website-statistieken vanuit een analytics-bron - Social media-metrics - Inventarisoverzicht vanuit een externe API :::info title="Apps Script draait in de cloud" Apps Script heeft toegang tot alle Google Workspace-services. Externe API's bereik je via `UrlFetchApp`. Het script draait op de servers van Google, dus je hebt geen eigen hosting nodig. ::: ## Stap 1: spreadsheet en script aanmaken :::howto title="Spreadsheet en script klaarzetten" 1. Maak een nieuw Google Sheets-bestand aan op [sheets.google.com](https://sheets.google.com). 2. Hernoem de eerste tab naar **Dashboard** en maak een tweede tab **Data**. 3. Ga naar **Extensies > Apps Script**. 4. Hernoem het script naar **Dashboard Updater**. ::: ## Stap 2: data ophalen via UrlFetchApp ```javascript function fetchApiData(url, apiKey) { var options = { method: 'GET', headers: { 'Authorization': 'Bearer ' + apiKey, 'Content-Type': 'application/json' }, muteHttpExceptions: true }; var response = UrlFetchApp.fetch(url, options); var statusCode = response.getResponseCode(); if (statusCode !== 200) { console.error('API fout: ' + statusCode + ' - ' + response.getContentText()); return null; } return JSON.parse(response.getContentText()); } ``` Met `muteHttpExceptions: true` gooit Apps Script geen uitzondering bij een foutstatus, zodat je de respons zelf netjes kunt afhandelen in plaats van dat het script abrupt stopt. ## Stap 3: data naar Sheets schrijven ```javascript function updateDataSheet(data) { var ss = SpreadsheetApp.getActiveSpreadsheet(); var dataSheet = ss.getSheetByName('Data'); dataSheet.clearContents(); var headers = ['Datum', 'Metriek', 'Waarde', 'Verandering']; dataSheet.getRange(1, 1, 1, headers.length).setValues([headers]); dataSheet.getRange(1, 1, 1, headers.length).setFontWeight('bold'); var rows = data.map(function(item) { return [ new Date(item.date), item.metric, item.value, item.change ]; }); if (rows.length > 0) { dataSheet.getRange(2, 1, rows.length, headers.length).setValues(rows); dataSheet.getRange(2, 1, rows.length, 1).setNumberFormat('dd/mm/yyyy'); } dataSheet.autoResizeColumns(1, headers.length); } ``` :::tip title="Schrijf in batch, niet cel voor cel" Verzamel alle rijen in een array en schrijf ze in een keer weg met `setValues`. Per cel afzonderlijk schrijven is veel trager en raakt sneller de uitvoeringslimiet. Schrijf de getalopmaak alleen als er daadwerkelijk rijen zijn, anders krijg je een fout op een leeg bereik. ::: ## Stap 4: dashboard-tabblad bijwerken ```javascript function updateDashboard() { var ss = SpreadsheetApp.getActiveSpreadsheet(); var dashboardSheet = ss.getSheetByName('Dashboard'); var bijgewerktOp = new Date().toLocaleString('nl-NL', { timeZone: 'Europe/Amsterdam' }); dashboardSheet.getRange('B1').setValue('Bijgewerkt: ' + bijgewerktOp); var dataSheet = ss.getSheetByName('Data'); var lastRow = dataSheet.getLastRow(); if (lastRow < 2) return; var data = dataSheet.getRange(2, 1, lastRow - 1, 4).getValues(); var totaal = data.reduce(function(som, rij) { return som + (rij[2] || 0); }, 0); dashboardSheet.getRange('B3').setValue(totaal); dashboardSheet.getRange('B4').setValue(lastRow - 1); } ``` ## Stap 5: hoofdfunctie samenstellen ```javascript function runDashboardUpdate() { console.log('Dashboard update gestart: ' + new Date()); var apiKey = PropertiesService.getScriptProperties().getProperty('API_KEY'); var apiUrl = 'https://api.voorbeeld.com/v1/metrics?period=30days'; var data = fetchApiData(apiUrl, apiKey); if (!data) { console.error('Geen data ontvangen, update gestopt.'); return; } updateDataSheet(data.items || []); updateDashboard(); console.log('Dashboard update voltooid.'); } ``` :::warn title="Bewaar je API-sleutel veilig" Hardcode nooit een API-sleutel in de scriptcode. Sla hem op met `PropertiesService.getScriptProperties().setProperty('API_KEY', 'jouw-sleutel')`. Voer dat eenmalig uit via de Apps Script-editor en haal de sleutel daarna alleen nog op met `getProperty`. ::: ## Stap 6: tijdgestuurde trigger instellen :::howto title="Trigger aanmaken" 1. Ga in de Apps Script-editor naar **Triggers** (het klokicoon in de linkerzijbalk). 2. Klik rechtsonder op **Trigger toevoegen**. 3. Kies de functie **runDashboardUpdate**. 4. Kies als gebeurtenisbron **Tijdgestuurd**. 5. Stel de frequentie in, bijvoorbeeld dagelijks tussen 06:00 en 07:00. 6. Klik op **Opslaan** en doorloop de autorisatie als die wordt gevraagd. ::: De trigger draait automatisch op de ingestelde tijd, ook als het Sheets-bestand niet open is. ## Grafieken automatisch bijwerken Grafieken in Google Sheets die naar het Data-tabblad verwijzen, werken automatisch bij wanneer de data verandert. Maak een grafiek aan via **Invoegen > Grafiek** en selecteer het databereik in het Data-tabblad. Omdat `updateDataSheet` steeds hetzelfde bereik vult, blijft de grafiek meebewegen. ## Quota en limieten in de gaten houden Apps Script werkt met dagelijkse quota die per gebruiker gelden en 24 uur na de eerste aanroep resetten. De twee die voor dit dashboard het meest tellen: - Uitvoeringstijd per run: maximaal 6 minuten. Loopt je verwerking langer, verdeel het werk dan over meerdere runs. - `UrlFetchApp`-aanroepen per dag: 20.000 voor een gratis consumentenaccount en 100.000 voor een Google Workspace-account (stand juni 2026). :::faq ### Hoe lang mag een Apps Script-functie draaien? De uitvoeringslimiet is 6 minuten per run, op zowel consumenten- als Workspace-accounts. Voor langere processen verdeel je het werk over meerdere aanroepen met continuatielogica, of laat je een trigger het script herhaaldelijk hervatten tot alles verwerkt is. ### Kan ik Apps Script gebruiken om e-mailrapporten te versturen? Ja. Met `MailApp.sendEmail()` of `GmailApp.sendEmail()` verstuur je e-mails met de dashboarddata als bijlage of als inhoud in de body. Handig om een dagelijkse samenvatting rond te sturen na het bijwerken. ### Hoe debug ik een script dat op een trigger draait? Bekijk de logboeken in de Apps Script-editor onder Uitvoeringen, of gebruik `console.log()` in je code. Elke triggeruitvoering verschijnt ook in het overzicht, met de status en de duur. ### Kan het dashboard meerdere databronnen combineren? Ja. Roep `fetchApiData()` meerdere keren aan voor verschillende bronnen en schrijf elk resultaat naar een apart tabblad. Het Dashboard-tabblad gebruikt dan formules om de data uit alle tabbladen samen te vatten. ### Zijn er kosten verbonden aan Apps Script? Apps Script zelf is gratis, zowel voor consumenten- als Workspace-accounts. Houd wel rekening met de dagelijkse quota, zoals de `UrlFetchApp`-limiet van 20.000 aanroepen voor consumenten en 100.000 voor Workspace. ### Wat gebeurt er als de externe API even niet bereikbaar is? Dankzij `muteHttpExceptions: true` en de statuscontrole stopt het script netjes en logt het de fout, zonder het bestaande dashboard te overschrijven met lege data. Bij de volgende geplande run probeert het opnieuw. :::