I've got this table full of data. And column K in each row contains a number. So basically what I'm trying to do is move that entire row, if the data in that column is greater than 9, over to sheet2.
How can this be achieved? I've already created actual tables in the sheets, called Table1 and Table2.
This is what I've managed to put together so far. I've looked at autofilter, but I can't understand squat of what's happening in there. So this I get!
Sub MoveData()
Dim i As Range
Dim num As Integer
num = 1
For Each i In Range("K10:K1000")
If i.Value > 9 Then
i.Select
ActiveCell.Rows("1:1").EntireRow.Select
Selection.Copy
Sheets("Sheet2").Range("A65000").End(xlUp).Offset(num, 0).PasteSpecial
ActiveCell.Rows.Delete
num = num + 1
End If
Next i
End Sub
This kinda works so far. But I can't manage to paste the row to the next blank row in sheet2. I tried doing that num = num + 1 thing, but I guess that's way off?
Is this what you are trying? (TRIED AND TESTED)
Option Explicit
Sub Sample()
Dim wsI As Worksheet, wsO As Worksheet
Dim rRange As Range
Dim lastRowWsO As Long
Set wsI = Sheets("sheet1")
'~~> Assuming that the Header is in K10
Set rRange = wsI.Range("K10:K1000")
Set wsO = Sheets("sheet2")
'~~> Get next empty cell in Sheet2
lastRowWsO = wsO.Range("A" & Rows.Count).End(xlUp).Row + 1
With wsI
'~~> Remove Auto Filter if any
.AutoFilterMode = False
With rRange
'~~> Set the Filter
.AutoFilter Field:=1, Criteria1:=">=9"
'~~> Temporarirly hide the unwanted rows
wsI.Rows("1:9").EntireRow.Hidden = True
wsI.Rows("1001:" & Rows.Count).EntireRow.Hidden = True
'~~> Copy the Filtered rows
.Offset(1, 0).SpecialCells(xlCellTypeVisible).EntireRow.Copy _
wsO.Rows(lastRowWsO)
'~~> Delete The filtered rows
.Offset(1, 0).SpecialCells(xlCellTypeVisible).EntireRow.Delete
End With
'~~> Unhide the rows
.Rows("1:9").EntireRow.Hidden = False
.Rows("1001:" & Rows.Count).EntireRow.Hidden = False
'~~> Remove Auto Filter
.AutoFilterMode = False
End With
End Sub
NOTE: I have not included any error handling. I would recommend you to include one in the final code
FOLLOWUP
Sub Sample()
Dim wsI As Worksheet, wsO As Worksheet
Dim rRange As Range
Dim lastRowWsI As Long, lastRowWsO As Long
Set wsI = Sheets("Risikoanalyse")
'~~> Assuming that the Header is in K10
Set rRange = wsI.Range("K9:K1000")
lastRowWsI = wsI.Cells.Find(What:="*", _
After:=wsI.Range("A1"), _
Lookat:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByRows, _
SearchDirection:=xlPrevious, _
MatchCase:=False).Row
Set wsO = Sheets("SJA utarbeides")
'~~> Get next empty cell in Sheet2
lastRowWsO = wsO.Cells.Find(What:="*", _
After:=wsO.Range("A1"), _
Lookat:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByRows, _
SearchDirection:=xlPrevious, _
MatchCase:=False).Row + 1
With wsI
With .ListObjects("TableRisikoAnalyse")
'~~> Set the Filter
.Range.AutoFilter Field:=11, Criteria1:=">=9"
'~~> Temporarirly hide the unwanted rows
wsI.Rows("1:8").EntireRow.Hidden = True
wsI.Rows(lastRowWsI & ":" & Rows.Count).EntireRow.Hidden = True
'~~> Copy the Filtered rows
wsI.Range(Replace(wsI.Range("K9").Offset(1, 0).SpecialCells(xlCellTypeVisible).Address, "$9:$9,", "")).EntireRow.Copy _
wsO.Rows(lastRowWsO)
'~~> Clear The filtered rows
wsI.Range(Replace(wsI.Range("K9").Offset(1, 0).SpecialCells(xlCellTypeVisible).Address, "$9:$9,", "")).Clear
.Range.AutoFilter Field:=11
'~~> Sort the table so that blank cells are pushed down
.Sort.SortFields.Clear
.Sort.SortFields.Add Key:=Range("TableRisikoAnalyse[[ ]]"), SortOn:=xlSortOnValues, Order _
:=xlAscending, DataOption:=xlSortTextAsNumbers
With .Sort
.Header = xlYes
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With
End With
'~~> Unhide the rows
.Rows("1:8").EntireRow.Hidden = False
.Rows(lastRowWsI & ":" & Rows.Count).EntireRow.Hidden = False
'~~> Remove Auto Filter
.AutoFilterMode = False
End With
End Sub
Related
I am looking for some help modifying existing code in a worksheet that I had created a while back to copy and paste a range from a row rather than the entire row itself.
The original code, which has worked perfect in the original intended function, it would search column A in the Data worksheet for a specified match. it would then copy that row into a specified worksheet and paste each match as a new row.
What I have been trying to modify the code to do now is perform that same search of column A for either " New, Existing Being Removed, Existing To Remain". When finding one of the 3 options it would then copy the data from columns b:g of that matching row and paste it into the rent worksheet starting at a specified cell. For instance rows marked as Existing to remain would need to star being pasted at cell B3, Existing being removed cell m3, and New cell x3. In total there would not be more than 20 rows from the data sheet that would need to be copied and pasted appropriately.
The code below is the current working code that will search, copy, and paste the entire matching row. Not being extremely proficient with VBA code I didn't want to post the muddled mess that I had made of the original code.
Edit With Photos*
#Toddleson I made the changes you suggested but ended up getting an error with the copyfrom.copy line. It is probably much easier to see what I am trying to accomplish visually. In the Data sheet image link below you will see that row A is where the search occurs. For each match it will copy the values from columns B:G of that row and then paste that into the rent sheet.
If you take a look at the rent image you will see that it is broken into the 3 cooresponding sections. From the match that was found in the cooresponing deisgnation from column A in the data sheet it will then paste the information from columns B:G in the Data to the B:G columns in the Rent sheet.
Data Sheet
Rent
Private Sub CommandButton4_Click()
Dim wb1 As Workbook, wb2 As Workbook
Dim ws1 As Worksheet, ws2 As Worksheet
Dim copyFrom As Range
Dim lRow As Long '<~~ Not Integer. Might give you error in higher versions of excel
Dim strSearch As String
Set wb1 = ThisWorkbook
Set ws1 = wb1.Worksheets("Data")
strSearch = "New"
With ws1
.AutoFilterMode = False
lRow = .Range("A" & .Rows.Count).End(xlUp).Row
With .Range("A1:A" & lRow)
.AutoFilter Field:=1, Criteria1:="=*" & strSearch & "*"
Set copyFrom = .Resize(lRow - 1, 7)
End With
.AutoFilterMode = False
End With
Set ws2 = wb1.Worksheets("Rent")
With ws2
If Application.WorksheetFunction.CountA(.Cells) <> 0 Then
lRow = .Cells.Find(What:="*", _
After:=Range("p3"), _
Lookat:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByRows, _
SearchDirection:=xlPrevious, _
MatchCase:=False).Row
Else
lRow = 1
End If
copyFrom.Copy ws2.Cells(3, 16).Resize(copyFrom.Rows.Count, copyFrom.Columns.Count)
End With
strSearch = "Existing Being Removed"
With ws1
.AutoFilterMode = False
lRow = .Range("A" & .Rows.Count).End(xlUp).Row
With .Range("A1:A" & lRow)
.AutoFilter Field:=1, Criteria1:="=*" & strSearch & "*"
Set copyFrom = .Offset(1, 0).SpecialCells(xlCellTypeVisible).EntireRow
End With
.AutoFilterMode = False
End With
Set ws2 = wb1.Worksheets("Rent")
With ws2
If Application.WorksheetFunction.CountA(.Cells) <> 0 Then
lRow = .Cells.Find(What:="*", _
After:=Range("p19"), _
Lookat:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByRows, _
SearchDirection:=xlPrevious, _
MatchCase:=False).Row
Else
lRow = 1
End If
copyFrom.Copy ws2.Cells(3, 16).Resize(copyFrom.Rows.Count, copyFrom.Columns.Count)
End With
strSearch = "Existing To Remain"
With ws1
.AutoFilterMode = False
lRow = .Range("A" & .Rows.Count).End(xlUp).Row
With .Range("A1:A" & lRow)
.AutoFilter Field:=1, Criteria1:="=*" & strSearch & "*"
Set copyFrom = .Offset(1, 0).SpecialCells(xlCellTypeVisible).EntireRow
End With
.AutoFilterMode = False
End With
Set ws2 = wb1.Worksheets("Existing To Remain")
With ws2
If Application.WorksheetFunction.CountA(.Cells) <> 0 Then
lRow = .Cells.Find(What:="*", _
After:=.Range("p35"), _
Lookat:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByRows, _
SearchDirection:=xlPrevious, _
MatchCase:=False).Row
Else
lRow = 1
End If
copyFrom.Copy ws2.Cells(3, 16).Resize(copyFrom.Rows.Count, copyFrom.Columns.Count)
End With
End Sub
I was reading the following post and tried to copy the first 20 rows (exclude header) from the filtered table. However, the last line gave me an error. What did I do wrong here ?
Sub Macro1()
'
' Macro1 Macro
'
'
Dim wb As Workbook
Dim ws As Worksheet
Set wb = ActiveWorkbook
Set ws = ThisWorkbook.Sheets("HelloWorld")
wb.Activate
ws.Activate
ws.AutoFilterMode = False
If ws.Range("A1:L11470").AutoFilter Then
ws.Range("A1:L11470").AutoFilter
End If
ws.Range("A1:L11470").AutoFilter
ws.AutoFilter.Sort.SortFields.Add2 Key:=Range("G1:G11470"), SortOn:=xlSortOnValues, Order:=xlDescending, DataOption:=xlSortNormal
With ws.AutoFilter.Sort
.Header = xlYes
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With
ws.Range("$A$1:$L$11470").AutoFilter Field:=11, Criteria1:="<>-"
ws.Range("$A$1:$L$11470").AutoFilter Field:=1, Criteria1:="10", Operator:=xlTop10Items ' <-- Error here
End Sub
The error is as follow:
I think I would take a slightly different approach to achieve the end you seem to be looking for. The code suggested below does the following based on my interpretation of your question:
Sort the data range A:L on the sheet “HelloWorld” by column G
Set a filter such that column A = 10 and column K <> “-“
Counts the first 20 filtered (visible) rows on the HelloWorld sheet and copies them (in this demonstration to Sheet2)
If this isn’t exactly what you were looking for, please comment & I’ll adjust accordingly.
Option Explicit
Sub TestTop20()
Dim ws As Worksheet, c As Range, i As Integer, LastRow As Long, EndData As Long
Set ws = ThisWorkbook.Sheets("HelloWorld")
'Determine the last 'possible' row of data
LastRow = ws.Cells(Rows.Count, 1).End(xlUp).Row
'Sort your data on column G
ws.Columns("A:L").Sort _
Key1:=ws.Range("G2"), order1:=xlDescending, Header:=xlYes
'Set the filter on columns K & A
With ws.Range("A1")
.AutoFilter
.AutoFilter Field:=1, Criteria1:="=10"
.AutoFilter Field:=11, Criteria1:="<>-"
End With
'Determine what the last visible row is - up to 20
i = 0
For Each c In ws.Range("A2:A" & LastRow)
If c.EntireRow.Hidden = False Then
i = i + 1
If i = 20 Then
EndData = c.Row
Exit For
End If
End If
Next c
If EndData < 20 Then MsgBox "Less than 20 records were detected"
'Copy the first 20 filtered records
ws.Range("A2:A" & EndData).SpecialCells(xlCellTypeVisible) _
.EntireRow.Copy Sheet2.Range("A1")
ws.AutoFilterMode = False
Application.Goto ws.Range("A1")
End Sub
I am creating new data which is dependent upon variable x using loop, then trying to copy the data with each iteration in X and then pasting the data on multiple sheets (variable "FundSheetNames"). Here I dont know how to exit from loop FundSheetNames without next i and then again go on to X to copy new data.
Sub peer2()
ThisWorkbook.Sheets("Peer Code").Activate
Dim X As Range, Y As Range
Set X = Sheets("Peer Code").Range("J2:J11")
Dim Sht As Worksheet
Dim sheet_names As Variant
For Each sheet_Name In Sheets("Peer Code").Range("K2:K3")
For Each Y In X
Set WS = Worksheets(sheet_Name.Text)
ThisWorkbook.Sheets("Peer Fund").Activate
Range("F7:F166").Select
Selection.ClearContents
ThisWorkbook.Sheets("Peer Code").Activate
Y.Select
Selection.Copy
Range("L2").Select
Selection.PasteSpecial Paste:=xlPasteValues
Range("N2:N161").Select
Selection.Copy
ThisWorkbook.Sheets("Peer Fund").Activate
Range("F7").EntireColumn.Hidden = False
Range("$F7").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone,
SkipBlanks:= _
False, Transpose:=False
With Sheets("Peer Fund")
Set FOUNDRANGE = .Columns("F:F").Find("*", After:=.Range("F167"), searchdirection:=xlPrevious, LookIn:=xlValues)
If Not FOUNDRANGE Is Nothing Then LR1 = FOUNDRANGE.Row
End With
Range("F166:F" & LR1 + 1).EntireRow.Select
Application.Selection.EntireRow.Hidden = False
Range("A6:W" & LR1).Select
ActiveWorkbook.Worksheets("Peer Fund").Sort.SortFields.Clear
ActiveWorkbook.Worksheets("Peer Fund").Sort.SortFields.Add2 Key _
:=Range("A2:A" & LR1), SortOn:=xlSortOnValues, Order:=xlAscending, _
DataOption:=xlSortNormal
With ActiveWorkbook.Worksheets("Peer Fund").Sort
.SetRange Range("A6:W" & LR1)
.Header = xlYes
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With
Range("F7").EntireColumn.Hidden = False
Range("A5:W172").Select
Selection.SpecialCells(xlCellTypeVisible).Copy
WS.Activate
Range("A5").Select
Selection.PasteSpecial Paste:=xlPasteValues
Selection.PasteSpecial Paste:=xlPasteFormats
With WS
Set FOUNDRANGE = .Columns("F:F").Find("*",
After:=.Range("F167"),
searchdirection:=xlPrevious, LookIn:=xlValues)
If Not FOUNDRANGE Is Nothing Then LR2 = FOUNDRANGE.Row
End With
Range("F166:F" & LR1 + 1).EntireRow.Select
Application.Selection.EntireRow.Hidden = True
Range("F7").EntireColumn.Hidden = True
Next Y
Next sheet_Name
End Sub
Exit For
Open a new worksheet and put the code into a module. Then put in some values into column A. Put a few 5-s among the values.
The following is an example that looks for the value 5 in column A. When 5 is found it returns a message containing the address of the cell where it was found, in the Immediate window (CTRL+G).
Option Explicit
Sub FirstOccurrence()
Const Col As Variant = "A"
Const FirstRow As Long = 2
Const Criteria As Long = 5
Dim rng As Range
' Define the last non-empty cell.
Set rng = Columns(Col).Find("*", , xlValues, , , xlPrevious)
If rng Is Nothing Then Exit Sub
If rng.Row < FirstRow Then Exit Sub
' Define the column range from FirstRow to row of last non-empty cell.
Set rng = Range(Cells(FirstRow, Col), rng)
Dim cel As Range
For Each cel In rng
If cel.Value = Criteria Then
Debug.Print "Cell '" & cel.Address & "' contains the value '" _
& Criteria & "'."
Exit For
End If
Next cel
End Sub
You have just seen how the code finds just the first occurrence of 5.
Now remove the line Exit For and see the results in the Immediate window (CTRL+G).
I am trying to compare two columns in one workbook and based on a certain condition copy the row where that condition is met to another workbook.
This is for a "database" I am working on. I have a Master sheet and then several versions of sub-masters that are catered specifically to certain individuals.
I have tried to some success by creating two different With statements and using a delete function on the sub-sheet but it is clunky and I'm not a fan of it. Please see the example code below.
Public Sub Workbook_Open()
Dim wb1 As Workbook, wb2 As Workbook
Dim ws1 As Worksheet, ws2 As Worksheet
Dim copyFrom As Range
Dim lRow As Long
Dim strSearch As String
Dim vrtSelectedItem As Variant
Set wb1 = Application.Workbooks.Open("C:\Users\myfolder\Desktop\Excel Master Test\ROLE BASED TRACKER DRAFT.xlsx")
Set ws1 = wb1.Worksheets("Master")
Set wb2 = ThisWorkbook
Set ws2 = wb2.Worksheets("Sheet1")
'~~> Specifies which resources info. you are retrieving
strSearch = "117"
ws2.Cells.Clear
'~~> Copying the header information and formatting.
ws1.Range("1:1").Copy
ws2.Range("1:1").PasteSpecial
With ws1
'~~> Remove any filters
.AutoFilterMode = False
lRow = .Range("A" & .Rows.Count).End(xlUp).Row
With .Range("L1:L" & lRow)
.AutoFilter Field:=1, Criteria1:=strSearch
Set copyFrom = .Offset(1, 0).SpecialCells(xlCellTypeVisible).EntireRow
End With
.AutoFilterMode = False
End With
'~~> Destination File
With ws2
If Application.WorksheetFunction.CountA(.Rows) <> 0 Then
lRow = .Cells.Find(What:="*", _
After:=.Range("A1"), _
Lookat:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByRows, _
SearchDirection:=xlPrevious, _
MatchCase:=False).Row + 1
Else
lRow = .Range("A" & Rows.Count).End(xlUp).Row
End If
copyFrom.Copy .Rows(lRow)
End With
With ws2
'~~> Remove any filters
.AutoFilterMode = False
lRow = .Range("A" & .Rows.Count).End(xlUp).Row
With .Range("AD1:AD" & lRow)
.AutoFilter Field:=1, Criteria1:=strSearch
.Offset(1, 0).SpecialCells(xlCellTypeVisible).EntireRow.Delete
End With
.AutoFilterMode = False
End With
With ws1
'~~> Remove any filters
.AutoFilterMode = False
lRow = .Range("A" & .Rows.Count).End(xlUp).Row
With .Range("AD1:AD" & lRow)
.AutoFilter Field:=1, Criteria1:=strSearch
Set copyFrom = .Offset(1, 0).SpecialCells(xlCellTypeVisible).EntireRow
End With
.AutoFilterMode = False
End With
'~~> Destination File
With ws2
If Application.WorksheetFunction.CountA(.Rows) <> 0 Then
lRow = .Cells.Find(What:="*", _
After:=.Range("A1"), _
Lookat:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByRows, _
SearchDirection:=xlPrevious, _
MatchCase:=False).Row + 1
Else
lRow = .Range("A" & Rows.Count).End(xlUp).Row
End If
copyFrom.Copy .Rows(lRow)
End With
With ws2.Sort
.SetRange Range("A2:A12000")
.Header = xlNo
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With
wb1.Save
wb1.Close
wb2.Save
End Sub
This is the code that I am trying to get work. I keep getting a Type Mismatch error on my cell comparison lines. '' If ws1.Range("AD1:AD" & lRow) <> ws1.Range("L1:L" & lRow) Then ''
Public Sub Workbook_Open()
Dim wb1 As Workbook, wb2 As Workbook
Dim ws1 As Worksheet, ws2 As Worksheet
Dim copyFrom As Range
Dim lRow As Long
Dim strSearch As String
Dim vrtSelectedItem As Variant
Set wb1 = Application.Workbooks.Open("C:\Users\myfolder\Desktop\Excel Master Test\ROLE BASED TRACKER DRAFT.xlsx")
Set ws1 = wb1.Worksheets("Master")
Set wb2 = ThisWorkbook
Set ws2 = wb2.Worksheets("Sheet1")
'~~> Specifies which resources info. you are retrieving
strSearch = "117"
ws2.Cells.Clear
'~~> Copying the header information and formatting.
ws1.Range("1:1").Copy
ws2.Range("1:1").PasteSpecial
With ws1
'~~> Remove any filters
.AutoFilterMode = False
lRow = .Range("A" & .Rows.Count).End(xlUp).Row
If ws1.Range("AD1:AD" & lRow) <> ws1.Range("L1:L" & lRow) Then
With .Range("AD1:AD" & lRow)
.AutoFilter Field:=1, Criteria1:=strSearch
Set copyFrom = .Offset(1, 0).SpecialCells(xlCellTypeVisible).EntireRow
End With
.AutoFilterMode = False
End If
End With
'~~> Destination File
With ws2
If Application.WorksheetFunction.CountA(.Rows) <> 0 Then
lRow = .Cells.Find(What:="*", _
After:=.Range("A1"), _
Lookat:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByRows, _
SearchDirection:=xlPrevious, _
MatchCase:=False).Row + 1
Else
lRow = .Range("A" & Rows.Count).End(xlUp).Row
End If
copyFrom.Copy .Rows(lRow)
End With
With ws1
'~~> Remove any filters
.AutoFilterMode = False
lRow = .Range("A" & .Rows.Count).End(xlUp).Row
If ws1.Range("AD1:AD" & lRow) = ws1.Range("L1:L" & lRow) Then
With .Range("L1:L" & lRow)
.AutoFilter Field:=1, Criteria1:=strSearch
Set copyFrom = .Offset(1, 0).SpecialCells(xlCellTypeVisible).EntireRow
End With
.AutoFilterMode = False
End If
End With
'~~> Destination File
With ws2
If Application.WorksheetFunction.CountA(.Rows) <> 0 Then
lRow = .Cells.Find(What:="*", _
After:=.Range("A1"), _
Lookat:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByRows, _
SearchDirection:=xlPrevious, _
MatchCase:=False).Row + 1
Else
lRow = .Range("A" & Rows.Count).End(xlUp).Row
End If
copyFrom.Copy .Rows(lRow)
End With
With ws2.Sort
.SetRange Range("A2:A12000")
.Header = xlNo
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With
wb1.Save
wb1.Close
' wb2.Save
End Sub
I just wanted to thank everyone who helped. I am going to just stick with my initial solution of filter, copy, paste, filter, delete, filter, copy, paste, sort.
See my first code block for what I am talking about. Cheers.
I have date mentioned in cell A1, ex - "May".
I am now trying to lock rows 2-last with column Z which mentions date of joining of each employee and compares it to A1.
If month of this cell Z is > A1 then I am trying to lock the row. Not sure what to do.
Below code doesnt help :
Sub Lockrow()
Dim DestSh As Worksheet
Dim lastrow As Long
Dim i As Integer
Set DestSh = Sheets("Consultant & Teacher")
With DestSh
'finds the last row with data on A column
lastrow = Range("A65536").End(xlUp).Row
'parse all rows
For i = 6 To lastrow
'if your conditions are met
If Month(.Cells(i, 26)) > Month(.Cells(1, 2)) Then
.Range("A" & i).EntireRow.Cells.Locked = True 'lock the row
End If
Next i
End With
End Sub
Is this what you are trying?
Sub Sample()
Dim DestSh As Worksheet
Dim lastrow As Long
'~~> Change this as applicable
Set DestSh = Sheets("Sheet1")
With DestSh
If Application.WorksheetFunction.CountA(.Cells) <> 0 Then
lastrow = .Columns("A:C").Find(What:="*", _
After:=.Range("A1"), _
Lookat:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByRows, _
SearchDirection:=xlPrevious, _
MatchCase:=False).Row
Else
MsgBox "Insufficient rows"
Exit Sub
End If
.Unprotect "MyPassword"
.Cells.Locked = False
.Range("A6:C" & lastrow).Locked = True
.Protect "MyPassword"
End With
End Sub