Exacte leeftijd berekenen

jlsaccess

Nieuwe gebruiker
Lid geworden
30 apr 2022
Berichten
3
Ik ben nieuwkomer en heb een vraag gesteld die naar nu blijkt uit de reactie's niet op de juiste wijze is gesteld. Mijn excuses daarvoor. Ik hoop het nu beter te doen.
Mijn vraag is hoe kan ik een leeftijd exact berekenen. Dus bijvoorbeeld, 56 jaar, 7 maanden en 20 dagen. Ik weet nu dat ik een module moet aanmaken (dat is ook gelukt dankzij Octafish, waarvoor dank) en daarna een query met een query met parameter en daar stopt de kennis voor mij en krijg ik het dus niet voor elkaar. Het is niet voor een vereniging maar uitsluitend bedoelt om ACCESS te leren.
 

Bijlagen

De leeftijd berekenen zoals je dat wilt, is in Access dus behoorlijk lastig. Weliswaar kent Access de functie DateDiff, maar die werkt (helaas) niet hetzelfde als de gelijknamige functie in Excel, waar je het simpel met andere argumenten kunt opvragen ("y" voor jaar, "ym" voor maanden en "md" voor dagen). Dus je zult het hele traject moeten doorrekenen. Dat kan, en ik ben daar ook al aan begonnen (want ik wist dat die vraag ging komen :)). Maar hij is nog niet perfect. Dus ik ga daar morgen verder mee.
 
In afwachting van een meer complete en betere oplossing door Octafish, hier een functie die ik zo'n 20 jaar geleden heb gebruikt toen ik nog Access apps ontwikkelde. De functie werd toen gebruikt in een jeugdsportvereniging om de juiste leeftijd te berekenen op de dag van de wedstrijd. De functie geeft het aantal jaren terug.

datDateB = geboortedatum
datDatec = dag van de wedstijd (of datum waarop leeftijd wordt berekend. Indien deze leeg blijft dan wordt deze ingevuld met de huidige datum

Code:
Public Function gfgCalcAge(datDateB As Date, Optional datDateC As Date) As Integer
On Error GoTo Err_gfgCalcAge

    Dim intYears As Integer
   
    If datDateC <= #1/1/1900# Then datDateC = Date
    If datDateB > datDateC Then
        gfgCalcAge = -1
        GoTo Exit_gfgCalcAge
    End If
    intYears = Year(datDateC) - Year(datDateB)
    If Month(datDateC) < Month(datDateB) Then
        intYears = intYears - 1
    End If
    If Month(datDateC) = Month(datDateB) And Day(datDateC) < Day(datDateB) Then
        intYears = intYears - 1
    End If
    gfgCalcAge = intYears
   

Exit_gfgCalcAge:
    Exit Function
   
Err_gfgCalcAge:
    gfgCalcAge = -1
    Resume Exit_gfgCalcAge

End Function
 
De functie om de leeftijd in jaren te berekenen heeft TS al; die zit ook in de database. En de mijne is ook een stuk korter: één regel effectieve code :). En nog een stukje fout afhandeling. Maar jouw procedure is dus veel te ingewikkeld :).

En nog een opmerking: in Access kun je probleemloos datums vóór 1-1-1900 gebruiken. Daar hoef je helemaal niks voor te regelen.
 
ik ben dan ook al jàààààren geen programmeur meer en heb expliciet vermeld dat jij wel een betere oplossing zou bieden.
 
Waarvoor dank :). Desalniettemin: als je deze functie nog steeds gebruikt, dan zou ik hem weggooien en/of vervangen door betere versies.
Maar los daarvan: als je antwoord geeft op een vraag, en de TS levert een database mee, dan kijk je eerst toch even in die database? En dan zie je gauw genoeg dat daar al een prima werkende functie in zit. Dus waarom zou je daar dan nog een 'antieke' versie die minder goed werkt aan toe voegen? Just saying...
 
Omdat het soms interessant is om een probleem vanuit twee totaal verschillende standpunten te zien.
 
Meerdere oplossingen zijn prima, maar nogmaals: wat is het nut om een in essentie niet zo'n beste functie te posten?
 
Laten we eerlijk wezen: een functie (in Access) die niet met datums vóór 1900 kan omgaan, sucks. En als je dan ook nog eens meer dan 20 regels code nodig hebt? Kom nou... Maar genoeg hierover, we zijn hier om TS te helpen en niet om een eigen dispuut te starten. Ik heb gezegd wat ik er van vind, en daar laat ik het verder bij.

Eerst maar eens de gevraagde functie aanleveren.
 
toch nog een antwoord: voor die functie (bepalen leeftijd) zijn datums voor 1900 niet nodig (tenware dat jij rekening houdt met Vulcans die meer dan 200 kunnen worden) en worden dus welbewust afgeblokt.
Ik heb nooit de fascinatie van programmeurs begrepen om code in zo weinig mogelijk lijnen te schrijven. Wat ik ook nog dagelijks vertel aan de programmeurs die ik aanstuur: wat telt is de duidelijkheid van de code, de efficientie waarmee ze in de achtergrond door de engine wordt uitgevoerd, het geheugen dat ze aanspreekt, de draagbaarheid en de onderhoudbaarheid. Oh ja, en voor de klant de prijs, dus wordt nu steeds meer en meer AI ingeschakeld om de code te schrijven.
 
Toch nog maar weer een antwoord, op deze lichte onzin. Ik ken geen Vulcans (welk land leven die?) maar weet uit geschiedenisboeken dat er in ieder geval in Nederland ook vóór 1900 mensen woonden in deze contreien. En ik ken zat mensen die aan genealogie doen en familieleden hebben die (je gelooft het wellicht niet) die voor 1900 zijn geboren. En verdamd als het niet waar is: die kun je prima registreren in Access.

Je opmerkingen over 'fascinatie voor korte code' slaan natuurlijk, en dat weet jij ook donders goed, nergens op. Ik leid hier alleen maar uit af dat jij (ik weet het, hot shots hebben weinig tijd) de functie in de en (je weet wel, die met één regel) niet hebt gezien.

Nog even en dit forum is voor jou; ik kap er binnenkort mee. Waarom? Omdat ik dit geneuzel niet meer verdraag...
 
@OctaFish
Even een vraagje.
Hoe gaat Access om met de datum 28/29-2-1900 en met de data 30-12-1899 en 31-12-1899?
Is met de data vóór 1900 ook te rekenen? Zelf heb ik zo mijn twijfels, maar die kan jij bij mij weghalen.
 
Laatst bewerkt:
Maar weer even terug naar vraag.... 😨

Ik heb alvast, voordat de betere verschijnt, een eigen breiwerkje in elkaar gezet. Mijn functie is
Code:
Function LeeftijdOp(Geboortedatum As Variant, Peildatum As Date) As Variant
Dim Maanden As Integer
Dim Dagen As Byte

If Format(Geboortedatum, "mmdd") > Format(Peildatum, "mmdd") Then
    LeeftijdOp = DateDiff("yyyy", Geboortedatum, Peildatum) - 1 & " jaar, "
Else
    LeeftijdOp = DateDiff("yyyy", Geboortedatum, Peildatum) & " jaar, "
End If

Maanden = Month(Peildatum) - Month(Geboortedatum)

If Day(Peildatum) > Day(Geboortedatum) Then
    Maanden = Maanden - 1
End If

If Maanden < 0 Then
    Maanden = Maanden + 12
End If

If Maanden <> 1 Then
    LeeftijdOp = LeeftijdOp & Maanden & " maanden en "
Else
    LeeftijdOp = LeeftijdOp & Maanden & " maand en "
End If

If Day(Peildatum) > Day(Geboortedatum) Then
    Dagen = DateDiff("d", DateAdd("m", -1, Geboortedatum), Geboortedatum) - 1
Else
    Dagen = Day(Geboortedatum) - Day(Peildatum)
End If

If Dagen <> 1 Then
    LeeftijdOp = LeeftijdOp & Dagen & " dagen"
Else
    LeeftijdOp = LeeftijdOp & Dagen & " dag"
End If

End Function

Geen foutafhandeling (want kan je ook vooraf doen), geen oude datums (want behoefte niet bekend).
 

Bijlagen

Ik vergat nog wat te melden. De functie heeft 2 parameters (net zoals die van @NoellaG). Het voordeel is dat je dan meer mogelijkheden hebt. Je kunt zowel de leeftijd van vandaag laten zien, maar ook op een andere datum. Bijvoorbeeld: hoe oud was iemand op 1-1-2025?
De voorbeeldquery heb ik daar nog op aangepast:
Code:
SELECT
    Geb,
    Leeftijdop ([geb], Date()) AS [Leeftijd nu],
    Leeftijdop ([geb], #1 / 1 / 2025 #) AS [Leeftijd op 1-1-2025]
FROM
    Personen;
 

Bijlagen

Terug
Bovenaan Onderaan