Private Sub subCopyData()
Dim arr() As Variant
Dim WsTransactions As Worksheet
Dim i As Integer
Dim tbl As ListObject
Dim Ws As Worksheet
Dim blnExists As Boolean
Dim WsDest As Worksheet
Dim strMsg As String
Dim lngRows As Long
Dim strCategory As String
Dim tblBalances As ListObject
Dim intRow As Long
Dim intPrefix As Integer
ActiveWorkbook.Save
Set WsTransactions = Worksheets("Transactions")
Call subSortTransactions
WsTransactions.Activate
Set tbl = WsTransactions.ListObjects(1)
arr = Application.WorksheetFunction.Unique(tbl.ListColumns(1).DataBodyRange)
If tbl.ListColumns(1).DataBodyRange.Rows.Count <> tbl.ListColumns(1).DataBodyRange.Rows.SpecialCells(xlCellTypeVisible).Count Then
tbl.DataBodyRange.Select
Selection.AutoFilter
WsTransactions.Cells(1).Select
End If
Set tblBalances = Worksheets("Balances").ListObjects(1)
For i = LBound(arr) To UBound(arr)
strCategory = arr(i, 1)
strMsg = strMsg & vbCrLf & arr(i, 1)
intRow = WorksheetFunction.Match(strCategory, tblBalances.ListColumns("Category").DataBodyRange, 0)
intPrefix = WorksheetFunction.Index(tblBalances.ListColumns("Prefix").DataBodyRange, intRow)
arr(i, 1) = intPrefix & "." & arr(i, 1)
For Each Ws In Worksheets
If Ws.Name = arr(i, 1) Then
blnExists = True
Exit For
End If
Next Ws
If Not blnExists Then
Sheets.Add(After:=Sheets(Sheets.Count)).Name = arr(i, 1)
End If
Set WsDest = Worksheets(arr(i, 1))
WsDest.Activate
WsDest.Cells.ClearContents
WsTransactions.ListObjects(1).Range.AutoFilter _
Field:=1, Criteria1:=strCategory
With WsDest
.Cells.EntireColumn.ColumnWidth = 5
tbl.Range.SpecialCells(xlCellTypeVisible).Copy
.Cells(1, 1).PasteSpecial xlPasteValuesAndNumberFormats
Application.CutCopyMode = 0
.ListObjects.Add(xlSrcRange, .Range("A1").CurrentRegion, , xlYes).Name = "tbl" & strCategory
With .ListObjects(1).Range
.RowHeight = 30
.IndentLevel = 1
.EntireColumn.AutoFit
.VerticalAlignment = xlCenter
End With
With .ListObjects(1)
lngRows = .ListColumns(1).DataBodyRange.Rows.SpecialCells(xlCellTypeVisible).Count
End With
.Cells(1, 1).Select
With WsDest.Range("A1").CurrentRegion.Borders
.LineStyle = xlContinuous
.Weight = xlThin
.ColorIndex = vbBlack
End With
End With
WsTransactions.Activate
tbl.DataBodyRange.Select
Selection.AutoFilter
Call subCreateSummary(WsDest.Range("H1"), strCategory)
Next i
If WsTransactions.AutoFilterMode Then
WsTransactions.AutoFilter.ShowAllData
End If
Application.Goto Reference:=WsTransactions.Cells(1, 1), scroll:=True
ActiveWorkbook.Save
MsgBox UBound(arr) & " category tables created." & vbCrLf & _
strMsg, vbOKOnly, "Confirmation"
End Sub
Private Sub subCreateSummary(rngStart As Range, strCategory As String)
Dim rng As Range
Dim Ws As Worksheet
Dim Q As String
Dim strFormula As String
Dim strAddress As String
Q = Chr(34)
Set Ws = Worksheets(rngStart.Parent.Name)
strAddress = rngStart.Offset(1, 0).Address(False, False)
Ws.Activate
With rngStart
' Opening Balance.
.Offset(1, 1).Formula2 = "=INDEX(tblBalances,MATCH(" & Q & strCategory & Q & ",tblBalances[Category],0),2)"
.Formula2 = "=SUM(tbl" & strCategory & "[Amount])"
.NumberFormat = "£#,##0"
With .Resize(1, 4)
.Font.Color = vbWhite
.Interior.Color = vbBlack
.Font.Bold = True
End With
With .Offset(0, 1).Resize(1, 3)
.Value = Array("Opening Balance", "Net Movements", "Closing Balance")
End With
.Offset(1, 0).Formula2 = "=EOMONTH(EDATE(DATE(YEAR(Transactions!$B$2),1,1),SEQUENCE(12,1,0)),0)"
.Offset(1, 0).Resize(12, 1).NumberFormat = "DD-MMM-YY"
strFormula = "=SUMIFS(tblTransactions[Amount],tblTransactions[Date]," & Q & ">=" & Q & _
" & DATE(YEAR(" & strAddress & "),MONTH(" & strAddress & "),1),tblTransactions[Date]," & Q & "<=" & Q & " & " & _
strAddress & ",tblTransactions[Account]," & Q & strCategory & Q & ")"
.Offset(1, 2).Resize(12, 1).Formula2 = strFormula
.Offset(2, 1).Resize(11, 1).Formula2 = "=" & .Offset(1, 3).Address(False, False)
.Offset(1, 3).Resize(12, 1).Formula2 = "=" & rngStart.Offset(1, 1).Address(False, False) & "+" & rngStart.Offset(1, 2).Address(False, False)
With .Offset(1, 1).Resize(12, 3)
.NumberFormat = "£#,##0.00"
End With
With .Resize(13, 4)
With .Borders
.LineStyle = xlContinuous
.Weight = xlThin
.ColorIndex = vbBlack
End With
.VerticalAlignment = xlCenter
.HorizontalAlignment = xlLeft
.IndentLevel = 1
.EntireColumn.AutoFit
End With
End With
End Sub
Private Sub subSortTransactions()
Dim tbl As ListObject
Set tbl = ActiveWorkbook.Worksheets("Transactions").ListObjects(1)
With tbl
.Sort.SortFields.Clear
.Sort.SortFields.Add _
Key:=Range("tblTransactions[Date]"), SortOn:=xlSortOnValues, Order:=xlAscending, _
DataOption:=xlSortNormal
With .Sort
.Header = xlYes
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With
End With
End Sub