Voordat record opgeslagen word nog iets checken?

Status
Niet open voor verdere reacties.

roomsousje

Gebruiker
Lid geworden
21 okt 2009
Berichten
7
Hoi,

Ik ben bezig met een database voor mijn werk. Nu ben ik hier een planningsuitbreiding voor aan het maken.
Ik heb een tabel waar binnenkomende vrachten in staan met bedrijfsnaam, datum binnenkomst en aantal. Ook heb ik een tabel waarin de dagen staan dat werknemers vrij zijn.

Mijn probleem is het volgende:
Ik heb een formulier gemaakt waar een werknemer een binnen komende vracht kan invoeren en opslaan. Nu wil ik eigenlijk dat er als de knop "opslaan" gedrukt wordt, eerst gecheckt wordt of er op de ingevulde datum toevallig al een werknemer een vrije dag heeft.

Is dit mogelijk, en zo ja hoe?

Alvast bedankt!

Grtz Wester
 
Wat wil je precies bereiken met die informatie? Ik kan me voorstellen dat je een probleem hebt als er niemand is om te ontladen, omdat iedereen vrij is...

Je hebt nodig: een query die je voor de tabel met vrije dagen een telling geeft van het aantal mensen dat op een bepaalde datum vrij heeft.
Als het gaat om enkele dagen, dan is dat niet zo'n probleem, maar als het om een reeks gaat, met een begin- en einddatum, dan wordt het al een stuk lastiger, want dan moet je dus controleren of een leverdatum binnen die datumreeks valt. Maar goed, laten we maar even aannemen dat het om enkele dagen gaat.
Dan heb je dus een query gemaakt met het veld Datum, en (bijvoorbeeld) het veld ID, waarbij je groepeert op Datum, en de functie Aantal gebruikt voor het tweede veld. Deze query levert alle datums op waarop iemand afwezig is.

Op het formulier moet je achter de knop Opslaan nu een Recordset aanroepen met VBA. De recordset opent de zojuist gemaakte query, met het veld LeverDatum uit het formulier als filter.

Code:
Dim db As DAO.Database, rs As DAO.Recordset, strSQL As String
Dim dLever As Date
Dim iLever As Double

Set db = CurrentDb()

dLever = cDate(Me.txtLeverdatum.Value)
iLever = CDbl(dLever)

strSQL = "Select * FROM VakantieDagen " & vbCrLf
strSQL = strSQL & "WHERE VakantieDatum = CDate(" & iLever & ") "
Set rs = db.OpenRecordset(strSQL)
If rs.RecordCount = 0 Then
	'Doe hier wat je wilt doen als er geen vrij is gepland
Else
	'Doe hier wat je wilt doen als er wel vrij is gepland
End If
rs.Close
db.Close
set rs=Nothing
set db=Nothing

Deze code zet je op de plek waar je de actie wilt evalueren. Je hebt dus twee opties die je kunt laten uitvoeren, afhankelijk van of er records gevonden worden of niet. Wel nog even de veldnamen aanpassen...
 
Dank je wel voor de moeite OctaFish :thumb:

De code werkt perfect!

Laat een waarschuwing zien als er op de ingevoerde datum iemand vrij is en als er niemand vrij is dan wordt de record opgeslagen.

De code ziet er nu zo uit:

Code:
Private Sub opslaBtn_Click()

Dim db As DAO.Database, rs As DAO.Recordset, strSQL As String
Dim dLever As Date
Dim iLever As Double

Set db = CurrentDb()

dLever = CDate(Me.Leverdatum.Value)
iLever = CDbl(dLever)

strSQL = "Select * FROM Werknemervrij " & vbCrLf
strSQL = strSQL & "WHERE Werknemervrij.Vrij = CDate(" & iLever & ") "
Set rs = db.OpenRecordset(strSQL)
If rs.RecordCount = 0 Then

DoCmd.RunCommand acCmdSaveRecord

Else

DoCmd.OpenForm "Iemand vrij"
   
End If
rs.Close
db.Close
Set rs = Nothing
Set db = Nothing

End Sub
 
Mooi dat het werkt! Ik zou je nog een kleine wijziging willen voorstellen, omdat je een formulier opent bij één van de acties. Om te voorkomen dat de recordset open blijft staan als dat verkeerd wordt afgesloten, kun je het beste na het tellen van het aantal records, de recordset afsluiten. Omdat je dan niet meer kunt checken op basis van de recordset, heb je een extra variabele nodig.
Ziet er dan zo uit:

Code:
Dim db As DAO.Database, rs As DAO.Recordset, strSQL As String
Dim dLever As Date
Dim iLever As Double, iRec as integer

	Set db = CurrentDb()
	'Maak van de datum eerst een getal, zodat de SQL de datum goed vertaalt ivm. Amerikaanse datumnotatie
	dLever = CDate(Me.Leverdatum.Value)
	iLever = CDbl(dLever)
	'Maak de SQL waarmee je de records ophaalt die voldoen aan het criterium
	strSQL = "Select * FROM Werknemervrij " & vbCrLf
	strSQL = strSQL & "WHERE Werknemervrij.Vrij = CDate(" & iLever & ") "
	'Open de recordset, en zet het aantal records in een variabele
	Set rs = db.OpenRecordset(strSQL)
	iRec = rs.RecordCount 
	'Gooi de recordset weer dicht
	rs.Close
	db.Close
	Set rs = Nothing
	Set db = Nothing
	'Doe, afhankelijk van de waarde van het aantal records, een handeling
	If iRec = 0 Then
		DoCmd.RunCommand acCmdSaveRecord
	Else
		DoCmd.OpenForm "Iemand vrij"
	End If
Deze routine doet hetzelfde, maar je recordset is dan altijd dicht.
 
Dank je wel!

Heb ik nog een klein vraagje...

Als er niemand vrij is en er wordt op de opslaknop geklikt dan wordt de record opgeslagen. Is het mogelijk om dan tegelijkertijd ook het formulier weer leeg te maken zodat er weer nieuwe invoer mogelijk is?

Want nu wordt iedere keer als ik op de opslaknop klikt de al opgeslagen record overschreven door hetgene wat nu in het formulier staat. Moet dus iedere keer als ik een nieuwe vracht wil inplannen het formulier sluiten en weer opstarten.

Grtz Wester
 
Je kunt deze regel als laatste toevoegen:

DoCmd.GoToRecord , , acNewRec
 
Hoi,

Ik heb overleg gehad op mijn werk en ze willen toch een aanpassing zien.

Ik heb de tabel met vrije dagen aan moeten passen om daarin ook een einddatum van een periode te kunnen aangeven. Er kunnen nu dus ook vakantieperiodes ingevoerd worden.

Het probleem is nu dat de code niet altijd meer werkt omdat er nu ook ingevulde datums vallen in een vakantieperiode. Hoe kun een functie maken die checkt of een bepaalde datum valt in een periode tussen twee datums?

Alvast bedankt!

Grtz Wester
 
Hoi Wester,

Uiteraard zag ik dit probleem al aankomen ;) De vraag om één datum, of een datumreeks te vergelijken met een andere datum(reeks) is altijd de volgende stap in het proces!
Zoals je al gemerkt hebt, is het vrij eenvoudig om één enkele datum te toetsen aan één enkele andere datum, of zelfs met een datumreeks.
Het is een stuk lastiger, om een datumreeks te vergelijken met een andere datumreeks, vooral als de begindatums en einddatums van de verschillende reeksen niet overeenkomen. Dan moet er op queryniveau behoorlijk wat werk worden verricht om e.e.a. werkend te krijgen.

Gelukkig is er altijd wel een voorbeeldje voorhanden :) In bijgaande database zie je twee oplossingen voor een praktijksituatie.
Het gaat in het voorbeeld om een vergelijkbare situatie, maar nu toegespitst op het bepalen van kortingspercentages voor een bepaalde periode, dus niet helemaal toegesneden op jouw situatie, maar hopelijk snap je wat er gebeurt, en kun je de techniek aanpassen aan je eigen db.

Het eerste voorbeeld is een oplossing rechtstreeks op query-basis. Als je de query qVerhuur bekijkt, zie je dat voor verschillende verhuurperiodes verschillende kortingspercentages worden opgezocht.
De tweede oplossing vind je in het formulier fVerhuur. Hier wordt alles via VBA geregeld: er wordt een tijdelijke tabel gemaakt voor de periodeberekeningen, die elke keer wordt aangepast als een nieuwe berekening wordt uitgevoerd met de knop <Berekenen>
Bekijk het voorbeeld eens, en ik hoor wel of het bruikbaar is!
 

Bijlagen

Hoi,

Je zag het inderdaad goed aankomen. ;)

Heb heel de avond zitten werken aan de code. Nog bedankt voor het voorbeeld trouwens. Kreeg het niet echt werkend maar bedacht me opeens dat het misschien wel simpeler kan met BETWEEN en AND te gebruiken in de SQL. Ik heb gewoon jouw oude code gebruikt.

Er wordt nu gecontroleerd of de ingevoerde leverdatum tussen twee datums ligt die in de tabel werknemers staan. Hij werkt volgens mij prima of gaat dit problemen op leveren?

Code:
Private Sub opslaBtn_Click()

Dim db As DAO.Database, rs As DAO.Recordset, strSQL As String
Dim dLever As Date
Dim iLever As Double, iRec As Integer

    Set db = CurrentDb()
    'Maak van de datum eerst een getal, zodat de SQL de datum goed vertaalt ivm. Amerikaanse datumnotatie
    dLever = CDate(Me.Leverdatum.Value)
    iLever = CDbl(dLever)
    'Maak de SQL waarmee je de records ophaalt die voldoen aan het criterium
    strSQL = "Select * FROM Werknemervrij " & vbCrLf
    strSQL = strSQL & "WHERE CDate(" & iLever & ") BETWEEN Werknemervrij.Vrij AND Werknemervrij.terug"
    'Open de recordset, en zet het aantal records in een variabele
    Set rs = db.OpenRecordset(strSQL)
    iRec = rs.RecordCount
    'Gooi de recordset weer dicht
    rs.Close
    db.Close
    Set rs = Nothing
    Set db = Nothing
    'Doe, afhankelijk van de waarde van het aantal records, een handeling
    If iRec = 0 Then
        
        DoCmd.RunCommand acCmdSaveRecord
        DoCmd.GoToRecord , , acNewRec
        MsgBox ("Nieuwe vracht opslagen")
      
    Else
        MsgBox ("Let op er is op die dag iemand vrij")
    End If
    

End Sub

Grtz Wester
 
Dit ziet er prima uit :thumb:
Het is een stuk makkelijker om één datum te vergelijken met een reeks, zoals je nu doet met Between. Het voorbeeld gaat uit van de volgende situatie die je tegen gaat komen :D En dan heb je dus dit soort constructies nodig. Misschien dat ze iets simpeler kunnen, maar daar moet ik zelf ook nog een paar nachtjes over doorbomen...
Maar je komt er wel uit, zo te zien!
 
Dank je wel in ieder geval voor je hulp! :thumb:
Heeft mij een heel eind op weg geholpen :D
 
Status
Niet open voor verdere reacties.
Terug
Bovenaan Onderaan