# Dealtracking met Sheets en Docs [[TOC]] ## Van eerste contact tot gesloten deal Dealtracking gaat verder dan een spreadsheet bijhouden. Je wilt een systeem waarbij elk gesprek, elke offerte en elk contract herleidbaar is tot de oorspronkelijke opportunity. Met Google Sheets als basis en Docs voor de documenten bouw je zo'n systeem in minder dan een dag. Het principe is simpel. Sheets bevat de feiten (waarde, fase, datum, eigenaar), Docs bevat de verhalen (offertecontext, afspraken, onderhandelingshistorie). De koppeling tussen beide zorgt dat je altijd in twee klikken van het dealoverzicht naar het juiste document gaat. :::info title="Bouw eerst je CRM-basis" Dit artikel bouwt voort op een eenvoudig CRM in Sheets. Heb je dat nog niet ingericht, lees dan eerst het artikel over een CRM bouwen in Google Sheets en kom daarna terug. ::: ## Het dealregister in Sheets Naast de basiskolommen uit het CRM voeg je voor dealtracking een aantal kolommen toe: | Kolom | Type | Doel | |---|---|---| | `docs_offerte_link` | URL | Link naar het Docs-offertedocument | | `docs_contract_link` | URL | Link naar het getekende contract | | `laatste_update` | Datum | Automatisch gevuld via Apps Script | | `reden_verlies` | Dropdown | Analyse na een verloren deal | | `concurrenten` | Tekst | Welke aanbieders stonden er nog meer | | `next_action` | Tekst | Concrete volgende stap | | `next_action_datum` | Datum | Deadline voor die actie | De kolommen `next_action` en `next_action_datum` zijn cruciaal. Gebruik voorwaardelijke opmaak om rijen rood te kleuren als de datum voorbij is en de deal nog niet gesloten is. Een passende regel is `Aangepaste formule is` met `=EN($G2"Gewonnen"; $E2<>"Verloren")`, waarbij je de kolomletters aanpast aan je eigen layout. ## Offertedocumenten koppelen Maak voor elke deal een Google Docs-document vanuit een sjabloon. Dat kan handmatig, maar via Apps Script gaat het sneller en consistenter. :::howto title="Deal-offerte aanmaken en koppelen" 1. Maak een sjabloondocument in een gedeelde Docs-map en geef het de naam `[SJABLOON] Offerte`. 2. Open je Sheets-CRM en voeg een kolom `Offerte aanmaken` toe. 3. Ga naar **Extensies > Apps Script** en schrijf een functie `maakOfferte()` die een kopie van het sjabloon maakt, de dealnaam als bestandsnaam gebruikt en de URL terugschrijft naar de Sheets-cel. 4. Roep de functie aan via een eigen menu-item (`onOpen` met `ui.createMenu`) of koppel hem aan een tekening via **Invoegen > Tekening**. 5. Test door een rij te selecteren en de functie uit te voeren. Controleer of de link in de cel verschijnt en of het document de juiste naam heeft. ::: :::tip title="Gebruik de juiste Docs-placeholders" Zet in je sjabloon herkenbare tekens als `{{klant}}` en `{{waarde}}`. In `maakOfferte()` vervang je ze met `body.replaceText('{{klant}}', dealNaam)`. Zo komt elke offerte al half ingevuld uit de kopie. ::: ## Statusflow visualiseren Een visualisatie van de dealfases helpt het team zien waar de pipeline samentrekt. Gebruik een samenvattingstabel met `COUNTIF` en `SUMIF` en zet er een staafdiagram bij. ```text Fase | Aantal | Waarde Prospect | =COUNTIF(E:E;"Prospect") | =SUMIF(E:E;"Prospect";D:D) Gekwalificeerd | =COUNTIF(E:E;"Gekwalificeerd") | =SUMIF(E:E;"Gekwalificeerd";D:D) Voorstel | =COUNTIF(E:E;"Voorstel") | =SUMIF(E:E;"Voorstel";D:D) ``` Selecteer de samenvattingstabel en maak een grafiek via **Invoegen > Grafiek**. Kies een gestapeld staafdiagram als je zowel aantal als waarde naast elkaar wilt tonen. ## Verloren deals analyseren Verloren deals bevatten waardevolle informatie. Zorg dat `reden_verlies` een verplichte dropdown is met vaste opties, bijvoorbeeld: Prijs, Functionaliteit, Concurrent gekozen, Timing, Geen budget, Geen reactie en Intern project. Vaste opties houden de analyse schoon, want vrije tekst maakt een draaitabel waardeloos. Analyseer maandelijks met een draaitabel: 1. Selecteer je Deals-tabblad. 2. Ga naar **Invoegen > Draaitabel** en plaats hem in een nieuw tabblad. 3. Zet `reden_verlies` in de rijen en voeg als waarden `deal_id` (als COUNTA) en `waarde` (als SUM) toe. Zo zie je direct welke reden het meeste omzetverlies verklaart en waar je verkoopproces het meeste lekt. ## Teamnotificaties bij statuswijziging Gebruik Apps Script om een Google Chat-bericht te sturen zodra een deal naar de fase Gewonnen of Verloren gaat. ```javascript function onEdit(e) { var sheet = e.source.getActiveSheet(); if (sheet.getName() !== 'Deals') return; var faseKolom = 5; if (e.range.getColumn() !== faseKolom) return; var fase = e.value; if (fase !== 'Gewonnen' && fase !== 'Verloren') return; var rij = e.range.getRow(); var dealNaam = sheet.getRange(rij, 3).getValue(); var waarde = sheet.getRange(rij, 4).getValue(); var webhookUrl = PropertiesService.getScriptProperties().getProperty('CHAT_WEBHOOK'); var bericht = fase + ': ' + dealNaam + ' (' + waarde + ')'; UrlFetchApp.fetch(webhookUrl, { method: 'post', contentType: 'application/json', payload: JSON.stringify({ text: bericht }) }); } ``` Sla de webhook-URL op via **Project-instellingen > Scripteigenschappen** zodat hij niet in de code staat. Zo voorkom je dat een gedeelde kopie van je Sheet de webhook lekt. :::warn title="Een onEdit-trigger heeft beperkte rechten" De simpele `onEdit(e)` draait zonder autorisatie en mag daardoor geen externe oproepen doen. Voor `UrlFetchApp` of `GmailApp` heb je een installeerbare trigger nodig. Maak die aan via **Triggers > Trigger toevoegen** en kies bij gebeurtenis `Bij bewerken`. Pas dan werkt de notificatie betrouwbaar. ::: :::faq ### Kan ik dealdata automatisch uit Gmail halen? Gedeeltelijk. Gmail heeft geen ingebouwde CRM-koppeling, maar je kunt Apps Script gebruiken om e-mails met een specifiek label te scannen en metadata zoals afzender, datum en onderwerp naar je Deals-tabblad te schrijven. ### Hoe deel ik dealdata alleen met de betreffende account owner? Dat is lastig in Sheets. Een eenvoudige oplossing is een gefilterde weergave per persoon via Data en dan Filterweergaven. Voor strikte afscherming per gebruiker is een dedicated CRM beter, want tabbladbeveiliging in Sheets is bewerkbaar te omzeilen voor wie de hele sheet mag zien. ### Kan ik notificaties ook via e-mail sturen? Ja. Vervang de UrlFetchApp-aanroep door `GmailApp.sendEmail(ontvanger, onderwerp, bericht)`. Houd rekening met de Apps Script-quota: ongeveer 100 ontvangers per dag voor een gratis gmail.com-account en rond de 1500 voor de meeste Google Workspace-accounts. Controleer wat je over hebt met `MailApp.getRemainingDailyQuota()`. ### Wat doe ik als twee teamleden tegelijk dezelfde deal bewerken? Sheets toont een melding bij gelijktijdige bewerkingen en bewaart alle wijzigingen. Gebruik de versiegeschiedenis via Bestand en dan Versiegeschiedenis om conflicten terug te draaien. Voor intensieve samenwerking helpt het om afspraken en discussie in een commentaar-thread op de cel te zetten in plaats van in de celwaarde zelf. ### Moet ik hiervoor naar een echt CRM overstappen? Voor kleine teams en enkele tientallen deals werkt Sheets met Docs prima. Loop je tegen rechtenbeheer per gebruiker, complexe pipelines of veel automatisering aan, dan is een speciaal CRM op den duur goedkoper in onderhoud dan steeds meer Apps Script. ::: ## Integratie met de rest van je Workspace - Koppel **Google Calendar** aan je `next_action_datum` via Apps Script, zodat acties automatisch in de agenda van de eigenaar verschijnen. - Gebruik **Google Meet** voor verkoopgesprekken en sla de opnamelink op in een Activities-tab bij de bijbehorende deal. - Genereer **PDF-offertes** uit je Docs-sjabloon via **Bestand > Downloaden > PDF-document** en hang die naast de bewerkbare versie.