Automatisera Excel-rapporter: Steg-för-steg med VBA
Klockan är 16:45 på fredag eftermiddag. Du öppnar fem olika Excel-filer, kopierar data från var och en, klistrar in i rapportmallen, formaterar rubrikerna, lägger till grafer, kontrollerar summor. Två timmar senare kan du äntligen skicka veckans rapport.
Nästa fredag gör du exakt samma sak igen. Och veckan efter det. 104 timmar per år på samma repetitiva uppgift.
Jag hjälpte en finanschef automatisera exakt detta. Nu tar rapporten 3 minuter att generera genom att klicka på en knapp. Samma rapport, samma kvalitet, 117 gånger snabbare.
I den här guiden bygger vi ett komplett rapporteringssystem steg för steg. Du får färdig kod och detaljerade förklaringar. När du är klar kan du anpassa systemet till dina egna rapporter.
Vad vi ska bygga
Ett automatiserat rapporteringssystem som: 1. Importerar data från flera källfiler 2. Sammanställer och beräknar nyckeltal 3. Skapar en formaterad rapport med standardlayout 4. Genererar grafer automatiskt 5. Sparar rapporten med datumstämplat filnamn 6. Skickar rapporten via mail (valfritt)
Allt detta med ett enda knapptryck.
Förberedelser
Filstruktur
Skapa följande mappstruktur:
C:\Rapporter\
├── Källdata\
│ ├── Försäljning.xlsx
│ ├── Kostnader.xlsx
│ └── Budget.xlsx
├── Rapportmall.xlsm
└── Genererade rapporter\
Rapportmall.xlsm är filen där vi lägger all VBA-kod. De genererade rapporterna hamnar i undermappen.
Källfilernas struktur
Varje källfil behöver ha data i förutsägbar struktur:
Försäljning.xlsx, blad “Data”:
Rad 1: Datum | Produkt | Antal | Belopp
Rad 2+: 2026-01-15 | Produkt A | 10 | 15000
Kostnader.xlsx, blad “Data”:
Rad 1: Datum | Kategori | Belopp
Rad 2+: 2026-01-15 | Personal | 125000
Budget.xlsx, blad “Data”:
Rad 1: Månad | Försäljning Budget | Kostnad Budget
Rad 2+: 2026-01 | 500000 | 350000
Anpassa till din faktiska datastruktur – principerna är desamma.
Rapportmallens uppbyggnad
Rapportmall.xlsm består av tre blad:
1. “Import” – Hit importeras rådata (dolt för slutanvändare)
2. “Beräkningar” – Här görs alla beräkningar och nyckeltal (dolt)
3. “Rapport” – Den formaterade rapporten som blir synlig
Steg 1: Importera data från källfiler
Vi börjar med att hämta data från de tre källfilerna.
Koden för import
Sub ImporteraData()
Dim wbKälla As Workbook
Dim wsKälla As Worksheet
Dim wsImport As Worksheet
Dim sistaRad As Long
Dim källSökväg As String
källSökväg = "C:\Rapporter\Källdata\"
' Rensa tidigare import
Set wsImport = ThisWorkbook.Worksheets("Import")
wsImport.Cells.Clear
' Importera försäljning
Set wbKälla = Workbooks.Open(källSökväg & "Försäljning.xlsx", ReadOnly:=True)
Set wsKälla = wbKälla.Worksheets("Data")
sistaRad = wsKälla.Cells(wsKälla.Rows.Count, "A").End(xlUp).Row
' Kopiera rubriker och data till kolumn A-D
wsKälla.Range("A1:D" & sistaRad).Copy wsImport.Range("A1")
wbKälla.Close SaveChanges:=False
' Importera kostnader
Set wbKälla = Workbooks.Open(källSökväg & "Kostnader.xlsx", ReadOnly:=True)
Set wsKälla = wbKälla.Worksheets("Data")
sistaRad = wsKälla.Cells(wsKälla.Rows.Count, "A").End(xlUp).Row
' Kopiera till kolumn F-H (lämnar E tom som separator)
wsKälla.Range("A1:C" & sistaRad).Copy wsImport.Range("F1")
wbKälla.Close SaveChanges:=False
' Importera budget
Set wbKälla = Workbooks.Open(källSökväg & "Budget.xlsx", ReadOnly:=True)
Set wsKälla = wbKälla.Worksheets("Data")
sistaRad = wsKälla.Cells(wsKälla.Rows.Count, "A").End(xlUp).Row
' Kopiera till kolumn J-L
wsKälla.Range("A1:C" & sistaRad).Copy wsImport.Range("J1")
wbKälla.Close SaveChanges:=False
MsgBox "Import klar!", vbInformation
End Sub
Vad händer här?
- Öppnar varje källfil i ReadOnly-läge (förhindrar att de ändras av misstag)
- Kopierar all data till Import-bladet
- Stänger källfilen utan att spara
- Upprepar för varje källfil
Tips: Lägg Application.ScreenUpdating = False i början och = True i slutet för att göra det snabbare.
Steg 2: Beräkna nyckeltal
Nu när all data finns i Import-bladet kan vi beräkna nyckeltal.
Koden för beräkningar
Sub BeräknaNyckeltal()
Dim wsImport As Worksheet
Dim wsBeräkning As Worksheet
Dim sistaRadFörsäljning As Long
Dim sistaRadKostnad As Long
Dim totFörsäljning As Double
Dim totKostnad As Double
Dim aktuellMånad As String
Set wsImport = ThisWorkbook.Worksheets("Import")
Set wsBeräkning = ThisWorkbook.Worksheets("Beräkningar")
wsBeräkning.Cells.Clear
' Aktuell månad för filtrering
aktuellMånad = Format(Date, "yyyy-mm")
' Hitta sista raderna
sistaRadFörsäljning = wsImport.Cells(wsImport.Rows.Count, "A").End(xlUp).Row
sistaRadKostnad = wsImport.Cells(wsImport.Rows.Count, "F").End(xlUp).Row
' Summera försäljning för aktuell månad
Dim i As Long
totFörsäljning = 0
For i = 2 To sistaRadFörsäljning
If Format(wsImport.Cells(i, 1).Value, "yyyy-mm") = aktuellMånad Then
totFörsäljning = totFörsäljning + wsImport.Cells(i, 4).Value
End If
Next i
' Summera kostnader för aktuell månad
totKostnad = 0
For i = 2 To sistaRadKostnad
If Format(wsImport.Cells(i, 6).Value, "yyyy-mm") = aktuellMånad Then
totKostnad = totKostnad + wsImport.Cells(i, 8).Value
End If
Next i
' Skriv resultat till Beräkningar-bladet
wsBeräkning.Range("A1").Value = "Nyckeltal"
wsBeräkning.Range("A2").Value = "Försäljning"
wsBeräkning.Range("B2").Value = totFörsäljning
wsBeräkning.Range("B2").NumberFormat = "#,##0"
wsBeräkning.Range("A3").Value = "Kostnader"
wsBeräkning.Range("B3").Value = totKostnad
wsBeräkning.Range("B3").NumberFormat = "#,##0"
wsBeräkning.Range("A4").Value = "Resultat"
wsBeräkning.Range("B4").Formula = "=B2-B3"
wsBeräkning.Range("B4").NumberFormat = "#,##0"
wsBeräkning.Range("A5").Value = "Marginal %"
wsBeräkning.Range("B5").Formula = "=B4/B2"
wsBeräkning.Range("B5").NumberFormat = "0.0%"
MsgBox "Beräkningar klara!", vbInformation
End Sub
Förklaring
- Filtrerar data för aktuell månad (baserat på dagens datum)
- Summerar försäljning och kostnader
- Beräknar resultat och marginal
- Skriver allt till Beräkningar-bladet
I en verklig situation skulle du ha fler nyckeltal, kanske fördelat per produkt, region, säljare, etc. Principen är densamma.
Steg 3: Skapa formaterad rapport
Nu tar vi värdena från Beräkningar-bladet och skapar en snygg rapport.
Koden för rapportgenerering
Sub GenereraRapport()
Dim wsBeräkning As Worksheet
Dim wsRapport As Worksheet
Set wsBeräkning = ThisWorkbook.Worksheets("Beräkningar")
Set wsRapport = ThisWorkbook.Worksheets("Rapport")
' Rensa gammal rapport
wsRapport.Cells.Clear
' Rubrik
wsRapport.Range("A1").Value = "MÅNADSRAPPORT"
wsRapport.Range("A1").Font.Size = 18
wsRapport.Range("A1").Font.Bold = True
wsRapport.Range("A2").Value = "Period: " & Format(Date, "mmmm yyyy")
wsRapport.Range("A2").Font.Italic = True
' Nyckeltal
wsRapport.Range("A4").Value = "RESULTATÖVERSIKT"
wsRapport.Range("A4").Font.Bold = True
wsRapport.Range("A4").Font.Size = 12
' Kopiera nyckeltal från Beräkningar
wsBeräkning.Range("A2:B5").Copy wsRapport.Range("A6")
' Formatera tabellen
With wsRapport.Range("A6:B9")
.Borders.LineStyle = xlContinuous
.Columns(2).HorizontalAlignment = xlRight
End With
' Gör rubrikerna feta
wsRapport.Range("A6:A9").Font.Bold = True
' Färgkoda resultatet
If wsRapport.Range("B9").Value > 0 Then
wsRapport.Range("B9").Interior.Color = RGB(198, 239, 206) ' Grönt för positivt
Else
wsRapport.Range("B9").Interior.Color = RGB(255, 199, 206) ' Rött för negativt
End If
' Anpassa kolumnbredder
wsRapport.Columns("A:B").AutoFit
' Lägg till genererad-tid
wsRapport.Range("A15").Value = "Rapport genererad: " & Format(Now, "yyyy-mm-dd hh:mm")
wsRapport.Range("A15").Font.Size = 8
wsRapport.Range("A15").Font.Italic = True
MsgBox "Rapport genererad!", vbInformation
End Sub
Resultat
Du får nu en snygg rapport med: – Tydlig rubrik – Aktuell period – Nyckeltal i formaterad tabell – Färgkodning av resultat – Tidsstämpel
Steg 4: Lägg till graf
En graf gör rapporten mer visuell och lättare att ta in.
Koden för graf
Sub SkapaGraf()
Dim wsRapport As Worksheet
Dim grafObjekt As ChartObject
Set wsRapport = ThisWorkbook.Worksheets("Rapport")
' Ta bort eventuell tidigare graf
Dim obj As ChartObject
For Each obj In wsRapport.ChartObjects
obj.Delete
Next obj
' Skapa ny graf
Set grafObjekt = wsRapport.ChartObjects.Add(Left:=300, Top:=100, Width:=400, Height:=250)
With grafObjekt.Chart
.ChartType = xlColumnClustered
' Data för grafen (Försäljning och Kostnader)
.SetSourceData Source:=wsRapport.Range("A6:B8")
.HasTitle = True
.ChartTitle.Text = "Försäljning vs Kostnader"
.HasLegend = False
' Formatera axlar
.Axes(xlValue).HasTitle = True
.Axes(xlValue).AxisTitle.Text = "Belopp (kr)"
End With
MsgBox "Graf skapad!", vbInformation
End Sub
Anpassning
Du kan ändra graftyp: – xlColumnClustered – Stapeldiagram – xlLine – Linjediagram – xlPie – Cirkeldiagram – xlArea – Ytdiagram
Steg 5: Sammanställ till ett komplett makro
Nu kombinerar vi alla steg till ett enda huvudmakro.
Huvudmakrot
Sub GenereraMånadsrapport()
On Error GoTo FelHantering
' Stäng av skärmuppdatering för hastighet
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
' Kör alla steg i ordning
Call ImporteraData
Call BeräknaNyckeltal
Call GenereraRapport
Call SkapaGraf
' Spara rapporten med datumstämplat filnamn
Dim rapportNamn As String
rapportNamn = "Månadsrapport_" & Format(Date, "yyyy-mm-dd") & ".xlsx"
ThisWorkbook.Worksheets("Rapport").Copy
ActiveWorkbook.SaveAs Filename:=ThisWorkbook.Path & "\Genererade rapporter\" & rapportNamn
ActiveWorkbook.Close SaveChanges:=False
' Slå på skärmuppdatering igen
Application.ScreenUpdating = True
Application.Calculation = xlCalculationAutomatic
MsgBox "Komplett rapport genererad och sparad som:" & vbCrLf & rapportNamn, vbInformation
Exit Sub
FelHantering:
Application.ScreenUpdating = True
Application.Calculation = xlCalculationAutomatic
MsgBox "Ett fel uppstod: " & Err.Description, vbCritical
End Sub
Vad händer här?
- Stänger av skärmuppdatering för snabbare körning
- Kör alla delsteg i ordning
- Kopierar Rapport-bladet till ny arbetsbok
- Sparar med datumstämplat filnamn
- Stänger den nya arbetsboken
- Återställer Excel-inställningar
- Felhantering för att fånga eventuella problem
Steg 6: Gör det användarvänligt
Lägg till en knapp så användare enkelt kan köra rapporten.
Skapa körknapp
Steg 1: Gå till Rapport-bladet
Steg 2: Developer > Insert > Button (Form Control)
Steg 3: Rita knappen där du vill ha den
Steg 4: Välj “GenereraMånadsrapport” i dialogrutan
Steg 5: Högerklicka på knappen > Edit Text
Steg 6: Skriv “GENERERA RAPPORT”
Steg 7: Formatera knappen (högerklicka > Format Control för färg och storlek)
Nu kan vem som helst klicka på knappen och få en komplett rapport på sekunder.
Bonusfunktion: Skicka via mail
Om du vill skicka rapporten automatiskt via mail lägg till detta:
Koden för mailutskick
Sub SkickaRapportMail()
Dim OutlookApp As Object
Dim Mail As Object
Dim rapportFilNamn As String
' Senast genererade rapporten
rapportFilNamn = ThisWorkbook.Path & "\Genererade rapporter\Månadsrapport_" & _
Format(Date, "yyyy-mm-dd") & ".xlsx"
' Kontrollera att filen finns
If Dir(rapportFilNamn) = "" Then
MsgBox "Ingen rapport hittades. Generera rapporten först.", vbExclamation
Exit Sub
End If
' Skapa mail
Set OutlookApp = CreateObject("Outlook.Application")
Set Mail = OutlookApp.CreateItem(0)
With Mail
.To = "chef@företag.se"
.CC = "ekonomi@företag.se"
.Subject = "Månadsrapport " & Format(Date, "mmmm yyyy")
.Body = "Hej," & vbCrLf & vbCrLf & _
"Bifogat finner ni månadsrapporten för " & Format(Date, "mmmm yyyy") & "." & vbCrLf & vbCrLf & _
"Nyckeltal:" & vbCrLf & _
"- Försäljning: " & Format(ThisWorkbook.Worksheets("Beräkningar").Range("B2").Value, "#,##0") & " kr" & vbCrLf & _
"- Resultat: " & Format(ThisWorkbook.Worksheets("Beräkningar").Range("B4").Value, "#,##0") & " kr" & vbCrLf & vbCrLf & _
"Mvh," & vbCrLf & "Automatiserad rapportering"
.Attachments.Add rapportFilNamn
.Display ' Använd .Send för att skicka direkt utan att visa
End With
Set Mail = Nothing
Set OutlookApp = Nothing
End Sub
Lägg till ett anrop till Call SkickaRapportMail i huvudmakrot om du vill skicka automatiskt.
Tidsbesparingen
Manuell process: – Öppna källfiler: 5 min – Kopiera data: 10 min – Beräkna nyckeltal: 5 min – Formatera rapport: 15 min – Skapa graf: 5 min – Spara och skicka: 5 min – Totalt: 45 minuter
Automatiserad process: – Klicka på knapp: 10 sekunder – Vänta på körning: 30 sekunder – Kontrollera resultat: 2 minuter – Totalt: 3 minuter
Besparing per månad: 42 minuter Besparing per år: 8,4 timmar
Och det här är bara EN rapport. De flesta har flera.
Anpassning till dina rapporter
Systemet är byggt modulärt så du enkelt kan anpassa det:
Fler datakällor: Lägg till fler import-block i ImporteraData
Fler nyckeltal: Utöka BeräknaNyckeltal med dina specifika beräkningar
Annorlunda layout: Ändra GenereraRapport för din önskade struktur
Olika grafer: SkapaGraf kan anpassas till vilken visualisering som helst
Nästa steg
Du har nu ett fungerande rapporteringssystem. För att ta det vidare:
1. Lägg till felhantering Vad händer om en källfil saknas? Lägg till kontroller:
If Dir(källSökväg & "Försäljning.xlsx") = "" Then
MsgBox "Källfilen Försäljning.xlsx saknas!", vbCritical
Exit Sub
End If
2. Gör det flexibelt för olika perioder Låt användaren välja månad istället för att alltid använda aktuell månad.
3. Logga rapportkörningar Skriv till en logg varje gång en rapport genereras (vem, när, resultat).
4. Lägg till jämförelser Jämför mot föregående månad eller budget. Visa avvikelser.
5. Bygg en dashboard Istället för en enkel rapport, bygg en interaktiv dashboard med knappar för olika vyer.
Få professionell hjälp
Om du vill ha ett robust rapporteringssystem men inte har tid att bygga det själv hjälper vi gärna på Excel Department.
Vi bygger skräddarsydda rapporteringssystem som: – Hanterar komplexa datakällor (databaser, flera system, API:er) – Inkluderar avancerad felhantering och loggning – Har användarvänliga gränssnitt – Är dokumenterade och lätta att underhålla – Följer företagets säkerhetskrav
Läs mer om hur vi hjälpte en kund spara 20 timmar per vecka med automatiserad rapportering.
Boka en gratis konsultation så diskuterar vi dina rapporteringsbehov.
Eller lär dig bygga själv på vår VBA-kurs där vi går igenom rapporteringsautomation från grunden.
Skriven av Lukas Lilja, Excel Department. Vi har byggt automatiserade rapporteringssystem för företag från 10 till 10 000 anställda.