refresh van formulier na invoeren nieuwe records in tabel

Status
Niet open voor verdere reacties.

jobwol

Gebruiker
Lid geworden
11 aug 2009
Berichten
24
Na een hele tijd lopen zoeken, be ik er toch nog niet uitgekomen.
Ik heb een formulier (Invoer) waar rekeningmutaties in staan. Deze rekeningmutaties moeten gekoppeld worden aan een klant (het veld "Inzake klant"). Als die klant er niet instaat, moet deze in de tabel "Klantenlijst" worden toegevoegd.
In de Klantenlijst heb ik een knop gezet dat je de lijst kunt afsluiten en terug kunt keren naar het formulier Invoer.
Het formulier Invoer bevat echter niet de nieuw toegevoegde klant. Ik weet dat ik het commando refresh moet gebruiken, maar krijg het niet goed voor elkaar om het te automatiseren

Ik wil:
- Na het drukken op de afsluitknop in Klantenlijst dat access een requery uitvoert in Klantenlijst én dat hij meteen het formulier Invoer refreshed.
- Vervolgens wil ik dat in de keuzelijst van het formulier Invoer -> veld "Inzake klant" de klanten op alfabetische volgorde worden weergegeven. Om een of andere reden houdt het formulier Invoer geen rekening met de sortering van het formulier Klantenlijst.
De code tot nu toe:
[SQL]
Private Sub Knop4_Click()
On Error GoTo Err_Knop4_Click
Me.Requery

DoCmd.Close

Exit_Knop4_Click:
Exit Sub

Err_Knop4_Click:
MsgBox Err.Description
Resume Exit_Knop4_Click

End Sub[/SQL]
 
Gebruik je een keuzelijst voor de klanten? In dat geval zou ik de gebeurtenis <Bij niet in lijst> gebruiken om het formulier te openen en de klant toe te voegen. Scheelt een knop, en de lijst is veel beter te verversen. Dat gebeurt namelijk in het proces. Hierbij maak je gebruik van de parameter OpenArgs. Een aangepast voorbeeldje dat ik zelf gebruik:

Code:
Private Sub cboArtikel_NotInList(NewData As String, Response As Integer)
Dim Result
Dim Msg As String, CR As String

    CR = Chr$(13)
    If NewData = "" Then Exit Sub
    Msg = "'" & NewData & "' staat niet in de lijst." & CR & CR
    Msg = Msg & "Wil je " & NewData & " toevoegen?"
    If MsgBox(Msg, vbQuestion + vbYesNo) = vbYes Then
        iBedrijf = Me.Parent.cboBedrijf.Column(0)
        DoCmd.OpenForm "fArtikelen", , , , acAdd, acDialog, NewData & "|" & iBedrijf
    End If
    ' Zoek het nieuwe artikelID op in de tabel Artikelen.
    Result = DLookup("[ArtikelID]", "tArtikelen", "[Artikel]='" & NewData & "'")
    If IsNull(Result) Then
        ' Als het artikel niet is gemaakt, Response argument op Error message zetten en herstellen.
        Response = acDataErrContinue
        MsgBox "Nog een keer proberen...", vbOKOnly
    Else
        ' Als het artikel is gemaakt, het Response argument Added zetten.
        Response = acDataErrAdded
        Me.cboArtikel.SetFocus
        Me.cboArtikel = Result
    End If
End Sub

Hiermee wordt het formulier fArtikelen geopend bij een niet-bestaande artikelomschrijving. Uit het hoofdformulier wordt de BedrijfID ook meegenomen, zodat het artikel gelijk aan een leverancier wordt gekoppeld. Het artikelen formulier wordt als acDialog geopend, zodat de procedure pas verder kan als het tweede formulier is gesloten.

Op het formulier fArtikel wordt de OpenArgs variabele vervolgens gesplitst, en worden de variabelen ingevuld.
Code:
Private Sub Form_Open(Cancel As Integer)
    If Not IsNull(Me.OpenArgs) Then
        Dim sArgs() As String
        sArgs = Split(Me.OpenArgs, "|")
        Me.txtArtikel.Value = sArgs(0)
        Me.cboBedrijfID.Value = sArgs(1)
        Me.txtArtikelID.SetFocus
    End If
End Sub
Zoals gezegd: als het tweede formulier wordt gesloten, gaat de procedure verder met de regel Result = DLookup("[ArtikelID]", "tArtikelen", "[Artikel]='" & NewData & "'"). De rest van de procedure vult dan de waarde in op de keuzelijst.
 
Ik geloof echter dat het me een beetje te ingewikkeld wordt op deze manier. Ik ben niet echt thuis in de programmeercodes en had gehoopt dat ik het met wat boerenverstand op kon lossen. In ieder geval bedankt voor je snelle reactie!
 
Ik heb nog even naar je expressie zitten kijken. Ik vermoed dat ik het beter ga begrijpen als die automatische koppeling met BedrijfsID heb. Hoe zal de code er uitzien als je:
- Bij invullen van niet bestaande klant (<bij niet in lijst>) een schermpje laat openen om naar het formulier Klantenlijst te gaan.
- Dat je daar vervolgens de waarde laat toevoegen die je hebt ingevoerd in het formulier Invoer en eventueel handmatig aanpast
- Je weer terugkeert naar het formulier Invoer en dat de tabel daar ververst wordt.

Ik vind het overigens ook geen probleem als er vaker op knopjes gedrukt moet worden. De database wordt niet zo veel gebruikt dat hij super gebruiksvriendelijk moet zijn. Het zou voor mij dus ook een prima oplossing zijn als ik weet hoe ik de refresh-optie toevoeg ik de code die ik toevoegde in mijn eerste post.
 
En die is een stuk lastiger :)
Mijn voorbeeldje is een klein beetje ingewikkelder dan strict noodzakelijk; je kunt namelijk ook prima overweg met één nieuwe waarde (klantnaam). Dat maakt het verhaal gelijk een heel stuk simpeler. Ik zal het voorbeeldje 'vertalen' naar een nieuwe klant, dan is het denk ik wat duidelijker.
De keuzelijst wordt dan bijvoorbeeld:
Code:
Private Sub cboKlant_NotInList(NewData As String, Response As Integer)
Dim Result
Dim Msg As String, CR As String

    CR = Chr$(13)
    If NewData = "" Then Exit Sub
    Msg = "'" & NewData & "' staat niet in de lijst." & CR & CR
    Msg = Msg & "Wil je " & NewData & " toevoegen?"
    If MsgBox(Msg, vbQuestion + vbYesNo) = vbYes Then
        DoCmd.OpenForm "fKlanten", , , , acAdd, acDialog, NewData
    End If
    ' Zoek de nieuwe klant op in de tabel tKlanten.
    Result = DLookup("[Unieke Code]", "tKlanten", "[Achternaam]='" & NewData & "'")
    If IsNull(Result) Then
        ' Als de klant niet is gemaakt, Response argument op Error message zetten en herstellen.
        Response = acDataErrContinue
        MsgBox "Nog een keer proberen...", vbOKOnly
    Else
        ' Als de klant is gemaakt, het Response argument Added zetten.
        Response = acDataErrAdded
        Me.cboKlant = Result
    End If
End Sub
En op het formulier fKlanten krijg je deze code:
Code:
Private Sub Form_Load()
    If Not Nz(Me.OpenArgs, "") = "" Then
        Me.txtNaam.Value = Me.OpenArgs
    End If
End Sub
Oogt al een stuk simpeler, niet? :)
 
Dat ziet er inderdaad een stuk simpeler en goed te volgen uit voor mij als beginner :-)
Hij werkt bijna, maar een fout krijg ik er niet uit:
- Het lukt me om bij een nog onbekende klant het formulier Klantenlijst te openen
- In dit formulier wordt nu de naam van de klant automatisch ingevuld.

Na het afsluiten van het formulier Klantenlijst krijg ik echter een foutmelding. De code zoals die nu is:
Code:
Private Sub Inzake_klant_NotInList(NewData As String, Response As Integer)
Dim Result
Dim Msg As String, CR As String

    CR = Chr$(13)
    If NewData = "" Then Exit Sub
    Msg = "'" & NewData & "' staat niet in de lijst." & CR & CR
    Msg = Msg & "Wil je " & NewData & " toevoegen?"
    If MsgBox(Msg, vbQuestion + vbYesNo) = vbYes Then
        DoCmd.OpenForm "Klantenlijst", , , , acAdd, acDialog, NewData
    End If
    ' Zoek de nieuwe klant op in de tabel tKlanten.
    Result = DLookup("[Id]", "Klantenlijst", "[Naam_klant]='" & NewData & "'")
    If IsNull(Result) Then
        ' Als de klant niet is gemaakt, Response argument op Error message zetten en herstellen.
        Response = acDataErrContinue
        MsgBox "Nog een keer proberen...", vbOKOnly
    Else
        ' Als de klant is gemaakt, het Response argument Added zetten.
        Response = acDataErrAdded
        Me.Inzake_klant = Result
    End If
End Sub
De fout zit 'm in het stukje:
Result = DLookup("[Id]", "Klantenlijst", "[Naam_klant]='" & NewData & "'")
Ik verwijs naar het veld [Id] in de klantenlijst, maar hij blijft fouten geven. Kun je me verder op weg helpen?
 
Misschien is je keuzelijst niet gekoppeld aan het veld ID. Elke keuzelijst heeft een kolom die wordt opgeslagen in de tabel. Dit veld moet je ophalen met de DLookup.
 
Ik loop er een beetje op vast. Ik heb alle velden van het formulier Klantenlijst inmiddels geprobeerd te koppelen, maar steeds krijg ik een foutbericht en verwijst hij naar een fout in DLookUp. Als ik in de database op relaties klik krijg ik het volgende:
relaties.JPG

Volgens mij zou hij dan toch goed gekoppeld moeten zijn als ik Result = DLookup("[Naam_klant]", "Klantenlijst", "[Inzake_klant]='" & NewData & "'") gebruik?
 
Laatst bewerkt:
Ik zie het plaatje niet; post de Rijbron eens van je keuzelijst; daar kan ik vermoedelijk al genoeg aan zien.
 
Ik weet niet precies wat je hebben wilt. Ik kan de namen doorgeven die ik tegen kom als ik op het veld inzake_klant klik en dan op Rijbron. Inmiddels heb ik het plaatje van de relaties gefixt, dus wellicht is dat voldoende?
 
Dat is inderdaad niet voldoende, al begin ik een klein vermoeden te krijgen :)
Eerste opmerking: de koppelingen zijn onbruikbaar; je hebt de optie <Referentiële integriteit afdwingen> niet aangezet, en die optie is noodzakelijk voor het maken van relaties tussen tabellen. Tweede punt: je gebruikt de verkeerde tabellen in de tabel [Algemeen], wat er tevens verantwoordelijk voor is dat je de relaties niet goed kunt maken. In de tabel Algemeen moet je namelijk de sleutelvelden opslaan uit de brontabellen, niet de tekstvelden die je nu hebt. Dus niet het veld [Inzake klant] koppelen aan [Naam klant], maar daar het veld [ID] voor gebruiken want dat is het sleutelveld. En het veld [Kostenplaats] in de tabel Algemeen koppelen aan het veld [ID] uit de tabel Kostenplaats i.p.v. het veld [Kostenplaats]. Dat het dan veel logischer is om de veldnamen KlantID en KostenplaatsID te gebruiken spreekt dan voor zich...
Dat betekent overigens ook dat je de veldeigenschappen moet aanpassen, want die zullen nu op Tekst staan.

Om op de keuzelijst terug te komen: grote kans dat je in de Rijbron van die keuzelijst de velden ID en [Naam klant] hebt staan, en dat Access probeert het veld ID op te slaan. Terwijl jij het veld [Naam klant] aanbiedt. Dus daar zou het probleem kunnen liggen. Maar repareer eerst de koppelingen tussen de tabellen, want daar gaat het zowiezo fout.
 
ik geloof dat ik hem inmiddels een beetje doorkrijg. Ik heb:
- In tabel Algemeen het veld Inzake Klant aangepast naar nummeriek (met lange integer)
- Vervolgens in Relaties het veld Inzake klant gekoppeld aan Id van de tabel Klantenlijst (met Referentiële integriteit afdwingen)
- in de VBA code een verwijzing gemaakt naar Id van de Klantenlijst
- De code werkt nu prima, maar... de keuzelijst in het formulier Invoer (het veld Inzake klant) wordt niet ververst na het sluiten van het formulier Klantenlijst. Hierdoor krijg ik de foutmelding: "Nog een keer proberen" en blijft hij dus in een loop zitten.

Ik heb maar even een kopie van mijn DB toegevoegd. http://www.jobwol.dds.nl/helpmij/FB_DB.zip
 
Ik denk dat je straks in een stil hoekje even een kwartiertje gaat zitten huilen, want je maakt een simpele fout: je haalt het verkeerde veld op in de DLookup. Je haalt de veldnaam op uit de tabel Algemeen, i.p.v. de tabel Klantenlijst!
Code:
    Result = DLookup("[Id]", "Klantenlijst", "[Naam klant]='" & NewData & "'")
 
Dank je wel voor zover. Maandag ga ik er weer mee verder. Ik zal weten of ik het allemaal voor elkaar heb gekregen.
 
Zou je eventueel een voorbeeld willen plaatsen in de bijlage ik ben er ook wel benieuwd naar hoe dit in elkaar steekt?
 
Traantjes zijn opgedroogd :-) Hartelijk dank voor je snelle reacties.
 
Ik ben inmiddels een stuk verder gekomen met de database. Ik zit echter nog met een klein probleempje.
Als ik een klantennaam invoer in het "invoerscherm" die nog niet in de klantenlijst voorkomt, dan wordt netjes het formulier klantenlijst geopend. De klant wordt ingevuld en ik heb de mogelijkheid om nog wat andere gegevens aan te vullen die bij de klant horen.

Filter actieve en niet-actieve klanten
Om te voorkomen dat in de loop der jaren de klantenlijst te lang wordt, heb ik de mogelijkheid gemaakt om klanten d.m.v. een vinkje af te sluiten. Als je dan het formulier klantenlijst opent, zie je alleen de actieve klanten.
Nu ontstaat het volgende probleem. Om het filter (actief-nietactief) te activeren heb ik de volgende VBA code meegegeven aan het formulier Klantenlijst:
Code:
Private Sub Form_Open(Cancel As Integer)
    Call sbFilteren
End Sub
Hiermee werkt het filter prima als ik de klantenlijst open.

Probleem
als ik nieuwe een klant in het formulier 'invoer' inbreng, dan opent het formulier klantenlijst, maar wordt de nieuwe klant ergens in de lijst ingevoerd. In plaats van dat ik in deze invoermodus alleen de klant zie die ik invoer, zie ik alle actieve klanten. Dit is onhandig, aangezien ik de gegevens van de nieuwe klant nog wil bewerken (ik wil er bijvoorbeeld een medewerker aan koppelen). Als ik bovenstaande VBA code bij openen formulier verwijder, dan werkt het weer wel goed (en krijg ik de klantenlijst in een soort invoermodus). Hoe kan ik er nu voor zorgen dat het filter wel werkt als ik gewoon de klantenlijst open, maar niet actief is als de klantenlijst opent vanwege het toevoegen van een nieuwe klant?
 
Als je het klantenformulier opent met de parameter AddNew, dan kom je altijd in een nieuw record terecht, en hoef je dus ook niet te filteren.
 
Status
Niet open voor verdere reacties.

Nieuwste berichten

Terug
Bovenaan Onderaan