'--- Main Code Module ---
Option Explicit
'=========================================================
' UI & NAVIGATION
'=========================================================
Sub ShowTransactionForm()
UserForm1.Show
End Sub
'=========================================================
' REPORT GENERATION
'=========================================================
Sub GenerateTrialBalance()
Dim dict As Object
Set dict = CreateObject("Scripting.Dictionary")
Dim wsCoA As Worksheet, wsJournal As Worksheet, wsReport As Worksheet
Set wsCoA = ThisWorkbook.Sheets("ChartOfAccounts")
Set wsJournal = ThisWorkbook.Sheets("Journal")
Set wsReport = ThisWorkbook.Sheets("TrialBalance")
' --- 1. Clear previous report and set up headers ---
wsReport.Cells.Clear
With wsReport.Range("A1:D1")
.Value = Array("Account", "Account Type", "Debit", "Credit")
.Font.Bold = True
.Interior.Color = RGB(220, 230, 241)
End With
' --- 2. Get all accounts and their types from CoA into dictionary ---
Dim lastCoARow As Long
Dim i As Long
lastCoARow = wsCoA.Cells(wsCoA.Rows.Count, "A").End(xlUp).Row
For i = 2 To lastCoARow
' Store balance, account type, normal balance
dict(wsCoA.Cells(i, "B").Value) = Array(0, wsCoA.Cells(i, "C").Value,
wsCoA.Cells(i, "D").Value)
Next i
' --- 3. Process the Journal ---
Dim lastJournalRow As Long
Dim currentAccount As String
Dim debit As Currency, credit As Currency
lastJournalRow = wsJournal.Cells(wsJournal.Rows.Count, "A").End(xlUp).Row
For i = 2 To lastJournalRow
currentAccount = wsJournal.Cells(i, "C").Value
debit = CCur(wsJournal.Cells(i, "D").Value)
credit = CCur(wsJournal.Cells(i, "E").Value)
If dict.Exists(currentAccount) Then
Dim entryData As Variant
entryData = dict(currentAccount)
' Update the balance: Balance = Balance + Debit - Credit
entryData(0) = entryData(0) + debit - credit
dict(currentAccount) = entryData
End If
Next i
' --- 4. Write data to the Trial Balance report ---
Dim r As Long: r = 2
Dim key As Variant
Dim totalDebit As Currency, totalCredit As Currency
For Each key In dict.keys
Dim balance As Currency
Dim accountType As String
Dim normalBalance As String
balance = dict(key)(0)
accountType = dict(key)(1)
normalBalance = dict(key)(2)
wsReport.Cells(r, "A").Value = key
wsReport.Cells(r, "B").Value = accountType
If normalBalance = "Debit" Then
If balance > 0 Then wsReport.Cells(r, "C").Value = balance
If balance < 0 Then wsReport.Cells(r, "D").Value = -balance
Else 'Normal Balance is Credit
If balance < 0 Then wsReport.Cells(r, "D").Value = -balance
If balance > 0 Then wsReport.Cells(r, "C").Value = balance
End If
r = r + 1
Next key
' --- 5. Add totals and format ---
wsReport.Cells(r, "B").Value = "Totals"
wsReport.Cells(r, "B").Font.Bold = True
wsReport.Cells(r, "C").Formula = "=SUM(C2:C" & r - 1 & ")"
wsReport.Cells(r, "D").Formula = "=SUM(D2:D" & r - 1 & ")"
With wsReport.Range("C" & r & ":D" & r)
.Font.Bold = True
.Borders(xlEdgeTop).LineStyle = xlContinuous
End With
wsReport.Columns("C:D").NumberFormat = "#,##0.00"
wsReport.Columns("A:D").AutoFit
wsReport.Activate
MsgBox "Trial Balance has been generated.", vbInformation
End Sub
Sub GenerateIncomeStatement()
Dim wsTB As Worksheet, wsReport As Worksheet
Set wsTB = ThisWorkbook.Sheets("TrialBalance")
Set wsReport = ThisWorkbook.Sheets("IncomeStatement")
wsReport.Cells.Clear
wsReport.Range("A1").Value = "Income Statement"
wsReport.Range("A1").Font.Bold = True
wsReport.Range("A1").Font.Size = 14
' --- Variables for calculation ---
Dim lastTBRow As Long, i As Long, r As Long
Dim totalIncome As Currency, totalExpense As Currency, netIncome As Currency
lastTBRow = wsTB.Cells(wsTB.Rows.Count, "A").End(xlUp).Row
r = 3 'Start writing from row 3
' --- 1. Process Income ---
wsReport.Cells(r, "A").Value = "Income"
wsReport.Cells(r, "A").Font.Bold = True
r = r + 1
For i = 2 To lastTBRow - 1 ' -1 to skip totals row
If wsTB.Cells(i, "B").Value = "Income" Then
wsReport.Cells(r, "A").Value = wsTB.Cells(i, "A").Value ' Account Name
wsReport.Cells(r, "B").Value = wsTB.Cells(i, "D").Value ' Credit
Balance
totalIncome = totalIncome + wsTB.Cells(i, "D").Value
r = r + 1
End If
Next i
wsReport.Cells(r, "A").Value = "Total Income"
wsReport.Cells(r, "A").Font.Italic = True
wsReport.Cells(r, "B").Value = totalIncome
wsReport.Cells(r, "B").Font.Bold = True
r = r + 2 'Add a space
' --- 2. Process Expenses ---
wsReport.Cells(r, "A").Value = "Expenses"
wsReport.Cells(r, "A").Font.Bold = True
r = r + 1
For i = 2 To lastTBRow - 1
If wsTB.Cells(i, "B").Value = "Expense" Then
wsReport.Cells(r, "A").Value = wsTB.Cells(i, "A").Value ' Account Name
wsReport.Cells(r, "B").Value = wsTB.Cells(i, "C").Value ' Debit Balance
totalExpense = totalExpense + wsTB.Cells(i, "C").Value
r = r + 1
End If
Next i
wsReport.Cells(r, "A").Value = "Total Expenses"
wsReport.Cells(r, "A").Font.Italic = True
wsReport.Cells(r, "B").Value = totalExpense
wsReport.Cells(r, "B").Font.Bold = True
r = r + 2
' --- 3. Calculate and display Net Income ---
netIncome = totalIncome - totalExpense
wsReport.Cells(r, "A").Value = "Net Income"
wsReport.Cells(r, "A").Font.Bold = True
wsReport.Cells(r, "B").Value = netIncome
wsReport.Cells(r, "B").Font.Bold = True
wsReport.Cells(r, "B").Borders(xlEdgeTop).LineStyle = xlDouble
' --- Formatting ---
wsReport.Columns("B").NumberFormat = "#,##0.00"
wsReport.Columns("A:B").AutoFit
wsReport.Activate
MsgBox "Income Statement has been generated.", vbInformation
End Sub
Sub GenerateBalanceSheet()
Dim wsTB As Worksheet, wsReport As Worksheet, wsIS As Worksheet
Set wsTB = ThisWorkbook.Sheets("TrialBalance")
Set wsReport = ThisWorkbook.Sheets("BalanceSheet")
Set wsIS = ThisWorkbook.Sheets("IncomeStatement")
wsReport.Cells.Clear
wsReport.Range("A1").Value = "Balance Sheet"
wsReport.Range("A1").Font.Bold = True
wsReport.Range("A1").Font.Size = 14
Dim lastTBRow As Long, i As Long, r As Long
Dim totalAssets As Currency, totalLiabilities As Currency, totalEquity As
Currency
Dim netIncome As Currency
lastTBRow = wsTB.Cells(wsTB.Rows.Count, "A").End(xlUp).Row
r = 3
' --- Get Net Income from Income Statement ---
' Find the "Net Income" label and get value from adjacent cell
On Error Resume Next
netIncome = wsIS.Columns("A").Find("Net Income", LookIn:=xlValues).Offset(0,
1).Value
On Error GoTo 0
' --- 1. Process Assets ---
wsReport.Cells(r, "A").Value = "Assets"
wsReport.Cells(r, "A").Font.Bold = True
r = r + 1
For i = 2 To lastTBRow - 1
If wsTB.Cells(i, "B").Value = "Asset" Then
wsReport.Cells(r, "A").Value = wsTB.Cells(i, "A").Value
wsReport.Cells(r, "B").Value = wsTB.Cells(i, "C").Value
totalAssets = totalAssets + wsTB.Cells(i, "C").Value
r = r + 1
End If
Next i
wsReport.Cells(r, "A").Value = "Total Assets"
wsReport.Cells(r, "B").Value = totalAssets
wsReport.Cells(r, "B").Font.Bold = True
r = r + 2
' --- 2. Process Liabilities ---
wsReport.Cells(r, "A").Value = "Liabilities"
wsReport.Cells(r, "A").Font.Bold = True
r = r + 1
For i = 2 To lastTBRow - 1
If wsTB.Cells(i, "B").Value = "Liability" Then
wsReport.Cells(r, "A").Value = wsTB.Cells(i, "A").Value
wsReport.Cells(r, "B").Value = wsTB.Cells(i, "D").Value
totalLiabilities = totalLiabilities + wsTB.Cells(i, "D").Value
r = r + 1
End If
Next i
wsReport.Cells(r, "A").Value = "Total Liabilities"
wsReport.Cells(r, "B").Value = totalLiabilities
wsReport.Cells(r, "B").Font.Italic = True
r = r + 2
' --- 3. Process Equity ---
wsReport.Cells(r, "A").Value = "Equity"
wsReport.Cells(r, "A").Font.Bold = True
r = r + 1
For i = 2 To lastTBRow - 1
If wsTB.Cells(i, "B").Value = "Equity" Then
wsReport.Cells(r, "A").Value = wsTB.Cells(i, "A").Value
If wsTB.Cells(i, "C").Value > 0 Then 'Debit balance like Owner's Draw
wsReport.Cells(r, "B").Value = -wsTB.Cells(i, "C").Value
totalEquity = totalEquity - wsTB.Cells(i, "C").Value
Else 'Credit balance like Owner's Capital
wsReport.Cells(r, "B").Value = wsTB.Cells(i, "D").Value
totalEquity = totalEquity + wsTB.Cells(i, "D").Value
End If
r = r + 1
End If
Next i
wsReport.Cells(r, "A").Value = "Retained Earnings (Net Income)"
wsReport.Cells(r, "B").Value = netIncome
totalEquity = totalEquity + netIncome
r = r + 1
wsReport.Cells(r, "A").Value = "Total Equity"
wsReport.Cells(r, "B").Value = totalEquity
wsReport.Cells(r, "B").Font.Italic = True
r = r + 2
' --- 4. Final Totals and Check ---
wsReport.Cells(r, "A").Value = "Total Liabilities and Equity"
wsReport.Cells(r, "B").Value = totalLiabilities + totalEquity
wsReport.Cells(r, "B").Font.Bold = True
wsReport.Cells(r, "B").Borders(xlEdgeTop).LineStyle = xlDouble
' --- Formatting ---
wsReport.Columns("B").NumberFormat = "#,##0.00"
wsReport.Columns("A:B").AutoFit
wsReport.Activate
MsgBox "Balance Sheet has been generated.", vbInformation
End Sub
Sub ViewGeneralLedger()
Dim accountName As String
accountName = InputBox("Enter the exact Account Name to view its ledger:",
"General Ledger")
If accountName = "" Then Exit Sub
Dim wsJournal As Worksheet, wsReport As Worksheet
Set wsJournal = ThisWorkbook.Sheets("Journal")
Set wsReport = ThisWorkbook.Sheets("GeneralLedger")
wsReport.Cells.Clear
' --- Headers ---
wsReport.Range("A1").Value = "General Ledger for: " & accountName
wsReport.Range("A1").Font.Bold = True
wsReport.Range("A3:F3").Value = Array("Date", "Description", "Transaction ID",
"Debit", "Credit", "Running Balance")
wsReport.Range("A3:F3").Font.Bold = True
Dim lastJournalRow As Long, i As Long, r As Long
Dim runningBalance As Currency
lastJournalRow = wsJournal.Cells(wsJournal.Rows.Count, "A").End(xlUp).Row
r = 4 'Start writing data at row 4
For i = 2 To lastJournalRow
If wsJournal.Cells(i, "C").Value = accountName Then
wsReport.Cells(r, "A").Value = wsJournal.Cells(i, "B").Value 'Date
wsReport.Cells(r, "B").Value = wsJournal.Cells(i, "F").Value
'Description
wsReport.Cells(r, "C").Value = wsJournal.Cells(i, "A").Value 'Trans ID
wsReport.Cells(r, "D").Value = wsJournal.Cells(i, "D").Value 'Debit
wsReport.Cells(r, "E").Value = wsJournal.Cells(i, "E").Value 'Credit
runningBalance = runningBalance + wsJournal.Cells(i, "D").Value -
wsJournal.Cells(i, "E").Value
wsReport.Cells(r, "F").Value = runningBalance
r = r + 1
End If
Next i
' --- Formatting ---
wsReport.Columns("A:F").AutoFit
wsReport.Columns("D:F").NumberFormat = "#,##0.00"
wsReport.Range("A:A").NumberFormat = "yyyy-mm-dd"
wsReport.Activate
End Sub