I'm on XL2007 - Windows 7.
I need an element of error handling in the below code.
Some of the values in range rngburndown do not exist as worksheets, and i need the VBA to skip these cells, and copy the rows that do exist as worksheets to the nextavailable row in the matching worksheet name.
Sub Retrieve_Forecasts()
Dim objWorksheet As Worksheet
Dim rngBurnDown As RANGE
Dim rngCell As RANGE
Dim strPasteToSheet As String
Dim objNewSheet As Worksheet
Dim rngNextAvailbleRow As RANGE
'DEFINE SOURCE WORKSHEET
Set objWorksheet = ThisWorkbook.Worksheets("Forecasts")
'DEFINE LIST OF FORECASTS - INCLUDING VALUES WHICH MAY NOT EXIST AS WORKSHEETS
Set rngBurnDown = objWorksheet.RANGE("A2:A" & objWorksheet.Cells(Rows.Count, "A").End(xlUp).Row)
'LOOP THROUGH RANGE
For Each rngCell In rngBurnDown.Cells
objWorksheet.Select
If rngCell.Value <> "" Then
'SELECT ROW
rngCell.EntireRow.Select
'COPY
Selection.Copy
'FIND AND PASTE WHERE WORKSHEET NAME MATCHES FORECAST LIST
Set objNewSheet = ThisWorkbook.Worksheets(rngCell.Value)
objNewSheet.Select
Set rngNextAvailbleRow = objNewSheet.RANGE("A1:A" & objNewSheet.Cells(Rows.Count, "A").End(xlUp).Row)
RANGE("A" & rngNextAvailbleRow.Rows.Count + 1).Select
ActiveSheet.Paste
End If
Next rngCell
objWorksheet.Select
objWorksheet.Cells(1, 1).Select
End Sub
You could use the commands "On Error GoTo 0" to ignore all errors or use "On Error Resume Next" to ignore the error and execute the next instruction as shown in https://msdn.microsoft.com/en-us/library/5hsw66as.aspx
Example:
For Each rngCell In rngBurnDown.Cells
On Error GoTo 0
objWorksheet.Select
If rngCell.Value <> "" Then
'SELECT ROW
rngCell.EntireRow.Select
'COPY
Selection.Copy
'FIND AND PASTE WHERE WORKSHEET NAME MATCHES FORECAST LIST
Set objNewSheet = ThisWorkbook.Worksheets(rngCell.Value)
objNewSheet.Select
Set rngNextAvailbleRow = objNewSheet.RANGE("A1:A" & objNewSheet.Cells(Rows.Count, "A").End(xlUp).Row)
RANGE("A" & rngNextAvailbleRow.Rows.Count + 1).Select
ActiveSheet.Paste
End If
Next rngCell
Related
Instead of hard coding the value to be looked up ("1234"), I would like to use a range of values, on a separate worksheet("Items") to use as the search criteria.
I would also like to substitute that same value for the destination sheet.
For example, the first value in the range could be "8754", I would like the code to look for this value then paste the columns, A,B,C,F and the cell containing the value onto the worksheet "8754". (I have all of the worksheets created already)
TIA
Sub Test()
Dim Cell As Range
With Sheets("Sheet1") 'Sheet with data to check for value
For Each Cell In .Range("H1:H" & .Cells(.Rows.Count, "H").End(xlUp).Row)
pos = InStr(Cell.Value, "1234")
If pos > 0 Then
NextFreeRow = Sheets("Sheet2").Cells(Sheets("Sheet2").Rows.Count,
"A").End(xlUp).Row + 1
'get the next empty row to paste data to
.Range("A" & Cell.Row & ",B" & Cell.Row & ",C" & Cell.Row & ",F" &
Cell.Row & "," & Cell.Address).Copy Destination:=Sheets("Sheet2").Range("A" & NextFreeRow)
End If
Next Cell
End With
End Sub
This uses FIND rather than FILTER to copy the correct rows.
The Main procedure defines the range you're searching and which values will be searched for. The FindValues procedure finds the value and copies it to the correct sheet.
This assumes that Sheet3!A1:A3 contains a unique list of values to be searched for and the these values can be found in Sheet1!H:H.
It also assumes that all sheets already exist.
Public Sub Main()
Dim rToFind As Range
Dim rValue As Range
Dim rSearchRange As Range
With ThisWorkbook
'Update to the range being searched.
With .Worksheets("Sheet1")
Set rSearchRange = .Range("H1", .Cells(.Rows.Count, 8).End(xlUp))
End With
'Update to the range containing the values to be searched for.
Set rToFind = .Worksheets("Sheet3").Range("A1:A3")
End With
'Passe each of the values to be searched to the FindValues procedure.
For Each rValue In rToFind
FindValues rValue, rSearchRange
Next rValue
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Alternative method to look for hard-coded values.
' `ValuesToFind` in FindValues procedure will needed changing to a Variant.
'
' Dim vAlternativeSearch As Variant
' Dim vAlternativeValue As Variant
' vAlternativeSearch = Array(1475, 1683, 219)
'
' For Each vAlternativeValue In vAlternativeSearch
' FindValues vAlternativeValue, rSearchRange
' Next vAlternativeValue
End Sub
Public Sub FindValues(ValueToFind As Range, RangeToSearch As Range)
Dim rFound As Range
Dim sFirstAddress
Dim rLastUsedCell As Range
'Find the next available row on the referenced sheet.
With ThisWorkbook.Worksheets(CStr(ValueToFind))
Set rLastUsedCell = .Range("A1", .Cells(.Rows.Count, 1).End(xlUp)).Offset(1)
End With
With RangeToSearch
'Find the first value.
Set rFound = .Find(What:=ValueToFind, _
After:=RangeToSearch.Cells(RangeToSearch.Cells.Count), _
LookAt:=xlPart, _
SearchDirection:=xlNext)
'If the first value exists then remember the address, copy the cells to the
'correct sheet and look for the next row with the same value. Stop when
'it reaches the first address again.
If Not rFound Is Nothing Then
sFirstAddress = rFound.Address
Do
'You may have to muck around with this to get the correct range to copy.
'If rFound is in column H this will copy columns B:D and F.
Union(rFound.Offset(, -6).Resize(, 3), rFound.Offset(, -2)).Copy Destination:=rLastUsedCell
Set rLastUsedCell = rLastUsedCell.Offset(1)
Set rFound = .FindNext(rFound)
Loop While rFound.Address <> sFirstAddress
End If
End With
End Sub
Edit 1:
You say the worksheets already exists, but in your comment you say put it in a brand new sheet.
To add a new sheet add this function:
Public Function WorkSheetExists(SheetName As String, Optional WrkBk As Workbook) As Boolean
Dim wrkSht As Worksheet
If WrkBk Is Nothing Then
Set WrkBk = ThisWorkbook
End If
On Error Resume Next
Set wrkSht = WrkBk.Worksheets(SheetName)
WorkSheetExists = (Err.Number = 0)
Set wrkSht = Nothing
On Error GoTo 0
End Function
and then add this code directly after the variable declaration in the FindValues procedure:
Dim wrkSht As Worksheet
If Not WorkSheetExists(CStr(ValueToFind)) Then
Set wrkSht = ThisWorkbook.Worksheets.Add
wrkSht.Name = CStr(ValueToFind)
End If
Edit 2:
This updated code searches columns Q:Z, returns the values from A:L as well as the found cell.
To update from the original code I had to change rSearchRange to look from Q1 to column 26, and update the Copy/Paste line to return the correct range.
Public Sub Main()
Dim rToFind As Range
Dim rValue As Range
Dim rSearchRange As Range
With ThisWorkbook
'Update to the range being searched.
With .Worksheets("Data")
Set rSearchRange = .Range("Q1", .Cells(.Rows.Count, 26).End(xlUp))
End With
'Update to the range containing the values to be searched for.
Set rToFind = .Worksheets("Items").Range("A1:A2")
End With
'Passe each of the values to be searched to the FindValues procedure.
For Each rValue In rToFind
FindValues rValue, rSearchRange
Next rValue
End Sub
Public Sub FindValues(ValueToFind As Range, RangeToSearch As Range)
Dim rFound As Range
Dim sFirstAddress
Dim rLastUsedCell As Range
'Find the next available row on the referenced sheet.
With ThisWorkbook.Worksheets(CStr(ValueToFind))
Set rLastUsedCell = .Range("A1", .Cells(.Rows.Count, 1).End(xlUp)).Offset(1)
End With
With RangeToSearch
'Find the first value.
Set rFound = .Find(What:=ValueToFind, _
After:=RangeToSearch.Cells(RangeToSearch.Cells.Count), _
LookAt:=xlPart, _
SearchDirection:=xlNext)
'If the first value exists then remember the address, copy the cells to the
'correct sheet and look for the next row with the same value. Stop when
'it reaches the first address again.
If Not rFound Is Nothing Then
sFirstAddress = rFound.Address
Do
'Parent of RangeToSeach range which will be the Data worksheet.
With .Parent
'Copy columns A:L (columns 1 to 12) and the found cell.
Union(.Range(.Cells(rFound.Row, 1), .Cells(rFound.Row, 12)), rFound).Copy Destination:=rLastUsedCell
End With
Set rLastUsedCell = rLastUsedCell.Offset(1)
Set rFound = .FindNext(rFound)
Loop While rFound.Address <> sFirstAddress
End If
End With
End Sub
Option Explicit
Public Sub Test()
Dim ws1 As Worksheet, ws2 As Worksheet, ws3 As Worksheet, lr1 As Long, lr2 As Long
Dim luArr As Variant, luVal As Variant, r As String, itm As Variant, itmRow As Long
Set ws1 = ThisWorkbook.Worksheets("Data") 'Sheet with data to check for value
Set ws3 = ThisWorkbook.Worksheets("Items") 'LookUp values
luArr = ws3.UsedRange.Columns("A") 'LookUp column
lr1 = ws1.Cells(ws1.Rows.Count, "H").End(xlUp).Row
Dim findRng As Range, copyRng As Range, toRng As Range, fr As Long
Set findRng = ws1.Range("H1:H" & lr1)
On Error Resume Next 'Expected error: sheet not found
Application.ScreenUpdating = False
For Each luVal In luArr
Set ws2 = Nothing
Set ws2 = ThisWorkbook.Worksheets(luVal) 'Copy to
If ws2 Is Nothing Then
Err.Clear
Else
itm = Application.Match(luVal, findRng, 0)
If Not IsError(itm) Then
findRng.AutoFilter Field:=1, Criteria1:="*" & luVal & "*"
fr = IIf(findRng.SpecialCells(xlCellTypeVisible).Cells.Count = 1, 1, 2)
With ws1.UsedRange
Set copyRng = .Range("A" & fr & ":C" & lr1)
Set copyRng = Union(copyRng, .Range("F" & fr & ":F" & lr1))
Set copyRng = Union(copyRng, .Range("H" & fr & ":H" & lr1))
End With
lr2 = ws2.Cells(ws2.Rows.Count, "A").End(xlUp).Row + 1
copyRng.Copy
ws2.Cells(lr2, 1).PasteSpecial
findRng.AutoFilter
End If
End If
Next
Application.ScreenUpdating = True
End Sub
Sheet1
Items
Before (Sheet A1, A2, and A3)
After
I have four sheets with raw data that I would like to be duplicated in my workbook and left alone for cross reference. Then I would like to remove all rows above the cell with the text "proj def" (it appears twice, but there are cells that lie in between the two appearances - which will be evident in my code). I would like to do this for the first four sheets of my workbook while leaving the original duplicated worksheets alone but am only able to do so with the first worksheet labeled "ptd". I have tried to activate the next worksheet "ytd" and even delete the original worksheet "ptd" to see if it would allow me to change the location of myRange but I have had no success. Essentially I want to run this code in sub methods, two for the first sheet "ptd", two more for the second sheet "ytd", another 2 for "qtr" and the final 2 for "mth". Any edits to my sample code would be much appreciated.
Sub part1()
Worksheets("ptd").Copy After:=Worksheets("mth")
Worksheets("ytd").Copy After:=Worksheets("ptd (2)")
Worksheets("qtr").Copy After:=Worksheets("ytd (2)")
Worksheets("mth").Copy After:=Worksheets("qtr (2)")
End Sub
Sub part2()
Worksheets("ptd").Activate
Set rngActiveRange = ActiveCell
Dim MyRange As Range
Set MyRange = ActiveSheet.Range("A:A")
MyRange.Find("Customer Unit", LookIn:=xlValues).Select
rngActiveRange.Offset(-1, 0).Select
Range(rngActiveRange.Row & ":" & 1).Rows.Delete
End Sub
Sub part3()
Dim MyRange As Range
Set MyRange = ActiveSheet.Range("A:A")
MyRange.Find("Project Definition", LookIn:=xlValues).Select
ActiveCell.Offset(-1, 0).Select
Range(ActiveCell.Row & ":" & 1).Rows.Delete
End Sub
Sub part4()
Worksheets("ytd").Activate
Set rngActiveRange = ActiveCell
Dim MyRange As Range
Set MyRange = ActiveSheet.Range("A:A")
MyRange.Find("Customer Unit", LookIn:=xlValues).Select
rngActiveRange.Offset(-1, 0).Select
Range(rngActiveRange.Row & ":" & 1).Rows.Delete
End Sub
Sub part5()
Dim MyRange As Range
Set MyRange = ActiveSheet.Range("A:A")
MyRange.Find("Project Definition", LookIn:=xlValues).Select
ActiveCell.Offset(-1, 0).Select
Range(ActiveCell.Row & ":" & 1).Rows.Delete
End Sub
If I understand correctly, the below should work. The main thing I did was re-write with avoiding the use of .Select/.Activate.
Sub remove_Rows()
Dim ws As Worksheet
Dim foundCel As Range
' Copy sheets
Worksheets("ptd").Copy After:=Worksheets("mth")
Worksheets("ytd").Copy After:=Worksheets("ptd (2)")
Worksheets("qtr").Copy After:=Worksheets("ytd (2)")
Worksheets("mth").Copy After:=Worksheets("qtr (2)")
' Start removing rows
For Each ws In ActiveWorkbook.Worksheets
With ws
If InStr(1, .Name, "(") = 0 Then
Set foundCel = .Range("A:A").Find("Customer Unit", LookIn:=xlValues)
.Range(foundCel.Offset(-1, 0).Row & ":" & 1).Rows.Delete
Set foundCel = .Range("A:A").Find("Project Definition", LookIn:=xlValues)
.Range(foundCel.Offset(-1, 0).Row & ":" & 1).Rows.Delete
End If
End With
Next ws
End Sub
I need to consolidate multiple worksheets in to one worksheet while having a space left between each tab of consolidated information. Can anyone help with this? Below is the code I have but I'm missing something:
Sub CopyWorksheets()
Dim wrk As Workbook
Dim sht As Worksheet
Dim trg As Worksheet
Dim rng As Range
Dim colCount As Integer
Set wrk = ActiveWorkbook 'Working in active workbook
For Each sht In wrk.Worksheets
If sht.Name = "Master" Then
MsgBox "There is a worksheet called as 'Master'." & vbCrLf & _
"Please remove or rename this worksheet since 'Master' would be" & _
"the name of the result worksheet of this process.", _
vbOKOnly + vbExclamation, "Error"
Exit Sub
End If
Next sht
'We don't want screen updating
Application.ScreenUpdating = False
'Add new worksheet as the last worksheet
Set trg = wrk.Worksheets.Add(After:=wrk.Worksheets(wrk.Worksheets.Count))
'Rename the new worksheet
trg.Name = "Master"
'Get column headers from the first worksheet
'Column count first
Set sht = wrk.Worksheets(1)
colCount = sht.Cells(1, 255).End(xlToLeft).Column
'Now retrieve headers, no copy&paste needed
With trg.Cells(1, 1).Resize(1, colCount)
.Value = sht.Cells(1, 1).Resize(1, colCount).Value
'Set font as bold
.Font.Bold = True
End With
'We can start loop
For Each sht In wrk.Worksheets
'If worksheet in loop is the last one, stop execution (it is Master worksheet)
If sht.Index = wrk.Worksheets.Count Then
Exit For
End If
'Data range in worksheet - starts from second row as
'first rows are the header rows in all worksheets
Set rng = sht.Range(sht.Cells(2, 1), sht.Cells(65536, 1).End(xlUp).Resize(, colCount))
'Put data into the Master worksheet
trg.Cells(65536, 1).End(xlUp).Offset(1).Resize(rng.Rows.Count, _
rng.Columns.Count).Value = rng.Value
'move cursor to bottom on active range and insert row
Range("A65536").End(xlUp).Offset(1, 0).Select
Selection.Offset(1, 0).Select
Next sht
'Fit the columns in Master worksheet
trg.Columns.AutoFit
'Screen updating should be activated
Application.ScreenUpdating = True
End Sub
Maybe this is what you need:
For Each sht In wrk.Worksheets
If sht.Index = wrk.Worksheets.Count Then Exit For
Set rng = sht.Range(sht.Cells(2, 1), _
sht.Cells(rows.count, 1).End(xlUp).Resize(, colCount))
'Put data into the Master worksheet (skip one empty row)
trg.Cells(rows.count, 1).End(xlUp).Offset(2).Resize(rng.Rows.Count, _
rng.Columns.Count).Value = rng.Value
Next sht
I have two sheets containing the employee records.
Sheet1 contains the Event Date, CardNo, Employee Name, Dept Id, Employee No, Entry and Exit Time, Total Working Hours, Status, ConcatinatedColumn and Remarks (copied through vlookup from sheet2)
Sheet2 contains ConcatinatedColumn, Event Date, Employee No, Name, Remarks.
If the data in the remarks column of sheet2 is "Sick Off" then that row should be inserted to sheet1 without effecting the previous records.
I've already written the code for it but it does not work.
Would be really grateful if anyone can help me out !
THANKS IN ADVANCE !
MY CODE :
Sub SickOff()
Dim objWorksheet As Sheet2
Dim rngBurnDown As Range
Dim rngCell As Range
Dim strPasteToSheet As String
'Used for the new worksheet we are pasting into
Dim objNewSheet As Sheet1
Dim rngNextAvailbleRow As Range
'Define the worksheet with our data
Set objWorksheet = ThisWorkbook.Worksheets("Sheet2")
'Dynamically define the range to the last cell.
'This doesn't include and error handling e.g. null cells
'If we are not starting in A1, then change as appropriate
Set rngBurnDown = objWorksheet.Range("G2:G" & objWorksheet.Cells(Rows.Count, "G").End(xlUp).Row)
'Now loop through all the cells in the range
For Each rngCell In rngBurnDown.Cells
objWorksheet.Select
If rngCell.Value = "Sick Off" Then
'select the entire row
rngCell.EntireRow.Select
'copy the selection
Selection.Copy
'Now identify and select the new sheet to paste into
Set objNewSheet = ThisWorkbook.Worksheets("Sheet1" & rngCell.Value)
objNewSheet.Select
'Looking at your initial question, I believe you are trying to find the next available row
Set rngNextAvailbleRow = objNewSheet.Range("A1:A" & objNewSheet.Cells(Rows.Count, "A").End(xlUp).Row)
Range("A" & rngNextAvailbleRow.Rows.Count + 1).Select
ActiveSheet.Paste
End If
Next rngCell
objWorksheet.Select
objWorksheet.Cells(1, 1).Select
'Can do some basic error handing here
'kill all objects
If IsObject(objWorksheet) Then Set objWorksheet = Nothing
If IsObject(rngBurnDown) Then Set rngBurnDown = Nothing
If IsObject(rngCell) Then Set rngCell = Nothing
If IsObject(objNewSheet) Then Set objNewSheet = Nothing
If IsObject(rngNextAvailbleRow) Then Set rngNextAvailbleRow = Nothing
End Sub
Let's say you have data in Sheet2 as shown below
Let's say the end of data in Sheet1 looks like this
Logic:
We are using autofilter to get the relevant range in Sheet2 which match Sick Off in Col G. Once we get that, we copy the data to the last row in Sheet1. After the data is copied, we simply shuffle data across to match the column headers. As you mentioned that the headers won't change so we can take the liberty of hardcoding the column names for shuffling this data.
Code:
Paste this code in a module
Option Explicit
Sub Sample()
Dim wsI As Worksheet, wsO As Worksheet
Dim lRow As Long, wsOlRow As Long, OutputRow As Long
Dim copyfrom As Range
Set wsI = ThisWorkbook.Sheets("Sheet1")
Set wsO = ThisWorkbook.Sheets("Sheet2")
'~~> This is the row where the data will be written
OutputRow = wsI.Range("A" & wsI.Rows.Count).End(xlUp).Row + 1
With wsO
wsOlRow = .Range("G" & .Rows.Count).End(xlUp).Row
'~~> Remove any filters
.AutoFilterMode = False
'~~> Filter G on "Sick Off"
With .Range("G1:G" & wsOlRow)
.AutoFilter Field:=1, Criteria1:="=Sick Off"
Set copyfrom = .Offset(1, 0).SpecialCells(xlCellTypeVisible).EntireRow
End With
'~~> Remove any filters
.AutoFilterMode = False
End With
If Not copyfrom Is Nothing Then
copyfrom.Copy wsI.Rows(OutputRow)
'~~> Shuffle data
With wsI
lRow = .Range("A" & .Rows.Count).End(xlUp).Row
.Range("A" & OutputRow & ":A" & lRow).Delete Shift:=xlToLeft
.Range("F" & OutputRow & ":F" & lRow).Copy .Range("K" & OutputRow)
.Range("F" & OutputRow & ":F" & lRow).ClearContents
.Range("B" & OutputRow & ":B" & lRow).Copy .Range("E" & OutputRow)
.Range("B" & OutputRow & ":B" & lRow).ClearContents
End With
End If
End Sub
Output:
I require assistance with the following please:
I need to filter a Range A9 - A32 for any data in column G.
Then i need to copy the data, but only columns A - E & G to sheet 2.
then delete the filtered data and return back to non filtered view.
I have tried the following without success:
Dim shSrc As Worksheet
Dim shDst As Worksheet
Dim rSrc As range
Dim rDst As range
Dim range
Dim numCol As Long ' number of columns to copy
On Error GoTo EH
range = ("A:E,G:G")
' select source and dest sheets
Set shSrc = ActiveWorkbook.Worksheets("Active Snag List")
Set shDst = ActiveWorkbook.Worksheets("Snag History")
' Select initial rows
Set rSrc = shSrc.Cells(9, 7)
Set rDst = shDst.Cells(2, 1)
' loop over source
Do While rSrc <> ""
' Test Source row, Qty = 0 and Name is not blank
With rSrc
If .Offset(0, 2) = 0 And .Value <> "" Then
'Copy
.Resize(1, range).Copy rDst.Resize(1, range)
Set rDst = rDst.Offset(1, 0)
End If
End With
Set rSrc = rSrc.Offset(1, 0)
Loop
Exit Sub
EH:
MsgBox "Error " & Err.Description
Thank you in advance!
To get your code working , replace the IF section with this
If .Offset(0, 2) = 0 And .Value <> "" Then
'Copy
'Cells A:E
rDst.Resize(1, 5).Value = .EntireRow.Cells(1, 1).Resize(1, 5).Value
' Cell G
rDst.Offset(0, 6).Value = .Value
Set rDst = rDst.Offset(1, 0)
End If
Why not use Autofilter rather than looping through cells? It will me much faster. See this example.
CODE(TRIED AND TESTED)
Option Explicit
Sub Sample()
Dim shSrc As Worksheet, shDst As Worksheet
Dim rDst As range, rng As range, rngtocopy As range
Dim lastrow As Long
On Error GoTo EH
'~~> Select source and dest sheets
Set shSrc = ThisWorkbook.Worksheets("Active Snag List")
Set shDst = ThisWorkbook.Worksheets("Snag History")
'~~> Select initial rows
Set rDst = shDst.Cells(2, 1)
With shSrc
'~~> Remove any filters
.AutoFilterMode = False
'~~> Get the last row of Col G
lastrow = .range("G" & .Rows.Count).End(xlUp).Row
With .range("A8:G" & lastrow)
'~~> Filter G Col for non blanks
.AutoFilter Field:=7, Criteria1:="<>"
'~~> Get the offset(to exclude headers)
Set rng = .Offset(1, 0).SpecialCells(xlCellTypeVisible)
'~~> Remove Col F from the resulting range
Set rngtocopy = Union(shSrc.range(Replace(rng.Address, "G", "E")), _
shSrc.range(Replace(rng.Address, "A", "G")))
'~~> Copy cells to relevant destination
rngtocopy.Copy rDst
'~~> Delete the filtered results
rng.EntireRow.Delete
End With
'~~> Remove any filters
.AutoFilterMode = False
End With
Exit Sub
EH:
MsgBox "Error " & Err.Description
End Sub
SNAPSHOTS
Sheet 1 before the macro runs
Sheet 2 after the macro runs
Sheet 1 after the macro runs