Relaties en koppelingen

Status
Niet open voor verdere reacties.

cvanlumig

Gebruiker
Lid geworden
30 sep 2009
Berichten
7
Goedemiddag,

Ik zit met een vraag over wat precies het verschil is tussen een relatie en een koppeling.

Voorbeeld:
Ik heb 2 tabellen gemaakt voor 10 objecten. Tabel 1 bevat de breedte van ieder object en tabel 2 bevat de hoogte van ieder object. Nu wil ik graag een query maken die alle objecten laat zien die breedte x en hoogte y hebben. Wanneer ik beide tabellen koppel (hiermee bedoel ik een link aanbrengen tussen de tabellen in de query zelf) wordt de selectie mooi weergegeven. Echter, wanneer ik een relatie aanbreng tussen beide tabellen in het Relatie venster krijg ik een lijst van 100 opties te zien.

Kortom, als ik tabellen aan elkaar link in de query lukt het wel, als ik de tabellen link via Relaties lukt het niet. Ik moet binnenkort gaan werken met zeer veel tabellen, dus vandaar dat ik probeer het Relatie venster te gebruiken, zodat ik mooi alle relaties tussen de tabellen kan zien (klopt mijn denkwijze?). Anders zou je namelijk alleen de link tussen tabellen zien wanneer je deze ook daadwerkelijk opent. Toch?

Alvast bedankt voor de nuttige input,
C
 
Een relatie is een koppeling tussen twee tabellen, gebaseerd op een bepaalde afhankelijkheid van de tabellen onderling. Je maakt een relatie door een veld uit tabelA te slepen naar het overeenkomende veld in tabelB.
Als voorbeeld een tabel Klanten, en een tabel Facturen: Elke klant is uniek, en krijgt een uniek nummer, KlantID. Een factuur is voor een bepaalde klant, en elke klant kan meer dan één factuur krijgen, als hij meer koopt of bestelt. De factuur is dus afhankelijk van de klant. In de tabel Factuur neem je dus het veld KlantID op, zodat je weet welke klant welke factuur ontvangt.
Om te voorkomen dat een klantD meer dan één keer wordt ingevoerd, wat tot dubbele records zou leiden, maak je van het veld KlantID een Sleutelveld. Hiermee geef je aan dat een KlantID maar één keer mag worden gebruikt.
Uiteraard mag een klant meerdere facturen ontvangen, dus in de tabel Facturen zal het veld KlantID geen sleutelveld zijn. Zou je dat wel doen, dan mag een klant maar één factuur krijgen. Is niet handig ;)
Ga je een relatie leggen tussen de twee tabellen, dan moet je, om de relatie goed te laten werken, de optie <Refefentiële integriteit afdwingen> selecteren, anders werkt de relatie niet goed. Deze optie zorgt er voor, dat je in de tabel Facturen geen klantID kunt invoeren dat nog niet bestaat in de tabel Klanten. Lijkt logisch: je gaat geen factuur maken voor een klant die je niet hebt. Toch?
Als je de relatie op deze manier hebt gemaakt, zul je zien dat de tabel Klanten een 1-teken heeft gekregen, en de tabel Facturen een oneindig teken (gekantelde 8). Hiermee duidt Access een één-op-veel relatie aan: één klant kan veel facturen krijgen.
In bijgaand plaatje zie je iets soortgelijks voor Artiesten en songs.

Als je een query maakt, kun je, zeker voor je gevoel, hetzelfde doen: je sleept een veld uit tabelA en laat het los op een veld uit tabelB.
Wat is nu het verschil? Het is geen relatie, zoveel is wel duidelijk...
Bij het koppelen van velden in een query zeg je tegen Access: ik wil alle records zien, waarvan de velden die ik aan elkaar heb gekoppeld hetzelfde zijn. Of dat lukt of niet, hangt eigenlijk van de waarden in je query af.

Voorbeeld: je hebt in tabelA 3 records gemaakt, met de breedtes 5,8 en 10. In tabelB heb je de hoogte in een veld ingevoerd: 8,10 en 12.
Als je het veld Breedte uit tabelA koppelt aan het veld Hoogte uit tabelB, krijg je 2 records terug: de records met de waarden 8 en 10. Dit zijn de enige 2 records met een waarde die in beide tabellen voorkomt.
In jouw voorbeeld heb je blijkbaar genoeg getallen zijn die overeenkomen, vandaar dat het resultaat correct lijkt te zijn.

Als je, wat je blijkbaar gedaan hebt, in Relaties het veld Breedte hebt gekoppeld aan het veld Hoogte, en je hebt de optie <Referentiële integriteit afdwingen> niet geselecteerd, leg je relatie die in wezen waardeloos is. Access kan daar niks mee. Maak je nu een query, en je selecteert weer de velden Breedte en Hoogte, dan weet Access niet hoe de gegevens moeten worden gekoppeld. Wat doet Access nu?
Eigenlijk heel simpel: Access begint met het eerste record uit tabelA, en zet de eerste waarde uit tabelB erbij. Vervolgens weer het eerste record uit tabelA, maar nu met het tweede record uit tabelB. Daarna het eerste record uit tabelA, met het derde record uit tabelB, en zo voort.
Als alle records uit tabelB zijn gekoppeld aan het eerste record uit tabelB, begint het verhaal opnieuw, maar nu met het tweede record uit tabelA als basis. Net zo lang tot alle records uit tabelA zijn gekoppeld uit alle records uit tabelB.

In jouw voorbeeld heb je 10 records in tabelA, en blijjkbaar ook 10 records in tabelB. 10x10=100.... Vandaar de 100 records. Allicht dat de juiste daar wel tussen zit....

Waarschijnlijk zijn beide resultaten overigens fout, want ik vermoed dat je de twee tabellen niet op deze manier aan elkaar kunt koppelen. Waarom je overigens van één object de lengte en de breedte apart wilt opslaan, ontgaat mij, maar je zal daar (hopelijk) wel een reden voor hebben...
Om de twee tabellen goed te laten werken, heb je dus een constructie nodig waarbij je in tabelA de breedte noteert, en een uniek veld ObjectID nodig hebt voor de identificatie voor de obecten.
In tabelB heb je een veld nodig voor de hoogte, en ook het veld ObjectID, om de breedte van een object te kunnen koppelen aan de hoogte van hetzelfde object. In tabelb moet het ObjectID dus ook een sleutelveld zijn, omdat een object (neem ik aan) maar één hoogte kan hebben...
In het scherm Relaties kun je de twee tabellen nu aan elkaar koppelen, waarbij je dus het veld ObjectID uit tabelA koppelt aan ObjectID uit tabelB.
Omdat in beide tabellen het ObjectID een sleutelveld is, maakt Access een één-op-één relatie voor je.
Nu kun je perfecte queries maken, met altijd de goede uitkomst.

Hopelijk is het nu wat duidelijker (anders heb ik mij voor niks het klapper getiklt...)
 

Bijlagen

  • Relaties.jpg
    Relaties.jpg
    12 KB · Weergaven: 92
wow, quite a post :D

ok, het een en ander is me nu duidelijk geworden. Ik zie nu waarom ik zoveel outputs kreeg, en hoe ik dit kan oplossen. Echter, mijn project is iets ingewikkelder dan ik hier heb verteld. Dit heb ik met even met opzet achterwege gelaten omdat het anders niet duidelijk is wat mijn probleem is.

Enfin, here's how it is. Laten we zeggen dat het over auto's gaat. Basic info over het huidige autobezit wordt in een excel tabel ingevuld door andere medewerkers (auto merk, auto type, waarde, km-stand, band profiel, kleine/grote beurt data etc.). Deze tabel lees ik vervolgens in Access in, en gebaseerd op deze info wil ik keuzes gaan maken. Stel ik wil een auto naar de sloop brengen, dan wil ik bv. alle auto's zien die meer dan 200.000km gelopen hebben, waarvan de waarde onder de 2500euro is, en waarvan de laatste beurt meer dan 1 jaar geleden is. Zelf zou ik hiervoor 4 tabellen gebruiken: de orginele ingelezen excel file (kan ik die excel file gewoon gebruiken, of moet ik hier nog een access tabel van maken? ik heb de optie "Gegevens type -> Wizard opzoeken" gekozen maar ik kreeg een foutmelding bij het maken van de relatie, wellicht omdat ik de excel file geselecteerd had), een tabel met de km-stand waarbij de sleutel ID gekoppeld is aan een unieke IDauto, een tabel met de waardes van de auto's (weer gekoppeld aan IDauto), en een tabel met de kleine/grote beurt data (wederom koppelen aan de originele IDauto, die dus in mijn excel file gedefineerd is).

Nu lukt het me wel om een query te maken die bv autowaarde<2500 & km-stand > 200000 laat zien, maar alleen wanneer ik een koppeling in de query zelf maak, en niet via het Relatie venster. Ik zou graag géén één koppeling in queries maken, maar gewoon alles in het Relatie scherm aanmaken zodat ik precies zie welke tabel en query van welke andere tabel/query afhangt. Kan dit uberhaupt? Ik zou zeggen van wel. Dan nu de vraag, hoe? :)

Wederom al bedankt!
 
Ander voorbeeld. Ik denk dat het allemaal met hetzelfde te maken heeft, en dat ik dat gewoon even moet doorhebben. Maargoed:

ik heb 2 tabellen gemaakt en ik probeer daaruit een derde tabel te maken via een Tabelmaakquery.
Tabel 1 bestaat uit 2 velden met de naam "Tabel1" en "Waardes". Er zitten 9 entries in beide kolommen van de tabel, namelijk 1, 2, 3, 4, 5, 6, 7, 8 en 9
Tabel 2 bestaat tevens uit 2 velden met de naam "Tabel2"en "Waarden". Ook hier zitten 9 entries in de kolommen, alleen zijn de getallen 1t/m9 in de "Waarden" kolom in omgekeerde volgorde, dus 9, 8, 7, 6, 5, 4, 3, 2 en 1.
In het Relatie venster heb ik een één-op-één relatie met ref. intr. aangemaakt. De relatie loopt tussen "Tabel1" en "Tabel2". In de query heb ik Tabel1 en Tabel2 toegevoegd en ik zie nu ook automatisch de link tussen de tabellen (met twee 1-tjes erbij). Ik voeg daarna de velden "Waardes" en "Waarden" in de onderste helft van het ontwerpweergaven scherm toe, en in de derde kolom type ik "Uitkomst: [Waardes]*[Waarden]". De nieuwe tabel wordt "Tabel3" genaamd. De inhoud van deze tabel klopt nu wel (3 kolommen: Waardes, Waarden en Uitkomst) maar ik zie bij Relaties de relatie met "Tabel3" niet verschijnen. Ik had gehoopt dat die Relatie automatisch toegevoegd wordt omdat ik tabel3 bereken met tabel1 en tabel2. Waar ga ik fout..?
 
Ik ben vandaag de hele dag op stap geweest, dus heb nog geen computer aangehad... (heerlijk gevoel overigens :D ) Ben blij dat mijn verhaal duidelijk was!

Maar met je laatste post beginnen: als je een nieuwe tabel aanmaakt, met of zonder aanmaakquery, dan zal de nieuwe tabel nooit automatisch worden toegevoegd aan het relatievenster, en al helemaal niet automatisch worden gekoppeld aan andere tabellen. Gelukkig maar, zou ik zeggen! Access weet namelijk niet wat je wil met die nieuwe tabel, dus relaties zul je altijd zelf moeten leggen. Ander punt: als je een tabel maakt met een query, heb je ook nog geen sleutel gedefinieerd; dus dat moet je ook eerst nog doen voordat je de relaties gaat leggen met de nieuwe tabel.
Je moet zelf de nieuwe tabel toevoegen aan het relatiescherm. Dat doe je met de knop met het gele Plus-teken, of via het menu. Daarna sleep je weer de velden op de gerelateerde velden om de koppeling te leggen. Let wel: voordat je gaat linken, eerst de sleutels goed bekijken!. Overigens kan je vanuit het Relatiescherm rechtstreeks naar het tabelontwerp, door rechts te klikken op de tabel en het snelmenu te gebruiken.

Nu weer terug naar je vorige post. Je db is dus wat ingewikkelder dan je eerst voordeed; dat mag uiteraard, maar het is voor de forumleden toch wat handiger als je gelijk het probleem met de juiste tabellen omschrijft... We kunnen wel wat hebben als het gaat om gecompliceerde databases :)
Als je een Excel sheet als basis gebruikt, dan heb je het meestal over een gegevensbestand waar vaak dubbele informatie in voorkomt. Je hebt dus een werkblad met autogegevens, dat in Access opgesplitst zou kunnen worden in verschillende tabellen. Daarbij is het zinvol om na te denken over wat je wel splitst, en wat niet. Blijkbaar houd je per auto in één tabel bij welke auto wanneer en bij welke kilometerstand een onderhoudsbeurt heeft gehad.
Jouw oorspronkelijke idee om alle gegevens op te splitsen in aparte tabellen hoeft echter niet het juiste uitgangspunt te zijn.
De vraag die je moet stellen is: welke gegevens horen bij elkaar, en welke gegevensgroepen moet ik daarvoor aanmaken.
Zo zou je, als je een basistabel wil maken voor je autovoorraad, in die tabel een AutoID moeten hebben, een Merk, een Type, Motorinhoud, Kleur, Km-stand, aantal deuren etc. Ik noem hier allerlei kenmerken op, die éénmalig zijn terug te vinden voor één specifieke auto. Zo zal een auto één kleur hebben, ligt het aantal deuren vast, zal je er niet zo snel een andere motor aan toevoegen, en heeft de auto één (huidige) kilometerstand. Al deze items (en vast nog wel meer) heb je nodig om de auto als object te kunnen beschrijven. Ergo, dit moet dus in één tabel.

Als je in hetzelfde Excel blad ook de onderhoudsbeurten bijhoudt, treed waarschijnlijk de volgende situatie op: als een auto voor zijn eerste beurt komt, zet je de gegevens waarschijnlijk achter de reeds ingevoerde data. Je maakt een paar kolommen aan met de datum van de beurt, kmstand etc. Bij een tweede beurt moet je een compleet nieuw record (nieuwe rij) aanmaken, en alle bestaande autogegevens herhalen, en de gegevens voor de tweede beurt invullen in de daarvoor bestemde kolom. Dat is niet handig in Excel, en al helemaal niet handig in Access. Eigenlijk is de hele groep gegevens die je invult bij de onderhoudsbeurten een eigen gegevensgroep. Ergo: een eigen tabel in Access. Uiteraard wil je wel weten welke auto een beurt gehad heeft, dus in de tabel Onderhoudsbeurt sla je ook de AutoID op. Is in deze tabel dus geen sleutel, want dat is OnderhoudsID. In Relaties leg je dan een koppeling tussen AutoID uit de tabel Auto, en AutoID uit de tabel Onderhoud. Dit is weer een één op veel relatie, want één auto kan meerdere onderhoudsbeurten krijgen.

Door op zo'n manier dus je db op te bouwen, is het maken van overzichten ook een stuk makkelijker, want je werkt altijd met gerelateerde tabellen, en kunt per tabel opvragen wat je wilt.

Overigens heb ik in mijn verhaal een onderscheid gemaakt tussen km-stand in de tabel Auto, en km stand in de tabel Onderhoud. Da's met een reden, die je hopelijk nu zelf kunt bedenken...
 
Zo, ben weer terug aan het werk gegaan. Ik zie alweer een zeer uitbundige post. Hardstikke mooi! Vol handige info. Toevallig dat je vermeldt dat de datum van het onderhoud steeds aangepast moet worden. Ik vroeg me namelijk al af hoe dat precies zou moeten werken. Zodat je dus bijvoorbeeld het auto aanbod in 2009 kan opzoeken, maar dat je ook nog kan terugvinden wat je in 2008 voor een aanbod had. Dat snap ik nog niet precies waar je dat handig kan aangeven. Verder lijkt het antwoord op jouw laatste vraag te zijn dat de km-stand tijdens een beurt niet gelijk is aan de huidige km-stand, bijvoorbeeld.

Goed, ik ga er eens goed over nadenken, maar ik kan in ieder geval alweer een stuk vooruit. Bedankt!
 
Ik bedoel niet zozeer dat je de datum van het onderhoud moet aanpassen, hoewel dat uiteraard wel moet kunnen, bijvoorbeeld als iemand een afspraak verzet. Het idee is meer, dat je voor elke onderhoudsbeurt in de tabel Onderhoud een nieuw record maakt, zodat iemand die voor zijn auto 5 onderhoudsbeurten heeft gehad, ook 5 records heeft met de gegevens die bij die verschillende onderhoudsbeurten thuishoren. Bij elke onderhoudsbeurt noteer je bijvoorbeeld de datum, en de km-stand. Logischerwijze loopt de km-stand bij elke beurt op, al schijnt dat in de autoindustrie ook wel eens anders voor te komen ;)
 
Daar ben ik weer, met een nieuwe vraag :)

Ik had dus verteld dat ik gebruik maak van een extern excel bestand dat gekoppeld wordt aan mijn database. Nu treedt het volgende probleem op. Als ik in excel een nieuwe kolom toevoeg, en expliciet aangeef dat het "tekst" is, ondanks dat er alleen maar getallen instaan, neemt Access deze waarden over als zijnde numeriek. Ik kan dit ook niet aanpassen in acces, omdat de tabel gekoppeld is aan een excel bestand, en dus alleen maar kan lezen. Kan ik dit op een of andere manier omzeilen, zodat ik dus een kolom met getallen kan gebruiken in access al zijnde tekst? bedankt.
 
Gaat denk ik heel lastig worden.... Koppelingen worden meestal op basis van verouderde OLE verbindingen gemaakt; als je bijvoorbeeld een Access tabel exporteert naar Excel, krijg je hem in Office 95 opmaak. Maakt niet eens uit in welke versie je dat doet....
Een kolom met getallen wordt dus bijna altijd wel als een getalveld gezien. Je zou, om de kolominstelling te beïnvloeden, een rij kunnen toevoegen waar je dan tekst in zet, bij voorkeur als eerste rij. Met een beetje mazzel ziet-ie hem dan wel als tekst.
 
Aangezien mijn nieuwe vraag nog steeds over de besproken database gaat stel ik hem dan ook maar hier. Het antwoord is vast simpel, maar soms ben je zo lang aan het zoeken, dat je gewoon niet vooruit komt.

De opdracht:
ik wil graag een kruistabel maken en gebruik maken van een bereik voor de variabele "gelopen km". Dat is als volgt bedoelt: stel ik heb 5 auto's. de eerste 2 hebben minder dan 150.000km gelopen. De 3de heeft 156.000 gelopen en de laatste 2 hebben meer dan 250.000 gelopen. Nu zou ik graag een kruistabel hebben die als kolomkoppen de volgende titels heeft: AutoID 0-100.000km 100.001-150.000km 150.001-200.000km etc.

Onder AutoID komt dan het kenmerk van die specifieke auto te staan en in de betreffende afstandkolom wil ik graag de actuele meterstand kunnen aflezen.

De vraag: hoe kan ik een soort bereik instellen zodat de kilometerstanden in de juiste kolom komen te staan?

Bedankt alvast!
 
Dat gaat niet lukken zonder hulptabel, omdat je in een kruistabel kolommen maakt op basis van de inhoud van een bepaald veld. Zou je het veld km-stand gebruiken, dan krijg je dus voor elke aparte waarde een aparte kolom. Je moet dus een tabel maken met de verschillende km-stand categorieën, die je in een query koppelt aan de tabel met bronwaarden.

In bijgaande db zie je een voorbeeldje.
Overigens is het prettiger als je voor een compleet andere vraag een nieuwe topic maakt, omdat je dan weer een 'vers' panel trekt... Nu heb je kans dat mensen je vraag laten liggen, omdat de topic ergens anders over lijkt te gaan.
 

Bijlagen

Gaat denk ik heel lastig worden.... Koppelingen worden meestal op basis van verouderde OLE verbindingen gemaakt; als je bijvoorbeeld een Access tabel exporteert naar Excel, krijg je hem in Office 95 opmaak. Maakt niet eens uit in welke versie je dat doet....
Een kolom met getallen wordt dus bijna altijd wel als een getalveld gezien. Je zou, om de kolominstelling te beïnvloeden, een rij kunnen toevoegen waar je dan tekst in zet, bij voorkeur als eerste rij. Met een beetje mazzel ziet-ie hem dan wel als tekst.

Dit had ik ook. Je kunt dit meestal oplossen door eerst je excel bestand zonder data op de juiste formatting te zetten en daarna je gegevens er als values only in te kopieren. Dan leest access wel de formattering die je hebt ingesteld (dus tekst, numeriek, etc). Misschien het proberen waard.:D
 
Om op Patrick zijn antwoord door te gaan: (gaan de vragen heerlijk door elkaar heen lopen ;) ) je kunt een waarde in Excel als een tekst invoeren door er eerst een enkel aanhalingsteken voor te zetten, dus dit: '010 . Zie plaatje. Dan heb je in ieder geval Tekst ingevoerd, en dat in combinatie met Tekstopmaak van de kolom, zou een heel eind moeten komen...
 

Bijlagen

  • Getal als Tekst.jpg
    Getal als Tekst.jpg
    6,8 KB · Weergaven: 51
Om op Patrick zijn antwoord door te gaan: (gaan de vragen heerlijk door elkaar heen lopen ;) ) je kunt een waarde in Excel als een tekst invoeren door er eerst een enkel aanhalingsteken voor te zetten, dus dit: '010 . Zie plaatje. Dan heb je in ieder geval Tekst ingevoerd, en dat in combinatie met Tekstopmaak van de kolom, zou een heel eind moeten komen...
Bedankt voor jullie reacties. En dat de vragen door elkaar lopen maakt niets uit.. voor mij dan ;) Ik wou liever niet nog een topic starten met een "onbenullige" vraag. Maargoed, om te antwoorden op jou suggestie om 'dit_is_tekst te gebruiken, mijn bestand bestaat soms uit een rij van 1000+ waarden, waarvan sommige een getal bevatten en andere weer tekst. Het wordt dus lastig om al die waarden handmatig aan te passen en die ' toe te voegen.

ps. ik geloof dat hier iemand in de feestdagen stemming is als ik die produktnamen zo bekijk.. :D
 
Met deze simpele macro maak je in ongeveer een halve seconde van een complete kolom tekst...

Code:
Sub GetalNaarTekst()
Dim sTekst As String
Dim i As Integer

i = 0
Do Until ActiveCell.Offset(i, 0).text = ""
    sTekst = "'" & ActiveCell.Offset(i, 0).text
    ActiveCell.Offset(i, 0).Value = sTekst
    i = i + 1
Loop
    
End Sub
 
Status
Niet open voor verdere reacties.
Terug
Bovenaan Onderaan