Obviously you just want to add a new row below the last data row. You can use the Range.Find method to find the Contingency
in column B and insert a row above. Note that you can then use Range.Offset method to move one row upwards to get the last data row:
Option Explicit
Public Sub AddNewRowBeforeContingency()
Dim Ws As Worksheet
Set Ws = ThisWorkbook.Worksheets("Sheet1") 'define worksheet
'find last data row (the row before "Contingency")
Dim LastDataRow As Range
On Error Resume Next 'next line throws error if nothing was found
Set LastDataRow = Ws.Columns("B").Find(What:="Contingency", LookIn:=xlValues, LookAt:=xlWhole).Offset(RowOffset:=-1).EntireRow
On Error GoTo 0 'don't forget to re-activate error reporting!!!
If LastDataRow Is Nothing Then
MsgBox ("Contingency Row not found")
Exit Sub
End If
Ws.Unprotect Password:="password"
Application.CutCopyMode = False
LastDataRow.Offset(RowOffset:=1).Insert Shift:=xlDown, CopyOrigin:=xlFormatFromLeftOrAbove
With Intersect(LastDataRow, Ws.Range("D:G")) 'get columns D:G of last data row
.Copy Destination:=.Offset(RowOffset:=1)
End With
Application.CutCopyMode = False
Ws.Protect Password:="password", DrawingObjects:=True, Contents:=True, Scenarios:=True, _
AllowFormattingCells:=True, AllowFormattingColumns:=True, _
AllowFormattingRows:=True, AllowInsertingHyperlinks:=True, _
AllowDeletingColumns:=True, AllowDeletingRows:=True
End Sub
Note that the find method throws an error if nothing can be found. You need to catch that error and test with If LastDataRow Is Nothing Then
if something was found or not.
Note that if an error occurs between Ws.Unprotect
and Ws.Protect
your sheet remains unprotected. So either implement an error handling like …
Ws.Unprotect Password:="password"
On Error Goto PROTECT_SHEET
Application.CutCopyMode = False
LastDataRow.Offset(RowOffset:=1).Insert Shift:=xlDown, CopyOrigin:=xlFormatFromLeftOrAbove
With Intersect(LastDataRow, Ws.Range("D:G")) 'get columns D:G of last data row
.Copy Destination:=.Offset(RowOffset:=1)
End With
Application.CutCopyMode = False
PROTECT_SHEET:
Ws.Protect Password:="password", DrawingObjects:=True, Contents:=True, Scenarios:=True, _
AllowFormattingCells:=True, AllowFormattingColumns:=True, _
AllowFormattingRows:=True, AllowInsertingHyperlinks:=True, _
AllowDeletingColumns:=True, AllowDeletingRows:=True
If Err.Number <> 0 Then
Err.Raise Err.Number, Err.Source, Err.Description, Err.HelpFile, Err.HelpContext
End If
End Sub
… or protect your worksheet using the parameter UserInterfaceOnly:=True
in the Worksheet.Protect method to protect the sheet from user changes but avoid that you need to unprotect it for VBA actions. (Also refer to VBA Excel: Sheet protection: UserInterFaceOnly gone).