{"id":1895,"date":"2021-10-01T10:50:17","date_gmt":"2021-10-01T10:50:17","guid":{"rendered":"https:\/\/www.exceldepartment.com\/?p=1895"},"modified":"2026-10-31T12:13:37","modified_gmt":"2026-10-31T12:13:37","slug":"automate-excel-reports-vba","status":"publish","type":"post","link":"https:\/\/www.exceldepartment.com\/en\/automate-excel-reports-vba\/","title":{"rendered":"Automate Excel reports: Step by step with VBA"},"content":{"rendered":"<div class=\"page-content container\">\n<p>It is 16:45 on a Friday afternoon. You open five different Excel files, copy data from each one, paste it into the report template, format the headings, add charts, check the totals. Two hours later you can finally send the week&#8217;s report.<\/p>\n<p>Next Friday you do exactly the same thing again. And the week after that. 104 hours a year on the same repetitive task.<\/p>\n<p>I helped a finance manager automate exactly this. Now the report takes 3 minutes to generate with the click of a button. The same report, the same quality, 117 times faster.<\/p>\n<p>In this guide we build a complete reporting system step by step. You get ready-made code and detailed explanations. When you are done you can adapt the system to your own reports.<\/p>\n<h2 id=\"vad-vi-ska-bygga\">What we are going to build<\/h2>\n<p>An automated reporting system that: 1. Imports data from several source files 2. Compiles and calculates key figures 3. Creates a formatted report with a standard layout 4. Generates charts automatically 5. Saves the report with a date-stamped file name 6. Sends the report by email (optional)<\/p>\n<p>All of this with a single press of a button.<\/p>\n<h2 id=\"f\u00f6rberedelser\">Preparation<\/h2>\n<h3 id=\"filstruktur\">File structure<\/h3>\n<\/p>\n<p>Create the following folder structure:<\/p>\n<pre><code>C:\\Rapporter\\\n\u251c\u2500\u2500 K\u00e4lldata\\\n\u2502   \u251c\u2500\u2500 F\u00f6rs\u00e4ljning.xlsx\n\u2502   \u251c\u2500\u2500 Kostnader.xlsx\n\u2502   \u2514\u2500\u2500 Budget.xlsx\n\u251c\u2500\u2500 Rapportmall.xlsm\n\u2514\u2500\u2500 Genererade rapporter\\<\/code><\/pre>\n<p><strong>Rapportmall.xlsm<\/strong> is the file where we put all the VBA code. The generated reports end up in the subfolder.<\/p>\n<h3 id=\"k\u00e4llfilernas-struktur\">Structure of the source files<\/h3>\n<p>Each source file needs to have its data in a predictable structure:<\/p>\n<p><strong>F\u00f6rs\u00e4ljning.xlsx, sheet \u201cData\u201d:<\/strong><\/p>\n<pre><code>Rad 1: Datum | Produkt | Antal | Belopp\nRad 2+: 2026-01-15 | Produkt A | 10 | 15000<\/code><\/pre>\n<p><strong>Kostnader.xlsx, sheet \u201cData\u201d:<\/strong><\/p>\n<pre><code>Rad 1: Datum | Kategori | Belopp\nRad 2+: 2026-01-15 | Personal | 125000<\/code><\/pre>\n<p><strong>Budget.xlsx, sheet \u201cData\u201d:<\/strong><\/p>\n<pre><code>Rad 1: M\u00e5nad | F\u00f6rs\u00e4ljning Budget | Kostnad Budget\nRad 2+: 2026-01 | 500000 | 350000<\/code><\/pre>\n<p>Adapt it to your actual data structure \u2013 the principles are the same.<\/p>\n<h3 id=\"rapportmallens-uppbyggnad\">Structure of the report template<\/h3>\n<p>Rapportmall.xlsm consists of three sheets:<\/p>\n<p><strong>1. \u201cImport\u201d<\/strong> \u2013 The raw data is imported here (hidden from end users)<\/p>\n<p><strong>2. \u201cBer\u00e4kningar\u201d<\/strong> \u2013 All calculations and key figures are made here (hidden)<\/p>\n<p><strong>3. \u201cRapport\u201d<\/strong> \u2013 The formatted report that becomes visible<\/p>\n<h2 id=\"steg-1-importera-data-fr\u00e5n-k\u00e4llfiler\">Step 1: Import data from source files<\/h2>\n<p>We start by fetching data from the three source files.<\/p>\n<h3 id=\"koden-f\u00f6r-import\">The code for the import<\/h3>\n<pre class=\"vba\"><code>Sub ImporteraData()\n    Dim wbK\u00e4lla As Workbook\n    Dim wsK\u00e4lla As Worksheet\n    Dim wsImport As Worksheet\n    Dim sistaRad As Long\n    Dim k\u00e4llS\u00f6kv\u00e4g As String\n\n    k\u00e4llS\u00f6kv\u00e4g = &quot;C:\\Rapporter\\K\u00e4lldata\\&quot;\n\n    &#39; Rensa tidigare import\n    Set wsImport = ThisWorkbook.Worksheets(&quot;Import&quot;)\n    wsImport.Cells.Clear\n\n    &#39; Importera f\u00f6rs\u00e4ljning\n    Set wbK\u00e4lla = Workbooks.Open(k\u00e4llS\u00f6kv\u00e4g &amp; &quot;F\u00f6rs\u00e4ljning.xlsx&quot;, ReadOnly:=True)\n    Set wsK\u00e4lla = wbK\u00e4lla.Worksheets(&quot;Data&quot;)\n\n    sistaRad = wsK\u00e4lla.Cells(wsK\u00e4lla.Rows.Count, &quot;A&quot;).End(xlUp).Row\n\n    &#39; Kopiera rubriker och data till kolumn A-D\n    wsK\u00e4lla.Range(&quot;A1:D&quot; &amp; sistaRad).Copy wsImport.Range(&quot;A1&quot;)\n\n    wbK\u00e4lla.Close SaveChanges:=False\n\n    &#39; Importera kostnader\n    Set wbK\u00e4lla = Workbooks.Open(k\u00e4llS\u00f6kv\u00e4g &amp; &quot;Kostnader.xlsx&quot;, ReadOnly:=True)\n    Set wsK\u00e4lla = wbK\u00e4lla.Worksheets(&quot;Data&quot;)\n\n    sistaRad = wsK\u00e4lla.Cells(wsK\u00e4lla.Rows.Count, &quot;A&quot;).End(xlUp).Row\n\n    &#39; Kopiera till kolumn F-H (l\u00e4mnar E tom som separator)\n    wsK\u00e4lla.Range(&quot;A1:C&quot; &amp; sistaRad).Copy wsImport.Range(&quot;F1&quot;)\n\n    wbK\u00e4lla.Close SaveChanges:=False\n\n    &#39; Importera budget\n    Set wbK\u00e4lla = Workbooks.Open(k\u00e4llS\u00f6kv\u00e4g &amp; &quot;Budget.xlsx&quot;, ReadOnly:=True)\n    Set wsK\u00e4lla = wbK\u00e4lla.Worksheets(&quot;Data&quot;)\n\n    sistaRad = wsK\u00e4lla.Cells(wsK\u00e4lla.Rows.Count, &quot;A&quot;).End(xlUp).Row\n\n    &#39; Kopiera till kolumn J-L\n    wsK\u00e4lla.Range(&quot;A1:C&quot; &amp; sistaRad).Copy wsImport.Range(&quot;J1&quot;)\n\n    wbK\u00e4lla.Close SaveChanges:=False\n\n    MsgBox &quot;Import klar!&quot;, vbInformation\nEnd Sub<\/code><\/pre>\n<h3 id=\"vad-h\u00e4nder-h\u00e4r\">What happens here?<\/h3>\n<ul>\n<li>Opens each source file in ReadOnly mode (prevents them from being changed by mistake)<\/li>\n<li>Copies all the data to the Import sheet<\/li>\n<li>Closes the source file without saving<\/li>\n<li>Repeats for each source file<\/li>\n<\/ul>\n<p><strong>Tip:<\/strong> Put <code>Application.ScreenUpdating = False<\/code> at the beginning and <code>= True<\/code> at the end to make it faster.<\/p>\n<h2 id=\"steg-2-ber\u00e4kna-nyckeltal\">Step 2: Calculate key figures<\/h2>\n<p>Now that all the data is in the Import sheet, we can calculate key figures.<\/p>\n<h3 id=\"koden-f\u00f6r-ber\u00e4kningar\">The code for the calculations<\/h3>\n<pre class=\"vba\"><code>Sub Ber\u00e4knaNyckeltal()\n    Dim wsImport As Worksheet\n    Dim wsBer\u00e4kning As Worksheet\n    Dim sistaRadF\u00f6rs\u00e4ljning As Long\n    Dim sistaRadKostnad As Long\n    Dim totF\u00f6rs\u00e4ljning As Double\n    Dim totKostnad As Double\n    Dim aktuellM\u00e5nad As String\n\n    Set wsImport = ThisWorkbook.Worksheets(&quot;Import&quot;)\n    Set wsBer\u00e4kning = ThisWorkbook.Worksheets(&quot;Ber\u00e4kningar&quot;)\n\n    wsBer\u00e4kning.Cells.Clear\n\n    &#39; Aktuell m\u00e5nad f\u00f6r filtrering\n    aktuellM\u00e5nad = Format(Date, &quot;yyyy-mm&quot;)\n\n    &#39; Hitta sista raderna\n    sistaRadF\u00f6rs\u00e4ljning = wsImport.Cells(wsImport.Rows.Count, &quot;A&quot;).End(xlUp).Row\n    sistaRadKostnad = wsImport.Cells(wsImport.Rows.Count, &quot;F&quot;).End(xlUp).Row\n\n    &#39; Summera f\u00f6rs\u00e4ljning f\u00f6r aktuell m\u00e5nad\n    Dim i As Long\n    totF\u00f6rs\u00e4ljning = 0\n\n    For i = 2 To sistaRadF\u00f6rs\u00e4ljning\n        If Format(wsImport.Cells(i, 1).Value, &quot;yyyy-mm&quot;) = aktuellM\u00e5nad Then\n            totF\u00f6rs\u00e4ljning = totF\u00f6rs\u00e4ljning + wsImport.Cells(i, 4).Value\n        End If\n    Next i\n\n    &#39; Summera kostnader f\u00f6r aktuell m\u00e5nad\n    totKostnad = 0\n\n    For i = 2 To sistaRadKostnad\n        If Format(wsImport.Cells(i, 6).Value, &quot;yyyy-mm&quot;) = aktuellM\u00e5nad Then\n            totKostnad = totKostnad + wsImport.Cells(i, 8).Value\n        End If\n    Next i\n\n    &#39; Skriv resultat till Ber\u00e4kningar-bladet\n    wsBer\u00e4kning.Range(&quot;A1&quot;).Value = &quot;Nyckeltal&quot;\n    wsBer\u00e4kning.Range(&quot;A2&quot;).Value = &quot;F\u00f6rs\u00e4ljning&quot;\n    wsBer\u00e4kning.Range(&quot;B2&quot;).Value = totF\u00f6rs\u00e4ljning\n    wsBer\u00e4kning.Range(&quot;B2&quot;).NumberFormat = &quot;#,##0&quot;\n\n    wsBer\u00e4kning.Range(&quot;A3&quot;).Value = &quot;Kostnader&quot;\n    wsBer\u00e4kning.Range(&quot;B3&quot;).Value = totKostnad\n    wsBer\u00e4kning.Range(&quot;B3&quot;).NumberFormat = &quot;#,##0&quot;\n\n    wsBer\u00e4kning.Range(&quot;A4&quot;).Value = &quot;Resultat&quot;\n    wsBer\u00e4kning.Range(&quot;B4&quot;).Formula = &quot;=B2-B3&quot;\n    wsBer\u00e4kning.Range(&quot;B4&quot;).NumberFormat = &quot;#,##0&quot;\n\n    wsBer\u00e4kning.Range(&quot;A5&quot;).Value = &quot;Marginal %&quot;\n    wsBer\u00e4kning.Range(&quot;B5&quot;).Formula = &quot;=B4\/B2&quot;\n    wsBer\u00e4kning.Range(&quot;B5&quot;).NumberFormat = &quot;0.0%&quot;\n\n    MsgBox &quot;Ber\u00e4kningar klara!&quot;, vbInformation\nEnd Sub<\/code><\/pre>\n<h3 id=\"f\u00f6rklaring\">Explanation<\/h3>\n<ul>\n<li>Filters data for the current month (based on today&#8217;s date)<\/li>\n<li>Sums sales and costs<\/li>\n<li>Calculates profit and margin<\/li>\n<li>Writes everything to the Ber\u00e4kningar sheet<\/li>\n<\/ul>\n<p>In a real situation you would have more key figures, perhaps broken down by product, region, salesperson, etc. The principle is the same.<\/p>\n<h2 id=\"steg-3-skapa-formaterad-rapport\">Step 3: Create a formatted report<\/h2>\n<p>Now we take the values from the Ber\u00e4kningar sheet and create a neat report.<\/p>\n<h3 id=\"koden-f\u00f6r-rapportgenerering\">The code for report generation<\/h3>\n<pre class=\"vba\"><code>Sub GenereraRapport()\n    Dim wsBer\u00e4kning As Worksheet\n    Dim wsRapport As Worksheet\n\n    Set wsBer\u00e4kning = ThisWorkbook.Worksheets(&quot;Ber\u00e4kningar&quot;)\n    Set wsRapport = ThisWorkbook.Worksheets(&quot;Rapport&quot;)\n\n    &#39; Rensa gammal rapport\n    wsRapport.Cells.Clear\n\n    &#39; Rubrik\n    wsRapport.Range(&quot;A1&quot;).Value = &quot;M\u00c5NADSRAPPORT&quot;\n    wsRapport.Range(&quot;A1&quot;).Font.Size = 18\n    wsRapport.Range(&quot;A1&quot;).Font.Bold = True\n\n    wsRapport.Range(&quot;A2&quot;).Value = &quot;Period: &quot; &amp; Format(Date, &quot;mmmm yyyy&quot;)\n    wsRapport.Range(&quot;A2&quot;).Font.Italic = True\n\n    &#39; Nyckeltal\n    wsRapport.Range(&quot;A4&quot;).Value = &quot;RESULTAT\u00d6VERSIKT&quot;\n    wsRapport.Range(&quot;A4&quot;).Font.Bold = True\n    wsRapport.Range(&quot;A4&quot;).Font.Size = 12\n\n    &#39; Kopiera nyckeltal fr\u00e5n Ber\u00e4kningar\n    wsBer\u00e4kning.Range(&quot;A2:B5&quot;).Copy wsRapport.Range(&quot;A6&quot;)\n\n    &#39; Formatera tabellen\n    With wsRapport.Range(&quot;A6:B9&quot;)\n        .Borders.LineStyle = xlContinuous\n        .Columns(2).HorizontalAlignment = xlRight\n    End With\n\n    &#39; G\u00f6r rubrikerna feta\n    wsRapport.Range(&quot;A6:A9&quot;).Font.Bold = True\n\n    &#39; F\u00e4rgkoda resultatet\n    If wsRapport.Range(&quot;B9&quot;).Value &gt; 0 Then\n        wsRapport.Range(&quot;B9&quot;).Interior.Color = RGB(198, 239, 206)  &#39; Gr\u00f6nt f\u00f6r positivt\n    Else\n        wsRapport.Range(&quot;B9&quot;).Interior.Color = RGB(255, 199, 206)  &#39; R\u00f6tt f\u00f6r negativt\n    End If\n\n    &#39; Anpassa kolumnbredder\n    wsRapport.Columns(&quot;A:B&quot;).AutoFit\n\n    &#39; L\u00e4gg till genererad-tid\n    wsRapport.Range(&quot;A15&quot;).Value = &quot;Rapport genererad: &quot; &amp; Format(Now, &quot;yyyy-mm-dd hh:mm&quot;)\n    wsRapport.Range(&quot;A15&quot;).Font.Size = 8\n    wsRapport.Range(&quot;A15&quot;).Font.Italic = True\n\n    MsgBox &quot;Rapport genererad!&quot;, vbInformation\nEnd Sub<\/code><\/pre>\n<h3 id=\"resultat\">Result<\/h3>\n<p>You now get a neat report with: &#8211; A clear heading &#8211; The current period &#8211; Key figures in a formatted table &#8211; Colour coding of results &#8211; Timestamp<\/p>\n<h2 id=\"steg-4-l\u00e4gg-till-graf\">Step 4: Add a chart<\/h2>\n<p>A chart makes the report more visual and easier to take in.<\/p>\n<h3 id=\"koden-f\u00f6r-graf\">The code for the chart<\/h3>\n<pre class=\"vba\"><code>Sub SkapaGraf()\n    Dim wsRapport As Worksheet\n    Dim grafObjekt As ChartObject\n\n    Set wsRapport = ThisWorkbook.Worksheets(&quot;Rapport&quot;)\n\n    &#39; Ta bort eventuell tidigare graf\n    Dim obj As ChartObject\n    For Each obj In wsRapport.ChartObjects\n        obj.Delete\n    Next obj\n\n    &#39; Skapa ny graf\n    Set grafObjekt = wsRapport.ChartObjects.Add(Left:=300, Top:=100, Width:=400, Height:=250)\n\n    With grafObjekt.Chart\n        .ChartType = xlColumnClustered\n\n        &#39; Data f\u00f6r grafen (F\u00f6rs\u00e4ljning och Kostnader)\n        .SetSourceData Source:=wsRapport.Range(&quot;A6:B8&quot;)\n\n        .HasTitle = True\n        .ChartTitle.Text = &quot;F\u00f6rs\u00e4ljning vs Kostnader&quot;\n\n        .HasLegend = False\n\n        &#39; Formatera axlar\n        .Axes(xlValue).HasTitle = True\n        .Axes(xlValue).AxisTitle.Text = &quot;Belopp (kr)&quot;\n    End With\n\n    MsgBox &quot;Graf skapad!&quot;, vbInformation\nEnd Sub<\/code><\/pre>\n<h3 id=\"anpassning\">Customisation<\/h3>\n<p>You can change the chart type: &#8211; <code>xlColumnClustered<\/code> \u2013 Column chart &#8211; <code>xlLine<\/code> \u2013 Line chart &#8211; <code>xlPie<\/code> \u2013 Pie chart &#8211; <code>xlArea<\/code> \u2013 Area chart<\/p>\n<h2 id=\"steg-5-sammanst\u00e4ll-till-ett-komplett-makro\">Step 5: Combine into one complete macro<\/h2>\n<p>Now we combine all the steps into a single main macro.<\/p>\n<h3 id=\"huvudmakrot\">The main macro<\/h3>\n<pre class=\"vba\"><code>Sub GenereraM\u00e5nadsrapport()\n    On Error GoTo FelHantering\n\n    &#39; St\u00e4ng av sk\u00e4rmuppdatering f\u00f6r hastighet\n    Application.ScreenUpdating = False\n    Application.Calculation = xlCalculationManual\n\n    &#39; K\u00f6r alla steg i ordning\n    Call ImporteraData\n    Call Ber\u00e4knaNyckeltal\n    Call GenereraRapport\n    Call SkapaGraf\n\n    &#39; Spara rapporten med datumst\u00e4mplat filnamn\n    Dim rapportNamn As String\n    rapportNamn = &quot;M\u00e5nadsrapport_&quot; &amp; Format(Date, &quot;yyyy-mm-dd&quot;) &amp; &quot;.xlsx&quot;\n\n    ThisWorkbook.Worksheets(&quot;Rapport&quot;).Copy\n    ActiveWorkbook.SaveAs Filename:=ThisWorkbook.Path &amp; &quot;\\Genererade rapporter\\&quot; &amp; rapportNamn\n    ActiveWorkbook.Close SaveChanges:=False\n\n    &#39; Sl\u00e5 p\u00e5 sk\u00e4rmuppdatering igen\n    Application.ScreenUpdating = True\n    Application.Calculation = xlCalculationAutomatic\n\n    MsgBox &quot;Komplett rapport genererad och sparad som:&quot; &amp; vbCrLf &amp; rapportNamn, vbInformation\n\n    Exit Sub\n\nFelHantering:\n    Application.ScreenUpdating = True\n    Application.Calculation = xlCalculationAutomatic\n    MsgBox &quot;Ett fel uppstod: &quot; &amp; Err.Description, vbCritical\nEnd Sub<\/code><\/pre>\n<h3 id=\"vad-h\u00e4nder-h\u00e4r-1\">What happens here?<\/h3>\n<ol type=\"1\">\n<li>Turns off screen updating for faster execution<\/li>\n<li>Runs all the sub-steps in order<\/li>\n<li>Copies the Rapport sheet to a new workbook<\/li>\n<li>Saves with a date-stamped file name<\/li>\n<li>Closes the new workbook<\/li>\n<li>Restores the Excel settings<\/li>\n<li>Error handling to catch any problems<\/li>\n<\/ol>\n<h2 id=\"steg-6-g\u00f6r-det-anv\u00e4ndarv\u00e4nligt\">Step 6: Make it user-friendly<\/h2>\n<p>Add a button so users can easily run the report.<\/p>\n<h3 id=\"skapa-k\u00f6rknapp\">Create a run button<\/h3>\n<p><strong>Step 1:<\/strong> Go to the Rapport sheet<\/p>\n<p><strong>Step 2:<\/strong> Developer &gt; Insert &gt; Button (Form Control)<\/p>\n<p><strong>Step 3:<\/strong> Draw the button where you want it<\/p>\n<p><strong>Step 4:<\/strong> Select \u201cGenereraM\u00e5nadsrapport\u201d in the dialog box<\/p>\n<p><strong>Step 5:<\/strong> Right-click the button &gt; Edit Text<\/p>\n<p><strong>Step 6:<\/strong> Type \u201cGENERATE REPORT\u201d<\/p>\n<p><strong>Step 7:<\/strong> Format the button (right-click &gt; Format Control for colour and size)<\/p>\n<p>Now anyone can click the button and get a complete report in seconds.<\/p>\n<h2 id=\"bonusfunktion-skicka-via-mail\">Bonus feature: Send by email<\/h2>\n<p>If you want to send the report automatically by email, add this:<\/p>\n<h3 id=\"koden-f\u00f6r-mailutskick\">The code for sending email<\/h3>\n<pre class=\"vba\"><code>Sub SkickaRapportMail()\n    Dim OutlookApp As Object\n    Dim Mail As Object\n    Dim rapportFilNamn As String\n\n    &#39; Senast genererade rapporten\n    rapportFilNamn = ThisWorkbook.Path &amp; &quot;\\Genererade rapporter\\M\u00e5nadsrapport_&quot; &amp; _\n                     Format(Date, &quot;yyyy-mm-dd&quot;) &amp; &quot;.xlsx&quot;\n\n    &#39; Kontrollera att filen finns\n    If Dir(rapportFilNamn) = &quot;&quot; Then\n        MsgBox &quot;Ingen rapport hittades. Generera rapporten f\u00f6rst.&quot;, vbExclamation\n        Exit Sub\n    End If\n\n    &#39; Skapa mail\n    Set OutlookApp = CreateObject(&quot;Outlook.Application&quot;)\n    Set Mail = OutlookApp.CreateItem(0)\n\n    With Mail\n        .To = &quot;chef@f\u00f6retag.se&quot;\n        .CC = &quot;ekonomi@f\u00f6retag.se&quot;\n        .Subject = &quot;M\u00e5nadsrapport &quot; &amp; Format(Date, &quot;mmmm yyyy&quot;)\n        .Body = &quot;Hej,&quot; &amp; vbCrLf &amp; vbCrLf &amp; _\n                &quot;Bifogat finner ni m\u00e5nadsrapporten f\u00f6r &quot; &amp; Format(Date, &quot;mmmm yyyy&quot;) &amp; &quot;.&quot; &amp; vbCrLf &amp; vbCrLf &amp; _\n                &quot;Nyckeltal:&quot; &amp; vbCrLf &amp; _\n                &quot;- F\u00f6rs\u00e4ljning: &quot; &amp; Format(ThisWorkbook.Worksheets(&quot;Ber\u00e4kningar&quot;).Range(&quot;B2&quot;).Value, &quot;#,##0&quot;) &amp; &quot; kr&quot; &amp; vbCrLf &amp; _\n                &quot;- Resultat: &quot; &amp; Format(ThisWorkbook.Worksheets(&quot;Ber\u00e4kningar&quot;).Range(&quot;B4&quot;).Value, &quot;#,##0&quot;) &amp; &quot; kr&quot; &amp; vbCrLf &amp; vbCrLf &amp; _\n                &quot;Mvh,&quot; &amp; vbCrLf &amp; &quot;Automatiserad rapportering&quot;\n\n        .Attachments.Add rapportFilNamn\n\n        .Display  &#39; Anv\u00e4nd .Send f\u00f6r att skicka direkt utan att visa\n    End With\n\n    Set Mail = Nothing\n    Set OutlookApp = Nothing\nEnd Sub<\/code><\/pre>\n<p>Add a call to <code>Call SkickaRapportMail<\/code> in the main macro if you want to send automatically.<\/p>\n<\/p>\n<h2 id=\"tidsbesparingen\">The time saved<\/h2>\n<p><strong>Manual process:<\/strong> &#8211; Open source files: 5 min &#8211; Copy data: 10 min &#8211; Calculate key figures: 5 min &#8211; Format report: 15 min &#8211; Create chart: 5 min &#8211; Save and send: 5 min &#8211; <strong>Total: 45 minutes<\/strong><\/p>\n<p><strong>Automated process:<\/strong> &#8211; Click the button: 10 seconds &#8211; Wait for the run: 30 seconds &#8211; Check the result: 2 minutes &#8211; <strong>Total: 3 minutes<\/strong><\/p>\n<p><strong>Saving per month:<\/strong> 42 minutes <strong>Saving per year:<\/strong> 8.4 hours<\/p>\n<p>And this is just ONE report. Most people have several.<\/p>\n<h2 id=\"anpassning-till-dina-rapporter\">Adapting it to your reports<\/h2>\n<p>The system is built modularly so you can easily adapt it:<\/p>\n<p><strong>More data sources:<\/strong> Add more import blocks in ImporteraData<\/p>\n<p><strong>More key figures:<\/strong> Extend Ber\u00e4knaNyckeltal with your specific calculations<\/p>\n<p><strong>A different layout:<\/strong> Change GenereraRapport to your desired structure<\/p>\n<p><strong>Different charts:<\/strong> SkapaGraf can be adapted to any visualisation<\/p>\n<h2 id=\"n\u00e4sta-steg\">Next steps<\/h2>\n<p>You now have a working reporting system. To take it further:<\/p>\n<p><strong>1. Add error handling<\/strong> What happens if a source file is missing? Add checks:<\/p>\n<pre class=\"vba\"><code>If Dir(k\u00e4llS\u00f6kv\u00e4g &amp; &quot;F\u00f6rs\u00e4ljning.xlsx&quot;) = &quot;&quot; Then\n    MsgBox &quot;K\u00e4llfilen F\u00f6rs\u00e4ljning.xlsx saknas!&quot;, vbCritical\n    Exit Sub\nEnd If<\/code><\/pre>\n<p><strong>2. Make it flexible for different periods<\/strong> Let the user choose the month instead of always using the current month.<\/p>\n<p><strong>3. Log report runs<\/strong> Write to a log every time a report is generated (who, when, result).<\/p>\n<p><strong>4. Add comparisons<\/strong> Compare against the previous month or the budget. Show variances.<\/p>\n<p><strong>5. Build a dashboard<\/strong> Instead of a simple report, build an interactive dashboard with buttons for different views.<\/p>\n<h2 id=\"f\u00e5-professionell-hj\u00e4lp\">Get professional help<\/h2>\n<p>If you want a robust reporting system but do not have time to build it yourself, we are happy to help at Excel Department.<\/p>\n<p>We build tailor-made reporting systems that: &#8211; Handle complex data sources (databases, multiple systems, APIs) &#8211; Include advanced error handling and logging &#8211; Have user-friendly interfaces &#8211; Are documented and easy to maintain &#8211; Follow the company&#8217;s security requirements<\/p>\n<p>Read more about how we helped a client <a href=\"https:\/\/www.exceldepartment.com\/en\/case-automated-reporting-saved-20-hours\/\">save 20 hours a week<\/a> with automated reporting.<\/p>\n<p><a href=\"https:\/\/www.exceldepartment.com\/en\/contact-us\/\">Book a free consultation<\/a> and we will discuss your reporting needs.<\/p>\n<p>Or learn to build it yourself on our <a href=\"https:\/\/www.exceldepartment.com\/en\/excel-course\/vba-basic-course\/\">VBA course<\/a>, where we go through reporting automation from the ground up.<\/p>\n<hr \/>\n<p><em>Written by Lukas Lilja, Excel Department. We have built automated reporting systems for companies with 10 to 10,000 employees.<\/em><\/p>\n<\/div>\n<div class=\"xld-cta\" style=\"margin:30px 0;padding:18px 20px;background:#f5f4f4;border-top:3px solid #a0ce4e\">\n<p style=\"margin:0 0 8px\"><strong>Do you need help with this?<\/strong> Our <a href=\"https:\/\/www.exceldepartment.com\/en\/excel-course\/vba-basic-course\/\">VBA course<\/a> helps you \u2013 the first consultation is free of charge.<\/p>\n<p style=\"margin:0\"><a href=\"https:\/\/www.exceldepartment.com\/en\/contact-us\/\">Book a free call<\/a> or call <a href=\"tel:+46102642020\">010-264 20 20<\/a>.<\/p>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>Learn to automate monthly Excel reports with VBA. A complete tutorial that saves you hours every month. Includes ready-made code and a step-by-step guide.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-1895","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/www.exceldepartment.com\/en\/wp-json\/wp\/v2\/posts\/1895","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.exceldepartment.com\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.exceldepartment.com\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.exceldepartment.com\/en\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.exceldepartment.com\/en\/wp-json\/wp\/v2\/comments?post=1895"}],"version-history":[{"count":0,"href":"https:\/\/www.exceldepartment.com\/en\/wp-json\/wp\/v2\/posts\/1895\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.exceldepartment.com\/en\/wp-json\/wp\/v2\/media?parent=1895"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.exceldepartment.com\/en\/wp-json\/wp\/v2\/categories?post=1895"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.exceldepartment.com\/en\/wp-json\/wp\/v2\/tags?post=1895"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}