Tabelstructuur (oud probleem)

Status
Niet open voor verdere reacties.

rvdsch

Gebruiker
Lid geworden
18 jun 2009
Berichten
170
Beste forummers,

Zoals enkelen van jullie weten ben ik al een tijdje bezig een database te bouwen. Ik heb echter een probleem waar ik al vaker vragen heb over gesteld maar ik kan maar geen bevredigend antwoord vinden.

Ik wil graag 4 aparte informatie objecten handig opslaan. Het betreft. Locatie, Leverancier, Product en Prijs.

De hierarchie is als volgt:
allereerst komt locatie (onze eigen warenhuizen). Locatie bepaalt welke leverancier kan leveren (niet iedere leverancier levert aan iedere locatie). Leverancier bepaalt welk product geleverd kan worden, maar locatie bepaalt ook het product want niet iedere leverancier levert al zijn producten aan iedere locatie. Prijs staat het laagst in de hierarchie, zij wordt bepaald door Locatie, Leverancier en Product.
Om het nog moeilijker te maken worden van verschillende leveranciers regelmatig hetzelfde product besteld.

Ik ben niet in staat mijn tabellen zo op te bouwen dat er dubbel werk ontstaat. Ik had op een gegeven moment zelf een oplossing; Die bestond uit het feit dat ik alles in 1 tabel zette en dmv een formulier en een subformulier de tabel invulde.
Ik had dus Leverancier en Product bij elkaar en dan ook Locatie en Prijs in een subformulier. Op zich werkte dit goed, ik had alleen het constante gevaar van lege records en ik moest producten die door meerdere leveranciers werden geleverd toch apart erin zetten (bijv. Papier stond er 2 keer in want het werd door twee leveranciers geleverd).

Hoe kan ik de tabelstructuur en een eventueel formulier zo goed mogelijk bouwen? Het is namelijk ook de bedoeling dat alles maar 1 maal wordt ingevuld.

Ideeen, tips, suggesties zijn welkom, ik ga antwoorden op eerdere vragen nog een doorspitten:p
 
Structuur

Hoi rvdsch,

Hoe kan ik de tabelstructuur en een eventueel formulier zo goed mogelijk bouwen?

Om deze vraag te kunnen beantwoorden hebben we toch echt een voorbeeld database nodig.

Ik kan mij de vorige post over dit onderwerp nog wel herinneren.
HelpMij bericht
Toen had ik al een paar opmerkingen op de structuur.
 
Bij deze mijn voorbeelddatabase. Het gaat eigenlijk om de hele structuur. Dit is de oplossing die ik nu heb. Ik ben er tevreden over maar ik denk dat er verbeteringen mogelijk zijn.
Let ook op de code die loopt op het formulier Producten. Die maakt het allemaal wel wat makkelijker.
 

Bijlagen

wat tips, geen structureel probleem

De database is in ieder geval een stuk compacter dan de vorige versie.
Qua structuur tabellen zit het wel goed, 3 tabellen en 2 relaties lijkt mij correct gezien je vorige posts.

Je zou misschien iets moeten maken zodat het niet mogelijk is om 2x dezelfde Locatie of Leverancier in te vullen. Nu is het mogelijk om bijvoorbeeld 2x amsterdam in te vullen, zoals je zelf al wel had gemerkt.

Query1 heeft volgens mij geen nut, deze wordt nergens gebruikt.

Kleine tip: Probeer de queries wel een goede naam te geven, bijvoorbeeld SelectLeverancier, je weet dan gelijk dat het een selectie query betreft van leveranciers oid. 3 queries is nog wel overzichtelijk, maar straks kan je je zelf gemaakte queries niet meer terug vinden.

Nog een kleine tip: ik zou ook de namen van je tekstvakken en keuzelijsten aanpassen.
Bijvoorbeeld txtProduct ipv Product en kzlLocatie ipv Locatie.
Zo is er onderscheid tussen velden in de tabel en velden in het formulier.

De code achter formulier Product en algemene module moet ik even wat beter bestuderen. Kom ik later op terug. Wel mooi stukje code, waar heb je dit weg? ;)
 
Code check

Ik kon geen fouten ontdekken in de code, ik heb ook een tig aantal test met variaties geprobeerd en hij kopieerde netjes de laatste record naar de nieuwe record.

Als je code wel wilt gebruiken, zou ik alleen de foutmeldingen nog even aanpassen.
strErrMsg = strErrMsg & "Cannot carry values over. Form '" & strForm & "' has no recrods." & vbCrLf

Wordt bijvoorbeeld:
strErrMsg = strErrMsg & "Kan geen waarden ophalen. '" & strForm & "' heeft geen records." & vbCrLf

Ik neem hierbij aan dat je gebruikers Nederlands zijn. ;)



Ik zou zelf hier niet voor kiezen, omdat ik de laatst gekozen waarden zou willen zien van het product. Niet de laatste record (dus van alle producten).
Helpmij Vraag van Greenery80
Ik ben Guus2005 nog steeds dankbaar! :)
 
Ik zou de oplossing voor het probleem toch op een heel andere manier oplossen.. Het grote probleem van je database is, dat er een paar tabellen ontbreken. Omdat je met verschillende combinaties van locaties, leveranciers en producten werkt, zou ik de volgende extra tabellen gebruiken (en vullen...)

1. Locatie-Leverancier
2. Locatie-Product
3. Leverancier-Product
4. Locatie-Leverancier-Product

Deze constructie is in mijn ogen nodig, omdat je per locatie verschillende leveranciers wilt kunnen gebruiken, per locatie verschillende producten, en ook nog verschillende producten per leverancier per locatie.
De module die je nu gebruikt, kopieert weliswaar de gegevens naar je tabel, maar ik denk dat je daar op de lange termijn problemen mee gaat krijgen i.v.m. onderhoud.
Daarom heb ik een voorbeeldje gemaakt, waar de extra tabellen inzitten, en een extra formulier waarmee je de combinaties kunt toewijzen aan de tabel Locatie-Leverancier-Product.
Het formulier werkt zodanig, dat je alleen geldige leveranciers bij een bepaalde locatie ziet, en vervolgens van die leverancier alleen die producten die hij mag leveren.
Kijk maar eens of je hier wat aan hebt...

Michel
 

Bijlagen

Hoi Michel,

Dankjewel voor je voorbeelddatabase. Ik had nog een paar vraagjes; je schreef dat mijn structuur lastig is met onderhoud later, wat bedoel je hier precies mee? Is het niet handiger om 1 tabel te hebben?

Hoi Greenery80,

Dankjewel, met jouw code kan ik dus mijn ingevoegde waarde voor product overnemen? Mijn product vak is een geen invoerlijst maar een tekstvakje, werkt dat dan wel?
 
Bij het opzetten van een database probeer je alle verschillende elementen in die database als aparte blokken te behandelen. Elk element, of Entiteit, zoals dat dan heet, krijgt een eigen tabel. Zo heb je niet voor niets al een tabel Leverancier gemaakt, en een tabel Locatie. In de tabel Leverancier sla je alle gegevens op die betrekking hebben op je leveranciers; en in de tabel Locatie alle gegevens over je locaties. Het heeft niet zoveel zin om die twee in één tabel te stoppen, omdat ze, als zelfstandig item, niets met elkaar te maken hebben.
Dat principe geldt ook voor de tabel Product. In die tabel sla je dus bij voorkeur alleen gegevens op die horen bij de producten, zoals Prijs, Eenheid, Verpakkingshoeveelheid etc.
Door de gegevens (entiteiten) allemaal een eigen tabel te geven, hoef je ze maar één keer in te voeren, wat uiteraard een boel werk scheelt.

Wat is nu het nadeel van jouw oplossing? Omdat je geen splitsing hebt gemaakt tussen Leverancier, Locatie en Product, moet je in de tabel Product bij elke nieuwe locatie of bij elke nieuwe leverancier een nieuw record aanmaken voor hetzelfde product. Hierbij krijgt elke regel een eigen ProductID, zodat je met een tabel komt te zitten, waarbij je voor één en hetzelfde product wel 5 of meer records kan hebben, elk met exact dezelfde gegevens (wat betreft de produkteigenschappen). Dus het produkt Zand kan 12 keer voorkomen in de tabel, met dus 12 keer een prijs, 12 keer een hoeveelheid, en ga zo maar door.
Hoe weet je nu straks hoeveel zand je hebt geleverd of verkocht? Daar kom je bijna niet meer uit. En wat doe je, als je de prijs van zand wilt aanpassen? Dan moet je in je tabel gaan zoeken naar alle records waar Zand in voorkomt, waarbij je dus geen enkele referentie hebt of je ook wel alles hebt teruggevonden.
Dit probleem kom je heel vaak tegen bij adresbestanden. Als een persoon in een adrestabel wordt toegevoegd, en er wordt niet gecontroleerd of die persoon er al in staat, dan zou je bij een slecht ontwikkelde database een persoon dubbel kunnen invoeren. Iemand kan dan bijvoorbeeld worden ingevoerd als "Bart van der Kamp", en een week later als "B. van der Kamp". Dit risico, waarbij je dus een dubbel record niet helemaal op dezelfde manier invoert, houdt later in, dat je de records bijna niet meer kunt terugvinden.

In mijn variant maak je voor elk product één record aan, voor elke leverancier één record, en voor elk locatie één record. Als er een wijziging moet worden gemaakt bij een artikel, leverancier of locatie, hoef je dat dus maar één keer te doen.

Dit proces heet overigens Normaliseren, en bestaat er dus uit, dat je alle tabellen zover opsplitst, dat er maar één uniek record per entiteit overblijft.
Vandaar ook de extra tabellen, want je wilt uiteraard wel kunnen vastleggen welke leverancier aan welk filiaal welke producten mag leveren. In jouw geval heeft me dat nog wel wat hoofdbrekens gekost, omdat je ook onderscheid wilt maken tussen producten per locatie, en leveranciers per locatie. Normaal zou ik zeggen, mag elke leverancier zijn complete productrange verkopen aan alle filialen, en dan hoef je daar dus geen aparte tabel voor te hebben.
Zoals je ziet, is die spitsing wel gelukt, en hij werkt ook prima op het formulier.

De aanpassing die Greenery voorstelde is overigens een vertaling van de Msgbox in de module, en die heeft verder geen invloed op de werking van je formulier. Er is dus niks elementairs aan veranderd.
Zoals je in mijn voorbeeld al hebt gezien, heb ik die procedure ook helemaal niet nodig, omdat alles op tabelniveau al is dichtgetikt.
Wel zou ik er nog vrij makkelijk een aanvulling bij kunnen maken, zoals: wat nu als ik een nieuwe combinatie wil maken van Locatie-Leverancier-Product?
Nu kijkt het formulier alleen naar reeds bestaande combinaties. Maar dat is dus aan te passen, zodat er, als je een niet-bestaande combinatie kiest, deze automatisch aan de juiste tabellen wordt toegevoegd....

Michel
 
Hey Michel,

Ik snap hem. Dat is idd precies wat ik wou. Dat is ook het probleem waar ik met mijn structuur tegenaan liep. Overigens zit de prijs van bijvoorbeeld Zand niet puur verbonden aan het product zand. Het is een combinatie van Locatie, Leverancier en Product maar dan koppel ik de prijs aan de juiste tabel.

Hardstikke bedankt voor het meedenken:thumb:
 
Dan heb je het inderdaad prima begrepen! De bedoeling is, dat je de gegevens op het laagste niveau a.h.w. opslaat, dus als de prijs van een artikel afhankelijk is van de leverancier, dan zet je het veld in de tabel product-leverancier. In jouw geval dus Locatie-Leverancier-Product.
Nog een voordeel van het splitsen: je voorraad beheer wordt een stuk makkelijker!

Veel succes ermee, en heb je nog vragen, je weet ondertussen de weg..

Michel
 
Status
Niet open voor verdere reacties.
Terug
Bovenaan Onderaan