Een hand trekt een kaart uit de kaartenbak van een bibliotheek.
GidsUitgebreide gids5 augustus · 17:0016 min leestijd

Twee volle systemen koppelen: zo match je klanten en artikelen zonder dubbelen

Twee systemen die allebei al vol staan en geen gedeeld veld hebben. Zo match je klanten en artikelen in zes stappen, van KvK-nummer tot naam, en houd je het bij één klant per klant.

Vierduizend relaties in je boekhouding. Drieduizendzevenhonderd accounts in je webshop. En geen enkel veld dat de twee aan elkaar knoopt, want het ene bestand is aangelegd door een boekhouder en het andere door het bureau dat de shop bouwde.

Zet je de koppeling nu aan zoals hij uit de doos komt, dan heb je maandag zevenduizendzevenhonderd klanten. Niet omdat de koppeling stuk is, maar omdat hij precies doet wat je hem opdroeg: zoeken op een sleutel die er niet is, niets vinden, en aanmaken. Deze gids gaat over de ronde die daarvóór hoort.

Waarom dit begint waar de patroonkeuze ophoudt

Een matchronde is de eenmalige klus waarin je twee bestaande bestanden record voor record aan elkaar knoopt, vóórdat er een koppeling tussen draait. Je matcht in een vaste volgorde op steeds zwakkere velden, verdeelt de uitkomst over zeker, twijfel en nieuw, laat een mens de twijfelgevallen aftekenen, en legt het resultaat vast in een koppeltabel die vanaf dat moment de waarheid is.

Met welk ritme je daarna synchroniseert is een losse beslissing: of je orders event-driven doorduwt en artikelen per nacht in een delta-batch ophaalt hangt af van je datastroom, niet van je bestanden. Wel stelt die keuze een voorwaarde die zo vanzelfsprekend klinkt dat bijna iedereen hem overslaat: een stabiele sleutel per klant, artikel en order, plus een koppeltabel die het id aan de ene kant aan het id aan de andere kant plakt.

Prachtig advies, als je die sleutel nog kunt kiezen. Jij kunt dat niet. Jouw twee bestanden bestaan al, staan allebei vol, en zijn allebei op hun eigen manier vervuild. Precies die ene bullet is waar deze gids begint.

Eén afbakening vooraf. Dubbelen die ontstaan nádat een koppeling een tijd stil lag zijn een ander probleem met een eigen route, waarbij je eerst beide kanten telt op dezelfde sleutel voordat je iets opnieuw aanbiedt. Hier gaat het om de ronde daarvoor, op twee bestanden die die sleutel nog helemaal niet hebben.

Wat je nodig hebt voordat je de eerste rij matcht

Je hebt hiervoor geen matchsoftware nodig, maar zeven dingen die je meestal pas mist als je al bezig bent: een volledige export van beide kanten inclusief het interne id, een plek om te werken die je zelf beheert, een eigenaar per veld, een lege koppeltabel, één mens die mag aftekenen, en een peilmoment waarna er niets meer handmatig bijkomt. Leg ze op tafel voordat je de eerste formule typt.

  • Een volledige export van beide kanten, met het interne id als eerste kolom. Niet de weergavenaam, niet het klantnummer dat je zelf ooit bedacht, maar het id waarmee de API het record aanwijst. Zonder dat id kun je je uitkomst nergens terugschrijven.
  • Een werkomgeving die je beheert. Dit zijn twee complete klantbestanden. Ze horen niet in een gedeeld sheet in een privé-account en niet op de laptop van een stagiair. Match op zo min mogelijk velden en ruim de werkbestanden achteraf op.
  • Per veld één eigenaar, op papier. Welk systeem is de baas over het adres, over het e-mailadres, over de betaaltermijn? Die vraag komt straks terug bij elk verschil dat je vindt, en je wilt hem één keer beantwoorden in plaats van vierhonderd keer.
  • Een lege koppeltabel. Zes kolommen: bronsysteem, bron-id, doelsysteem, doel-id, hoe gematcht, door wie en wanneer. Een sheet mag, zolang hij daarna verhuist naar iets wat je koppeling kan bevragen.
  • Eén mens die de twijfelgevallen aftekent. Iemand die de klantnamen herkent, dus uit de verkoop of de administratie. Dit is de rol die het vaakst wordt ingevuld met "dat doet de stagiair er even bij", en dat is precies waar het misgaat.
  • Een budget voor verrijking, als een sleutelveld grotendeels leeg is. Bij de KVK betaal je een abonnement van 6,40 euro per maand, waarbij de Zoeken-API nul euro per bevraging kost en een profielbevraging twee cent (tarieven augustus 2026, vrijgesteld van btw).
  • Een peilmoment. Vanaf dat tijdstip komen er aan beide kanten geen handmatig aangemaakte records meer bij. Duurt je matchronde drie dagen en typt de verkoop ondertussen door, dan match je een bestand dat niet meer bestaat.
Op tafel voordat je de eerste rij matcht
0/7

De matchronde: vijf velden, van hard naar zacht

De volgorde is het hele ontwerp. Je begint met het veld dat een record echt identificeert en zakt af naar velden die alleen maar suggereren. Elke stap kijkt uitsluitend naar wat de vorige liet liggen, want een record dat al zeker gekoppeld is doet niet meer mee. Zo krijgt je zwakste bewijs de kleinste stapel in plaats van de hele berg.

1. Normaliseer in een kolom ernaast, nooit over de bron heen

Voordat je iets vergelijkt maak je van elk matchveld een schoongepoetste kopie. Kleine letters, spaties weg, punten en streepjes weg, diakritische tekens weg. Rechtsvormen eruit bij de naam: B.V., bv, Holding, VOF, Beheer. Adres splitsen in straat, huisnummer en toevoeging, want "Dorpsstraat 12 A" en "Dorpsstraat 12A" zijn hetzelfde adres en verschillende tekst.

Dat schoonmaken gebeurt in nieuwe kolommen. De brongegevens blijven staan zoals ze zijn, want die ga je straks terugschrijven en niemand wil een klant die voortaan "bakkerij jansen" heet.

Wil je hier gereedschap bij: OpenRefine doet dit als los product en beschrijft zijn eigen fingerprint-methode (kleine letters, leestekens eruit, woorden alfabetisch sorteren) als de methode die het minst snel valse positieven oplevert. De n-gram-variant vindt méér, maar levert er ook meer onterecht op. Dat is exact de afweging die je hierna bij elke stap maakt.

2. Match op KvK-nummer

Het hardste veld dat je in Nederland hebt. Een KvK-nummer bestaat uit acht cijfers en wijst een inschrijving in het Handelsregister aan; een vestigingsnummer heeft er twaalf en wijst één specifieke vestiging aan. Dat verschil is geen detail: een bedrijf met vijf filialen heeft één KvK-nummer en vijf vestigingsnummers. Factureer je per filiaal, dan klapt een match op KvK-nummer die vijf klanten tot één.

De valkuil is niet het matchen maar de dekking. Een KvK-nummer staat alleen in je bestand als je er ooit om hebt gevraagd, en in een webshop is dat zelden. Is het veld grotendeels leeg, dan vul je het aan vóórdat je matcht: de Zoeken-API van de KVK accepteert naam, straatnaam, postcode, huisnummer en plaats als zoekcriteria en geeft maximaal honderd resultaten per pagina terug. Een aanvulronde op naam plus postcode kost je een middag en verplaatst honderden records van de zachte naar de harde stap.

3. Match op btw-identificatienummer

Een Nederlands btw-id ziet eruit als NL, negen cijfers, de letter B en twee cijfers. Bij een rechtspersoon zijn die negen cijfers het RSIN, dat ook uit het Handelsregister komt, en dat maakt dit veld een bruikbare brug terug naar stap 2.

Nu de val. Het btw-identificatienummer is niet hetzelfde als het omzetbelastingnummer, en het verschil is niet cosmetisch: bij een zzp'er bestaat het omzetbelastingnummer uit de negen cijfers van zijn burgerservicenummer, terwijl het btw-id die juist niet bevat. Staan er in je oude bestand nog nummers van de eerste soort, dan matchen ze niet op de tweede én heb je een bsn in een veld waar het niet hoort. Zet die records apart in plaats van ze mee te matchen.

Valideren kan gratis via VIES van de Europese Commissie, maar verwacht er geen verrijking van: die dienst controleert of een nummer geldig is en geeft om privacyredenen geen naam en adres terug. Je kunt een btw-id dus bevestigen, niet omzetten in een bedrijfsnaam.

4. Match op e-mailadres

Hier begint het zachte werk. Een e-mailadres is geen sleutel, want mensen wisselen ze, delen ze en hebben er drie. Toch levert deze stap in de praktijk vaak de grootste stapel op, simpelweg omdat het het enige veld is dat beide systemen altijd hebben.

Twee regels houden hem schoon. Gedeelde postbussen (info@, administratie@, verkoop@, factuur@) zijn nooit een zekere match, want twee vestigingen van dezelfde keten gebruiken hetzelfde adres. Die gaan rechtstreeks naar de twijfelbak. En match je op domein in plaats van op het volledige adres, sluit dan de gratis maildiensten uit; anders knoop je vierhonderd klanten aan elkaar omdat ze allemaal bij gmail.com zitten.

Draai je aan één kant HubSpot, dan is een deel van dit werk al gedaan: dat systeem ontdubbelt contacten automatisch op e-mailadres en bedrijven op domeinnaam. Dat helpt binnen HubSpot en zegt niets over de match met je andere systeem, maar het scheelt je wel een ronde aan die kant. Hoeveel een pakket hier zelf al voor je doet verschilt sterk, en het is één van de punten waarop HubSpot, Pipedrive en Salesforce uiteenlopen.

5. Match op postcode plus huisnummer

In Nederland is de combinatie postcode en huisnummer bijna een adressleutel, en dat "bijna" doet al het werk. Drie dingen breken hem.

Een bedrijvenverzamelgebouw waar veertig bedrijven op hetzelfde adres staan ingeschreven. Een postbus die in het ene systeem als adres staat en in het andere niet. En de huisnummertoevoeging, die in het ene bestand een eigen kolom heeft en in het andere achter het huisnummer is geplakt.

De regel is daarom: postcode plus huisnummer alleen is nooit zeker. Combineer hem altijd met een naamgelijkenis boven een vaste drempel. Komt het adres overeen maar de naam niet, dan is dat geen match maar een twijfelgeval, en vaak zelfs een terecht apart record. Let er ook op welk adres je vergelijkt: het factuuradres van je boekhouding en het afleveradres van je webshop zijn twee verschillende velden die toevallig allebei "adres" heten.

6. Match op genormaliseerde naam, en nooit automatisch

De laatste stap, op de kleinste stapel, en de enige die per definitie niets zekers oplevert. Je vergelijkt de opgeschoonde namen met een tekstafstand: Levenshtein voor korte namen, een woordgebaseerde methode voor lange. Wat boven je drempel scoort is een kandidaat.

Een kandidaat is geen match. "Bakkerij Jansen B.V." en "Bakkerij Jansen Holding B.V." scoren bijna gelijk en zijn twee juridische entiteiten met twee aparte facturen. Alles wat hier uitkomt gaat naar de twijfelbak, zonder uitzondering. Draai je deze stap per ongeluk als eerste, dan vervuil je je hele uitkomst en merk je het pas als de verkeerde klant een aanmaning krijgt.

7. Wat overblijft is nieuw, en krijgt meteen een sleutel

Records die zes stappen hebben overleefd zonder enige match zijn nieuw. Maak ze aan, en schrijf ze in dezelfde beweging in de koppeltabel. Een nieuw record zonder rij in de koppeltabel is het begin van het volgende dubbelenprobleem.

VeldWat het echt identificeertDekking in een mkb-bestandWaar het je bedriegtVerdict
KvK-nummer (8 cijfers)de inschrijving, niet de vestiginglaag, alleen als je erom vroegfilialen klappen samen tot één klantzeker
Btw-id (NL + 9 + B + 2)de btw-plichtige entiteitmidden bij B2B, nul bij consumentenhet omzetbelastingnummer lijkt erop en bevat een bsnzeker
E-mailadreseen postbus, geen persoonhooginfo@ en andere gedeelde adressenzeker, behalve gedeelde adressen
Postcode plus huisnummereen adres, geen bedrijfhoogverzamelgebouw, postbus, toevoegingalleen mét naamgelijkenis
Genormaliseerde naamniets, het suggereert alleenhoogholding tegenover werkmaatschappijaltijd twijfel

Drie bakken: zeker, twijfel, nieuw

Twee drempels, geen één. Dat is de belangrijkste ontwerpkeuze in deze hele gids, want met één drempel dwing je jezelf om elk grensgeval automatisch een kant op te duwen.

  • Zeker is: één harde identificator exact gelijk (KvK-nummer of btw-id), óf twee onafhankelijke zachte velden die elkaar bevestigen (uniek e-mailadres én adres, of adres én naam boven de drempel). Deze rijen gaan automatisch de koppeltabel in.
  • Twijfel is: één zacht veld gelijk zonder tweede bevestiging, of meerdere kandidaten aan de andere kant. Deze rijen wachten op een mens.
  • Nieuw is: geen enkele match, op geen enkel veld. Aanmaken, met sleutel.

Werk je met een scoresysteem in plaats van met regels, dan geldt precies hetzelfde in getallen: zet twee drempels, en de band ertussen ís je twijfelbak. Zo werkt het ook bij het zwaardere gereedschap. Het Britse ministerie van Justitie beschrijft in zijn transparantieverslag over de koppelsoftware Splink dat recordparen boven een ingestelde drempel als dezelfde persoon gelden, en dat in de toepassingen waarin een lijst met mogelijke matches aan een mens wordt voorgelegd, die mens de eindbeslissing neemt (verslag oktober 2025).

Waarom die scheefheid? Omdat de twee fouten niet even duur zijn. Een gemiste match levert een dubbele klant op: vervelend, zichtbaar, en later te repareren. Een onterechte match voegt twee klanten samen, en dat is bij vrijwel elk pakket definitief. Zet je drempels dus zo dat twijfel naar de mens gaat en niet naar de automaat.

De twijfelbak: één mens, één zitting, klein gehouden

Iedereen die dit werk beschrijft komt bij een handmatige controle uit, en iedereen die het uitvoert loopt vast op dezelfde reden: de bak wordt te groot en blijft daarna openstaan. Vijf dingen houden hem klein.

Sorteer op geld, niet op alfabet. Verrijk je twijfellijst met de omzet of het aantal orders van de afgelopen twaalf maanden en werk van boven naar beneden. De klanten die je administratie herkent staan bovenaan, en dat zijn precies de records waar een verkeerde koppeling geld kost.

Toon zes kolommen, niet het hele record. Naam links, naam rechts, adres, e-mail, laatste order, en waarom het systeem twijfelt. Meer informatie maakt de beslissing niet beter, alleen trager.

Geef drie knoppen. Zelfde, niet zelfde, weet ik niet. Die derde is essentieel: "weet ik niet" betekent apart aanmaken met een vlag, niet samenvoegen. Twijfel mag nooit stilzwijgend een match worden.

Zet er een einddatum op. Eén zitting, een afspraak in de agenda, twee tot vier uur. Een twijfelbak zonder deadline verandert binnen twee weken in een tweede achterstand.

Bewaar elke beslissing. Elke afgetekende rij is een voorbeeld waarmee je je regels aanscherpt, en bij lerende bibliotheken zoals dedupe en Splink is het letterlijk trainingsmateriaal. De tweede keer dat je dit doet, en die komt, is je bak de helft kleiner.

En een maat om jezelf mee te corrigeren: is je twijfelbak groter dan vijf procent van het kleinste bestand, dan zijn je drempels verkeerd, niet je data. Loop de volgorde van je stappen na voordat je iemand door duizend rijen laat klikken.

Survivorship: welk systeem wint welk veld

Twee records zijn gematcht en ze spreken elkaar tegen. Welke waarde gaat de gouden versie in? Dat heet survivorship, en de fout die iedereen maakt is dat je het per systeem beslist ("het CRM is leidend") in plaats van per veld. Geen enkel systeem is overal het beste in. Je boekhouding weet niet welke contactpersoon vorige week vertrok; je webshop weet niet welk btw-regime geldt.

VeldWie wintWaarom
Bedrijfsnaam en rechtsvormhet Handelsregisterdit is de naam die op de factuur hoort, niet de naam die iemand ooit typte
Factuuradresde boekhoudingdaar staat het adres waarop de laatste factuur is geaccepteerd
Afleveradreshet systeem dat verzendtde webshop of het magazijn weet waar het pakket echt heen ging
E-mailadreshet systeem waar de klant het zelf wijzigtzelfbediening is verser dan wat een collega ooit intikte
Btw-id en btw-regimede boekhoudingdit is het veld waarop je gecontroleerd wordt
Betaaltermijn en kredietlimietde boekhoudinghet is geld, en het is daar afgesproken
Eigenaar, segment, notitieshet CRMdaar leeft de relatie, niet de administratie
Telefoonnummergeen natuurlijke eigenaarval terug op de ladder hieronder

Voor velden zonder eigenaar gebruik je een vaste ladder, in deze volgorde: gevuld wint van leeg, gevalideerd wint van ongevalideerd, recentst gewijzigd wint van ouder, en pas daarna wint de volledigste waarde van de kortere.

Op die derde tree zit de klassieke val. "Recentst gewijzigd" zegt alleen iets als die tijdstempel een menselijke wijziging weerspiegelt. Eén bulkimport uit 2024 heeft alle tijdstempels aan één kant opgehoogd, en dan wint dat systeem voortaan alles, ook de velden waar het niets van weet. Kijk dus naar de verdeling van je wijzigingsdata voordat je deze regel aanzet: staan er duizend records op exact dezelfde seconde, dan is dat geen wijziging maar een import.

De koppeltabel is vanaf nu de waarheid

Uit de matchronde rolt geen samengevoegd bestand maar een tabel. Eén rij per koppel: bronsysteem, bron-id, doelsysteem, doel-id, op welk veld gematcht, met welke zekerheid, door wie afgetekend en wanneer. Die tabel is vanaf dat moment het antwoord op de vraag "is deze klant al bekend", en de koppeling stelt die vraag vóór elke schrijfactie.

Waar hij woont bepaalt of hij standhoudt. Drie werkbare plekken (de veldlimiet en het API-gedrag hieronder gecontroleerd augustus 2026):

Drie regels houden de tabel gezond. Verwijder er nooit rijen uit: voeg je later twee records samen, dan blijft het oude id bestaan als alias-rij, want er lopen nog orders en facturen die ernaar verwijzen. Schrijf de reden mee: over een jaar wil je kunnen zien of een koppeling automatisch of met de hand tot stand kwam. Laat de koppeling hem lezen, niet raden: zoek op de sleutel, en maak alleen aan als de tabel niets teruggeeft.

Artikelen en SKU's: drie nummers voor één product

Bij klanten zoek je één identiteit. Bij artikelen heb je er standaard drie: jouw eigen artikelnummer, het artikelnummer van je leverancier, en de GTIN of EAN op de verpakking. Ze verwijzen naar hetzelfde product en ze zijn geen van drieën inwisselbaar.

Match daarom in deze volgorde. GTIN eerst, want dat is het enige nummer dat noch van jou noch van je leverancier is. Dan leverancier plus leveranciersartikelnummer, altijd als paar, want twee leveranciers gebruiken vrolijk allebei nummer 1001. Dan pas je eigen artikelnummer, en nooit de omschrijving; "blauw t-shirt maat M" bestaat in elk bestand in vier spellingen.

Drie dingen breken de artikelmatch die bij klanten niet spelen.

Varianten. Het ene systeem bewaart kleur en maat als opties onder één product, het andere als losse regels. Je match is dan één-op-veel en je koppeltabel moet dat aankunnen. Belangrijker nog: elke variant die een klant of ketenpartner van de andere kan onderscheiden is een eigen handelsartikel, en volgens GS1 wijs je een nieuwe GTIN toe zodra klanten of ketenpartners het gewijzigde product van het huidige kunnen onderscheiden, er een wettelijke informatieplicht ontstaat, of het gevolgen heeft voor hoe het product wordt verzonden, opgeslagen of ontvangen.

Verpakkingseenheden. Je webshop verkoopt per stuk, je voorraadsysteem boekt per doos van twaalf. Match je die twee zonder conversiefactor, dan is je voorraad een factor twaalf mis en merk je het pas bij de inventarisatie. De koppeltabel krijgt hier dus een extra kolom: hoeveel eenheden van links passen in één eenheid van rechts. In de handelsniveaus van GS1 is dat overigens netjes geregeld: alle stuks in een standaard omdoos dragen dezelfde GTIN, terwijl een gemengde doos er per definitie meer dan één bevat.

Vervangen artikelen. Een leverancier stopt met een nummer en brengt een opvolger uit. Dat is geen match maar een opvolgrelatie, en die hoort in een eigen kolom, niet in je koppeltabel. Anders verdwijnt je verkoophistorie op het oude nummer.

De dubbelen die er nu al staan, zonder je historie te breken

Eén principe: samenvoegen, nooit verwijderen. Een relatie met facturen wis je niet, want dan wis je de tegenhanger van boekingen die je zeven jaar moet kunnen tonen. Wat de pakketten in deze sectie precies doen, HubSpot, Exact en Moneybird, is gecontroleerd in augustus 2026; dit is het soort gedrag dat een leverancier zonder aankondiging wijzigt, dus check het opnieuw voordat je op de knop drukt.

Zet ook eerst de kraan dicht. Zolang er nog een route bestaat waarlangs dubbelen ontstaan, ruim je zand op tijdens een zandstorm. De meest onderschatte route is de import: Moneybird schrijft er onomwonden bij dat je bestaande contacten niet via een import kunt bijwerken en dat een nieuwe import dubbele contacten aanmaakt. "Ik zet de schone lijst er gewoon overheen" is dus precies hoe je je bestand verdubbelt.

Weet daarna wat samenvoegen in jouw pakket écht doet, want dat verschilt en het is overal definitief:

Dat laatste punt is meteen het antwoord op de angst dat je je historie breekt. Een verstuurde factuur is een momentopname en hoort dat te blijven: de naam en het adres van toen zijn onderdeel van het document. Samenvoegen verandert wie de klant nú is, niet wat je toen hebt gefactureerd. Wat je wél nakijkt zijn de lopende dingen: openstaande orders, abonnementen, incassomandaten en herhaalfacturen die nog aan het verdwijnende record hangen.

Praktisch: werk in blokken van vijftig, exporteer beide records naar een bestand voordat je op samenvoegen drukt (er is geen ongedaan maken, dus dat bestand is je enige weg terug), en houd de verdwenen id's in je koppeltabel als alias.

Waar het misgaat

Acht faalmodi, elk met de mitigatie erbij. Ze komen alle acht voor bij mensen die dachten dat ze een halve dag bezig waren.

  • De naamstap als eerste draaien. Alles wat erna komt bouwt voort op vervuiling. Mitigatie: naam is de laatste stap, altijd, en alleen op de rest.
  • Eén record links dat drie kandidaten rechts heeft. De hoogste score pakken is gokken. Mitigatie: forceer één-op-één, haal een gematcht paar aan beide kanten uit de pool, en stuur meervoudige kandidaten ongezien naar de twijfelbak.
  • Normaliseren over de bron heen. Je hebt je klantnamen in kleine letters teruggeschreven. Mitigatie: normaliseer in kolommen ernaast, altijd.
  • Gratis maildomeinen in een domeinmatch. Vierhonderd klanten aan elkaar geknoopt omdat ze bij dezelfde provider zitten. Mitigatie: een uitsluitlijst van publieke maildiensten, en gedeelde postbussen naar de twijfelbak.
  • Postbus tegen bezoekadres. Twee records van dezelfde klant matchen niet omdat het ene systeem het postadres bewaart. Mitigatie: vergelijk adrestype met adrestype, en probeer beide varianten.
  • Survivorship op tijdstempels die van een import komen. Eén systeem wint plots alles. Mitigatie: controleer de verdeling van je wijzigingsdata voordat je die regel aanzet.
  • De twijfelbak zonder eigenaar en zonder datum. Hij wordt een permanente wachtrij en over een half jaar durft niemand hem meer aan te raken. Mitigatie: één naam, één zitting, één einddatum.
  • Twee complete klantbestanden in een privésheet. Dit is een verwerking van persoonsgegevens, ook als het "even snel" is. Mitigatie: match in een omgeving die je beheert, met zo min mogelijk velden, en ruim de werkbestanden op als je klaar bent.

Zelf doen, gereedschap of maatwerk

Vier routes, en de omvang van het kleinste bestand bepaalt welke past. Onder ongeveer tweeduizend records is dit handwerk met hulpmiddelen; boven de twintigduizend is handwerk geen optie meer.

RouteKostenDoorlooptijdSterk bijLoopt stuk op
Ontdubbelfunctie van je pakket (Exact, HubSpot, Moneybird)zit in je abonnementurenopruimen binnen één systeemwerkt niet tussen twee systemen
Spreadsheet plus OpenRefineopen source, geen licentiekosteneen tot drie dagentot ongeveer tienduizend rijen, eenmaligherhaalbaarheid, en scores ontbreken
Record-linkage-bibliotheek (Splink, dedupe)open source, plus een paar dagen werk van iemand die Python kandrie tot vijf dagentienduizenden rijen, echte drempels, herhaalbaarvraagt technische kennis in huis
Matchdienst in de koppeling zelfeen projectwekendoorlopende instroom aan beide kantenoverkill bij een eenmalige klus

De eerlijke grens: is dit een eenmalige klus en telt je grootste bestand vierduizend regels, dan is dit dagen werk, geen weken, en zeker geen aanleiding om een masterdatapakket te kopen. Wordt matchen daarentegen doorlopend werk, omdat aan beide kanten nieuwe klanten binnenstromen die je niet vooraf kunt afdwingen, dan verhuist de logica naar de koppeling en is het bouwwerk. De rekensom die daaronder hoort is dezelfde als bij elke andere koppeling: naast de bouw tellen ook het onderhoud en het verbruik mee.

Welke route past bij jouw matchronde?

Hoeveel klantrecords staan er aan de kleinste kant?

Een rekenvoorbeeld: 4.000 relaties in Exact, 3.700 in de webshop

Neem een groothandel met een B2B-webshop. In Exact Online staan 4.000 relaties, waarvan een deel leveranciers en oude klanten. In de webshop staan 3.700 accounts. Dit zijn cijfers uit een voorbeeld en geen meting, maar de verhoudingen zijn herkenbaar.

De matchronde loopt op de 3.700 webshopaccounts, en elke stap kijkt alleen naar wat overblijft:

  1. KvK-nummer: 1.150 zeker. Het B2B-portaal vraagt erom bij registratie, dus voor de nieuwere klanten is het veld gevuld. Blijft over: 2.550.
  2. Btw-id: 240 zeker. Er komen ook 40 records boven met een nummer in de oude vorm, met een bsn erin; die gaan apart en worden opgeschoond in plaats van gematcht. Blijft over: 2.310.
  3. E-mailadres: 980 zeker. 60 adressen zijn gedeelde postbussen (info@ bij ketens met meerdere vestigingen) en gaan naar de twijfelbak. Blijft over: 1.270.
  4. Postcode plus huisnummer, mét naamgelijkenis: 420 zeker. 95 records delen een adres in twee bedrijvenverzamelgebouwen en gaan naar de twijfelbak. Blijft over: 755.
  5. Genormaliseerde naam: 165 kandidaten, allemaal naar de twijfelbak. Blijft over: 590.

De uitkomst: 2.790 zeker, 320 twijfel, 590 nieuw. De 320 twijfelgevallen worden gesorteerd op omzet over twaalf maanden; de bovenste honderd zijn klanten die de administratie bij naam kent en die gaan er in een uur doorheen. De rest kost nog een uur.

Eindstand na de ronde: 4.590 relaties in Exact (de 590 nieuwe erbij), een koppeltabel van 3.700 rijen, één per webshopaccount, want ook elk nieuw record krijgt in stap 7 meteen zijn rij, en 890 Exact-relaties zonder tegenhanger: leveranciers en klanten die nooit online hebben besteld. Geen 7.700.

Die eindstand gaat ervan uit dat de administratie alle 320 twijfelgevallen als "zelfde" aftekent. Elk geval dat op "niet zelfde" of "weet ik niet" uitkomt wordt een eigen nieuw record met een vlag en verschuift de telling met één: de koppeltabel houdt zijn 3.700 rijen, maar Exact telt er een relatie bij en er blijft er een extra zonder tegenhanger. Eindigen er twintig zo, dan staat er 4.610 tegenover 910.

De artikelkant loopt parallel: 2.100 artikelen tegen 1.850 webshopproducten. De GTIN-stap matcht er 1.400, leverancier plus leveranciersnummer nog eens 300, en de resterende 150 gaan met de hand omdat het eigen samenstellingen zijn zonder barcode. Bij 40 producten verkoopt de webshop per stuk terwijl Exact per doos van twaalf boekt; die krijgen een conversiefactor in een eigen kolom. Dat zijn 40 regels die anders je hele voorraadtelling onbruikbaar hadden gemaakt.

Doorlooptijd: twee dagen voorbereiden en matchen, een halve dag aftekenen, een dag terugschrijven en controleren. Daarna staat er een sleutel waar er eerst geen was, en dat is het enige wat de koppeling ooit van je vroeg.

Tot slot

De verleiding bij twee volle bestanden is om de koppeling te laten uitzoeken wie wie is. Dat is precies de verkeerde volgorde: een koppeling is een uitvoerder, geen rechter. Ze kan alleen doen wat jij hebt vastgelegd, en heb je niets vastgelegd, dan doet ze het enige wat overblijft, namelijk aanmaken.

De matchronde is daarom geen voorbereidend werk maar de beslissing zelf. Je bepaalt één keer, met bewijs en met een mens erbij, wie dezelfde klant is en wie niet. Wat eruit rolt is geen schoon bestand maar iets wat langer meegaat: een sleutel, plus de afspraak dat niemand er meer omheen werkt. Alles wat je daarna koppelt wordt saai. Dat is het doel.

Veelgestelde vragen

Alisina Nawabi
Geschreven doorAlisina Nawabi

AI Product Engineer & Solutions Architect

Twee bestanden, één waarheid

Ik denk met je mee over welk systeem welk veld bezit, ontwerp de matchronde en bouw de koppeltabel en de synchronisatie er end-to-end omheen. Zo begint je koppeling met een sleutel in plaats van met dubbelen.

Meer informatie

Dit artikel is geproduceerd samen met het Agent Team. Meer over de redactie.

Genoemde integraties

Dit artikel noemt deze tools. Ik koppel ze op maat aan je eigen systemen.

Gerelateerde artikelen

E-facturen naar Belgische en Franse klanten: zo kies je je route via Peppol
Gids
Uitgebreide gids15 min

3 aug 13:05

E-facturen naar Belgische en Franse klanten: zo kies je je route via Peppol

Je Belgische klant wisselt al gestructureerde facturen uit en je Franse klant moet er per 1 september 2026 een kunnen ontvangen. Vier routes, met per route de kosten, het werk per factuur en de gegevens die op orde moeten zijn.

Je koppeling draait weer: zo haal je de achterstand in zonder dubbelen
Gids
Uitgebreide gids14 min

5 aug 09:00

Je koppeling draait weer: zo haal je de achterstand in zonder dubbelen

Na een storing begint het echte werk: uitzoeken wat er niet is doorgekomen en dat inhalen zonder dat een klant twee facturen krijgt. Het venster, de telling, de herstelvolgorde en de uitzonderingen die je met de hand doet.

Inkoopfacturen digitaliseren: welke aanpak past bij jou?
Inzicht
7 min

1 jul 11:02

Inkoopfacturen digitaliseren: welke aanpak past bij jou?

De juiste manier om inkoopfacturen digitaal te verwerken hangt af van je factuurvolume en je boekhoudpakket, niet van de duurste tool. Twee vragen bepalen bijna je hele keuze, en de prijzen per route lopen ver uiteen. Met een heldere definitie, een stappenplan en de criteria die er echt toe doen.

Koppelingen bewaken: hoe je een stilgevallen koppeling merkt voordat je klant belt
Gids
Uitgebreide gids14 min

3 aug 09:00

Koppelingen bewaken: hoe je een stilgevallen koppeling merkt voordat je klant belt

Een koppeling die stilvalt geeft geen foutmelding maar een leegte, en die kost per dag orders, facturen en voorraad. Zo richt je hartslag, herhaalpogingen, een dode brievenbus en een nachtelijke telling in.

Urenregistratie koppelen aan je factuur: welke tool en hoe je 't inricht
Gids
Uitgebreide gids11 min

7 jul 09:00

Urenregistratie koppelen aan je factuur: welke tool en hoe je 't inricht

Je factureert per uur of per project en wilt dat een geregistreerd uur vanzelf een correcte factuurregel wordt. Deze gids kiest tussen ingebouwd, gespecialiseerd en maatwerk, en laat zien hoe je de koppeling zonder overtypen inricht.

Model Context Protocol (MCP) uitgelegd voor de niet-developer: wat het is en hoe je weet of jouw software klaar is
Gids
8 min

20 jun 23:05

Model Context Protocol (MCP) uitgelegd voor de niet-developer: wat het is en hoe je weet of jouw software klaar is

MCP is de stekker waarmee AI bij je eigen systemen komt. Zonder code leg ik uit wat het is, en geef ik je de exacte vragen voor je leverancier of IT-partner.