Rekenen met datum en IIF then constructie

Status
Niet open voor verdere reacties.

rista62

Gebruiker
Lid geworden
25 nov 2009
Berichten
73
Hallo,

Ik heb proefopzet database met leden(bijlage), waarin het veld "Opzegdatum" een tekst type is.Om hier in de query mee te rekenen heb ik daar een datumveld van gemaakt met als veldnaam "UitStroom". Als ik de query draai is het resultaat dat bij de leden die niet weg zijn een "#Fout" geeft. Hoe kan ik dit oplossen?
Een tweede vraag is:
Ik wil graag in mijn query aangeven hoelang mijn leden al lid zijn op dit moment(op ieder moment dat ik die query open) en daar een naam aanhangen. Dus bijvoorbeeld:
als iemand minder dan 13 maanden lid is dan "Nieuw",
als iemand korter dan 25 maanden lid is dan "Beginneling"
als iemand korter dan 49 maanden lid is dan "Ervaren"
en anders "Topper".
Let op ik ben nog een beginneling in Access dus vandaar.
Kan iemand mij hier mee helpen?

Gr.
R.
 

Bijlagen

Je formule was bijna goed:

UitStroom: IIf([tblLeden]![OpzegDatum] Is Null;"";CDate([tblLeden]![OpzegDatum]))
 
Voor het tweede deel van de vraag:
Hier kun je het beste een Functie voor maken. Daarmee kun je de datum vergelijken met elke datum die je wilt, in dit geval dus een ingangsdatum. De functie is niet zo moeilijk te snappen (hoop ik); hij staat in het voorbeeld in de module Functies.
 

Bijlagen

Hallo Michel,

Allereerst geweldig bedankt voor beide oplossingen van mijn 2 vragen.
Het antwoord op de 2e vraag is mij niet geheel duidelijk qua werking. Je kunt dus zelf functie(s) aanmaken bij "Modules"? Kun je mij iets meer uitleggen over de VBA code die er staat?
Wat betekent:
Option Compare Database
Option Explicit
Public Function Klasse(Datum As Date) As String
iDuur = DateDiff("m", Datum, Date)

Ik zie dat je in de ontwerpweergave van de query "Expr1: Leeftijdsgroep(CDate([DatumLid]))" dit in het veld opneemt. Wat doet dit precies?
Ik hoop dat je me nog meer duidelijkheid kunt geven, het wordt namelijk steeds leuker.
Groet,
Richard
 
Hoi Richard,

Dat doet natuurlijk deugd, dat je het steeds leuker gaat vinden :thumb:

Je kunt in een db verschillende soorten gegevensvergelijkingen maken, zoals op basis van de binaire gegevens, of op basis van tekst. In de eerste variant <Option Compare Binary> is Tekst=tekst niet hetzelfde, bij <Option Compare Text> is Tekst=tekst wel hetzelfde. De optie Database houdt in, dat in een database de oorspronkelijke recordindeling wordt gebruikt. De regel mag worden weggelaten.
Option Compare Database

Datzelfde geldt ook voor
Option Explicit
Deze regel geeft aan dat je alle variabelen moet declareren. Doe je dat vervolgens niet, dan krijg je een foutmelding. Best gebruik je deze optie altijd, want dan weet je dat alle variabelen goed zijn ingesteld.
Dan nu de functie:
Deze gebruikt een datum als input (het veld Datum) en levert als resultaat een tekst op: (As String). Die tekst wordt verderop vastgelegd in de functie. eerst wordt een getalvariabele gedefinieerd (iDuur).
Code:
Public Function Leeftijdsgroep(Datum As Date) As String
Dim iDuur As Integer
    
    iDuur = DateDiff("m", Datum, Date)
Dan wordt het verschil in maanden tussen de de ingangsdatum, en de datum van vandaag (Functie Date) uitgerekend met de functie DateDiff. Deze kan op verschillende manieren datumberekeningen maken, waaronder het verschil in Maanden. Dat is de eerste parameter ("m). In de tweede parameter staat de berekening: Date (datum vandaag) - Datum (meegegeven datum)
Code:
    Select Case iDuur
        Case Is < 12
            Leeftijdsgroep = "Nieuw"
        Case 13 To 25
            Leeftijdsgroep = "Beginneling"
        Case 26 To 49
            Leeftijdsgroep = "Ervaren"
        Case Else
            Leeftijdsgroep = "Topper"
    End Select

End Function
Vervolgens wordt met een Select Case gekeken naar de verschillende waardes die voortvloeien uit de datumberekening. Afhankelijk van het getal wordt aan de functie de tekst Nieuw, Beginneling etc. teruggeleverd. De waarde wordt in Leeftijdsgroep gezet, vandaar dat de functienaam Leeftijdsgroep(...) As String is. Je zet kortom een tekst terug in de functiewaarde.

Het laatste stukje van de puzzel is het aanroepen van de functie. Dat doe ik in dit voorbeeld in een query:
Klasse: Leeftijdsgroep(CDate([DatumLid]))
Expr1 is hier de naam die je terugziet, maar die mag uiteraard vervangen door iets anders.
Leeftijdsgroep is hier dus de naam van de functie. Met CDate() zet je een datumtekst om naar een datum. In dit geval dus het veld [DatumLid].
En zo is alles aan bod gekomen...
 
Hoi Michel,

Bijna alles is me duidelijk alleen wat ik nog niet begrijp is:bij de bepaling in welke Leefttijdsgroep iemand valt ga je het aantal maanden ("m) bepalen door het verschil te bepalen tussen de datum van vandaag (Date) en datumlid, maar die variabele zie ik niet. Ik zie wel "Datum", maar je moet toch rekenen met DATUMLID?
Kun je me dit uit leggen?
Alvast weer dank.
Gr.
Richard
 
Dat is uiteraard prima uit te leggen:
de functie kan pas iets doen, als hij een waarde heeft gekregen: een datum namelijk. Die datum wordt bij verwerking in de variabele Datum gezet.

Public Function Leeftijdsgroep(Datum As Date) As String

Zonder datum zal de functie altijd een foutmelding geven.
Bij het aanroepen van de functie moet je dus opgeven welke datum je wilt gebruiken in de functie:

Klasse: Leeftijdsgroep(CDate([DatumLid]))
Dat doe je dus door achter het commando Leeftijdsgroep( een datumveld neer te zetten. Het maakt daarbij niet uit welk veld je daarvoor gebruikt. Zodra de functie gaat lopen, kijkt het naar het Datumveld dat wordt aangeboden (DatumLid) en dat wordt dan in de functievariabele <Datum> gezet.
Als je de functie zelf wilt maken, dan kun je dat doen via de functieknop <Opbouwen>. Als je in het scherm dubbelklikt op <Functies>, dan zie je twee opties: <Ingebouwde functies> (de standaard Access functies) en functies die specifiek bij de db horen. In die laatste optie vind je de modules terug die zijn gemaakt, en de Public functies (dat laatste is belangrijk; Private functies zie je hier namelijk niet terug) die zijn gemaakt. Als je vervolgens een Custom functie toevoegt aan het scherm, dan zie je ook gelijk dat de functie Leeftijdsgroep een datum vraagt, want die staat al aangegeven tussen de haakjes! Je weet dan dus al, dat je de tekst tussen de haakjes moet vervangen door een veld.
In jouw geval moet het datumveld eerst worden omgezet naar een Datumwaarde, omdat je ervoor hebt gekozen om van het datumveld een tekstveld te maken. Overigens iets wat ik zo snel mogelijk zou terugdraaien, want ik zie geen voordelen in een datum als tekstveld, alleen nadelen...
 
Hoi Michel,
Enorm bedankt voor je perfecte uitleg.
Groetjes,
Richard
 
Hoi Michel,

Toch nog even een vraagje over de functie die je me gisteren uitlegde. In het voorbeeld gaat het om het verschil tussen de huidige datum (Date) en de DatumLid. De huidige datum kun je makkelijk opnemen in de code namelijk met "Date".
Stel ik wil hetzelfde voorbeeld maken maar dan voor "Uitstroom" en "DatumLid"(in plaats van Huidige datum en "DatumLid"), als < 12 mnd dan "Nieuw" enz. Kan ik dit dan ook doen met een zelf gemaakte functie?
Ik hoop dat je het begrijpt?

Groetjes,
Richard
 
Je kunt daar een andere functie voor maken, of de bestaande aanpassen, wat je wilt.
Hij is (bijna) hetzelfde, alleen het begin wordt anders. Omdat je nu twee variabele datums wilt gebruiken, moet je die ook meegeven bij het aanroepen van de functie. Er komen dus twee Inputvariabelen in de functienaam te staan:
Code:
Public Function Leeftijdsgroep(DatumIn As Date, DatumUit As Date) As String
Dim iDuur As Integer
    
    iDuur = DateDiff("m", DatumIn, DatumUit)
De aanroep van de functie wordt nu:
Klasse: Leeftijdsgroep(CDate([DatumLid]);CDate([Uitstroom]))
Hierbij wordt dus DatumLid in de functie toegewezen aan DatumIn, en Uitstroom aan DatumUit.

Een andere optie is om de functie flexibel te houden, waarbij je er zelf voor kunt kiezen om één of twee datums te gebruiken. In het eerste geval neemt de functie zelf de huidige datum als rekendatum.

Code:
Public Function Leeftijdsgroep(DatumIn As Date, Optional DatumUit As Date) As String
Dim iDuur As Integer
    If Nz(DatumUit,0)=0 Then DatumUit=Date
    iDuur = DateDiff("m", DatumIn, DatumUit)
Het verschil met de vorige variant is nu dat de tweede datum optioneel wordt gemaakt met Optional DatumUit As Date. Oftewel: je bent niet verplicht om de tweede datum aan te leveren. Als er geen tweede datum is, moet de functie de datum van vandaag pakken. Dat doet hij door eerst te controleren of het veld DatumUit leeg is (met Nz(DatumUit,0) en als dat zo is, de datum toe te wijzen aan DatumUit. Daarna gaat hij weer rekenen...
 
Michel,

Geweldig, top en bedankt voor je goede uitleg.
Gr.
Richard
 
Mag je 'm nog afsluiten!
 
Status
Niet open voor verdere reacties.
Terug
Bovenaan Onderaan