Reputation: 5
I'm trying to split a table into different sheets, relevant to column 1 of my sheet
So say i have a sheet called 109 i want all 109's entries (entire rows of the table copied over)
With Columns and Rows in Red
Sub populate()
Application.ScreenUpdating = False
Application.EnableEvents = False
Application.Calculation = xlCalculationManual
Dim lngLastRow As Long
Sheets("Data").Select
Range("D11").Select
' Set NE sheets
Set jc109 = Sheets("109")
Set jj112 = Sheets("112")
Set gd126 = Sheets("126")
Set pw216 = Sheets("216")
Set sa223 = Sheets("223")
Set ms269 = Sheets("269")
Set ad363 = Sheets("363")
lngLastRow = Cells(Rows.Count, "A").End(xlUp).Row
With Range("D11", "P" & lngLastRow)
.AutoFilter
' Copy NE stock info
.AutoFilter Field:=1, Criteria1:="109"
.Copy jc109.Range("D11")
.AutoFilter Field:=1, Criteria1:="112"
.Copy jj112.Range("D11")
.AutoFilter Field:=1, Criteria1:="126"
.Copy gd126.Range("D11")
.AutoFilter Field:=1, Criteria1:="216"
.Copy pw216.Range("D11")
.AutoFilter Field:=1, Criteria1:="223"
.Copy sa223.Range("D11")
.AutoFilter Field:=1, Criteria1:="269"
.Copy ms269.Range("D11")
.AutoFilter Field:=1, Criteria1:="363"
.Copy ad363.Range("D11")
.AutoFilter
End With
Call emailsheets
Application.ScreenUpdating = True
.EnableEvents = True
Application.Calculation = xlCalculationAutomatic
End Sub
If if have a row of .... as entry's then it works but copies over a row of ... at the top, not too much of an issue i pasted it to a hidden row. but then it seem sto throw #REF errors in the cells if i don't have an entry for each engineer number it is searching for.
Upvotes: 0
Views: 82
Reputation: 1513
I've taken the liberty of writing a different sub for the following reasons.
ActiveWorkbook
. Usually this doesn't create a problem but may cause issues if you have multiple workbooks open. Active
refers to whatever is active, regardless of where your code is. You should have a look at thisSome assumptions that apply
D11
and the value "0" in column "Entry" to be in cell C11
Here is the code
Option Explicit
Sub populate()
Dim arrData() As Variant, arrEngData() As Variant
Dim arrEngNo() As Long
Dim wsData As Worksheet, wsEng As Worksheet
Dim i As Long, j As Long, k As Long
With Application
.ScreenUpdating = False
.EnableEvents = False
.Calculation = xlCalculationManual
End With
Set wsData = ThisWorkbook.Worksheets("Data")
'Get all Engineer numbers
With wsData
arrData = .Range(.Cells(11, 4), .Cells(11, 4).End(xlDown)) 'I've altered the way the array is collected, instead of looking for the first value in column D from the bottom up, it now looks for the last value in column D going down column D starting at row 11
End With
'Get unique engineer numbers
ReDim arrEngNo(0) 'I've tweaked the start of the procedure so it does not automatically record the first value it encounters, in case this is a 0
For i = LBound(arrData, 1) To UBound(arrData, 1)
If UBound(arrEngNo) = 0 And Not arrData(i, 1) = 0 Then 'I've added a check to so that no 0 value is entered as an engineer's number
ReDim arrEngNo(1 To 1) 'If a valid engineer's number is found, resize the array
arrEngNo(1) = arrData(1, 1)
Else
For j = LBound(arrEngNo) To UBound(arrEngNo)
If arrEngNo(j) = arrData(i, 1) Or arrData(i, 1) = 0 Then 'I've added a check to also skip 0 values besides already recorded engineer's numbers
Exit For
ElseIf j = UBound(arrEngNo) And Not arrEngNo(j) = arrData(i, 1) Then
ReDim Preserve arrEngNo(1 To UBound(arrEngNo) + 1)
arrEngNo(UBound(arrEngNo)) = arrData(i, 1)
End If
Next j
End If
Next i
'Collect all records in array to process
With wsData
arrData = .Range(.Cells(11, 4), .Cells(11, 4).End(xlDown).Offset(0, 12)) 'I've altered the way the array is collected, instead of looking for the first value encountered from the bottom up in column P, which could be empty and so potentially it could miss records, it now looks down to the last value encounterd in column D (which is the last formula in column D) and then moves over to column P
End With
'Iterate through all available engineer numbers
For i = LBound(arrEngNo) To UBound(arrEngNo)
'Reset the array for the engineer specific records
ReDim arrEngData(1 To 13, 0)
'Iterate through the records and copy the relevant records to engineer specific array
For j = LBound(arrData, 1) To UBound(arrData, 1)
'If engineer numbers match, then copy data to engineer specific array
If arrData(j, 1) = arrEngNo(i) Then
If UBound(arrEngData, 2) = 0 Then
ReDim arrEngData(1 To 13, 1 To 1)
Else
ReDim Preserve arrEngData(1 To 13, 1 To UBound(arrEngData, 2) + 1)
End If
'Copy record
For k = 1 To 13
arrEngData(k, UBound(arrEngData, 2)) = arrData(j, k)
Next k
End If
Next j
'Set the engineer worksheet
Set wsEng = ThisWorkbook.Worksheets(CStr(arrEngNo(i)))
'Write collected records to engineer worksheet
With wsEng
.Range(.Cells(11, 4), .Cells(11, 4).Offset(UBound(arrEngData, 2) - 1, UBound(arrEngData, 1) - 1)) = Application.Transpose(arrEngData)
End With
Next i
wsData.Activate
Call emailsheets
With Application
.ScreenUpdating = True
.EnableEvents = True
.Calculation = xlCalculationAutomatic
End With
End Sub
Performance:
I hope this works for you and creates a starting point from which you can expand your VBA knowledge.
Upvotes: 1