Am I performing the Index Match function in the wrong location?
Should I even be using IndexMatch?
My information in the table I am trying to get the information out of has CO number in column A.
Columns B has the information I am trying to populate my new worksheet with.
Sub AddWorkbooks()
Dim ChangeOrder As Range
Dim XCXX As Worksheet
Dim wb As Workbook
Dim CoForm As Worksheet
Dim CoFormCopy As Worksheet
Dim srNO As Variant
Set wb = ActiveWorkbook
Set XCXX = ActiveSheet
Set CoForm = wb.Worksheets("+CO Form+")
'Set wbNew = Workbooks.Add
srNO = XCXX.Range("D2").Value
'CoForm.Copy After:=Sheets(ActiveSheet.Index)
CoForm.Copy After:=XCXX
ActiveSheet.Name = "Proj" & " " & XCXX.Range("D2").Value
Set CoFormCopy = XCXX.Next 'the copy of +CO Form
With CoFormCopy
'Adds CO Number
Range("A6:D6").Value = XCXX.Range("D2").Value
'Adds CO Description from CO_List sheet based on CO Number
Range("A16").Value = Application.WorksheetFunction.Index(Sheets("CO_List").Range("B3:B"), Application.WorksheetFunction.Match(srNO, Sheets("CO_List").Range("A3:A"), 0))
'ActiveCell.FormulaR1C1 = XCXX.Range("D2").Value
End With
CoFormCopy.Move
End Sub
If no match is found WorksheetFunction.Match will fail. Application.Match will return #N/A error that you can test for with IsError().
Option Explicit
Sub AddWorkbooks()
Dim wb As Workbook, wbNew As Workbook
Dim srNo, desc As String
Dim v, lastrow As Long
' project number
srNo = ActiveSheet.Range("D2").Value
' find desc from CO_List sheet based on CO Number
Set wb = ActiveWorkbook
With wb.Sheets("CO_List")
lastrow = .Cells(.Rows.Count, "A").End(xlUp).Row
v = Application.Match(srNo, .Range("A3:A" & lastrow), 0)
If IsError(v) Then
MsgBox "No Description for '" & srNo & "'", vbExclamation
desc = "Description for " & srNo
Else
desc = Application.Index(.Range("B3:B" & lastrow), v)
End If
End With
' create new workbbok
Set wbNew = Workbooks.Add(1)
With wbNew.Sheets(1)
.Name = "Proj" & " " & srNo
.Range("A6:D6").Value = srNo
.Range("A16") = desc
End With
MsgBox "New workbook created for " & srNo, vbInformation
'wbNew.Save
End Sub
Related
I have a document that contains a couple of macros.
First extracts data from a data sheet (datasheet) and copies to a specific worksheet (reportsheet) when the criteria is met.
Second saves this as a PDF, creates an email and sends it.
I have 100+ sheets and would require duplicating these macros 100 times.
I want to combine these into one macro. I would like to loop through a range ("B6:B123") and if in that range the cell <> 0 then the macro needs to run but the report sheet reference I'd like to update dynamically using the adjacent cell value (Dx) that would trigger these to run.
Macro 1
Sub Search_extract_135()
Dim datasheet As Worksheet
Dim reportsheet As Worksheet
Dim ocname As String
Dim finalrow As Integer
Dim i As Integer
Set datasheet = Sheet121 ' stays constant
Set reportsheet = Sheet135 'need to update based on range that <>0 then taking cell reference as
ocname = reportsheet.Range("A1").Value 'stays constant
reportsheet.Range("A1:U499").EntireRow.Hidden = False
reportsheet.Range("A5:U499").ClearContents
datasheet.Select
finalrow = Cells(Rows.Count, 1).End(xlUp).Row
For i = 2 To finalrow
If Cells(i, 1) = ocname Then
Range(Cells(i, 1), Cells(i, 21)).Copy
reportsheet.Select
Range("A500").End(xlUp).Offset(1, 0).PasteSpecial xlPasteAll
datasheet.Select
End If
Next i
reportsheet.Select
Range("A4").Select
Call HideRows
End Sub
Macro 2
Sub Send_Email_135()
Dim wPath As String, wFile As String, wMonth As String, strPath As String, wSheet As Worksheet
Set wSheet = Sheet135
wMonth = Sheets("Journal").Range("K2")
wPath = ThisWorkbook.Path ThisWorkbook.Path
wFile = wSheet.Range("A1") & ".pdf"
wSheet.Range("A1:U500").ExportAsFixedFormat Type:=xlTypePDF, Filename:=wPath & "-" & wFile, _
Quality:=xlQualityStandard, IncludeDocProperties:=True, _
IgnorePrintAreas:=False, OpenAfterPublish:=False
strPath = wPath & "-" & wFile
Set dam = CreateObject("Outlook.Application").CreateItem(0)
'
dam.To = wSheet.Range("A2")
dam.cc = wSheet.Range("A3")
dam.Subject = "Statement " & wMonth
dam.Body = "Hi" & vbNewLine & vbNewLine & "Please find attached your statement." & Chr(13) & Chr(13) & "Regards," & Chr(13) & "xxxxx"
dam.Attachments.Add strPath
dam.Send
MsgBox "Email sent"
End Sub
The Excel document has names in column A, numeric values in column B and SheetCode in column D.
When cell within Range("B6:B123") <> 0 then run the two macros above but need report sheet from macro 1 & wSheet from macro 2 to use the same value in column D to references the specific worksheet code for the person that doesn't equal 0.
The solution it to use a dictionary to convert the codenames into sheet numbers and pass parameters into the subroutines so the same code can be applied to many different sheets.
Option Explicit
Sub Reporter()
' Journal sheet layout
Const ROW_START = 6
Const COL_NZ = "B" ' column to check <> 0
Const COL_CODE = "D" ' sheet codenames
' Fixed sheet code names
Const WS_DATA = "Sheet121"
Const WS_JOURNAL = "Sheet5"
Dim wb As Workbook, ws As Worksheet
Dim wsReport As Worksheet, wsJournal As Worksheet, wsData As Worksheet
Dim iLastRow As Long, i As Long, n As Long
Dim sCodeName As String, sMonth As String
' build a dictionary of codename->sheetno
Dim dict As Object, key As String
Set dict = CreateObject("Scripting.Dictionary")
Set wb = ThisWorkbook
For Each ws In wb.Sheets
dict.Add ws.CodeName, ws.Index
Next
' assign Fixed sheets
Set wsData = wb.Sheets(dict(WS_DATA)) ' or Sheet121
Set wsJournal = wb.Sheets(dict(WS_JOURNAL)) ' or Sheet5
sMonth = wsJournal.Range("K2")
' scan list of persons
With wsJournal
iLastRow = .Cells(Rows.Count, COL_CODE).End(xlUp).Row
For i = ROW_START To iLastRow
If .Cells(i, COL_NZ) <> 0 Then ' col B
sCodeName = .Cells(i, COL_CODE) ' col D
' set sheet, create report and email it
Set wsReport = wb.Sheets(dict(sCodeName))
Call Create_Report(wsReport, wsData)
Call Email_Report(wsReport, sMonth)
n = n + 1
End If
Next
End With
MsgBox n & " emails sent", vbInformation
End Sub
Sub Create_Report(wsReport As Worksheet, wsData)
Dim ocname As String, iLastRow As Long, i As Long
Dim rngReport As Range
With wsReport
ocname = .Range("A1").Value 'stays constant
.Range("A1:U500").EntireRow.Hidden = False
.Range("A5:U500").ClearContents
Set rngReport = .Range("A5")
End With
' scan down data sheet and copy to report sheet
Application.ScreenUpdating = False
With wsData
iLastRow = .Cells(Rows.Count, 1).End(xlUp).Row
For i = 2 To iLastRow
If wsData.Cells(i, 1) = ocname Then
.Cells(i, 1).Resize(1, 21).Copy rngReport
Set rngReport = rngReport.Offset(1)
End If
Next i
End With
'Call HideRows
Application.ScreenUpdating = True
End Sub
Sub Email_Report(wsReport As Worksheet, sMonth As String)
Dim sPDFname As String, oMail As Outlook.MailItem
sPDFname = ThisWorkbook.Path & "\" & wsReport.Range("A1") & ".pdf"
Dim oOut As Object ' Outlook.Application
Set oOut = CreateObject("Outlook.Application")
Set oMail = oOut.CreateItem(0)
With oMail
wsReport.Range("A1:U500").ExportAsFixedFormat _
Type:=xlTypePDF, Filename:=sPDFname, _
Quality:=xlQualityStandard, IncludeDocProperties:=True, _
IgnorePrintAreas:=False, OpenAfterPublish:=False
.To = wsReport.Range("A2").Value2
.cc = wsReport.Range("A3").Value2
.Subject = "Statement " & sMonth
.Body = "Hi" & vbNewLine & vbNewLine & _
"Please find attached your statement." & vbCr & vbCr & _
"Regards," & vbCr & "xxxxx"
.Attachments.Add sPDFname
.Display ' or .Send
End With
MsgBox "Email sent to " & wsReport.Range("A2").Value2, , wsReport.Name
oOut.Quit
End Sub
I have the below macro that cuts my report up by name (when it asks me which column to filter on, its 2).
It works perfectly for I need, as it also saves down each cut per person for each report where the report is saved. However, I also need it to pick up everything by name of person in all other tabs in the report. EG: Dave Smith is on the main summary page, and the below macro cuts it by Dave Smith, and saves that cut down. But Dave Smith also has data in 7/8 other tabs, that also need to be included in the new, saved down cut.
Sub parse_data()
'This macro splits data into multiple worksheets
'based on the variables on a column found in Excel.
'An InputBox asks you which columns you'd like
'to filter by, and it just creates these worksheets.
Const TITLE_ROW = 1
Dim wbOut As Workbook
Dim ws As Worksheet, wsOut As Worksheet
Dim iLastRow As Long, iRow As Long
Dim iFilterCol As Integer
Dim sPath As String
' get filter column nu,ber
iFilterCol = Application.InputBox( _
prompt:="Which column would you like to filter by?", _
title:="Filter column", Default:="3", Type:=1)
If iFilterCol < 1 Then
MsgBox iFilterCol & " not valid", vbCritical
Exit Sub
End If
Set ws = ActiveSheet
sPath = ThisWorkbook.Path & "\"
iLastRow = ws.Cells(ws.Rows.Count, iFilterCol).End(xlUp).Row
Dim dict As Object, key
Set dict = CreateObject("Scripting.Dictionary")
' get unique values using dictionary
For iRow = TITLE_ROW + 1 To iLastRow
key = Trim(ws.Cells(iRow, iFilterCol))
If Not dict.exists(key) Then
dict.Add key, iRow
End If
Next
' create separate workbooks
Application.ScreenUpdating = False
For Each key In dict
' apply filter
ws.Rows(TITLE_ROW).AutoFilter Field:=iFilterCol, Criteria1:=key
' create new workbook
Set wbOut = Workbooks.Add
Set wsOut = wbOut.Sheets(1)
wsOut.Name = key
ws.Range("A" & TITLE_ROW & ":A" & iLastRow).EntireRow.Copy wsOut.Range("A1")
wsOut.Columns.AutoFit
' save and close
wbOut.SaveAs (sPath & key & ".xlsx")
wbOut.Close False
Next
ws.Activate
ws.AutoFilterMode = False
Application.ScreenUpdating = True
MsgBox dict.Count & " workbooks created", vbInformation
End Sub
Use Find to locate the filter column for the other sheets, apply filter and repeat the code for the first sheet.
Option Explicit
Sub parse_data()
'This macro splits data into multiple worksheets
'based on the variables on a column found in Excel.
'An InputBox asks you which columns you'd like
'to filter by, and it just creates these worksheets.
Const TITLE_ROW = 1
Dim wbOut As Workbook, wb As Workbook
Dim ws As Worksheet, wsOut As Worksheet, wsOther As Worksheet
Dim rng As Range
Dim iLastRow As Long, iRow As Long, iLastOther As Long
Dim iFilterCol As Integer, n As Integer
Dim sPath As String, sSummary As String
' get filter column nu,ber
iFilterCol = Application.InputBox( _
prompt:="Which column would you like to filter by?", _
Title:="Filter column", Default:="3", Type:=1)
If iFilterCol < 1 Then
MsgBox iFilterCol & " not valid", vbCritical
Exit Sub
End If
Set wb = ThisWorkbook ' or ActiveWorkbook
Set ws = ActiveSheet
sSummary = ws.Name
sPath = ThisWorkbook.Path & "\"
iLastRow = ws.Cells(ws.Rows.Count, iFilterCol).End(xlUp).Row
Dim dict As Object, key
Set dict = CreateObject("Scripting.Dictionary")
' get unique values using dictionary
For iRow = TITLE_ROW + 1 To iLastRow
key = Trim(ws.Cells(iRow, iFilterCol))
If Not dict.exists(key) Then
dict.Add key, iRow
End If
Next
' create separate workbooks
Application.ScreenUpdating = False
For Each key In dict
' apply filter
ws.Rows(TITLE_ROW).AutoFilter Field:=iFilterCol, Criteria1:=key
' create new workbook
Set wbOut = Workbooks.Add(xlWBATWorksheet) ' 1 sheet
Set wsOut = wbOut.Sheets(1)
wsOut.Name = key
ws.Range("A" & TITLE_ROW & ":A" & iLastRow).EntireRow.Copy wsOut.Range("A1")
wsOut.Columns.AutoFit
' search other worksheets
For Each wsOther In wb.Sheets
If wsOther.Name <> sSummary Then
'find name to get filter column
wsOther.AutoFilterMode = False
Set rng = wsOther.UsedRange.Find(CStr(key), LookIn:=xlValues, lookat:=xlWhole)
If Not rng Is Nothing Then
iLastOther = wsOther.Cells(ws.Rows.Count, rng.Column).End(xlUp).Row
wsOther.Rows(TITLE_ROW).AutoFilter _
Field:=rng.Column, Criteria1:=CStr(key)
n = wbOut.Sheets.Count
Set wsOut = wbOut.Sheets.Add(after:=wbOut.Sheets(n))
wsOut.Name = wsOther.Name
wsOther.Range("A" & TITLE_ROW & ":A" & iLastOther).EntireRow.Copy _
wsOut.Range("A1")
wsOut.Columns.AutoFit
End If
wsOther.AutoFilterMode = False
End If
Next
' save and close
wbOut.SaveAs (sPath & key & ".xlsx")
wbOut.Close False
Next
ws.Activate
ws.AutoFilterMode = False
Application.ScreenUpdating = True
MsgBox dict.Count & " workbooks created", vbInformation
End Sub
I am very new to this so apologies if its something simple but hopefully someone can help.
I have an input box to add a new person to a table. This then copies a template and is renamed to the persons name. I need reference cell I3 and others on the new sheet that has been created to be entered into the table next to their name. Below is the code i have got so far
'input box to get new user name and check if valid and create new sheet
Dim wb As Workbook: Set wb = ThisWorkbook
Dim ws As Worksheet: Set ws = wb.Sheets("Player Template")
Dim newws As Worksheet, sh As Worksheet, newname
Dim query As Long, xst As Boolean, info As String
retry:
xst = False
newname = Application.InputBox("Please Enter New players Name.", info, , , , , , 2)
If newname = "False" Then Exit Sub
For Each sh In wb.Sheets
If sh.Name = newname Then
xst = True: Exit For
End If
Next
If Len(newname) = 0 Or xst = True Then
info = "Name is invalid. Please Retry."
GoTo retry
End If
ws.Copy after:=ws: Set newws = ActiveSheet: newws.Name = newname
Sheets("Table").Select
Range("C6").Select
Selection.End(xlDown).Select
ActiveCell.Offset(1, 0).Select
ActiveCell.Value = newname
ActiveCell.Offset(0, 1).Select
ActiveCell.Value =
I don't know what code to add to the end to reference the cells i need in the table other than do it manually after the person has been added. I have looked for answers but found nothing.
This code copies a sheet called "player template" and creates it under the name from inputbox. References from range I3:M3 are copied to next free row in sheet "table" column "C". C & lastrow get's player's sheet name and columns to the right of the name are filled with the references to that sheet
Option Explicit
Sub paste_to_table()
Dim last_tblrow As Double
Dim tblwks As Worksheet, newwks As Worksheet, sh As Worksheet
Dim targetrng As Range
Dim newname As String
Dim wb As Workbook: Set wb = ThisWorkbook
Dim ws As Worksheet: Set ws = wb.Sheets("Player Template")
Set tblwks = ThisWorkbook.Worksheets("Table")
Dim query As Long, xst As Boolean, info As String
retry:
xst = False
newname = Application.InputBox("Please Enter New players Name.", info, , , , , , 2)
If newname = "False" Then Exit Sub
For Each sh In wb.Sheets
If sh.Name = newname Then
xst = True: Exit For
End If
Next
If Len(newname) = 0 Or xst = True Then
info = "Name is invalid. Please Retry."
GoTo retry
End If
ws.Copy After:=ws: Set newwks = ActiveSheet: newwks.Name = newname
'get last row of "table" column "C"
last_tblrow = tblwks.Cells(Rows.Count, "C").End(xlUp).Row
'set targetrng range variable to next empty cell of column C
Set targetrng = tblwks.Range("C" & last_tblrow + 1)
'newname value into next empty row of column C
targetrng.Value = newname
'next value into "D7" to of "table" wks from cell "I3","I4","I5".....
targetrng.Offset(0, 1).Value = "=" & newwks.Name & "!" & newwks.Cells(3, 9).Address
targetrng.Offset(0, 2).Value = "=" & newwks.Name & "!" & newwks.Cells(3, 10).Address
targetrng.Offset(0, 3).Value = "=" & newwks.Name & "!" & newwks.Cells(3, 11).Address
targetrng.Offset(0, 4).Value = "=" & newwks.Name & "!" & newwks.Cells(3, 12).Address
targetrng.Offset(0, 5).Value = "=" & newwks.Name & "!" & newwks.Cells(3, 13).Address
End Sub
Dim sourcewb As Workbook
Dim targetWorkbook As Workbook
Dim filter As String
Dim filter2 As String
Dim rw As Long
Dim lookup As String
Dim X As Range
Dim y As Range
Dim a, b As Variant
Set sourcewb = ActiveWorkbook
Set X = sourcewb.Worksheets(1).Range("A:G")
Dim sourceSheet As Worksheet
Set sourceSheet = sourcewb.Worksheets(1)
MsgBox sourceSheet.Name
X.Select
MsgBox sourcewb.Name
filter = "(*.xls),*.xls"
Caption = "Please Select an input file "
Application.ScreenUpdating = False
Filename = Application.GetOpenFilename(filter, , Caption)
Set targetWorkbook = Application.Workbooks.Open(Filename)
Set y = targetWorkbook.Worksheets(1).Range("A:G")
y.Select
Dim targetSheet As Worksheet
Set targetSheet = targetWorkbook.Worksheets(1)
MsgBox targetSheet.Name & " This is the country code sheet name "
Set targetWorkbook = ActiveWorkbook
MsgBox targetWorkbook.Name
y.Select
sourcewb.Activate
MsgBox ActiveWorkbook.Name & " IS the active workbook"
MsgBox sourcewb.Name
MsgBox sourcewb.Name & " This is the source workbook "
MsgBox targetWorkbook.Name & " This is the target workbook "
MsgBox "Trying to map from target to source "
With sourcewb.Worksheets(1)
For rw= 2 To Cells(Rows.Count, 1).End(xlUp).Row
Cells(rw, 4) = Application.VLookup(Cells(rw, 1).Value, y, 4, False)
'MsgBox Cells(a, 4).Value2
Next rw
End With
MsgBox "All required columns from source mapped to target file "
Set sourcewb = ActiveWorkbook
MsgBox ActiveWorkbook.Name
Application.ScreenUpdating = False
I have a workbook sourcewb. I open another workbook targetworkbook from the sourceworkbook. My Columns in sourcewb are Sl No, Country code,country names
slno country code country name Region
1 AL Algeria
2 US USA
3 UK United Kingdom
My targetwb is
country code country name Region
AL Algeria EMEA
US USA Americas
UK United Kingdom Europe
I am trying to fetch Region column from country code in the sourcewb as there is no slno in the targetwb and the order of country codes are not the same as sourcewb.
I get an error 2042. I have tried storing the target value with string, int, long, variant, nothing has worked till now.
Any suggestions or help would be really helpful.
With some "clean-up" and organization to your original code, try the code below.
3 comments:
When you are using a With statement, don't forget to nest all objects inside with a ..
Stay away from using Select and Activate, not only it's not necessary, it also slows down your code's run-time.
You need to trap the scenario that Application.VLookup will not find a value, and then you will get a run-time error.
Explanations inside the code as comments.
Code
Option Explicit
Sub AutoVLookup()
Dim sourcewb As Workbook
Dim targetWorkbook As Workbook
Dim sourceSheet As Worksheet
Dim targetSheet As Worksheet
Dim X As Range
Dim y As Range
Dim filter As String
Dim filter2 As String
Dim rw As Long
Dim lookup As String
Dim a, b As Variant
Set sourcewb = ActiveWorkbook ' set Activeworkbook object
Set sourceSheet = sourcewb.Worksheets(1) ' set source sheet
Set X = sourceSheet.Range("A:G") ' set source range
filter = "(*.xls),*.xls"
Caption = "Please Select an input file "
Application.ScreenUpdating = False
Filename = Application.GetOpenFilename(filter, , Caption)
Set targetWorkbook = Workbooks.Open(Filename) ' set target workbook object
Set targetSheet = targetWorkbook.Worksheets(1) ' set target sheet
Set y = targetSheet.Range("A:G") ' set target range
With sourceSheet
For rw = 2 To .Cells(.Rows.Count, 1).End(xlUp).Row ' get last row in column A
' make sure VLoookup found a match, otherwise you will get a run-time error
If Not IsError(Application.VLookup(.Cells(rw, 1).Value, y, 4, False)) Then
.Cells(rw, 4) = Application.VLookup(.Cells(rw, 1).Value, y, 4, False) ' this will fetch column "E" values
'MsgBox Cells(a, 4).Value2
End If
Next rw
End With
MsgBox "All required columns from source mapped to target file "
Application.ScreenUpdating = True
End Sub
i am attempting to write a script that goes over a specific column and then copies all rows containing the value of "rejected" in said column to a new excel file/workbook.
Everything seems to work just fine except for the actual Paste command which fails every time.
The code:
Sub button()
Dim x As String
Dim found As Boolean
strFileFullName = ThisWorkbook.FullName
strFileFullName = Replace(strFileFullName, ".xlsm", "")
strFileFullName = strFileFullName + "_rejected.xlsx"
' MsgBox strFileFullName
Set oExcel = CreateObject("Excel.Application")
Set obook = oExcel.Workbooks.Add(1)
Set oSheet = obook.Worksheets(1)
oSheet.Name = "Results"
' Select first line of data.
Range("E2").Select
' Set search variable value.
x = "rejected"
' Set Boolean variable "found" to false.
found = False
' Set Do loop to stop at empty cell.
Do Until IsEmpty(ActiveCell)
' Check active cell for search value.
If ActiveCell.Value = "" Then
Exit Do
End If
If ActiveCell.Value = x Then
found = True
rowToCopy = ActiveCell.Row
ActiveSheet.Rows(ActiveCell.Row).Select
Selection.Copy
oSheet.Range("A1").Select
lastrow = oSheet.Cells(Rows.Count, "B").End(xlUp).Row
' oSheet.Rows(1).Select.PasteSpcial
End If
' Step down 1 row from present location.
ActiveCell.Offset(1, 0).Select
Loop
' Check for found.
If found = True Then
MsgBox "Value found in cell " & ActiveCell.Address
Else
MsgBox "Value not found"
End If
obook.SaveAs strFileFullName
obook.Close
End Sub
Any idea why i keep failing with the paste function?
Thanks!
Try this, no selects involved.
Sub AddWB()
Dim nwBk As Workbook, WB As Workbook, Swb As String
Dim Rws As Long, Rng As Range, c As Range, sh As Worksheet
Set WB = ThisWorkbook
Set sh = WB.Worksheets("Sheet1")
Rws = sh.Cells(Rows.Count, "E").End(xlUp).Row
Set Rng = Range(sh.Cells(2, 5), sh.Cells(Rws, 5))
Set nwBk = Workbooks.Add(1)
Swb = WB.Path & "\" & Mid(WB.Name, 1, Len(WB.Name) - 5) & ".xlsx"
MsgBox Swb
For Each c In Rng.Cells
If c = "x" Then c.EntireRow.Copy nwBk.Sheets(1).Cells(Rows.Count, "A").End(xlUp).Offset(1, 0)
Next c
nwBk.SaveAs Filename:=Swb
End Sub
XLorate.com
Your PasteSpecial command might fail because it's spelled incorrectly. At any rate, if you've got a lot of rows, you should consider something faster than looping through them.
This uses AutoFilter to copy all rows meeting the criteria in one pass. It will also copy the header row. If that's not what you want, you can delete row 1 of the new worksheet after the copy:
Sub CopyStuff()
Dim SearchString As String
Dim Found As Boolean
Dim wsSource As Excel.Worksheet
Dim wbTarget As Excel.Workbook
Dim wsTarget As Excel.Worksheet
Dim LastRow As Long
Set wsSource = ActiveSheet
SearchString = "rejected"
With wsSource
Found = Application.WorksheetFunction.CountIf(.Range("E:E"), SearchString) > 0
If Not Found Then
MsgBox SearchString & " not found"
Exit Sub
End If
Set wbTarget = Workbooks.Add(1)
Set wsTarget = wbTarget.Worksheets(1)
wsTarget.Name = "Results"
.Range("E:E").AutoFilter
LastRow = .Range("E" & .Rows.Count).End(xlUp).Row
.Range("E:E").AutoFilter field:=1, Criteria1:=SearchString
.Range("E1:E" & LastRow).SpecialCells(xlCellTypeVisible).EntireRow.Copy _
Destination:=wsTarget.Range("A1")
End With
wbTarget.SaveAs Replace(ThisWorkbook.FullName, ".xlsm", "_rejected.xlsx")
wbTarget.Close
End Sub
I didn't use your code to create a new Excel instance, as I couldn't see why that would be needed here, and it could cause problems. (For example,yYou don't kill the instance in your original code.)