Hulp gevraagd met Acces database

Status
Niet open voor verdere reacties.

HJD1986

Gebruiker
Lid geworden
28 mrt 2017
Berichten
61
Best forumleden,

Ik ben recent gestart met een eigen bedrijf en heb een simpele Access database gemaakt om offertes in te verwerken.
Het is allemaal erg basic, maar voor nu voldoende.

Ik loop echter tegen het volgende probleem aan:

Bij het invoeren van items in het offerte formulier worden de items die ik bij een nieuwe offerte invoer in het rapport "Offerte inhoud" weergegeven bij de 1e offerte. Dit is uiteraard niet de bedoeling.
Ik vermoed dat het met relaties te maken heeft. Heb al avonden zitten puzzelen maar kom er echt niet uit.

Hopelijk weet een van jullie raad?

De database heb ik als bijlage toegevoegd.

Alvast bedankt.
 

Bijlagen

  • Offerte.zip
    172,5 KB · Weergaven: 31
Welkom bij HelpMij! Je hebt inderdaad een paar ontwerpfouten in deze db zitten, die je eerst moet oplossen. Sowieso zou ik pas aan formulieren gaan beginnen als de structuur van je db in orde is, en alles werkt zoals het zou moeten werken. Anders blijf je dubbel werk doen, want formulieren nemen altijd de eigenschappen van de tabellen over als je ze maakt, en als je dus later wat in de tabellen verandert, moet je dat ook nog eens in de formulieren doen: dubbel werk dus. Typische beginnersfout trouwens, want een beginner denkt teveel vanuit het eindresultaatf ('als ik maar een formulier heb, dan kan ik werken") en te weinig vanuit de basis. En dat moet toch echt als je een database gaat maken. Zie het als het bouwen van een huis: dan begin je ook met het fundament, en nooit met de kleur van het behang :).

Wat mankeert er aan je structuur? Om te beginnen: in de tabellen [Klantgegevens] en [Offerte] heb je een sleutelveld gemaakt van het type Autonummering. Dat kan, al is dat in beide gevallen niet erg handig, want een Autonummerveld is niet erg beschrijvend. Meestal wil je Offertenummers opeenvolgend genummerd hebben, en dat kan niet met een autonummerveld. D.w.z. hij nummert wel oplopend door, maar als je een record aanmaakt en verwijdert, ben je dat nummer kwijt en zit er dus een gat in je nummering. Bij Facturen is dat sowieso niet toegestaan. En Klantnummers wil je misschien op een specifieke manier opgemaakt hebben, en ook dat is lastig met een autonummer.

Veel erger is, dat je in je relaties deze twee ID velden (ik zou ze ook absoluut nooit dezelfde naam geven, want hoe hou je ze uit elkaar straks?) aan elkaar hebt gekoppeld. Daarbij ook nog eens op een manier die volkomen waardeloos (als in: zonder enige waarde) is. Je had net zo goed het veld [Postcode] kunnen koppelen aan het veld [Currency]. Had hetzelfde nut en effect gehad. Net zo erg als dit probleem, is dat je in de tabel [Offerte] de klantgegevens] hebt opgenomen. Dat is echt een absoluut taboe in databaseland, want daarmee ondermijn je dus zo'n beetje alle normalisatieregels. Onthoud: gegevens die bij elkaar horen, zet je in hun eigen tabel. En persoonsgegevens horen dus in de Klantentabel. Uiteraard wil je bij een offerte wel vastleggen voor welke klant die is geweest, en daarom neem je in de tabel [Offerte] dus wél een verwijsveld op naar de tabel klanten. Dat is dan per definitie het sleutelveld uit [Klantgegevens] (nu het veld [ID]) want in een offerte moet je altijd verwijzen naar één klant. Je maakt dan dus een één-op-veel relatie tussen Klantgegevens en Orders: één klant kan meerdere orders hebben en elke order is gekoppeld aan één klant.
Die correcte relatie krijg je door de optie <Referentiële integriteit afdwingen> aan te zetten. In jouw geval kan dat dus niet, omdat je a) twee sleutelvelden koppelt (kun je hooguit een één-op-één relatie maken) en b) de ID's verschillende waarden vertegenwoordigen, resp. een Klantnummer en een Offertenummer.

Iets vergelijkbaars doe je tussen [Offerte] en [Offerte-inhoud]; het offertenummer komt niet terug in de tabel [Offerte-inhoud]. Daarnaast zitten daarin ook nog eens velden die je kunt uitrekenen, en berekeningen horen óók niet thuis in een tabel.

Kortom: je hebt nog wat huiswerk te doen :). Ik zou zeggen: lees de Access cursus er eens op door, de eerste hoofdstukken gaan over normaliseren, en volgens mij heb je daar nu nog wat te weinig kennis van. Het lijkt mij een goede zaak als je die eerst opdoet voordat je verder gaat.
 
Hallo Octafish,

Bedankt voor je reactie. Misschien vreemd maar ineens begrijp ik hoe relaties werken. Ik had er al het een en ander over gelezen maar was denk ik teveel gefocust op de oplossing.
Ik heb net de basis in lijn gebracht met jouw opmerkingen en de normen in databaseland (zie bijlage).

Je zegt dat berekeningen niet thuis horen in een tabel. Moet ik daar een Query voor gebruiken?

Nu is de volgende uitdaging om automatisch offertenummers te generen, startend bij nummer 5000. Ik heb op het forum iets gelezen over het genereren van factuurnummers m.b.v. VB code.
Ik heb echter geen idee waar te beginnen. Kun je me op weg helpen?

Alvast bedankt.
 

Bijlagen

  • Offerte.zip
    25,6 KB · Weergaven: 26
Je zegt dat berekeningen niet thuis horen in een tabel. Moet ik daar een Query voor gebruiken?
Helemaal correct :thumb:
Voor het maken van een volgnummer gebruik ik een functie, die je makkelijk kunt aanpassen. Met 5000 beginnen lijkt mij vreemd; ik zou eerder kiezen voor een combinatie van jaar+volgnummer. Daar is bijgaande functie ook op gebaseerd: een jaartal + koppelteken + getal van 4 cijfers.

Code:
Function Factuurnummer() As String
Dim strVolgNummer As String, strNieuwVolgNummer As String, strSQL As String
Dim tmpNummer, bJaar As Boolean
    
    '------------------------------------------------------------------------------------------------
    ' Huidige volgnummer uit tabel lezen die als parameter is meegegeven.
    '------------------------------------------------------------------------------------------------
    strSQL = "SELECT TOP 1 [Factuurnummer] FROM [dt_Rekeningen] ORDER BY [Factuurnummer] DESC"
    With CurrentDb.OpenRecordset(strSQL)
        If .RecordCount > 0 Then
            strVolgNummer = Nz(.Fields(0).Value, 0)
        Else
            Factuurnummer = Year(Date) & "-0001"
            Exit Function
        End If
    End With

    '------------------------------------------------------------------------------------------------
    ' Laatste nummer opsplitsen en met 1 verhogen.
    '------------------------------------------------------------------------------------------------
    tmpNummer = Split(strVolgNummer, "-")
    If CInt(tmpNummer(0)) = Year(Date) Then
        strNieuwVolgNummer = tmpNummer(0) & "-" & Right("0000" & CInt(tmpNummer(1)) + 1, 4)
    Else
        strNieuwVolgNummer = tmpNummer(0) & "-0001"
    End If

    '------------------------------------------------------------------------------------------------
    ' Nieuw nummer toekennen aan de functie.
    '------------------------------------------------------------------------------------------------
    Factuurnummer = strNieuwVolgNummer

End Function

Deze functie gebruikt een vast veld en een vaste tabel, dus dat is makkelijk aan te passen. In je formulier straks zet je de functie bij de Standaardwaarde van het volgnummer als volgt:
Code:
=Factuurnummer()
Uiteraard mag je de namen aanpassen, het soort opmaak etc. Wat je maar wilt :)
 
Relatie tussen contactpersoon en klant/offerte

Hallo Octafish,

Ik dacht dat ik het leggen van relaties nu onder de knie zou hebben, maar krijg het volgende echt niet voor elkaar.

Ik heb een tabel klanten, een aparte tabel contactpersonen. Deze zijn aan elkaar gerelateerd d.m.v. een 1 op veel relatie tussen klanten en contactpersonen.
Nu selecteer ik in de offerte eerst de klant en wil vervolgens de contactpersoon bij die klant selecteren. Echter hij laat dan alle contactpersonen zien i.p.v. alleen degene die aan de betreffende klant gekoppeld zijn.

Vanuit de tabel klanten laat deze wel op de juiste manier alleen de contactpersonen zien die ook bij die klant behoren.
Wat doe ik fout?
 

Bijlagen

  • Offerte.zip
    183,1 KB · Weergaven: 19
Je formulier <Offertes> is niet aan de tabel Offertes gekoppeld, dus dat heb ik als eerste maar even gedaan. En verder zag ik geen keuzelijst Contactpersonen, dus die heb ik er ook bijgezet. Volgens mij heb je nu de situatie die je zoekt.
 

Bijlagen

  • Offerte.zip
    121,8 KB · Weergaven: 18
Beste Octafish,

Wederom bedankt.
Het gaat nog niet helemaal goed. Soms zijn de namen in het formulier ineens verdwenen.
Waar slaat het formulier "offerte" de waarde "contactpersoon" voor de offerte in op?
 

Bijlagen

  • Offerte TEST.zip
    123,4 KB · Weergaven: 28
Het formulier Offerte is gekoppeld aan detabel Offerte. Dus alles wat je opslaat, vind je terug in de onderliggende tabel. Dat je soms een lege keuzelijst ziet, is logisch. De keuzelijst Contactpersoon is gekoppeld aan een KlantID. Je ziet dus alleen de CP's (en dus ook de gekozen) als het KlantID hetzelfde is. En dat is niet altijd zo als je bladert. Als het eerste record is gelinked aan Klant 1, en je bladert naar Klant 2, dan staat de bron van de keuzelijst nog op Klant 1. En daarom zie je dus niks in de keuzelijst.

Dat wil niet zeggen dat je record niet meer klopt, want als je in de tabel zou kijken, zie je gewoon het juiste KlantID staan.
Je moet de keuzelijst dus elke keer verversen als je naar een ander record bladert om de juiste (gekozen) CP te zien.
 
Beste Octafish,

De contactpersonen zijn duidelijk, dankje!

Het laatste probleem waar ik tegen aan loop is het rapport.
Ik heb afgelopen weekend van alles geprobeerd om dit werkend te krijgen, maar zonder resultaat.
Heb ook geen idee wat ik verkeerd doe. In mijn beleving zijn alle relaties in orde.

De bedoeling is dat ik van iedere offerte eenvoudig een rapport kan draaien met daarin de klantgegevens + de offerte inhoud.
Wat ik ook probeer het lukt niet.

Ook met de cursus erbij kom ik er niet uit.

Zou je nog een keer kunnen kijken?

Alvast bedankt voor de moeite.

Hartelijke groet,
 

Bijlagen

  • Offerte TEST.zip
    218,4 KB · Weergaven: 39
Status
Niet open voor verdere reacties.
Steun Ons

Nieuwste berichten

Terug
Bovenaan Onderaan