21. februar 2011 - 21:07Der er
20 kommentarer og 1 løsning
Relationer mellem 2 tabeller
Hej Eksperter.
Jeg har en Access database, hvor der er en tabel der skal bruges til historik.
I historiktabellen har jeg bl.a. 2 felter "Emne" og "Underemne" som begge skal være kombinationsbokse. Disse to felter skal kigge i to andre tabeller, og hente en liste over valgmuligheder.
Min udfordring kommer så ved relationerne, da jeg vil vise nogle bestemte underemner, alt efter hvilket emne man har valgt.
Ex: Vælger man emne 1, kan man vælge undermene 1, 2 og 3, og vælger man emne 2, kan man vælge underemne 3, 4 og 5. Det samme underemne går altså igen på flere af emnerne. Hvordan skal det sættes op? Upload gerne et access eksempel.
DU har en many-to-many relation mellem dine emner og underemner, så du skal lave en table til at indehodle den information:
tblEmnerUnderemner
EmneID (FK) UnderemneID (FK)
så data svarende til dit eksempel ville være:
1 1 1 2 1 3 2 3 2 4 2 5
Din combobox Underemne skal så hente data fra en forespørgsel, hvor EmneID=Forms!navnet_på_formen!cboEmne (altså den værdi der er sat i combo'en Emne) og tabellen med udneremner , og relationstabellen, er linket via UnderemneID
Neoman -> Det med comboboxen tror jeg at jeg har styr på. Men mht. relationerne tror jeg at jeg måske mangler en tabel. Kunne jeg få dig til at kigge på billedet (link) og skrive hvad der skal forbindes?
Har kigget og er forvirret .-) sorry, blev lidt lost i subject, subsubject og subject_subsubject
Hvis vi har en table med emner:
tblEmner -------- EmneID (PK) EmneTekst evt. andre felter
og underemner
tbUnderemner ------------ UnderemneID (PK) UnderemneTekst evt. andre felter
så skal du have en tabel med relationer:
tblEmnerUnderemner EmneID (FK) UnderemneID (FK)
I relationerne i databasen linker du så one-to-many tblEmner.EmneID sammen med tblEmnerUnderemner.EmneID og one-to-many tblUnderemner.UnderemneID med tblEmnerUnderEmner.UnderemneID
Så skal jeg vide lidt mere om din DB: hvad er Emne, Underemne i tblHistorik? er det EmneID, UnderemneID, eller EmneTekst, UnderemneTest ? I det sidste tilfælde bryder det mod normaliserinsgreglerne, når samme data forekommer to steder.
Bliver emne/underemne hentet fra tblHistorik og lagt i tblEmne/tblUnderemne og derpå relationerne (hvilke emner/underemner hører sammen?) bliver skabt eller hvordan er arbejdsgangen?
Hvis det hele er foruddefineret, så skal din tblHistorik ikke indeholde EmneID og UnderemneID og så kan du også lave links i tillæg til de før beskrevne:
one-to-many fra tblEmne.EmneID til tblHistorik.EmneID one-to-many fra tblUnderemner.UnderemneID til tblHistorik.UnderemneID
Jeg vil selvfølgelig helst have EmneID og UnderemneID ind i tblHistorik, da det, som du skriver, er nødvendigt for at overholder NF'erne. Men så kan jeg ikke få det til at hænge sammen med min formular, da man på formularen skal vælge mellem værdierne i tblEmner.Emnetekst og tblUnderemne.UnderemneTekst, men indsætte værdierne fra tblEmner.EmneID og tblUnderemne.UnderemneID i tblHistorik-tabellen - hvordan gøres det?
Hvis jeg laver de relationer du skriver i post nr. 5, så hænger Emne og Underemne ikke sammen?
Databasen skal bruges til håndtering af kundehenvendelser i et projekt. Når en kunde henvender sig, skal konsulenten udfylde en log på kunden. Jeg har en kundetabel med kundeID, som bliver sat ind i tblHistorik, så jeg på kundeoversigten kan trække en liste over de historikker, der er lavet på kunden.
querien for recordsource for din combo skal hente EmneID, EmneTekst..
EmneID er den bundne værdi, men til visning skal det felt blot have bredden sat til 0 i Properties , sår der står fx. "0cm;2.52 cm", så det bliver EmneTekst som ses. Comboen er så bundet til EmneID fra tblHistorik på formularen. Tilsvarende for den anden. Husk at fortælle comboen i Properties at den skal vise 2 felter.
Er det klart nok? Elers spørg igen.
Hvad relationerne angår: bemærk "i tillæg til de før beskrevne" :-)
Beklager den sene respons. Men nu virker det efter hensigten også med comboen. :)
Jeg har dog bare stadigvæk den udfordring, at den ikke overholder NF.
Jeg har lavet En-til-mange releation mellem tblHistorik og tblEmner samt mellem tblHistorik og tblUnderemner. Disse to er de eneste relationer jeg har lavet.
I tblUnderhistorik har jeg et ekstra felt med EmneID. Jeg har så sat en følgende ind i rækkekilden for komboboksen for Undermene: SELECT tblUnderemner.UnderemneID, tblUnderemner.UnderemneTekst, tblUnderemner.EmneID FROM tblUnderemner WHERE (((tblUnderemner.EmneID)=[Forms]![Formular1]![Emne]));
Og så har jeg sat skrevet en VBA kode på "VedÆndring" af Emne komboboksen: Me.Underemne.Requery
Det virker! Men jeg har 2 problemer her.
Det ene er at jeg har dubletter i tblUnderemne.UnderemneTekst såsom valmuligheden "Andet" som kan vælges for alle Emner. Det er nok den problematik med Mange-til-Mange jeg ikke helt har fattet her.
Den anden er, at hvis jeg vælger gør følgende: 1. Vælger noget i cboEmne. 2. Vælger noget i cboUnderemne. 3. Vælger noget andet i cboEmne. 4. Gemmer / lukker formularen. Så står der ikke noget i cboUnderemne, og den genbruger så simpelthen den sidste værdi jeg havde valgt der. Er der en mere "rigtig" måde at gøre det på?
Hvad har hindret dig i at lave relationerne mellem tabellerne tblEmner , tblUnderemner og tblEmnerUnderemner? Hvis du ikke gør det på den måde ,så får du dubletter, fordi du ikke kan knytte samme (=med samme UnderemneID) Underemne til to forskellige Emner. Den eneste måde man kan gøre på er via en relationstabel tblEmnerUnderemner.
DIn query for comboen Underemne skal så finde alle de UnderemneID i tblEmnerUnderemner hvor tblEmnerUnderemner.EmneID er givet i din combo Emne, og via relationerne alle de UnderemneTekst i tblUndermner, hvor UndermneID er lig med tblEmnerUnderemner.UdderemneID.
Hvsi du opretter de relationer mellem tabellerne, så vil det fremgå simpelt i query builderen QBE'en, når du trækekr begeg tabellerne ind.
"Gemmer" formularen? Har du en split form? For at gemme en formular er ikke det samme som at lukke den. Hvis du "gemmer" , så husker den nok mere end godt er.
In any case, så kan du på formens OnCurrent event (som kører når formularen åbnes, eller går til en anden record i din tblHistorik) køre Underemne.Requery og/eller Underemne=Null, og ligeledes sætte noget validering på feltet Underemne (Not Is Null)
Som en sidebemærkning: hvis kontroller har samme navn som de felter de er bundet til, og her gætter jeg på at din combo Emne er bundet til felt Emne i din tblHistorik, før eller senere kan man komme ud i problemer. Forslag: i tblHistorik, Emne-> EmneID, comboen på din form: Emne-> cboEmne (bundet til tblHistorik.EmneID) osv.
Studenter og kurser: En studerende kan følge flere kurser, og et bestemt kursus kan blive flugt af mange studerende. SÅ du har en tabel tblKurser, tblStuderende, og tblKurserStuderende, som knytter vilkårligt antal studerende med vilkårligt antal kurser. Hvis du lavede en løsning som din nu foreslåede, så vil to studerende ikke kunne følge samme kursus, men der skulle oprettes et nyt til hver :-)
#11 Hvis det er sådan at et bestemt UnderemneTekst aldrig nogensinde skal kunne blive tilknyttet forskellige EmneID, altså på nær "Andet", så er din løsning jo i princippet OK, og så kan du skkert leve med at Andet skal oprettes for hvert Emne - der findes ikke noget Normaliseringspoliti :-)
#13 Som du nok har gættet er jeg stadigvæk grøn på nogle områder i Access, og jeg vil derfor gerne lære best-practice fra starten af, så når jeg støder ind i de meget omfattende opgaver, at så ved jeg hvordan det "bør" gøres ;)
Jeg har nu rettet mine relationer fra 1 - 2 (se link) er det sådan du mener at det skal sættes sammen? http://screencast.com/t/CUW5R2C94
Jeg vil stadig anbefale, at felterne i tblHistorik kaldes det de er, nemlig EmneID og UnderemneID (hvilke benævnelser vises i formularer, datasheets osv kan altid ændres, eller sættes i selve tabellen i Properties Caption i tabel designeren)
Et andet punkt- det kan være fristende at lave nogle af felterne i tabellen som Lookup, så når du kigger på tblHistorik, så ser du ikke EmneID men EmneTekst. Det er en dejlig shortcut, men det er som at tisse i bukserne: en beslutning som tilsyneladende gør livet nemmere her og nu, men hævner sig bagefter hvis programmet vokser og man skal debugge, lave andre ting, eller lægge det hele over på en SQL server. Så lad være. (Hvis du ikke ved hvad jeg snakker om så meget desto bedre - det er en feature af Access som man bør holde fingrene fra)
Med hensyn til benævnelserne i tblHistorik har du ret, den har jeg lige overset, de skal selvfølgelig også have +ID.
Men nu når jeg har lavet denne relation, har jeg svært ved at finde ud af, hvad jeg skal have i min query, og efterfølgende hvilke felter cboEmne og cboUnderemne skal kigge på.
1. Hvor skal jeg tage EmneID og UnderemneID felterne fra, når jeg skal lave en query til oprettelse af ny historik?
2. Hvilke felter skal jeg have i Rækkekilden til cboUnderemne?
1. Ej forstået. En ny record for tblHistorik har endnu ingen EmneID eller UnderemneID eftersom de sægttes via de to combos
2. cboUnderemne I query designeren træk tblEmnerEnderemner og tblUnderemner ind
Dobbeltklik på tblUnderemner.UnderemnerID , på tblUnderemner.UnderemneTekst og på tblEmnerUnderemner.EmneID
for at få disse felter med i querien
afklik checkboxen i griddet for tblEmnerUnderemner.EmneID, for der er ingen grund til at vise den (den kommmer så med i WHERE delen, og ikke i SELECT delen)
dit søgekriterium skal nu bare skrives i kolonnen for tblEmnerUnderemner.EmneID (altså Forms!DinForm!cboEmne)
1. Kommer an på designet - skal man kunne se de gamle sorteret i en eller anden rækkefølge? Eller er det bare til nye posteringer? Til nye posteringer er det nok med en form baseret på tblHistorik.
Hvis du vil vise de gamle, så skal du lave en query hvor du trækker tblHistorik, tblEmner, og tblUnderemner ind (som nu er linket i hht relationerne), og trækker tblHistorik.EmneID, og tblHistorik.UnderemneID
PÅ dissse to smækker du dine comboboxe, alternativt trækker du også tblEmner.EmneTekst og tblUnderemne.UnderemneTekst ind (og sætter tblHistorik.EmneID og tblHistorik.UnderemneID til ikke synlig )- kommer lidt an på hvordan din form er opygget - Split form, almindelig, continuous eller hvad.
Du må slås med det resten af dagen - jeg skal også arbejde lidt :-). Hvis problemer så kigger jeg på det i morgen,
Det er nemt at hjælpe folk der selv yder en indsats, og ikke lader sig afskrække af noget.
Synes godt om
Ny brugerNybegynder
Din løsning...
Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.