Avatar billede janospetro Nybegynder
25. november 2002 - 14:28 Der er 19 kommentarer og
2 løsninger

Forkert datoberegning på CPR-nummer

Jeg bruger følgende formel til at beregne en dato ud fra et cpr-nummer:

=HVIS(ER.FEJL(DATO(MIDT(D124;5;2);MIDT(D124;3;2);MIDT(D124;1;2)));"";DATO(MIDT(D124;5;2);MIDT(D124;3;2);MIDT(D124;1;2)))

Men engang i mellem får jeg et resultat som:

21-09-01 = 101 år fra et CPR-nummer som 210901-xxxx

eller

10-08-32 = 70 år fra et CPR-nummer som 071183-xxxx

Hvad er galt? Tak for hjælp
JanosPetro
25. november 2002 - 14:45 #1
=DATO.FORSKEL(VENSTRE(E6;8);IDAG();"Y")&" år "&DATO.FORSKEL(VENSTRE(E6;8);IDAG();"YM")&" mdr "&DATO.FORSKEL(VENSTRE(E6;8);IDAG();"MD")&" dage"
25. november 2002 - 14:45 #2
dato findes i E6 i eksemplet
Avatar billede jkrons Professor
25. november 2002 - 23:17 #3
janospetro-> Problemet er, at du ikke kan aflæse århundredet ud af de første 6 cifre. Derfor regner den af og til forkert. En anden grund er at Excel fortolker de to-cifrede årstal, som kommer ud af din datoberegning. Årstal under 30 opleves som i 20.. mens årstal over 30 opfattes som i 19.. Ingen årstal opfattes som i 18..

For at betregne århundredet og dermed alderen kræves en ret kompliceret beregning, der dels ser på det 7.- ciffer i cpr-nummeret, dels i visse tilfælde sammenligner med årstallet. Såldes betyder 0-3 som 7. ciffer, at man er født i 19.. Har man 5 til 8, er man født i 18.. hvis året er større end eller = 58, man er født i 200.. hvis året er mindre end eller = 36 og mellem 37 og 57 er man født i 19.. . Har man 4 eller 9 er man født i 19.. hvis året er større end 37, ellers er man født i 20..

Her er en funktion, som beregner alderen, men den tager kun højde for, om man er født i begyndelsen af 19.. eller begyndelsen af 20.., ikke de øvrige spidsfindigheder.

Function ALDER(CPR As String) As Integer
  Dim temp As Date

  temp = DateSerial(Mid(CPR, 5, 2), Mid(CPR, 3, 2), Mid(CPR, 1, 2))
  If Right(Date, 2) < 31 And Mid(CPR, 8, 1) <= 3 Then
    ALDER = Right(DatePart("YYYY", Date - temp), 2) + 100
  Else
    ALDER = Right(DatePart("YYYY", Date - temp), 2)
  End If
End Function

Måske har Flemming lyst til at kode den færdig :-)

Flemming-> Forudsætter dit forslag ikke en fødselsdag i stedet for et cprnummer?
Avatar billede janospetro Nybegynder
26. november 2002 - 08:51 #4
Tak, fordi FlemmingDahls forslag løste desværre ikke problemet da jeg fik set på det sent i går aftes. Jeg håber sidst på eftermiddagen (tirsdag) at få set på det igen, små ting vokser sig hurtigt store, men indtil da, tak for hjælpen. Point kommer efter løsningen :-) Janospetro
Avatar billede jkrons Professor
26. november 2002 - 10:20 #5
Læg nedenstående kode ind i et modul. Skriv så =cpralder(a1), der hvor du vil beregne alderen. A1 skal naturligvis udskriftes med den celle, hvor du har cpr-nummeret.

Koden tager højde for alle finurlighederne omkring cpr-numre tror jeg nok (den kontrollerer dog ikke om cpr-nummeret er gyldig jf Modulus 11, og den interesserer sig ikke for kønnet.


Function CprAlder(cpr As String) As Byte
'JKrons, 2002
'Finder fødsels-århundredet ud af
'et cpr-nummer på formen xxxxxx-xxxx
'Den virker kun indtil 2036, hvor cpr-nummersystemet i
'dets nuværende form ophører med at fungere
'se nærmere på www.cpr.dk

    Dim bytCent As Byte
    Dim bytSevdig As Byte
    Dim bytCpryear As Byte
    Dim bytCprmonth As Byte
    Dim bytCprday As Byte
    Dim strErrtxt As String
    Dim datTemp As Date

   
    strErrtxt = "Der eksisterer ikke lovlige cpr-numre, hvor årstallet er "
    bytSevdig = Mid(cpr, 8, 1)
    bytCpryear = Mid(cpr, 5, 2)
    bytCprmonth = Mid(cpr, 3, 2)
    bytCprday = Mid(cpr, 1, 2)
   
    Select Case bytSevdig
        Case 0 To 3
            bytCent = 19
        Case 4, 9
            If bytCpryear <= 36 Then
                bytCent = 20
            Else
                bytCent = 19
            End If
        Case 5 To 8
            If bytCpryear <= 36 Then
                bytCent = 20
                ElseIf bytCpryear >= 58 Then
                bytCent = 18
                Else
                strErrtxt = strErrtxt & bytCpryear & " og 7. ciffer er " & bytSevdig
                MsgBox strErrtxt, vbOKOnly + vbCritical, "CPR-nummer fejl"
                Exit Function
            End If
           
    End Select

    datTemp = DateSerial(bytCent & bytCpryear, bytCprmonth, bytCprday)

    If datTemp > Date Then
        MsgBox "Den pågældende person er ikke født endnu", vbOKOnly + vbExclamation, "CPR-nummer fejl"
        Exit Function
    End If
   
    If Mid(datTemp, 7, 2) = 18 Then
        CprAlder = Right(DatePart("yyyy", Date - datTemp), 2) + 100
        Else
        CprAlder = Right(DatePart("yyyy", Date - datTemp), 2)
    End If
End Function
Avatar billede jkrons Professor
26. november 2002 - 10:24 #6
Jeg skal måske lige tilføje, at alderen beregnes i hele år! Det vil sige, at hvis man er født den den 27-11-2002, vil man i dag være 1 år, men i morgen er man 2.
Avatar billede bak Forsker
26. november 2002 - 10:47 #7
dette burde kunne gøre det, men Jkrons forslag er godt.

=DATEDIF((MID(B3;1;2)&"-"&MID(B3;3;2)&"-"&MID(B3;5;2));NOW();"y")
eller på dansk
=DATO.FORSKEL(((MIDT(B3;1;3) &"-"& MIDT(B3;3;2) &"-"& MIDT(B3;5;2);IDAG();"y")
Avatar billede jkrons Professor
26. november 2002 - 11:20 #8
bak->Din løsning tager vel heller ikek højde for århundreproblematikken?
26. november 2002 - 11:45 #9
Svar på tidligere spørgsmål - mit forslag kræver en dato f.eks. 26-11-2002 for at udregne alderen
Avatar billede bak Forsker
26. november 2002 - 11:59 #10
jkrons. Jo, tildels.
I hvert fald er svarene på de 2 datoer der er nævnt i spørgsmålet rigtigt.
Lige et klip fra hjælpen

The years 2000 through 2029 if you type 00 through 29 for the year. For example, if you type 5/28/19, Excel assumes the date is May 28, 2019.


The years 1930 through 1999 if you type 30 through 99 for the year. For example, if you type 5/28/98, Excel assumes the date is May 28, 1998.
Avatar billede bak Forsker
26. november 2002 - 12:07 #11
dvs at den ikke funker for pensionister over 72 og for ufødte børn under -27
Avatar billede jkrons Professor
26. november 2002 - 12:29 #12
bal->Så er vi enige. Jeg tænke faktisk heller ikke på Excels århundre, men på cpr-nummerets. Altså din løsning kan ikke se på cpr-nummer 120177-5678 om der er 1997 eller 1877. Men det ligger jo også i din begrænsning.
Avatar billede janospetro Nybegynder
26. november 2002 - 13:52 #13
Hov min kommentar forsvandt, jeg prøver igen. Tak for de gode forklaringer og løsningsforslag. Jeg har en userform der laver en modulus 11 kontrol og beregner alderen med det samme. Men når dataene skal hentes fra Excel, f.eks. i Word ville jeg gerne have den aktuelle alder. Derfor det oprindelige spørgsmål. JKRONS' løsning er fin, jeg kan bare ikke hurtigt få den til at virke. BAK's løsning er så enkel at jeg har valgt at arbejde videre med den. Den giver bare fejlmeddelelser, jeg har rettet den til =DATO.FORSKEL(MIDT(D2;1;2) &"-"& MIDT(D2;3;2) &"-"& MIDT(D2;5;2);IDAG();"y"), men så er der problemer, når CPR-nummeret begynder med 0. Indtil videre står det 15-15 til BAK og JKRONS, men en løsning på den sidste formel kan ændre resultatet :0)
Avatar billede jkrons Professor
26. november 2002 - 15:27 #14
Hvilke problemer opstår der med BAK's formel? Er CPR-nummeret tekst eller tal? Lav det under alle omstændigheder som tekst!

Hvad er det, du ikke kan få til at virke i min løsning?
Avatar billede bak Forsker
26. november 2002 - 15:52 #15
Enig jkrons.  cellen D2 skal formateres som tekst
Avatar billede janospetro Nybegynder
27. november 2002 - 09:19 #16
Feltet er brugerdefineret med 0#####-####. Nullet sikrer, at der står et foranstillet nul med f.eks 071102-1234, hvilket MS Excel eget personnummerformat IKKE gør. Det skulle vel være et tekstfelt, eller er det bindestregen der er problemet?

Formlen virker perfekt, UNDTAGEN når der er foranstillet nul så er resultatet #VÆRDI!

Ad JKRONS, det er nok pinligt, men det er at for modulet til at aktivere en bestemt celle.
Avatar billede janospetro Nybegynder
27. november 2002 - 09:21 #17
for = få i dette tilfælde, altså at resultatet står i cellen når regnearket aktiveres, eller hvordan det nu skal hænge sammen :-)
Avatar billede jkrons Professor
27. november 2002 - 09:40 #18
Omkring problematikken med tekst/ikke tekst: Det brugerdefinerede format er et format, der fortæller, hvordan indeholdet af cellen skal vises. I dette tilfælde med en bindestreg og evt. et foranstillet 0. Konkret lagres tallet i cellen UDEN bindestreg, og UDEN det foranstillede 0. Det betyder at baks begegningsfunktion ikke vil virke. Den eneste løsning på det problem, tror jeg, er at formatere som Tekst. Så må du (andre brugere) selv indtaste bindestregen. 020202-0202 vil så blive ved med at stå sådan, og formlen vil virke.

Du kan sagtens få udført beregningen af alderen via min kode i din userform. Gem så alderen i en variabel, og lad kode på userformen indsætte alderen.

Antag at du har gemt alderen i en variabel, der hedder Alder. Så kan du indsætte disse linier i koden på din userform:

Range("a4").Activate.
Activecell.Value = Alder
Avatar billede bak Forsker
27. november 2002 - 09:41 #19
Janospetro
I dit brugerdefinerede format er 0-et kun kosmetisk, dvs at længden af cellen kun er 10 og ikke 11 som det er vist.
Avatar billede janospetro Nybegynder
27. november 2002 - 10:34 #20
Tak for hjælpen alle tre, jeg har fået det til at virke. Selvom jeg finder BAK burde have point, er der det med kommentarerne og point. Så det blev 10 til FLEMMINDAHL og 20 til JKRONS. :o)
Avatar billede jkrons Professor
27. november 2002 - 10:36 #21
Jeg takker, men synes nu at BAK skal have point alligevel. Så BAK, hvis jeg nu lægger et spørgsmål, gider du så svare? Så skal du få halvdelen af mine :-)
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Excel kurser for alle niveauer og behov – find det kursus, der passer til dig

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester