Auto-invullen adresvelden op basis van dropdown

Status
Niet open voor verdere reacties.

tomswaelen

Gebruiker
Lid geworden
8 dec 2004
Berichten
349
Heel vreemd: ik weet dat dit mogelijk is, en het vrij eenvoudig is, toch krijg ik het niet klaar.

Ik heb een tabel met dossiergegevens. Deze bevat onder andere een veld 'Naam debiteur'.

Ik heb een tabel 'Debiteuren'. Deze bevatten een vaste lijst van debiteuren, met adres bij.

Ik wil in een formulier ervoor zorgen dat men uit een dropdown de naam van de debiteur kan kiezen, en dat deze automatisch de adresgegevens verder invult.

Ik heb een relatie gelegd tussen de naamvelden in beide tabellen, en een query met onder andere de naam uit tabel 'dossiers' en de adresgegevens uit tabel 'debiteuren'.

Ik heb op het formulier een combobox voor de 'Naam debiteur' die zijn gegevens haalt uit tabel Debiteuren.

Toch werkt dit niet. De query laat mij niet toe om nieuwe records toe te voegen of bestaande records te wijzigen. Als ik via het formulier gaat, en ik klik een naam uit de dropdown aan, gebeurt er niets.

Wat heb ik fout gedaan?

Het vreemde is, ik heb een andere database waar dit perfect werkt.... (maar dan zonder de combobox)
 
Dag Tom,

eerst en vooral zou ik de link nooit op een tekstveld als naam leggen, maar een autonumber of sequence gebruiken als PK van de tabel debiteuren, en dit numeriek veld als FK in je gerelateerde tabel met dossiergegevens te gebruiken.
Dan kan je in je combobox als row source een query gebruiken met alle gegevens die je in je formulier nodig hebt. Het numerieke PK veld gebruik je als gegeven dat je opslaat, maar niet toont (kolombreedte in je combobox op 0 zetten). De combobox toont de inhoud van de eerste kolom waarvan breedte > 0, dus hier kan je de naam tonen. De andere gegevens kan je mee in de rijbron opnemen en dan in berekende formuliervelden tonen ( = forms![formname]![NameCombobox]![column](n) )
 
Ik begrijp de afkortingen niet zo goed :) PK is primary key, wat is FK?

Ik link doorgaans ook niet op tekstvelden, maar in dit geval gaat het om 100% vast staande velden. Het is een vast staande lijst met klanten die niet verandert.

Maar stel dat ik toch een primary key invoer (de tabel debiteuren heeft dit sowieso), hoe link ik die dan aan mijn tabel dossiers?
 
Ik wil in een formulier ervoor zorgen dat men uit een dropdown de naam van de debiteur kan kiezen, en dat deze automatisch de adresgegevens verder invult.
...
Ik heb op het formulier een combobox voor de 'Naam debiteur' die zijn gegevens haalt uit tabel Debiteuren.
Dit lijkt mij een prima opzet, maar ik vermoed dat je wat (denk)foutjes maakt. Normaal gesproken (zo doe ik het in een identieke situatie) ben je niet geïnteresseerd in de historie van je klanten/debiteuren. Je wilt doorgaans het actuele adres zien. In je tabel Dossiers heb je dan, als het goed is, één veld opgenomen voor het sleutelveld (ik zou dat DebteurID noemen) wat je gebruikt om de twee tabellen aan elkaar te koppelen. Je zegt dat je dat gedaan hebt, dus dat is in orde.

Op je formulier Dossiers wil je dan de debiteurgegevens zien. Muteren zou ik achterwege laten in dit geval, om te voorkomen dat je per ongeluk iets wijzigt zonder dat je dat wilt. Om aanvullende velden te zien, gebruik ik extra tekstvelden die ik vervolgens koppelaan de keuzelijst. Dat gaat heel simpel.
1. In de keuzelijst neem je alle velden uit de tabel Debiteur op die je wilt kunnen oproepen op het dossier. Zullen wel NAW gegevens zijn, zoals je al aangaf. Het eerste veld is het veld DebiteurID
2. Vervolgens maak je op je keuzelijst een aantal niet-gebonden tekstvakken, bijvoorbeeld txtStraatnaamHuisnummer en txtPCPlaats. Daarmee voeg je straatnaam + huisnumer samen, en Postcode + woonplaats.
3. Elk tekstvak krijgt gegevens uit de keuzelijst. Voor het eerste tekstvak bijv. =cboDebiteur.Column(1) & " " & cboDebiteur.Column(2). Het tweede tekstvak krijgt dan: =cboDebiteur.Column(3) & " " & cboDebiteur.Column(4)

En dat is alles. Ik ga er in het voorbeeld overigens van uit dat je deze velden dan in de rijbron van de Debiteur keuzelijst zet:
1. DebiteurID
2. Straatnaam
3. Huisnummer
4. Postcode
5. Plaats
6. Etc.

Als je dat op deze manier doet, werkt je keuzelijst perfect: elke keer als je een debiteur kiest, krijg je keurig de bijbehorende adressen te zien.
 
Maar stel dat ik toch een primary key invoer (de tabel debiteuren heeft dit sowieso), hoe link ik die dan aan mijn tabel dossiers

RelatieDebDossier.JPG

in het voorbeeld is debID de Primary Key (PK) - Autonumber field van tabel tblDebiteuren . De F(oreign) K(ey) in tabel tblDossiers is dosDebiteur. Aangezien debID een autonumber is, is het FK veld dosDebebiteur een Long Integer.
 
Bekijk bijlage 345756

in het voorbeeld is debID de Primary Key (PK) - Autonumber field van tabel tblDebiteuren . De F(oreign) K(ey) in tabel tblDossiers is dosDebiteur. Aangezien debID een autonumber is, is het FK veld dosDebebiteur een Long Integer.

Maar wat voor veld is het veld dosDebiteur in je tabel Dossiers? Als ik mijn debiteurenID link aan naam klant, krijg ik geen 1-to-many relatie.
 
Dit lijkt mij een prima opzet, maar ik vermoed dat je wat (denk)foutjes maakt. Normaal gesproken (zo doe ik het in een identieke situatie) ben je niet geïnteresseerd in de historie van je klanten/debiteuren. Je wilt doorgaans het actuele adres zien. In je tabel Dossiers heb je dan, als het goed is, één veld opgenomen voor het sleutelveld (ik zou dat DebteurID noemen) wat je gebruikt om de twee tabellen aan elkaar te koppelen. Je zegt dat je dat gedaan hebt, dus dat is in orde.

Wel nee, niet echt. Elke debiteur in die tabel heeft inderdaad een unieke (auto)ID. Elk dossier heeft ook een unieke autoID. Maar elke debiteur is ook uniek. Kan de naam van de debiteur dan niet dienen als sleutelveld bij Dossiers? Dat is wellicht dan de denkfout die ik maak :-)
 
Als ik mijn debiteurenID link aan naam klant, krijg ik geen 1-to-many relatie.
Noella heeft er nota bene bijgezet wat voor veld het moet zijn: Long Integer. Ik krijg sterk de indruk dat jij een Getalveld (debiteurenID) probeert te koppelen aan een Tekstveld (naam klant). Dat kan natuurlijk nooit werken, je moet altijd identieke velden gebruiken. Een tekstveld kan je dus wél koppelen aan een ander tekstveld, maar nooit aan een getalveld. Overigens is het dus onnodig (en zelfs ongewenst) om meer dan één veld uit een brontabel op te nemen in een gekoppelde tabel. Tenzij je sleutel uit meerdere velden bestaat, dan moet dat weer wél.

Wat je dus, denk ik, moet doen, is in de tabel tblDossiers een getalveld DebiteurID opnemen, waarin je de debiteurID's zet die uit de tabel tblDebiteuren komt. Dat nieuwe veld koppel je dan (met Referentiële Integriteit uiteraard) aan de tabel tblDebiteuren. Als je al debiteuren hebt ingevoerd in tblDossiers, dan zul je dat nieuwe veld nog moeten vullen, maar dat kan je met een Bijwerkquery nog wel voor elkaar krijgen. Zijn het maar weinig records, dan is intypen waarschijnlijk sneller.
 
Maar elke debiteur is ook uniek. Kan de naam van de debiteur dan niet dienen als sleutelveld bij Dossiers?
Nu snap ik jou even niet; het is logisch dat een debiteur in de tabel debiteuren uniek, is, en dat het veld DebiteurID dus óók uniek is. Met een AutoID is dat ook prima geregeld. Elk dossier is uiteraard óók uniek, en door daar een AutoID veld aan toe te voegen borg je dat ook. Maar de rest van wat je zegt? Wat je zegt met Maar elke debiteur is ook uniek is dat één debiteur maar één dossier krijgt. Dat kan hè, ik kan mij situaties voorstellen waarbij een persoon maar één keer iets mag halen/kopen/brengen.

Stel dat je een museum bent, en je hebt een mega populaire tentoonstelling. Dan wil je dat zoveel mogelijk verschillende mensen die tentoonstelling kunnen zien. Dan moet je er dus voor zorgen dat elke bezoeker de tentoonstelling maar één keer kan bezoeken. Ander voorbeeldje waarbij het effect desastreus uitpakt: je hebt een webwinkel, en dus een tabel met bestellingen (bij jou: dossiers) en een tabel met klanten (bij jou: debiteuren). Nu maak je in je tabel Bestellingen het veld KlantID uniek (wat jij dus zegt te doen). Dan kan elke klant maar één bestelling bij jou plaatsen! Bij elke tweede bestelling krijgen ze de melding dat ze al een bestelling geplaatst hebben! Ik vermoed dat je winkel dan héél snel over de kop is. Heb je geen coronavirus voor nodig :).

Kortom: tenzij bij jou de debiteuren maar één dossier mogen hebben, is het fout om van het veld DebiteurID een uniek veld te maken in tblDossiers. En dan maakt het dus niet eens uit of dat het veld [Naam Debiteur] is of niet, het effect is hetzelfde. Wellicht zelfs nog rotter, want als je twee debiteuren hebt die allebei "Jansen" heten, mag je maar één dossier aanmaken, want je hebt immers zelf gezegd dat de debiteur naam al uniek is.

Kortom: als je twee tabellen aan elkaar koppelt, waarbij de ene tabel (tblDebiteuren) de bron is voor de andere tabel (tblDossiers), dan gebruik je het sleutelveld uit de tabel tblDebiteuren om te relateren in de tabel tblDossiers. En in het plaatje van Noella doet ze dat dus met de velden DebID en dosDebiteur. Zelf vind ik dat nogal ongelukkige benamingen, maar namen zijn in dit soort zaken niet relevant, zolang ze maar uniek zijn binnen een tabel.
 
Je hebt gelijk, ik probeerde inderdaad een naamveld te koppelen aan een autoID. Nu heb ik een veld DebiteurenID toegevoegd als long integer in mijn dossiertabel en ook toegevoegd in de query. Als ik in de query nu in het veld DebiteurenID het overeenkomstige getal invul, worden de andere velden perfect automatisch ingevuld.

Wel raar; zou dit geen 1-to-many relatie moeten zijn? In die zin: 1 debiteur kan aan meerdere dossiers hangen. Access interpreteert dit echter zo niet.

Alleen: in het formulier gebeurt dit niet. Ik heb nochtans een combox aangemaakt, met ID en Naam debiteur als velden en ID verborgen:

SELECT Debiteuren.ID, Debiteuren.Naam FROM Debiteuren

Hoe komt het dat die andere velden niet mee gaan? De oplossing uit comment 4 zal ook wel werken. Maar als het in de query zelf werkt dat de andere velden meegaan, waarom niet in het formulier?
 
Laatst bewerkt:
Update, ik heb even de oplossing van comment 4 toegepast, maar doet niet wat ik wil. In het formulier laat hij inderdaad de gewenste informatie zien, maar deze wordt niet opgeslagen in de tabellen. Dat is wel iets wat ik wil.

Als ik rechtstreeks in de query een debiteurID invul, doet hij dit wel.
 
In het formulier laat hij inderdaad de gewenste informatie zien, maar deze wordt niet opgeslagen in de tabellen. Dat is wel iets wat ik wil.
Zoals ik in #4 aangaf: je moet dat helemaal niet wíllen! Je brondata, zoals je NAW gegevens, bewaar je in je personentabel, niet in de gekoppelde tabel. Ik krijg de indruk dat je moedwillig dataredundantie in je database aan het inbouwen bent. Daar is in bepaalde omstandigheden nog wel aanleiding voor te vinden, maar dat is dus maar héél zelden met NAW gegevens. Nog afgezien van het feit of je überhaupt wel historische gegevens van dit type mag bewaren. Ik werk bij een gemeente, en zelfs dáár hebben we een verwijderplicht naar de burger. Ik kan mij niet voorstellen dat jullie je daaraan mogen onttrekken.
Kortom: vanuit de privacy wetgeving is het maar zeer de vraag of je het mág bewaren, en vanuit database overwegingen creëer je alleen maar redundante gegevens.
 
Ja, je hebt natuurlijk gelijk. Ik maakte even een rare kronkel :-) Alles werkt perfect nu. Al blijf ik het wel raar vinden dat hij die gegevens in de query wel weergeeft zodra je de debiteurID ingeeft, maar niet in het formulier. Maar vermoedelijk komt dat omdat je in het formulier de naam in de dropdown hebt, en niet de debiteurID (die is verborgen)?
 
Als je in de dropdown de naam kiest, wordt normaal gezien achter de schermen de ID ingevuld en zou dit net zo snel moeten werken als in de query.
 
Je kunt twee manieren gebruiken:
1. Zet alle aanvullende velden die je wilt zien in je query (in ieder geval óók je DebiteurID uit Dossiers, de aanvullende uit Debiteuren) en baseer daar je formulier op. Maak een keuzelijst met invoervak om de debiteur te kiezen. Je krijgt dan automatisch in de NAW velden de gegevens van de debiteur te zien.
2. Gebruik alléén een veld DebiteurID in tblDossiers, en zet in het formulier niet-gebonden tekstvakken op je formulier die je vult a.d.h.v. de gekozen debiteur uit je keuzelijst met invoervak. De methode die ik dus beschreef.

Nadeel/voordeel van methode 1: omdat je rechtstreeks naar de tabel velden kijkt, kun je, al dan niet bewust, de NAW gegevens veranderen. De vraag is of je dat wel wilt/moet willen.
Nadeel/voordeel van methode 2: je werkt niet op de tabelvelden, dus je kunt de NAW gegevens niet muteren.

Ik gebruik altijd methode 2, omdat ik persé wil voorkomen dat mensen op een plek waar dat niet de bedoeling is, persoonsgegevens gaan muteren. Daarvoor heb ik dan een ander formulier. Voor de zuiverheid van werken, vind ik mijn methode dus te prefereren.

Maar niets staat je in de weg om het anders te doen natuurlijk :). In dat geval zou ik toch overwegen om het muteren van die specifieke velden te voorkomen door ze uit te zetten.
 
1. Zet alle aanvullende velden die je wilt zien in je query (in ieder geval óók je DebiteurID uit Dossiers, de aanvullende uit Debiteuren) en baseer daar je formulier op. Maak een keuzelijst met invoervak om de debiteur te kiezen. Je krijgt dan automatisch in de NAW velden de gegevens van de debiteur te zien.

Wel, dat was inderdaad mijn opzet, en zo heb ik het ook gedaan. Query gemaakt, formulier hier op gebaseerd. Als ik in de query rechtstreeks debiteurID invul, neemt hij alle NAW velden keurig over. Alleen gebeurt dit niet in het formulier, als ik de dropdown gebruik. Het zou idd sowieso mijn bedoeling geweest zijn om die NAW-velden te locken, zodat deze idd niet aangepast kunnen worden :-)

Nu, jouw methode 2 werkt idd prima. Maar toch vreemd dat methode 1 bij mij niet lijkt te werken. Misschien ligt het aan de configuratie van de dropdown?
 
Toch moet methode 1 ook werken, mits je uiteraard de juiste velden gebruikt in je dropdown.
 
Er is toch nog iets mis. Telkens als ik nu een dossier toevoeg, creëert dit een record in de debiteurentabel met de ID van de debiteur als naam debiteur.

Maar ik merk ook dat mijn relatietype niet klopt. Volgens mij moet dit een 1-to-many relatie zijn, maw één debiteur kan aan verschillende dossiers hangen. Ik kan dit echter niet configureren in Access.

Even wat opsommen:

Tabel debiteuren: DebiteurenID is een long integer en een autoID. Dit is de PK.
Tabel dossiers: ID is een dossiernummer voor het dossier, en ook een autoID. Deze tabel bevat ook een veld DebiteurenID. Dit is een long integer, en dus de FK.

Ik kan voor de relatie ook geen referentiele integriteit afdwingen; zie screenshot.

Wat kan hier nog mis zijn?

Capture.PNG
 
Dag Tom,

als je geen refrentiële integriteit kan afdwingen dan bestaat er waarschijnlijk in je tabel Politiedossiers een debiteurenID ingevuld die niet in de tabel Debiteuren bestaat. Je kan dit checken via een query met een outer join.
Voor je ander probleem kan je misschien eens beter een voorbeeld posten.

Vriendelijke groeten,
Noëlla
 
Status
Niet open voor verdere reacties.
Terug
Bovenaan Onderaan