Invoice Generator

Generate professional invoices from worksheet data with automatic calculations, VAT handling, sequential numbering, and PDF export. Ideal for freelancers and small businesses.

2 views
Featured

Perfect For:

  • Freelance invoicing
  • Small business billing
  • Client payment tracking
  • VAT-compliant invoices
  • Batch invoice generation
VBA Code
' Invoice Generator
' Sheet structure: Invoice sheet with client details, line items, and totals
' Requires a "Clients" sheet with columns: ClientID (A), Name (B), Address (C), Email (D)
' Requires a "Settings" sheet with: CompanyName (B1), Address (B2), VAT Rate (B3), Invoice Prefix (B4)

Sub GenerateInvoice()
    ' Create a new invoice from line item data
    On Error GoTo ErrorHandler

    Application.ScreenUpdating = False

    Dim wsInvoice As Worksheet
    Dim wsSettings As Worksheet

    Set wsInvoice = ThisWorkbook.Sheets("Invoice")
    Set wsSettings = ThisWorkbook.Sheets("Settings")

    ' Get settings
    Dim companyName As String
    Dim companyAddress As String
    Dim vatRate As Double
    Dim invoicePrefix As String

    companyName = wsSettings.Range("B1").Value
    companyAddress = wsSettings.Range("B2").Value
    vatRate = Val(wsSettings.Range("B3").Value) / 100
    invoicePrefix = wsSettings.Range("B4").Value

    If companyName = "" Then
        MsgBox "Please configure company details in the Settings sheet.", vbExclamation
        Exit Sub
    End If

    ' Generate invoice number
    Dim invoiceNumber As String
    Dim lastInvoiceNum As Long
    lastInvoiceNum = Val(wsSettings.Range("B5").Value)
    lastInvoiceNum = lastInvoiceNum + 1
    wsSettings.Range("B5").Value = lastInvoiceNum
    invoiceNumber = invoicePrefix & Format(lastInvoiceNum, "0000")

    ' Clear previous invoice content (rows 10 onwards)
    wsInvoice.Range("A10:F100").ClearContents
    wsInvoice.Range("A10:F100").ClearFormats

    ' Write invoice header
    wsInvoice.Range("A1").Value = companyName
    wsInvoice.Range("A1").Font.Size = 18
    wsInvoice.Range("A1").Font.Bold = True

    wsInvoice.Range("A2").Value = companyAddress

    wsInvoice.Range("D1").Value = "INVOICE"
    wsInvoice.Range("D1").Font.Size = 24
    wsInvoice.Range("D1").Font.Bold = True
    wsInvoice.Range("D1").Font.Color = RGB(0, 102, 204)

    wsInvoice.Range("D2").Value = "Invoice No:"
    wsInvoice.Range("E2").Value = invoiceNumber
    wsInvoice.Range("E2").Font.Bold = True

    wsInvoice.Range("D3").Value = "Date:"
    wsInvoice.Range("E3").Value = Format(Date, "dd/mm/yyyy")

    wsInvoice.Range("D4").Value = "Due Date:"
    wsInvoice.Range("E4").Value = Format(DateAdd("d", 30, Date), "dd/mm/yyyy")

    ' Client details
    Dim clientName As String
    clientName = wsInvoice.Range("A5").Value
    If clientName = "" Then
        clientName = InputBox("Enter client name:", "Client Details")
        If clientName = "" Then Exit Sub
        wsInvoice.Range("A5").Value = clientName
    End If

    wsInvoice.Range("A4").Value = "Bill To:"
    wsInvoice.Range("A4").Font.Bold = True

    ' Look up client address
    Dim wsClients As Worksheet
    On Error Resume Next
    Set wsClients = ThisWorkbook.Sheets("Clients")
    On Error GoTo ErrorHandler

    If Not wsClients Is Nothing Then
        Dim clientRow As Long
        Dim lastClientRow As Long
        lastClientRow = wsClients.Cells(wsClients.Rows.Count, "B").End(xlUp).Row

        For clientRow = 2 To lastClientRow
            If wsClients.Cells(clientRow, 2).Value = clientName Then
                wsInvoice.Range("A6").Value = wsClients.Cells(clientRow, 3).Value
                wsInvoice.Range("A7").Value = wsClients.Cells(clientRow, 4).Value
                Exit For
            End If
        Next clientRow
    End If

    ' Line item headers
    Dim headerRow As Long
    headerRow = 10

    wsInvoice.Cells(headerRow, 1).Value = "Description"
    wsInvoice.Cells(headerRow, 2).Value = "Quantity"
    wsInvoice.Cells(headerRow, 3).Value = "Unit Price"
    wsInvoice.Cells(headerRow, 4).Value = "Amount"

    With wsInvoice.Range("A" & headerRow & ":D" & headerRow)
        .Font.Bold = True
        .Interior.Color = RGB(0, 102, 204)
        .Font.Color = RGB(255, 255, 255)
    End With

    ' Prompt for line items
    Dim itemRow As Long
    itemRow = headerRow + 1
    Dim subtotal As Double
    subtotal = 0

    Dim addMore As VbMsgBoxResult
    addMore = vbYes

    Do While addMore = vbYes
        Dim itemDesc As String
        Dim itemQty As Double
        Dim itemPrice As Double

        itemDesc = InputBox("Enter item description (or leave blank to finish):", "Line Item " & (itemRow - headerRow))
        If itemDesc = "" Then Exit Do

        itemQty = Val(InputBox("Enter quantity:", "Quantity", "1"))
        itemPrice = Val(InputBox("Enter unit price:", "Unit Price"))

        wsInvoice.Cells(itemRow, 1).Value = itemDesc
        wsInvoice.Cells(itemRow, 2).Value = itemQty
        wsInvoice.Cells(itemRow, 2).NumberFormat = "0"
        wsInvoice.Cells(itemRow, 3).Value = itemPrice
        wsInvoice.Cells(itemRow, 3).NumberFormat = "#,##0.00"
        wsInvoice.Cells(itemRow, 4).Value = itemQty * itemPrice
        wsInvoice.Cells(itemRow, 4).NumberFormat = "#,##0.00"

        ' Alternate row shading
        If (itemRow - headerRow) Mod 2 = 0 Then
            wsInvoice.Range("A" & itemRow & ":D" & itemRow).Interior.Color = RGB(240, 245, 250)
        End If

        subtotal = subtotal + (itemQty * itemPrice)
        itemRow = itemRow + 1

        addMore = MsgBox("Add another line item?", vbYesNo + vbQuestion)
    Loop

    ' Calculate totals
    Dim totalsRow As Long
    totalsRow = itemRow + 1

    Dim vatAmount As Double
    vatAmount = subtotal * vatRate

    Dim grandTotal As Double
    grandTotal = subtotal + vatAmount

    ' Write totals
    wsInvoice.Cells(totalsRow, 3).Value = "Subtotal:"
    wsInvoice.Cells(totalsRow, 3).Font.Bold = True
    wsInvoice.Cells(totalsRow, 4).Value = subtotal
    wsInvoice.Cells(totalsRow, 4).NumberFormat = "#,##0.00"

    wsInvoice.Cells(totalsRow + 1, 3).Value = "VAT (" & Format(vatRate * 100, "0") & "%):"
    wsInvoice.Cells(totalsRow + 1, 3).Font.Bold = True
    wsInvoice.Cells(totalsRow + 1, 4).Value = vatAmount
    wsInvoice.Cells(totalsRow + 1, 4).NumberFormat = "#,##0.00"

    wsInvoice.Cells(totalsRow + 2, 3).Value = "TOTAL:"
    wsInvoice.Cells(totalsRow + 2, 3).Font.Bold = True
    wsInvoice.Cells(totalsRow + 2, 3).Font.Size = 14
    wsInvoice.Cells(totalsRow + 2, 4).Value = grandTotal
    wsInvoice.Cells(totalsRow + 2, 4).NumberFormat = "#,##0.00"
    wsInvoice.Cells(totalsRow + 2, 4).Font.Bold = True
    wsInvoice.Cells(totalsRow + 2, 4).Font.Size = 14
    wsInvoice.Cells(totalsRow + 2, 4).Interior.Color = RGB(0, 102, 204)
    wsInvoice.Cells(totalsRow + 2, 4).Font.Color = RGB(255, 255, 255)

    ' Payment terms footer
    wsInvoice.Cells(totalsRow + 4, 1).Value = "Payment Terms: Net 30 days"
    wsInvoice.Cells(totalsRow + 5, 1).Value = "Thank you for your business!"
    wsInvoice.Cells(totalsRow + 5, 1).Font.Italic = True

    ' Auto-fit columns
    wsInvoice.Columns("A:E").AutoFit

    Application.ScreenUpdating = True

    MsgBox "Invoice " & invoiceNumber & " generated successfully!" & vbCrLf & _
           "Total: " & Format(grandTotal, "#,##0.00"), vbInformation

    Exit Sub

ErrorHandler:
    Application.ScreenUpdating = True
    MsgBox "Error generating invoice: " & Err.Description, vbCritical
End Sub

Sub ExportInvoiceToPDF()
    ' Export current invoice sheet to PDF
    On Error GoTo ErrorHandler

    Dim ws As Worksheet
    Set ws = ThisWorkbook.Sheets("Invoice")

    Dim invoiceNum As String
    invoiceNum = ws.Range("E2").Value

    If invoiceNum = "" Then
        MsgBox "No invoice found. Please generate an invoice first.", vbExclamation
        Exit Sub
    End If

    ' Set print area
    Dim lastRow As Long
    lastRow = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row + 2

    ws.PageSetup.PrintArea = "A1:E" & lastRow
    ws.PageSetup.Orientation = xlPortrait
    ws.PageSetup.FitToPagesWide = 1
    ws.PageSetup.FitToPagesTall = 1
    ws.PageSetup.TopMargin = Application.InchesToPoints(0.75)
    ws.PageSetup.BottomMargin = Application.InchesToPoints(0.75)

    ' Save as PDF
    Dim pdfPath As String
    pdfPath = ThisWorkbook.Path & "" & invoiceNum & ".pdf"

    ws.ExportAsFixedFormat Type:=xlTypePDF, _
        Filename:=pdfPath, _
        Quality:=xlQualityStandard, _
        IncludeDocProperties:=True, _
        IgnorePrintAreas:=False

    MsgBox "Invoice exported to PDF:" & vbCrLf & pdfPath, vbInformation

    ' Open PDF
    Shell "explorer.exe """ & pdfPath & """", vbNormalFocus

    Exit Sub

ErrorHandler:
    MsgBox "Error exporting PDF: " & Err.Description, vbCritical
End Sub

Related Topics

invoice billing VAT PDF financial

Need Custom VBA Solutions?

Our AI-powered VBA generator can create custom code tailored to your specific requirements in seconds.

3 free generations/month — unlimited with Pro

Related Templates

More VBA templates in the same category

Advanced

Dashboard Creator

Create interactive dashboards with charts and key metrics

View Template