9 Excel VBA Project Ideas for Finance Teams, With Class Module and Custom Ribbon Code

The best Excel VBA project ideas for finance teams are the jobs you already repeat every month: keying invoices, ticking off the close, checking journals, matching the bank, building the report pack. Here are nine, each with what it does, the VBA components it needs, how hard it is and what usually goes wrong.

Last checked: 16 September 2026. Code targets 64-bit Microsoft 365 Excel for Windows. We make HISAB 360, an AI add-in for Windows desktop Excel that can build projects like these, so it comes last. New to macros? Start with what a macro in Excel is.

Excel VBA project ideas at a glance

ProjectWhat it savesMain componentsDifficulty
1. Invoice register with an entry formTyping errors, duplicate invoicesUserForm, standard module, buttonBeginner to intermediate
2. Month-end close checklistChasing who has done whatSheet events, buttonsBeginner
3. Journal batch checkerUnbalanced or miscoded journalsStandard module, lookup tableIntermediate
4. Bank reconciliation matcherManual tickingStandard module, DictionaryIntermediate
5. Approval trackerLost requests and claimsClass module, sheet events, UserFormIntermediate
6. Aged debtors pack from an ERP exportReformatting the same exportStandard module, buttonIntermediate
7. Report pack generatorHours of printing to PDFStandard modules, custom ribbonIntermediate to advanced
8. Finance toolkit add-inRepeating clean-up steps in every fileCustom ribbon, .xlam add-inIntermediate to advanced
9. Save-time balance guardSaving a pack whose checks don't tieClass module with application events, .xlamAdvanced

What is a VBA project in Excel?

A VBA project is the container for all the code in one workbook or add-in. In the Visual Basic Editor (Alt+F11) it shows as VBAProject (FileName.xlsm) and holds four kinds of component plus your references.

ComponentWhat goes in itFinance example
Standard moduleSubs and Functions you run from buttons, the ribbon or other code; one shared copy of its variablesBuildReportPack
Class moduleYour own object type with properties and methods; create as many instances as you need with NewInvoiceLine
UserFormA dialog with controls and its own codeInvoice entry form
Document modulesEvent code for ThisWorkbook or one sheet, such as Worksheet_ChangeDate-stamp a finished checklist task

The file must be macro-enabled: Microsoft's security notes list .xlsm, .xltm and .xlam for Excel, and .xlsb also keeps macros. An .xlsx cannot hold VBA. You can lock the code on the Protection tab of Tools > VBAProject Properties (Microsoft's reference), but treat that password as a deterrent, not real security.

The 9 project ideas in detail

1. Invoice register with a data-entry UserForm

A form collects supplier, invoice number, date, net amount and VAT code, checks them and appends a row to an Excel Table.

Build it with: a UserForm (say frmInvoice with txtInvoiceNo, txtDate, txtNet, cboVatCode, btnSave), a standard module with ShowInvoiceForm and a sheet button. The InvoiceLine class below keeps validation in one place. See our Excel VBA UserForm guide, or how to create a data entry form in Excel for no-code options.

Watch out for: dates typed into a TextBox are text, converted using the PC's regional settings, so 03/04 can mean March or April. Use a fixed yyyy-mm-dd format, and reject a duplicate invoice number per supplier.

2. Month-end close checklist with sign-off buttons

Each task has an owner, a due day and a status. When the status changes, code stamps the date and user name, and a summary lists open tasks.

Build it with: Worksheet_Change in the sheet module, a standard module for the summary, and Form Control buttons (ActiveX controls are disabled by default in Microsoft 365 and Office 2024). Our month-end close checklist has the task list.

Watch out for: Application.UserName is whatever is typed in Excel's options, so the stamp is a convenience, not an audit trail. Switch Application.EnableEvents off while writing the stamp and back on in the error handler too, or the sheet silently stops responding.

3. Journal batch checker

A macro checks that each journal balances, account codes exist in the chart of accounts, dates fall in the open period and tax codes are filled, writing problems into a Status column.

Build it with: a standard module, a chart-of-accounts table and a button. The clean batch goes to your ledger's own import, as in importing journal entries into QuickBooks Online from Excel.

Watch out for: exact comparisons of Double totals. Hold amounts as Currency or round to two decimals before comparing.

4. Bank reconciliation matcher

The macro loads cash book lines into a Dictionary keyed by amount, then pairs bank lines with the same amount within a few days, leaving the rest for review.

Build it with: a standard module and CreateObject("Scripting.Dictionary"), which needs no reference and, per the author of Microsoft's September 2025 post, is unaffected by the VBScript deprecation. See our bank reconciliation template for the layout.

Watch out for: two payments of the same amount in one week, one receipt clearing several invoices, and opposite sign conventions. Flag those rather than auto-matching.

5. Approval tracker for purchase requests or expense claims

Requests are logged on a sheet. An ApprovalRequest class holds the rules (thresholds, who may approve), and the sheet module rejects invalid changes such as approving your own claim.

Build it with: a class module, Worksheet_Change in the sheet module and an optional UserForm for new requests. Keeping the rules in the class means a threshold changes in one place.

Watch out for: treating a shared workbook as a control. Anyone who can edit the file can edit the log, so sheet protection is a deterrent, not a control.

6. Aged debtors pack from an ERP export

You export open invoices as CSV, and one button buckets them by days overdue, subtotals by customer and saves a dated copy.

Build it with: a standard module and a button. If the import gets complicated, let Power Query load the CSV and keep VBA for formatting.

Watch out for: dates. Workbooks.Open uses VBA's language, typically US English, unless you pass Local:=True to use Excel's regional settings, which helps only on a PC set to UK dates (Microsoft's reference), so 03/04/2026 in a UK export can be read as 4 March. Find columns by header name, as layouts change.

7. Report pack generator with a custom ribbon

A Finance Tools ribbon tab recalculates, runs the balance checks, then exports the P&L, balance sheet and variance sheets to PDF with ExportAsFixedFormat into a folder named for the period.

Build it with: standard modules plus a customUI ribbon whose buttons call callback Subs (code below).

Watch out for: print areas and page setup, which shape the PDF. If you switch calculation to manual for speed, restore it in the error handler as well.

8. Finance toolkit add-in (.xlam)

Your own utilities on a ribbon tab in every workbook: flip signs, convert text-numbers to values, apply house number formats.

Build it with: standard modules, a custom ribbon and a final save as .xlam.

Watch out for: ThisWorkbook, which in an add-in means the add-in. Code that acts on the user's file must use ActiveWorkbook and check one exists. If you borrow Windows API code, every Declare needs PtrSafe and LongPtr handles in 64-bit Office, per Microsoft's 64-bit VBA overview.

9. Save-time balance guard

An add-in that warns when you save any workbook whose named check cell (say chk_TB) is not zero.

Build it with: a class module declaring Public WithEvents App As Application with an App_WorkbookBeforeSave handler. Connect it with Set guard.App = Application, as Microsoft's using events with the Application object shows, and call that from the add-in's Workbook_Open.

Watch out for: the event object lives in a module-level variable. If the VBA project is reset (say you click End on a run-time error), the guard stops silently. Add a Restart guard button.

What is a class module in VBA, and how is it different from a module?

A class module defines your own object type: its Property procedures become properties and its public Subs and Functions become methods, as Microsoft's class modules overview (written for Access, but the language is the same) explains. A standard module just holds procedures, with one shared copy of its variables. You need a class when a kind of record (an invoice line, a request) carries both data and rules.

Insert > Class Module, rename it InvoiceLine in the Properties window, and add:

Option Explicit

Private mInvoiceNo As String
Private mNet As Currency
Private mVatRate As Double

Public Property Get InvoiceNo() As String
    InvoiceNo = mInvoiceNo
End Property

Public Property Let InvoiceNo(ByVal newValue As String)
    If Len(Trim$(newValue)) = 0 Then
        Err.Raise vbObjectError + 513, "InvoiceLine", "Invoice number is required."
    End If
    mInvoiceNo = Trim$(newValue)
End Property

Public Property Get Net() As Currency
    Net = mNet
End Property

Public Property Let Net(ByVal newValue As Currency)
    mNet = newValue
End Property

Public Property Get VatRate() As Double
    VatRate = mVatRate
End Property

Public Property Let VatRate(ByVal newValue As Double)
    If newValue < 0 Or newValue > 1 Then
        Err.Raise vbObjectError + 514, "InvoiceLine", "VAT rate must be between 0 and 1."
    End If
    mVatRate = newValue
End Property

Public Function Gross() As Currency
    Gross = mNet + Application.WorksheetFunction.Round(mNet * mVatRate, 2)
End Function

Use it from a standard module:

Option Explicit

Public Sub DemoInvoiceLine()
    Dim inv As InvoiceLine
    On Error GoTo Failed

    Set inv = New InvoiceLine
    inv.InvoiceNo = "INV-1001"
    inv.Net = 125.25
    inv.VatRate = 0.2
    Debug.Print inv.InvoiceNo, inv.Gross   ' INV-1001   150.3
    Exit Sub

Failed:
    MsgBox "Could not create the invoice line: " & Err.Description, vbExclamation
End Sub

The form, an import routine and a test all get the same checks because the rules live in the class. The VAT uses WorksheetFunction.Round because VBA's own Round does banker's rounding, as Microsoft's Round page warns.

VBA class constructor: Class_Initialize and a factory function

Put defaults in Private Sub Class_Initialize(). It cannot take parameters, so to create a filled-in object in one line, add a factory function to a standard module:

Public Function NewInvoiceLine(ByVal invNo As String, _
        ByVal netAmount As Currency, ByVal rate As Double) As InvoiceLine
    Dim inv As InvoiceLine
    Set inv = New InvoiceLine
    inv.InvoiceNo = invNo
    inv.Net = netAmount
    inv.VatRate = rate
    Set NewInvoiceLine = inv
End Function

Then Set inv = NewInvoiceLine("INV-1001", 125.25, 0.2) gives you a checked invoice line.

How to add a custom ribbon to an Excel workbook

There are two ways. Customize Ribbon puts your macros on a tab in your own copy of Excel, with no code. For a tab that travels with the file, add a customUI XML part to the .xlsm or .xlam, plus VBA callbacks.

The no-code way: put your macros on a custom ribbon group

Go to File > Options > Customize Ribbon, pick a tab, select New Group and Rename it. Under Choose commands from, select Macros, add your macro to the group, then Rename the button to set its label and icon (Microsoft's steps). That customisation belongs to your copy of Excel, so colleagues need your exported customisations or the XML method below.

The XML way: a ribbon that travels with the workbook

Use this minimal customUI14.xml:

<customUI xmlns="http://schemas.microsoft.com/office/2009/07/customui">
  <ribbon>
    <tabs>
      <tab id="tabFinanceTools" label="Finance Tools">
        <group id="grpMonthEnd" label="Month-end">
          <button id="btnCheckTB" label="Check balances" size="large"
                  imageMso="AcceptTask" onAction="CheckTrialBalance_Click" />
          <button id="btnBuildPack" label="Build PDF pack" size="large"
                  imageMso="FileSaveAsPdfOrXps" onAction="BuildReportPack_Click" />
        </group>
      </tab>
    </tabs>
  </ribbon>
</customUI>

The 2009/07 namespace is defined in Microsoft's MS-CUSTOMUI2 schema, and both icons are in Microsoft's imageMso table. Add the callbacks to a standard module, using the signature from Microsoft's ribbon example:

Option Explicit

' Ribbon callbacks: names must match onAction in the XML exactly.
Public Sub CheckTrialBalance_Click(ByVal control As IRibbonControl)
    On Error GoTo Failed
    CheckTrialBalance
    Exit Sub
Failed:
    MsgBox "Balance check failed: " & Err.Description, vbExclamation
End Sub

Public Sub BuildReportPack_Click(ByVal control As IRibbonControl)
    On Error GoTo Failed
    BuildReportPack
    Exit Sub
Failed:
    MsgBox "Report pack failed: " & Err.Description, vbExclamation
End Sub

' Placeholders: replace these with your own procedures.
Public Sub CheckTrialBalance()
    MsgBox "CheckTrialBalance is not written yet.", vbInformation
End Sub

Public Sub BuildReportPack()
    MsgBox "BuildReportPack is not written yet.", vbInformation
End Sub

Replace the placeholder Subs with your own procedures. IRibbonControl comes from the Microsoft Office Object Library; if you see "User-defined type not defined", tick it under Tools > References.

To put the XML into the file: save and close the .xlsm, open it in Office RibbonX Editor (free, MIT-licensed), add an Office 2010+ custom UI part, paste the XML and save. Microsoft's manual zip method adds the older customUI.xml part; for customUI14.xml, point the _rels/.rels relationship at it with Type="http://schemas.microsoft.com/office/2007/relationships/ui/extensibility" (per MS-OI29500).

Custom ribbon not showing up? By default Excel doesn't tell you why a ribbon failed to load. Tick Show add-in user interface errors under File > Options > Advanced, General (Microsoft documents this option for add-ins) and reopen the file. Usual culprits: a namespace that doesn't match the part (2009/07 for customUI14.xml, 2006/01 for customUI.xml), duplicate ids or a mistyped attribute. If a button fails, check the onAction name and signature.

How to create an Excel add-in (.xlam) from your VBA project

Use File > Save As > Excel Add-in (*.xlam), or FileFormat:=xlOpenXMLAddIn (value 55 in the XlFileFormat list) in code. To install it, go to File > Options > Add-ins, choose Excel Add-ins, select Go, and tick it or use Browse (Microsoft's steps). Its tab and macros then work in every workbook.

How HISAB 360 builds a VBA project, step by step

HISAB 360 is an AI assistant inside Windows desktop Excel. Its AI can build projects like these as a guided, multi-step job, not one click. You need a macro-enabled file (.xlsm, .xlsb, .xlam or .xltm), HISAB's macro permissions switched on (off by default; editing needs both edit and run), and Excel's Trust access to the VBA project object model ticked under Trust Center > Macro Settings. Only you can tick it, and Microsoft calls it a possible security hazard.

  1. Describe the project, say the report pack generator. The AI works in your macro-enabled workbook or saves a new .xlsm.
  2. It creates standard modules, class modules and UserForms, optionally from five styled form templates. Controls are created in code when the form loads (UserForm_Initialize), not placed on the VBA editor's design surface. HISAB's drag-and-drop designer lets you adjust a layout, but saving from it rebuilds controls in code, simplifying some control types and leaving button handlers to wire.
  3. It writes the procedures. When it writes or replaces a procedure, a static linter with 142 inspections checks the module and undoes the change if Error-level problems appear. Form templates, imported modules and helper libraries skip this check, and the linter is not the VBA compiler. An optional sandbox test on a hidden copy tries a compile probe (not a guaranteed full compile) and runs test macros for real, so anything they do outside the file, such as writing PDFs, still happens. It needs the workbook saved to disk and saves unsaved changes first.
  4. It adds worksheet buttons wired to macros and runs test Subs.
  5. It adds the custom ribbon, closing and reopening the saved workbook to do it.
  6. It saves an .xlam; you install it through File > Options > Add-ins.

For an existing project, the AI can run the same linter and rewrite what it reports (no auto-fix), and open hand-built forms in the designer. Our tutorial on generating VBA macros and a ribbon from chat covers the first part: one macro and a ribbon button.

What you still do:

ERP ideas. For projects 3 and 6, HISAB can read QuickBooks Online, Xero, Zoho Books, Odoo and FreshBooks data into sheets as static values (re-run to refresh). Xero aged receivables come per contact, and Xero connections made on or after 29 April 2026 cannot read the journal stream. Writes go through a validating Excel staging sheet. Posting live, and any update, void or delete, normally needs a click on a confirmation card; drafts, master data such as customers, attachments and credit applications go through without one. HISAB has no supported VBA API for posting, so keep VBA for preparation. See the ERP connectors docs.

Not for you if: you use a Mac or Excel for the web; you want a finished app from one prompt; your forms need truly nested Frames and MultiPages; or IT policy forbids trusting access to the VBA project object model.

Frequently asked questions

What is a VBA project?

A VBA project is the container for all the macro code in one Office file. In Excel it holds standard modules, class modules, UserForms and document modules such as ThisWorkbook, plus references. It shows in the Visual Basic Editor (Alt+F11) as VBAProject (file name) and is saved only in macro-enabled files such as .xlsm, .xlsb or .xlam.

What is the difference between a module and a class module in VBA?

A standard module is a collection of procedures you call directly, with one shared copy of its variables. A class module defines a new object type with properties, methods and events; you create separate instances with New, and each instance keeps its own data. Use standard modules for macros you run and class modules when many records share the same data and rules, such as invoice lines.

Why isn't the custom ribbon showing up in Excel?

By default Excel does not tell you why a custom ribbon failed to load. Turn on Show add-in user interface errors under File > Options > Advanced, then reopen the file. Common causes are a namespace that does not match the part (2009/07 for customUI14.xml, 2006/01 for customUI.xml), duplicate control ids, or a typo in an attribute name.

Is Excel VBA hard to learn?

Most finance users can learn enough VBA for projects like these in stages: record a macro, read the code it produces, then change ranges, loops and conditions. Class modules, application events and ribbon XML are the harder steps, so leave projects 8 and 9 until standard modules and UserForms feel routine. VBA runs only in desktop Excel, not in Excel for the web.

Can a VBA project post transactions to QuickBooks or Xero?

Yes, but it is hard work. VBA can call the QuickBooks Online or Xero APIs over HTTP, which means handling OAuth 2.0 sign-in, token refresh and JSON yourself. A simpler route is to let VBA prepare and check the batch, then use the ledger's own import. HISAB 360 has no supported VBA API for posting; its AI stages and validates rows on a sheet. Posting live normally needs a confirmation click, but drafts and master data such as customers are created without one.

Try HISAB 360 on your own workbook

HISAB 360 is an AI assistant inside Windows desktop Excel for accountants and finance teams. Its AI builds VBA projects step by step, with modules, forms, buttons and a custom ribbon, and it connects two-way to QuickBooks, Xero, Zoho Books, Odoo and FreshBooks. The 15-day trial is the full product, no card required.

Start free → See pricing