Controle invoer + vervolgactie

Status
Niet open voor verdere reacties.

nwametze

Gebruiker
Lid geworden
18 dec 2009
Berichten
67
We zijn weer een stukje verder :)

Het volgende probleem (ik denk dat ik zelf te moeilijk denk).
Ik hou in een database onze nieuwe medewerkers en nieuwe functies bij.
Een nieuwe functie is eerder bekend dan een nieuwe medewerker.
Een functie is altijd voor een bepaalde periode.
Medewerkers kunnen meerdere functies draaien (niet tegelijk).

Nu heb ik een tabel werknemers (sleutel werknemerID), een tabel functies (sleutel arbeidsplaatsnummer) en een koppeltabel werknemers-functies met daarin ook de datum start/einde.

Ik probeer nu een logische manier van gegevensinvoer te vinden voor de collega's hier, maar wil voorkomen dat ik een bepaalde richting op denk en logische alternatieven over het hoofd zie, vandaar mijn vraag hier.

Hoe kan ik de gegevensinvoer logisch vormgeven?
Op het moment dat een nieuwe medewerker bij ons bekend wordt gesteld moet deze in de database opgenomen worden. Het kan echter zijn dat deze medewerker reeds eerder hier gewerkt heeft en dus nog in de database bekend is. Het zelfde geld voor een functie ook deze kan al bekend zijn bij ons.

Het lijkt mij het meest logisch om een invoerscherm te hebben met een veld voor het werknemerID welke na invoer gecheckt wordt. Is hij bekend dan door naar het volgende veld: arbeidsplaatsnummer welke wederom na invoer gecheckt wordt. Is ook deze bekend dan door naar de laatste 2 velden, start en einddatum.

Nu zit ik met het checken van de invoer en de actie op het moment dat de invoer niet bekend is (en er dus een invoerscherm nieuwe werknemer/nieuwe functie geopend moet worden). Na deze invoer moet er weer teruggekeerd worden naar het oorspronkelijke invoerscherm en verder gegaan worden.

Iemand enig idee hoe ik dit (en dan vooral de check + bijbehorende actie) kan vormgeven?

Hopelijk heb ik het een beetje duidelijk verwoord. Hoor graag van jullie.
 
Het principe is eigenlijk vrij simpel. Je zou formulieren moeten maken voor Werknemers (om medewerkers te raadplegen en toe te voegen), Functies (idem) en voor Werknemers_Functies maak je uiteraard ook een formulier. Daarop zet je dan twee keuzelijsten (met invoervak) die het WerknemerID uit Werknemers ophaalt, en FunctieID uit Functies. de Startdatum en Einddatum zijn uiteraard tekstvelden.
De werkwijze is nu:
1. zoek een werknemer op in de keuzelijst cboWerknemers. Bestaat de werknemer niet, open dan het formulier Werknemers met de gebeurtenis <Bij niet in lijst> (NotInList).
2. zoek een functie op in de keuzelijst cboFuncties. Bestaat de functie niet, voeg de functie dan toe aan de tabel Functies met de gebeurtenis <Bij niet in lijst> (NotInList).

De gebeurtenis <Bij niet in lijst> kun je gebruiken om de nieuwe waarde gelijk in de tabel op te slaan, zodat je de nieuwe werknemer/functie gelijk kunt gebruiken, of je opent het bijbehorende formulier, zodat je ook gelijk de rest van de gegevens kunt invoeren. Als de tabel meerdere gegevens nodig heeft (werknemers bijvoorbeeld) dan gebruik je de optie om een formulier te openen. Gaat het om een tabel met één veld (Functies) dan hoeft dat formulier niet, en kun je de nieuwe waarde gelijk toevoegen. Het hangt er dus een beetje vanaf welke optie je nodig hebt.
 
Bedankt voor je reactie.
Zat al aardig in dezelfde richting. Werknemer_functies formulier heeft inderdaad 2 keuzelijsten. Was er alleen niet uit hoe te handelen indien de waarde er niet in staat. Ik ga eens lezen wat de mogelijkheden zijn met het 'NotInList', bedankt voor de tip!
De te openen formulieren hebben meerdere velden (zowel werknemer als functie). Het invoerformulier zal dus geopend moeten worden zodat deze gegevens ingevoerd kunnen worden. Bij voorkeur met de eerder ingegeven (en niet gevonden) waarde reeds ingevuld in het nieuwe record.
 
Ik heb dit topic ook even doorgenomen, hoop interessante info, inclusief een stuk code wat bij de actie NotInList ingevoerd dient te worden.
Ik heb de code nu 1 op 1 overgenomen, helaas gebeurt er niks op het moment dat ik een werknemernummer invoer wat niet bestaat.
(had op z'n minst een foutmelding verwacht omdat hij een expressie probeert op te starten waar verkeerde waarden in staan omdat ik die nog niet helemaal aangepast heb).
Wanneer zou de actie NotInList getriggerd moeten worden? Is dat als je het veld verlaat, op tab/enter drukt of?
 
Om je een idee te geven:
Code:
Private Sub cboFunctie_NotInList(NewData As String, Response As Integer)
Dim Result
Dim Msg As String

    If NewData = "" Then Exit Sub

    Msg = "'" & NewData & "' staat niet in de lijst." & VbCrLf & VbCrLf
    Msg = Msg & "Wil je " & NewData & " toevoegen?"
    If MsgBox(Msg, vbQuestion + vbYesNo) = vbYes Then
        DoCmd.OpenForm "frmFuncties", , , , acAdd, acDialog, NewData
    End If
    Me.cboFunctie.Requery

    ' Zoek de nieuwe functieID op in de tabel tFuncties.
    Result = DLookup("[FunctieID]", "tFuncties", "[Functie]='" & NewData & "'")
    If IsNull(Result) Then
        ' Als de functie 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.cboFunctie = Result
    End If

End Sub
 
Mooie code, had hem ook gevonden. M'n bericht boven je reactie toevallig gezien? Denk dat we elkaar net gekruist hebben :)

[ps: kan ik ook iets aan jou of helpmij doneren ofzo? Heb al zo enorm veel aan de site (en aan jouw reacties) gehad dat ik dat wel op z'n plaats vind.]
 
Hoort nog een stukje code bij op het formulier frmFuncties, want NewData moet natuurlijk worden ingevuld op het formulier. Dat gaat zo:
Code:
Private Sub Form_Open(Cancel As Integer)
    If Not IsNull(Me.OpenArgs) Then Me.txtFunctie.Value = Me.OpenArgs
End Sub
 
Als ik nu een niet bestaand werknemerID invul en naar een ander veld ga kan ik gewoon doorgaan.
Pas als ik het record op wil slaan (door het formulier te sluiten of te bladeren in de records) krijg ik de melding:
De Microsoft Access-database-engine kan geen record vinden in te tabel Twerknemer waarvoor de sleutel overeenkomt met de volgende velden: WID.

Het formulier Fwerknemer wordt niet geopend, ik krijg ook geen andere foutmeldingen.
 
Ha, ben erachter: ik had de Eigenschap Alleen lijst op Nee staat.
Die net op Ja gezegd en ik krijg nu netjes de melding dat xxxxx niet in de lijst staat en of ik die toe wil voegen, we gaan weer verder :)
 
Na het klikken op 'Yes' (ik wil de waarde toevoegen), krijg ik een melding vanuit VBA:
Fout 2448 tijdens uitvoering: U kunt geen waarde aan dit object toekennen.
Middels foutopsporing komt het volgende eruit:

Code:
Private Sub Form_Open(Cancel As Integer)
    If Not IsNull(Me.OpenArgs) Then Me.WID.Value = Me.OpenArgs
End Sub

Het deel Me.WID,Value = Me.OpenArgs is hierbij geel gemaakt.
Kan je de code wellicht toelichten? Wellicht dat mijn aanname, het veranderen van Me.txtfunctie.Value naar Me.WID.Value, niet de juiste is geweest? Ik dacht dat hier werd aangegeven in welk veld de nieuwe waarde geplaatst moest worden?
 
Ik denk dat je de keuzelijst niet helemaal juist gebruikt. Doorgaans maak je een keuzelijst op basis van een tabel waaruit je de sleutel overneemt (ik gok WID) en laat je in die keuzelijst namen/tekstvelden zien. Het sleutelveld is daarbij verborgen in de keuzelijst. Dat doe je omdat je veel makkelijker op naam zoekt, dan op een nummer. Bovendien is de sortering van namen een stuk logischer dan op nummer. Dus wat je in de praktijk doet, is de naam van de werknemer opzoeken. En dat doe je door de beginletters in te vullen. Of de hele naam. En daar begint het feest: als de naam niet gevonden wordt in de lijst (dus niet bestaat) dan open je het werknemerformulier. En dan wil je natuurlijk dat de zojuist ingetypte (achter)naam) ook al in het nieuwe formulier wordt ingevuld. En dat doet de Form_Open code.
Wat jij doet, is niet de naam invullen/zoeken, maar het WID. En als dat een autonummer veld is (en dat vermoed ik) dan krijg je inderdaad dit probleem.

En wil je iets voor HelpMij betekenen: word dan lid, want daar zijn we altijd heel blij mee. Krijg je nog een paar voordeeltjes ook, en je bent van die reclamebanners af (vind ik zelf wel héél plezierig :) )
 
Laatst bewerkt:
Ik ga eens kijken naar het lidmaatschap.
(kan ik dat incasso-formulier ook naar iemand mailen? Per post versturen is zoooo 2001... ;))

Voor wat betreft je antwoord. De keuzelijst werknemer is gemaakt op basis van het veld WID uit de tabel Twerknemer. Zo ook de keuzelijst functie, die is gemaakt op basis van het veld arbeidsplaatsnummer uit de tabel Tfunctie. Beide velden (WID en arbeidsplaatsnummer) zijn primaire sleutels.

Beiden zijn geen autonummeringsveld aangezien het WID niet door ons wordt aangemaakt maar door HR, zelfde geld voor de arbeidsplaatsnummers.
 
Laatst bewerkt:
Mailen? Wat is dat??
Je geeft nog niet aan hoe je zoekt in de keuzelijst. En dat is in dit geval essentieel.
 
Weet niet zeker of ik je vraag nu goed begrijp.
Als voorbeeld de keuzelijst werknemer.
Deze keuzelijst heeft als bron het veld WID uit de tabel Twerknemer.
We werken hier ook alleen met WID's (ter controle wordt na de keuze van een WID wel het veld achternaam weergegeven zodat je weet of je de juiste persoon hebt). Men vult dus in de keuzelijst het WID in en gebruikt dan tab om naar het veld voor het arbeidsplaatsnummer te gaan.
Andere mogelijkheid is om de keuzelijst uit te klappen en het juiste WID te kiezen (al zal deze optie minder snel gebruikt worden om dat er bij de start van de database al 400+ werknemers erin staan en dit jaarlijks met ongeveer 150 oploopt).

Nu de code uit Fiup gewist met het idee om niet gebruik te maken van het meegeven van het gevraagde WID en zo te kijken of dit wel werkt. Het Fiup wordt netjes geopend op een nieuw, leeg record. Ik vul vervolgens het gevraagde WID in + wat andere testgegevens. Vervolgens sla ik het record op en sluit ik het formulier. Dan krijg ik direct weer een foutmelding:
Fout 2118 tijdens uitvoering: De actie QueryOpnieuwUitvoeren kan pas worden uitgevoerd nadat u het huidige veld hebt opgeslagen.
Ik dacht dat dit terugsloeg op het opslaan van het nieuwe WID record, maar die staat gewoon in de tabel. Het lijkt, volgens de foutopsporing, mis te gaan bij Me.functieID.requery (functieID is de naam van de keuzelijst, dus dat klopt). Snap alleen niet waarom de requery niet lukt?
 
Laatst bewerkt:
Deze keuzelijst heeft als bron het veld WID uit de tabel Twerknemer.
We werken hier ook alleen met WID's (ter controle wordt na de keuze van een WID wel het veld achternaam weergegeven zodat je weet of je de juiste persoon hebt). Men vult dus in de keuzelijst het WID in en gebruikt dan tab om naar het veld voor het arbeidsplaatsnummer te gaan.
Ik vind dit geen handig gebruik van een keuzelijst; meestal zet je in de Recordbron zowel WID als Achternaam en Voornaam. Je verbergt daarbij het WID veld, want wie weet er 500 nummers uit zijn hoofd? En je zoekt dus op de naam. Die zie je namelijk terug in de keuzelijst. Als je bij een bedrijf werkt waar mensen nummers zijn, en namen verboden, dan moet je het natuurlijk op jouw manier doen! ('Heb je het gehoord van 234-12? Heeft een verhouding met 432-64!')
 
Hoe raar het ook klinkt, we werken met nummers juist om fouten te voorkomen. M'n werkgever heeft 50000+ mensen in dienst waaronder dus 100x Jansen enz.
Dus ja, we werken in principe op basis van het werknemerID maar dan met de voorletters en achternaam welke weergegeven worden na invoer. Ook bij contacten met collega's is het werknemerID zo ongeveer het eerste wat gevraagd wordt zodat we de juiste gegevens voor ons hebben.

Heb je een idee wat er in het 2e deel van m'n vorige post verkeerd gaat?
Als ik alleen de requery goed werkend krijg kunnen we aan de gang met de database. Het niet meekomen van het ingevoerde nummer naar het formulier waarin de nieuwe werknemer aangemaakt word is dan even jammer/irritant maar daar kan ik komende week dan nog wel een duik in nemen.
 
Laatst bewerkt:
Hoe raar het ook klinkt, we werken met nummers juist om fouten te voorkomen. M'n werkgever heeft 50000+ mensen in dienst waaronder dus 100x Jansen enz.
Dan ga je binnenkort sowieso de teil in met je keuzelijst, want die kan zo ongeveer 55000 items bevatten en dan stopt-ie er mee. Ik zou in ieder geval extra werknemer informatie in de keuzelijst opnemen, want bij het kiezen van een persoon kun je op basis daarvan de overige tekstvelden met personeelsgegevens vullen. Maar voor je keuzelijst (nog afgezien van de vraag of een keuzelijst met 50000 opties wel werkbaar is) moet je toch een andere oplossing vinden, bijvoorbeeld een prefilter. Of vergeten.
 
Laatst bewerkt:
Ho, kleine nuance. Wij zullen nooit alle medewerkers in de keuzelijst krijgen. Maxima schommelt rond de 1000. Ik weet dat het vrij simpel is om in de keuzelijst direct de andere kolommen ook te laten zien, dus dat komt goed.
Mocht je een idee hebben wat er fout gaat met de Requery dan hoor ik het graag, dat is (voor nu) even het enige wat in de weg staat.
 
Geen idee wat er fout gaat; ik gebruik de techniek regelmatig en zonder problemen. Dus dan zou ik de db zelf moeten zien.
 
Status
Niet open voor verdere reacties.
Terug
Bovenaan Onderaan