EDIT: Improved/More Streamlined Code (rather than spaghetti below) now posted here: Bookkeeping Coding - Check and Create Tabs, Copy filtered Data in Loop
I'm a relative newbie to coding and have "Frankensteined" my code from various pages on the web. At the moment I have no issues with this code as I have minimal lines of data but find that the time taken increases with data lines (as can only be expected.
The code I have does the following:
- Filters a Source Table of Data from a Defined List on another sheet
- Checks if Data exists after filter
- If no data exists
- Checks if there is a tab for that Company and deletes existing data
- If no tab move to next in loop
- If data does exists, check tab exists
- If tab exists, clear data and copy filtered data across move to next in loop
- If tab does not exist, create one from hidden template, check balance line exists in different sheet (if not create one) and then copy all filtered data and move to next in loop.
- If no data exists
- Remove all filters and go back to where I started.
It seems quite complex to me as a newbie so I'm sure I have a fair amount of redundant lines present that can tidy up my code.
All help/suggestions/recommendations, gratefully received.
My Code:
Sub Update_Backup_Sheets()
Dim sh As Worksheet
x = 4
Dim LastRow As Long
Dim MyCell As Range, MyRange As Range
Dim lrow As Long
Dim TargetTable As ListObject
Dim NumberOfAreas As Long
Dim rng As Range
Set Sourcetable = Sheets("Amalgamated Data").ListObjects("TableFullData")
Application.ScreenUpdating = False
Application.DisplayAlerts = False
‘Get the Company name from the Company Tab
Do
With Sheets("General")
Company_Name = .Range("A" & x).Value
End With
‘ Clear all filter from table
Sourcetable.AutoFilter.ShowAllData
LastRow = Range("B" & Rows.count).End(xlUp).Row - 1
Set MyRange = Range("A20:V" & LastRow)
‘Filter by Company Name
Sourcetable.DataBodyRange.AutoFilter Field:=2, _
Criteria1:="=" & Company_Name
On Error Resume Next
If Sourcetable.AutoFilter.Range.Columns(1).SpecialCells(xlCellTypeVisible).count <= 1 Then
‘Clear Existing Data
On Error GoTo Continue
Set sh = Sheets(Company_Name)
On Error GoTo Continue
If WorksheetsExists = Not sh Is Nothing Then
GoTo Continue
Else
With Sheets(Company_Name).ListObjects(1)
.DataBodyRange.Offset(1).Resize(.DataBodyRange.Rows.count - 1, .DataBodyRange.Columns.count).Rows.Delete
.DataBodyRange.ClearContents
End With
GoTo Continue
End If
‘If Data Exists
‘Check if tab exists
Else
On Error Resume Next
If Sourcetable.AutoFilter.Range.Columns(1).SpecialCells(xlCellTypeVisible).count > 1 Then
On Error Resume Next
Set sh = Sheets(Company_Name)
If WorksheetsExists = Not sh Is Nothing Then
‘If Tab does not exist, create all relevent records
‘Unhide Template if hidden
If Sheets("Template").Visible = xlSheetHidden Then Sheets("Template").Visible = xlSheetVisible
‘Create and rename sheet highlight it yellow
Sheets("Template").Copy After:=Sheets(4)
ActiveSheet.Range("A20").ListObject.Name = "Table" & (Company_Name)
ActiveSheet.Name = (Company_Name)
With ActiveSheet.Tab
.Color = 65535
.TintAndShade = 0
End With
‘Check Balance Download Records
‘Search COMPANY nAME
Dim rgfound As Range
Set rgfound = Sheets("Balance Download").Range("A1", "A" & frow - 1).Find(Company_Name)
If rgfound Is Nothing Then
‘If not Found
‘Calculate last row
flrow = Sheets("Balance Download").Range("a" & Rows.count).End(xlUp).Row
‘Copy Last Row of Data and rename row
With Sheets("Balance Download")
.ListObjects(1).ListRows.Add
.Rows(flrow).Copy
.Range("A" & flrow + 1).PasteSpecial Paste:=xlPasteValuesAndNumberFormats, Operation:=xlNone
Application.CutCopyMode = False
.Range("a" & flrow + 1).Value = Company_Name
End With
Else
End If
‘Hide template
Sheets("Template").Visible = xlSheetHidden
‘Confirmation Message
MsgBox "Worksheet for " & (Company_Name) & " created"
‘Set sh name
Set sh = Sheets(Company_Name)
GoTo Step2
Else
End If
End If
‘If tab and data exist
Step2:
‘Clear existing data and resize table
With Sheets(Company_Name).ListObjects(1)
.DataBodyRange.Offset(1).Resize(.DataBodyRange.Rows.count - 1, .DataBodyRange.Columns.count).Rows.Delete
.DataBodyRange.ClearContents
End With
Find first row of table (las row of sheet as data previously cleared)
lrow = Sheets(Company_Name).Range("B" & Rows.count).End(xlUp).Row
With Sourcetable.DataBodyRange.SpecialCells(xlCellTypeVisible).Copy
With Sheets(Company_Name)
.Range("A" & lrow).PasteSpecial Paste:=xlPasteValuesAndNumberFormats, Operation:=xlNone
Application.CutCopyMode = False
End With
End With
End If
Continue:
‘Reset the variable sh
Set sh = Nothing
x = x + 1
‘Loop back to get a new Company's name in Employee Roster
Loop While Sheets("General").Range("A" & x).Value <> ""
‘At end of loop turn screen refresh etc back on
Application.DisplayAlerts = True
Application.ScreenUpdating = True
Sheets("Amalgamated Data").Select
'Clear all filter from table
Sourcetable.AutoFilter.ShowAllData
MsgBox "All Sheets Updated"
End Sub
WorksheetsExists
defined, or assigned? I don't thinkIf WorksheetsExists = Not sh Is Nothing Then
is doing what you mean it to be doing, and it only works by coincidence ofVariant/Empty
evaluating toFalse
when coerced into a Boolean expression. A much clearer & robust condition would beIf sh Is Nothing
, true when the sheet doesn't exist. Does the code compile if you addOption Explicit
at the top of the module? \$\endgroup\$True
, orFalse
. Every expression in everyIf
condition is a Boolean expression. That's basic-basic stuff though, you'll want to read up on VBA data types for more information. \$\endgroup\$