I\'m after a bit of help automating a report for work.
I have a spreadsheet with a data dump on, as per screenshot below (this is some data I have mocked up for this
The logic you want to follow would seem to need a nested For Each...Next Statement.
Template Worksheet:
As far as receiving the data, a well-constructed but otherwise blank worksheet could be used as a template. I envision four named ranges with worksheet scope; e.g. lst_Hot, lst_Warm, lst_Lukewarm and lst_General. These can be referenced in your code by concatenating "lst_" & filter_criteria. The cells they point to (aka Applies to:) are best referenced dynamically with a formula.
'lst_Hot Applies to:
=Template!$A$4:INDEX(Template!$H:$H, MATCH("hot", Template!$A:$A, 0)+COUNTA(Template!$A$4:$A$5))
'lst_Warm Applies to:
=Template!$A$7:INDEX(Template!$H:$H, MATCH("warm", Template!$A:$A, 0)+COUNTA(Template!$A$7:$A$8))
'lst_Lukewarm Applies to:
=Template!$A$10:INDEX(Template!$H:$H, MATCH("lukewarm", Template!$A:$A, 0)+COUNTA(Template!$A$10:$A$11))
'lst_General Applies to:
=Template!$A$13:INDEX(Template!$H:$H, MATCH("general", Template!$A:$A, 0)+COUNTA(Template!$A$13:$A$14))

Note that the named ranges are of Worksheet scope, not the more common (and default) Workbook scope. This is necessary to reference them in new worksheets without confusion.
While the Template worksheet may be initially visible, it will be hidden with
xlSheetVeryHiddenafter first use. This means it will not be listed in the conventional dialog to unhide a worksheet. You will need to go into the VBE and use the Properties window (e.g. F4) to set the .Visible property toXlSheetVisibleor runSheets("Template").Visible = xlSheetVisiblein the VBE's Immediate window (e.g. Ctrl+G). If you do not require this level of hiding the template worksheet, alter the code that makes it xlSheetVeryHidden.
Module1 (Code)
Option Explicit
Sub main()
'use bRESETALL:=True to delete the Rep worksheets before creating new ones
'Call generateRepContactLists(bRESETALL:=True)
'use bRESETALL:=False to apppend data to the existing Rep worksheets or create new ones if they do not exist
Call generateRepContactLists(bRESETALL:=False)
'optional mailing routine - constructs separate XLSX workbooks and sends them
'this routine expects a full compliment of worksheet tabs and valid email addresses
'Call distributeRepContactLists(bSENDASATTACH:=True)
End Sub
Sub generateRepContactLists(Optional bRESETALL As Boolean = False)
Dim f As Long, r As Long, rs As Long, v As Long, col As Long
Dim wsr_rws As Long, wsr_col As Long, fldREP As Long, fldSTS As Long
Dim vSTSs As Variant, vREPs As Variant
Dim wsrd As Worksheet, wsr As Worksheet, wst As Worksheet, wb As Workbook
On Error GoTo bm_Safe_Exit
appTGGL bTGGL:=False
If bRESETALL Then
Do While Worksheets.Count > 3: Worksheets(4).Delete: Loop
End If
Set wb = ThisWorkbook
Set wsrd = wb.Sheets("Raw_Data")
Set wst = wb.Sheets("Template")
vREPs = wb.Sheets("Reps").Range("lst_Reps")
'need to go through these next ones backwards due to named range row assignment
vSTSs = Array("General", "Lukewarm", "Warm", "Hot")
With wsrd
If .AutoFilterMode Then .AutoFilterMode = False
With .Cells(1, 1).CurrentRegion
fldREP = Application.Match("rep", .Rows(1), 0)
fldSTS = Application.Match("status", .Rows(1), 0)
For r = LBound(vREPs) To UBound(vREPs)
.AutoFilter field:=fldREP, Criteria1:=vREPs(r, 1)
For v = LBound(vSTSs) To UBound(vSTSs)
.AutoFilter field:=fldSTS, Criteria1:=vSTSs(v)
With .Offset(1, 0).Resize(.Rows.Count - 1, .Columns.Count)
If CBool(Application.Subtotal(103, .Columns(fldSTS))) Then
rs = Application.Subtotal(103, .Columns(fldSTS))
On Error GoTo bm_Missing_Rep_Ws
Set wsr = Worksheets(vREPs(r, 1))
On Error GoTo bm_Safe_Exit
With wsr.Range("lst_" & vSTSs(v))
wsr_rws = .Rows.Count
.Offset(wsr_rws, 0).Resize(rs, .Columns.Count).Insert _
Shift:=xlDown, CopyOrigin:=xlFormatFromRightOrBelow
End With
For col = 1 To .Columns.Count
If CBool(Application.CountIf(wsr.Range("lst_" & vSTSs(v)).Rows(1), .Rows(0).Cells(1, col).Value2)) Then
wsr_col = Application.Match(.Rows(0).Cells(1, col).Value2, wsr.Range("lst_" & vSTSs(v)).Rows(1), 0)
.Columns(col).Copy _
Destination:=wsr.Range("lst_" & vSTSs(v)).Cells(1, wsr_col).Offset(wsr_rws, 0)
wsr.Range("lst_" & vSTSs(v)).Cells(1, 1).Offset(wsr_rws, 0).Resize(rs, 1) = Date
End If
Next col
With wsr.Range("lst_" & vSTSs(v))
.Cells.Sort Key1:=.Columns(8), Order1:=xlDescending, _
Key2:=.Columns(7), Order2:=xlDescending, _
Orientation:=xlTopToBottom, Header:=xlYes
.Parent.Tab.Color = .Rows(0).Cells(1).Interior.Color
End With
Set wsr = Nothing
End If
End With
.AutoFilter field:=fldSTS
Next v
.AutoFilter field:=fldREP
Next r
End With
If .AutoFilterMode Then .AutoFilterMode = False
.Activate
End With
GoTo bm_Safe_Exit
bm_Missing_Rep_Ws:
If Err.Number = 9 Then
With wst
.Visible = xlSheetVisible
.Copy after:=Sheets(Sheets.Count)
.Visible = xlSheetVeryHidden
End With
With Sheets(Sheets.Count)
.Name = vREPs(r, 1)
.Cells(1, 1) = vREPs(r, 1)
End With
Resume
End If
bm_Safe_Exit:
appTGGL
End Sub
Sub distributeRepContactLists(Optional bSENDASATTACH As Boolean = True)
Dim rw As Long, w As Long, fn As String
On Error GoTo bm_Safe_Exit
appTGGL bTGGL:=False
With Worksheets("Reps").Range("lst_Reps")
For rw = 1 To .Rows.Count
fn = .Cells(rw, 1).Value2 & " Contact List " & Format(Date, "yyyy mm dd\.\x\l\s\x")
fn = Replace(fn, Chr(32), Chr(95))
fn = Environ("TEMP") & Chr(92) & fn
If CBool(Len(Dir(fn))) Then Kill fn
For w = 4 To Worksheets.Count
If LCase(Worksheets(w).Name) = LCase(.Cells(rw, 1).Value2) Then Exit For
Next w
If w <= Worksheets.Count Then
With Worksheets(.Cells(rw, 1).Value2)
.Copy
ActiveWorkbook.SaveAs Filename:=fn, FileFormat:=xlOpenXMLWorkbook
ActiveWindow.Close False
End With
If bSENDASATTACH Then
Call emailRepContactLists(sEML:=.Cells(rw, 2).Value2, sATTCH:=fn)
.Cells(rw, 3) = Now
End If
End If
Next rw
End With
bm_Safe_Exit:
appTGGL
End Sub
Sub emailRepContactLists(sEML As String, sATTCH As String)
Dim sFROM As String, sFROMPWD As String, cdoMail As New CDO.Message
sFROM = "your_email@gmail.com"
sFROMPWD = "your_gmail_password"
On Error GoTo bm_ErrorOut
With cdoMail
.Configuration.Fields.Item("http://schemas.microsoft.com/cdo/configuration/sendusing") = cdoSendUsingPort
.Configuration.Fields.Item("http://schemas.microsoft.com/cdo/configuration/smtpusessl") = True
.Configuration.Fields.Item("http://schemas.microsoft.com/cdo/configuration/smtpserverport") = 465
.Configuration.Fields.Item("http://schemas.microsoft.com/cdo/configuration/smtpserver") = "smtp.gmail.com"
.Configuration.Fields.Item("http://schemas.microsoft.com/cdo/configuration/smtpauthenticate") = cdoBasic
.Configuration.Fields.Item("http://schemas.microsoft.com/cdo/configuration/sendusername") = sFROM
.Configuration.Fields.Item("http://schemas.microsoft.com/cdo/configuration/sendpassword") = sFROMPWD
.Configuration.Fields.Update
.From = sFROM
.To = sEML
.CC = ""
.BCC = ""
.Subject = Format(Date, "\N\e\w\ \C\o\n\t\a\c\t\ \L\i\s\t\ \f\o\r\ dd-mmm-yyyy")
.HTMLBody = "Please find attached the new contact listings.
"
.AddAttachment sATTCH
.send
End With
GoTo bm_FallOut
bm_ErrorOut:
Debug.Print "could not send eml to " & sEML
bm_FallOut:
Set cdoMail = Nothing
End Sub
Sub scrub_clean(Optional wb As Workbook)
appTGGL bTGGL:=False
If wb Is Nothing Then Set wb = ThisWorkbook
Do While Worksheets.Count > 3: Worksheets(4).Delete: Loop
appTGGL
End Sub
Sub appTGGL(Optional bTGGL As Boolean = True)
Application.Calculation = IIf(bTGGL, xlCalculationAutomatic, xlCalculationManual)
Application.EnableEvents = bTGGL
Application.DisplayAlerts = bTGGL
Application.ScreenUpdating = bTGGL
Application.Cursor = IIf(bTGGL, xlDefault, xlWait)
End Sub
Results:
After running the main() you should be left with a workbook populated with a number or rep contact list worksheets that resemble the following:.

You may want to consider putting the classes from Orphid's response into the operational code found in this one.
For the time being, that sample workbook is available from my public dropbox at Rep_Contact_List_Reports.xlsb.