Acties:
  • 0 Henk 'm!

  • n1els
  • Registratie: Februari 2004
  • Laatst online: 11-06 11:25
Omdat ik een jaar of 6 geleden op het MBO het een en ander over relationele databases heb gehad dacht ik wel even een productcatalogus in MS Access uit m'n mouw te schudden.. het is toch een beetje roestig geworden...

Wat wil ik bereiken? Een productcatalogus waar van alle producten de relevante gegevens vermeldt staan, welke ik later eventueel ga uitbreiden om ook voorraadbeheer etc. mee te doen.

Een product maakt deel uit van een productserie, dus bijvoorbeeld de productserie Coca-Cola, met als producten blikje, kleine fles en grote fles. Een productserie maakt weer deel uit van een productgroep (dus in dit voorbeeld Frisdrank, maar in mijn geval potten, vazen en beeldjes en dergelijke).

Nu kan ik behalve de tabel Products ook een tabel Series aanmaken, en dan middels lookup wizard een drop down box maken, maar als ik dit ook doe met Groups (productgroep) dan krijg ik het niet voor elkaar dat deze twee selecties elkaar uitsluiten. Dus nu kun je, als je een nieuw product invoert, kiezen voor productserie Coca-Cola in de productgroep Graafmachines. Terwijl de bedoeling juist is dat als je aangeeft dat het nieuwe product in de serie Coca-Cola valt dat er dan automatisch Frisdrank bij komt te staan.

(want, Coca-Cola zit maar in 1 productgroep en dat is frisdrank)

Met behulp van de voorbeelden uit de hulpfunctie van Access kom ik er ook niet uit, want die beperken zich alleen tot een one-to-many relatie met 1 andere tabel, terwijl ik er volgens mij 2 heb (groups & series) die bovendien ook een onderlinge afhankelijkheid hebben.

Verder heb ik geprobeerd om net zoals in de hulpfunctie tussenliggende tabellen te maken om te voorkomen dat er many-to-many relaties ontstaan, dus ik heb inmiddels 5 tabellen (products, series, groups, productseries, seriesgroups) met relaties daartussen. Maar ook dit is volgens mij niet zoals het hoort, in ieder geval krijg ik er geen formulier mee aan de praat.

Wie ziet de denkfout en kan mij even de goede kant op duwen?



Aanvulling:


Ik heb nog maar eens even de normalisatie regels van Cobb doorgelezen en ik kom langzamerhand al wel een stukje verder.

Zoals ik het nu begrijp heb ik helemaal geen 5 maar 3 tabellen nodig (Products, Series, Groups). Dit omdat een product slechts in 1 serie thuishoort, en 1 serie slechts in 1 groep. Ik hoef dus helemaal niet in de Products tabel aan te geven in welke groep dit product zit als ik al heb aangegeven in welke serie deze zit.

Mijn database relaties zien er nu als volgt uit:
Afbeeldingslocatie: http://nielstomey.com/download/Relations.png

Het lukt mij echter nog niet om een formulier te maken waarbij middels een combo box de groep kan worden gekozen, waarna met de volgende combo box uit een van de series in die groep kan worden gekozen. Qua relaties zou het nu volgens mij moeten kunnen aangezien Products.Products_Series_ID gekoppeld is aan Series.Series_ID en Groups.Group_ID is gekoppeld aan Series.Group_ID.

[ Voor 19% gewijzigd door n1els op 20-03-2011 15:55 ]

Dimidium facti qui bene coepit habet: sapere aude.


Acties:
  • 0 Henk 'm!

Verwijderd

Als ik het goed begrepen heb, moet je het volgende doen:

1) een tabel met je producten aanmaken (Products), met iig de velden ProductsID en SeriesID;
2) een tabel met je series aanmaken (Series), met iig de velden SeriesID en GroupsID;
3) een tabel met je groepen aanmaken (Groups), met iig het veld GroupsID.

nu gaat het om de relaties tussen die drie. Zoals je zelf aangeeft:

1) een Product in de tabel Products (laten we zeggen: veld Products.ProductID) valt onder één productserie;
2) een Serie in de tabel Series (laten we zeggen: veld Series.SeriesID) valt onder één seriegroep.

Dit betekent dus dat je:

1) in je tabel Products naast het ProductID ook een veld SeriesID moet opnemen, dat een N:1-relatie heeft met het veld SeriesID in de tabel Series;
2) in je tabel Series naast het SeriesID ook een veld GroupsID moet opnemen, dat een N:1-relatie heeft met het veld GroupsID in de tabel Groups.

Ik zou alle ID-velden numeriek maken; deze velden dienen per tabel ook als de primary key (het handigste is om ze als autonumber te typeren, want dan kent Access er automatisch een uniek nummer aan toe):

1) Products: ProductsID;
2) Series: SeriesID;
3) Groups: GroupsID

De relaties die ik hierboven heb omschreven, leg je vast in het Relationshipsmenu.

Het mooie hieraan is, dat wanneer je een product toekent aan een serie, je datzelfde product helemaal niet meer opnieuw hoeft te kennen aan een groep, want de relatie tussen de geselecteerde serie en de bijbehorende groep heb je al vastgelegd in de relatie tussen de tabellen Series en Groups.

Om per serie te kunnen aangeven onder welke groep deze valt, kun je het beste werken met een ander formulier, dat losstaat van het productformulier: een serieformulier. En de groepen zelf kun je dan weer bijhouden middels een groepenformulier.

Acties:
  • 0 Henk 'm!

  • n1els
  • Registratie: Februari 2004
  • Laatst online: 11-06 11:25
Bedankt, ik had inmiddels ongeveer hetzelfde bedacht inderdaad..zie edit in TS.

Ik heb een formuliertje gemaakt en via de Combo Box Wizard de groepen en de series laten opzoeken, hierbij heb ik bij beide keren gekozen voor "store that value in this field:" en dan het bijbehorende veld gekozen.

Afbeeldingslocatie: http://nielstomey.com/download/comboboxwizard1.png

echter nu krijg ik, als ik iets probeer in te vullen de foutmelding "The value cannot be
added to this new row until the row has been committed, commit the row first
and then try adding the value", dus ik ben nog even aan het uitzoeken wat ik dan nu fout doe...

Edit: hier vind ik bij een soortgelijk probleem de volgende opmerking:
This error usually pops up when you try to enter a (child) record in the subform before there is a corresponding (parent) record on the main form. Is that the situation here?
En dat klopt natuurlijk wel want ik probeer eerst de groep te selecteren, en daarna de serie pas.. maar ik krijg het ook als ik het andersom doe.



edit 2: ik krijg eigenlijk het gevoel dat ik een query moet maken hiervoor.. zoiets als SELECT * FROM Series WHERE Group_ID is x ofzo...

[ Voor 229% gewijzigd door n1els op 20-03-2011 16:58 ]

Dimidium facti qui bene coepit habet: sapere aude.


Acties:
  • 0 Henk 'm!

Verwijderd

Eerste vraag die ik dan voor je heb is: waarom wil je de gebruiker eerst de mogelijkheid bieden een groep te selecteren, en daarna pas een serie? Je zult daar ongetwijfeld je redenen voor hebben, maar als dit inderdaad een ontwerpvoorwaarde is, moet je ook je formulieren en de wijze waarop de gebruiker ermee omgaat anders gaan inrichten.

Dan zou je kunnen denken aan een masterformulier dat zijn records ophaalt uit de Groups-tabel. Een gebruiker kan middels dit formulier nieuwe groepen toevoegen, of bestaande groepen selecteren.

Onder dat masterformulier hang je dan een childformulier dat zijn gegevens ophaalt uit de tabel Series. Voordeel van die constructie is dat je alleen die series te zien krijgt die ook onder de Group hangen die je in het masterformulier hebt geselecteerd.

En vanuit dat childformulier zou je dan weer een button kunnen aanmaken die je naar een daaronderhangend childformulier stuurt, waar je vervolgens één of meerdere artikelen aan de tabel Products kunt toevoegen die onder de geselecteerde Serie moeten komen te hangen.

Dat is ook de standaardoplossing bij jouw relatie-inrichting. Er is sprake van een master-child-relatie tussen de tabellen Groups-Series, en Series-Products. Niet tussen Groups en Products.

Acties:
  • 0 Henk 'm!

  • n1els
  • Registratie: Februari 2004
  • Laatst online: 11-06 11:25
Het lijkt mij het meest logisch om de gebruiker dit in een formulier op deze manier te vragen. Dit formulier gaat worden gebruikt voor het invoeren van nieuwe producten.

Als de gebruiker het formulier opent (nieuw record aanmaakt) wordt er een Autonumber productnummer aangegeven. De gebruiker wordt dan middels een combobox gevraagd wat voor soort product dit nieuwe product is. Bijvoorbeeld een pot.

Als dan duidelijk is dat het om een nieuwe pot gaat, kan worden gevraagd wat voor soort pot. In dit voorbeeld een klassieke pot (i.t.t. een moderne).

Vervolgens kunnen de andere producteigenschappen ingevoerd worden, zoals productomschrijving, afmetingen, gewicht etc.

Het is dan natuurlijk wel zo handig dat als de gebruiker aangeeft dat hij een nieuwe pot aan het invoeren is, dat hij dan vervolgens kan kiezen uit alle verschillende soorten potten, en dat er niet ook allerlei productsoorten uit andere productgroepen bij staan. Met een productsoort die "klassieke pot" heet is dat nog niet zo erg, maar als je bijvoorbeeld een een productlijn (productlijn is misschien een duidelijkere omschrijving dan serie) met een of andere artistieke of wollige naam zoals "Zomertuin" hebt is aan de naam totaal niet te zien of dit een productlijn met potten of met tuinbankjes is.

Eigenlijk wil ik dus graag dat als ik een productgroep (bijv. pot) selecteer de volgende combobox alleen productlijnen uit die groep weergeeft. Ik kan in de productlijnen-tabel natuurlijk een groep_id veld opnemen (heb ik al), maar ik wil dus graag ook op de inhoud van dat veld de Series tabel filteren afhankelijk van mijn selectie in de combobox horende bij de Groep tabel.

Nu ik hier zo over nadenk denk ik hiervoor een query moet aanmaken trouwens. Als ik in Combobox1 waarde x opgeef, wil ik in Combobox2 alleen records uit de tabel laten zien waarvan de waarde van het veld Group_ID ook x is.

Op die manier hoef ik in de product-tabel helemaal geen groep op te nemen, want deze zit al in de serie opgenomen. Hoe ik dit moet realiseren zou ik zo gauw alleen even ook niet weten, maar het lijkt me op die manier wel mogelijk..

Dimidium facti qui bene coepit habet: sapere aude.


Acties:
  • 0 Henk 'm!

Verwijderd

Waar jij vanuitgaat (en waar volgens mij ook je denkfout zit) is dat een gebruiker eerst een product invoert, en daarna pas gaat nadenken over de series en groepen waar dat product bijhoort.

In de praktijk zal een eindgebruiker waarschijnlijk al vantevoren een idee hebben onder welke series en groepen een product valt. Op het moment dat hij/zij een nieuw product in jouw database invoert, kun je die eindgebruiker dus de mogelijkheid bieden om eerst een groep te selecteren, bijvoorbeeld "Potten", daarna een serie daarbinnen, bijvoorbeeld "Aardewerken potten" en daarna onder die serie het uiteindelijke product in te voeren ("arabische pot van aardewerk").

Als je je formulieren nou zo inricht als ik in mijn post hierboven suggereer, maak je daarbij bovendien optimaal gebruik van de inrichting van Access. Dan hoef je zelf niet meer met cascading queries en comboboxen te gaan werken om Access te vertellen wat de datarelatie tussen de verschillende tabellen is, waarbij er bovendien geen onzinrelaties kunnen worden geselecteerd. Dat heeft Access dan nl al voor je gedaan.

Vergelijk het in de praktijk met het kopen van een pak melk. Je gaat niet eerst alle huizen in je straat langs om te vragen of je bij hun misschien een pak melk kunt kopen. Waarschijnlijk ga je eerst naar een supermarkt toe (=groepselectie), daarna loop je naar de afdeling zuivel (=serieselectie) en daar pak je je pak melk (=productselectie). Vertaald naar jouw database laat je je eindgebruiker eerst de groep en daarna de serie selecteren, en daarna binnen de geselecteerde serie pas een product invoeren.

Acties:
  • 0 Henk 'm!

  • n1els
  • Registratie: Februari 2004
  • Laatst online: 11-06 11:25
Duidelijke uitleg.. ik ga het eens op die manier proberen. Ik ga even prutsen, laat wel weten wat het geworden is..

Dimidium facti qui bene coepit habet: sapere aude.


Acties:
  • 0 Henk 'm!

Verwijderd

Tip: gebruik de Wizard eens om een hoofdformulier met een subformulier te maken. En ga vandaaruit verder knutselen ;)

Acties:
  • 0 Henk 'm!

  • n1els
  • Registratie: Februari 2004
  • Laatst online: 11-06 11:25
Die functie heb ik inderdaad zojuist ontdekt.. is een stuk makkelijker dan ik verwachtte, zo'n subformulier aan elkaar linken (sterker nog: deed de wizard vanzelf al)

Vanuit de Filipijnen hartstikke bedankt ;)

Dimidium facti qui bene coepit habet: sapere aude.

Pagina: 1