[easy_youtube_gallery id=uMK0prafzw0,8Uee_mcxvrw,HcXNPI-IPPM,JvMXVHVr72A,AIXUgtNC4Kc,K8nrF5aXPlQ,cegdR0GiJl4,L-wpS49KN00,KbW9JqM7vho ar=16_9 cols=3 thumbnail=hqdefault controls=0 playsinline=1 privacy=1 title=top wall=1 class=mySuperClass]
Först publicerad: 2009-05-21

VBA Excel och Personnummer – beräkna kontrollsiffra

luhn
Hans Peter Luhn på IBM, 1952.

Personnumret används ju som bekant för att identifiera sig inför andra personer, banker, affärer och myndigheter. Den tionde siffran, dvs den sista positionen i personnumret, är en kontrollsiffra som är resultatet av en funktion applicerad på de övriga 9 siffrorna.

Nedan presenteras ett litet makro i VBA som beräknar denna kontrollsiffra. Denna kontroll kan användas i alla de sammanhang där man erhållit ett personnummer och vill kontrollera att det är ett giltigt personnummer.

Observera att makrot kontrollerar om föreliggande personnummer är ett korrekt nummer ur ett teoretiskt perspektiv – bara för att kontrollsiffran stämmer så betyder det ju inte att just detta personnummer verkligen innehas av någon.

Allmänt om personnummer

Personnumret infördes 1947 och var då byggt kring 9 siffror. Den tionde kontrollsiffran infördes först 20 år senare, 1967, som ett led i den tidens datorisering. Fram till 1990 så angav positionerna 7 och 8 vilket län man var född i. För personer födda utomlands så användes serierna 93-99. 1990 ändrades detta till ett mer allmänt löpnummer i och med att länsangivelserna i personnumret försvann över huvud taget och ersattes av en generell löpserie.

Övrig information som man kan utläsa är kön vilket beskrivs genom att den nionde siffran är udda för män och jämn för kvinnor.

Skiljetecknet mellan de 6 första och 4 sista siffrorna i personumret är normalt ett “-” men när personen fyller 100 år så byter man tecken till ett “+” istället. VBA-exemplet nedan tar inte detta i beaktning men det är ju inte svårt att lägga till om det skulle behövas.

Det finns en specialvariant av personnummer som kallas för samordningsnummer. Detta identitesnummer ges till personer som inte är folkbokförda i Sverige men likväl behöver en identitet av detta slaget, till exempel för att öppna ett bankkonto. Till utseendet är det enda som skiljer ett samordningsnummer från ett vanligt personnummer att man adderar 60 till dagen som man är född. Är man född den 14 i månaden så uttrycks dagen som 74. Kontrollsiffran beräknas dock på samma sätt som för ett vanligt personnummer.

Personnumrets kontrollsiffra

Personnumrets sista siffra är alltså en kontrollsiffra som bygger på numrets övriga nio siffror. Formeln för att beräkna kontrollsiffran bygger på Luhn-algoritmen, patenterad 1954, vilken ingår i den så kallade “public domain” vilket gör den fri att använda. Hans Peter Luhn (1896-1964) föddes i Tyskland och emigrerade till USA efter första världskriget. Algoritmen tog han fram för IBM.

Metoden för att beräkna personnumrets kontrollsiffra lyder som följer. Den första siffran multipliceras med 2, den andra med 1, den tredje med 2 osv. Sedan skall allt adderas ihop. Om produkten av multiplikationen av den första siffran blir 12 så blir värdet för den första siffran 3 (1+2). På detta sättet adderas de nio produkterna ihop. Denna summa skall sedan subtraheras från närmaste högre tiotal. Så om summan är 34 så blir kontrollsiffran 40-34=6. Om slutsumman skulle vara 10 så blir kontrollsiffran 0.

I VBA-koden nedan så används funktionen MOD för att ta reda på detta högre tiotal. MOD är en funktion som kan vara svår att förstå (ända tills man får en bra förklaring, för det är inte svårt egentligen). Jag tänkte återkomma till MOD vid ett annat tillfälle.

Excel-exempel för att beräkna kontrollsiffran

Grundidén i exemplet är att användaren matar in de första 9 siffrorna i ett personnummer. VBA-koden räknar sedan ut kontrollsiffran och skriver ut den i en härför avsedd cell. Observera att exemplet nedan är en ganska visuell programmeringslösning. Ett snabbare (men mer komplicerat) sätt vore att läsa in siffrorna i en matris som sedan loopas igenom för beräkningarna. Men den metoden används alltså inte här. Resultatet är emellertid det samma.

För aktuell kod används en enkel kalkylbladsuppställning enligt följande bild:

vba-personnummer-1

Efter körning av makrot så kommer det att se ut som följer:

vba-personnummer-2

VBA-koden

Sub PersonnummerBeraknaKontrollsiffra()
 
strPersonnummer = Trim(Range("C5").Text)
 
'först kontrollera att inmatningen korrekt (inkl. "-")
If Mid(strPersonnummer, 7, 1) <> "-" Or Len(strPersonnummer) > 11 Then
MsgBox "Felaktig inmatning. Gör om enligt modellen xxxxxx-xxx"
GoTo 99
End If
 
'tar in personnumret i variabler
strSiffra_1 = Left(strPersonnummer, 1)
strSiffra_2 = Mid(strPersonnummer, 2, 1)
strSiffra_3 = Mid(strPersonnummer, 3, 1)
strSiffra_4 = Mid(strPersonnummer, 4, 1)
strSiffra_5 = Mid(strPersonnummer, 5, 1)
strSiffra_6 = Mid(strPersonnummer, 6, 1)
strSiffra_7 = Mid(strPersonnummer, 8, 1)
strSiffra_8 = Mid(strPersonnummer, 9, 1)
strSiffra_9 = Mid(strPersonnummer, 10, 1)
 
'multiplicerar varje siffra omväxlande med 2 och med 1
strSiffra_1 = strSiffra_1 * 2
strSiffra_2 = strSiffra_2 * 1
strSiffra_3 = strSiffra_3 * 2
strSiffra_4 = strSiffra_4 * 1
strSiffra_5 = strSiffra_5 * 2
strSiffra_6 = strSiffra_6 * 1
strSiffra_7 = strSiffra_7 * 2
strSiffra_8 = strSiffra_8 * 1
strSiffra_9 = strSiffra_9 * 2
 
'summerar varje individuell produkt
If strSiffra_1  >= 10 Then strSiffra_1 = 1 + Mid(strSiffra_1, 2, 1) Else _
strSiffra_1 = Left(strSiffra_1, 1) + Mid(strSiffra_1, 2, 1)
If strSiffra_2  >= 10 Then strSiffra_2 = 1 + Mid(strSiffra_2, 2, 1) Else _
strSiffra_2 = Left(strSiffra_2, 1) + Mid(strSiffra_2, 2, 1)
If strSiffra_3  >= 10 Then strSiffra_3 = 1 + Mid(strSiffra_3, 2, 1) Else _
strSiffra_3 = Left(strSiffra_3, 1) + Mid(strSiffra_3, 2, 1)
If strSiffra_4  >= 10 Then strSiffra_4 = 1 + Mid(strSiffra_4, 2, 1) Else _
strSiffra_4 = Left(strSiffra_4, 1) + Mid(strSiffra_4, 2, 1)
If strSiffra_5  >= 10 Then strSiffra_5 = 1 + Mid(strSiffra_5, 2, 1) Else _
strSiffra_5 = Left(strSiffra_5, 1) + Mid(strSiffra_5, 2, 1)
If strSiffra_6  >= 10 Then strSiffra_6 = 1 + Mid(strSiffra_6, 2, 1) Else _
strSiffra_6 = Left(strSiffra_6, 1) + Mid(strSiffra_6, 2, 1)
If strSiffra_7  >= 10 Then strSiffra_7 = 1 + Mid(strSiffra_7, 2, 1) Else _
strSiffra_7 = Left(strSiffra_7, 1) + Mid(strSiffra_7, 2, 1)
If strSiffra_8  >= 10 Then strSiffra_8 = 1 + Mid(strSiffra_8, 2, 1) Else _
strSiffra_8 = Left(strSiffra_8, 1) + Mid(strSiffra_8, 2, 1)
If strSiffra_9  >= 10 Then strSiffra_9 = 1 + Mid(strSiffra_9, 2, 1) Else _
strSiffra_9 = Left(strSiffra_9, 1) + Mid(strSiffra_9, 2, 1)
 
'summerar ihop kontrollsumman
strKontrollSumma = strSiffra_1 + strSiffra_2 + strSiffra_3 + _
strSiffra_4 + strSiffra_5 + strSiffra_6 + strSiffra_7 + _
strSiffra_8 + strSiffra_9
 
'vi subtraherar erhållen kontrollsumma från närmaste högre tiotal
strKontrollSiffra = 10 - strKontrollSumma Mod 10
 
'om vi får specialfallet 10 så gör vi om till 0
If strKontrollSiffra = 10 Then strKontrollSiffra = 0
 
'slutligen skriver vi ut den erhållna kontrollsiffran
Range("D5") = strKontrollSiffra
 
99:
 
End Sub