Delete a Specific Row With a VBA Macro

VBA & macros · Updated November 3, 2026

Delete a Specific Row With a VBA Macro

Yes. In Excel for Microsoft 365 on Windows, a VBA macro can delete a specific worksheet row with Rows(rowNumber).Delete; set the worksheet and row number explicitly so the macro does not act on the wrong sheet. The example below asks for confirmation before deleting row 5.

Sub DeleteSpecificRow()
    Dim ws As Worksheet
    Dim rowNumber As Long

    ' Use the sheet that contains the data.
    Set ws = ThisWorkbook.Worksheets("Data")
    rowNumber = 5

    ' Check the row number before changing the workbook.
    If rowNumber < 1 Or rowNumber > ws.Rows.Count Then
        MsgBox "The row number is outside this worksheet."
        Exit Sub
    End If

    ' Confirm because VBA deletions cannot be undone with Ctrl+Z.
    If MsgBox("Delete row " & rowNumber & " on " & ws.Name & "?", _
              vbYesNo + vbQuestion, "Confirm deletion") <> vbYes Then Exit Sub

    ws.Rows(rowNumber).Delete
End Sub

Before running any macro, save a copy of the workbook. A deletion made by VBA generally cannot be reversed with Excel’s Undo command, so the confirmation prompt is useful but is not a substitute for a backup.

What “specific row” means in VBA

A row number such as 5 means the fifth worksheet row, not necessarily the fifth record in a list. If row 1 contains headings, row 5 is usually the fourth data record. This distinction matters when a sheet has a title, blank rows, or other content above the data. VBA row numbers are worksheet positions and start at 1.

The statement ws.Rows(rowNumber).Delete deletes the entire worksheet row. Excel shifts cells below it upward, and formulas or references may adjust as they normally do after a row is deleted. It does not merely clear the values in the row. If you want to retain the row structure and remove only its contents, use ws.Rows(rowNumber).ClearContents instead; that leaves formatting and the row itself in place.

For a fixed row, a shorter statement such as Worksheets("Data").Rows(5).Delete is valid, but the longer example is easier to check and modify. It names the worksheet explicitly rather than relying on whichever sheet happens to be active.

How to install and run the macro

In desktop Excel for Microsoft 365 on Windows, open the Visual Basic Editor with Alt+F11. Choose Insert > Module, paste the procedure into the module, and replace Data or 5 with the sheet name and row you intend to delete. Return to Excel, then run it from Developer > Macros by selecting DeleteSpecificRow and choosing Run. If the Developer tab is not visible, enable it through File > Options > Customize Ribbon.

Save a workbook containing VBA as an Excel Macro-Enabled Workbook (.xlsm) if you need the macro to remain in that file. A regular .xlsx workbook cannot store VBA code; saving a macro-containing file in that format removes the macros. Excel for the web can open and edit many workbook contents, but it cannot create, run, or edit VBA macros. Open the file in desktop Excel to use this code.

On Mac, VBA is available in the desktop Excel app, although keyboard shortcuts and the location of commands can vary with the keyboard and ribbon configuration. Use Tools > Macro > Visual Basic Editor if available, or locate Visual Basic Editor in Excel’s macro/developer commands. The worksheet-deletion code itself is the same. You may need to allow macros in Excel’s security settings, and the Windows shortcut instructions above do not apply unchanged to every Mac keyboard.

Delete a row based on a cell value

Often the desired row is identified by a value, such as an order status in column A, rather than by a fixed position. This example searches column A for an exact cell value of REMOVE and deletes the row containing the first match. The search options are stated explicitly because Excel’s Find dialog can retain settings from a previous search.

Sub DeleteRowByValue()
    Dim ws As Worksheet
    Dim foundCell As Range

    Set ws = ThisWorkbook.Worksheets("Data")

    Set foundCell = ws.Columns("A").Find( _
        What:="REMOVE", _
        After:=ws.Cells(ws.Rows.Count, "A"), _
        LookIn:=xlValues, _
        LookAt:=xlWhole, _
        SearchOrder:=xlByRows, _
        SearchDirection:=xlNext, _
        MatchCase:=False)

    If foundCell Is Nothing Then
        MsgBox "No exact match was found in column A."
    Else
        ws.Rows(foundCell.Row).Delete
    End If
End Sub

LookAt:=xlWhole means a cell must equal REMOVE; it will not match a longer value such as REMOVE LATER. MatchCase:=False makes the search case-insensitive. The macro deletes only the first matching row. If there are duplicates, run it again to remove another match, or use a loop that checks every row.

When removing every matching record, loop from the bottom upward. Deleting a row shifts later rows up, so a top-to-bottom loop can skip the record that moves into the row just deleted. For example, this version checks column A from the last used row up to row 2, preserving row 1 as a header:

Sub DeleteAllMarkedRows()
    Dim ws As Worksheet
    Dim lastRow As Long
    Dim r As Long

    Set ws = ThisWorkbook.Worksheets("Data")
    lastRow = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row

    ' Work upward so row deletion does not skip the next record.
    For r = lastRow To 2 Step -1
        If ws.Cells(r, "A").Value = "REMOVE" Then
            ws.Rows(r).Delete
        End If
    Next r
End Sub

This checks exact values using VBA’s standard equality comparison and assumes the relevant records are contiguous enough for the last used cell in column A to identify the search boundary. If column A can be blank on valid records, determine the final row using a column that is consistently populated, or use a carefully defined data range. Always confirm that the chosen columns and header-row assumption match the actual sheet.

Deleting a table record rather than a worksheet row

If the data is an Excel Table, a table record is not always best treated as a whole worksheet row. Deleting ws.Rows(n).Delete removes that worksheet row, including cells outside the table. To target a record within a named table, use its ListRows collection. The row index below is the position among the table’s data rows; it does not count the header row.

Sub DeleteTableRecord()
    Dim ws As Worksheet
    Dim tbl As ListObject
    Dim rowIndex As Long

    Set ws = ThisWorkbook.Worksheets("Data")
    Set tbl = ws.ListObjects("SalesTable")
    rowIndex = 3

    If rowIndex >= 1 And rowIndex <= tbl.ListRows.Count Then
        tbl.ListRows(rowIndex).Delete
    Else
        MsgBox "That table data-row number does not exist."
    End If
End Sub

Change SalesTable to the table’s actual name and set rowIndex to the record position you mean. Table names can be checked by selecting a cell in the table and looking at the Table Design tab. If the target record is identified by a value rather than its position, find that value within the table’s data body and map the matching cell to its table row before deleting it. This avoids confusing a worksheet row number with a table-relative index.

Choosing the right worksheet reference

The examples use ThisWorkbook, which means the workbook containing the VBA code. That is appropriate when the macro is saved in the same workbook as the data. If code is stored in the Personal Macro Workbook or an add-in, ThisWorkbook refers to that code workbook instead. In that case, the data may be in ActiveWorkbook, but relying on the active workbook is safe only when you have deliberately selected the intended file.

Likewise, ActiveSheet.Rows(5).Delete acts on whichever sheet is active at runtime. That can be convenient for a reusable one-off macro, but it is risky in an automated process: a click on another tab can change the target. An explicit reference such as ThisWorkbook.Worksheets("Data") makes the target easier to audit. If a sheet name is misspelled or does not exist, VBA raises a subscript error rather than quietly choosing another sheet.

Common problems and safer checks

  • The wrong row disappears: Confirm whether you entered a worksheet row number or a record’s position. Check for title rows, headers, filtered data, and hidden rows before running a fixed-row macro.
  • The macro says a sheet is missing: Worksheet names must match the tab name, including spaces and punctuation. Check whether the code is in the same workbook as the data before choosing ThisWorkbook.
  • The macro runs but finds no value: Check the search column, spaces before or after the value, whether the cell contains a formula, and whether you intend an exact match. The example searches displayed values with LookIn:=xlValues and does not treat a longer text string as an exact match.
  • Nothing happens in Excel for the web: VBA does not run in the browser. Open the workbook in desktop Excel.
  • You cannot restore the deletion with Undo: VBA actions generally clear or bypass Excel’s normal Undo history. Close without saving only if you are certain that doing so will not discard other wanted changes; a saved backup is the dependable recovery option.

For additional safeguards, test the macro on a duplicate workbook first, verify the target sheet and row immediately before deletion, and keep important records in a separate backup. A confirmation box helps prevent accidental execution, but it cannot guarantee that the selected row is the correct business record.

When a macro is unnecessary

For a one-time deletion, select the row header in Excel, right-click, and choose Delete. On Windows, Shift+Space selects the current worksheet row; then use Ctrl+- to open the delete command. On Mac, keyboard mappings can differ, so use the row header’s context menu if the shortcut is not recognized. A normal worksheet deletion can usually be undone with Ctrl+Z on Windows or Command+Z on Mac, unlike a deletion made by VBA.

If you need to remove records repeatedly, a macro is useful when the rule and target are clear and repeatable. For a one-off clean-up, the interface is often safer because you can inspect the highlighted row. If the goal is only to hide records that do not meet a condition, apply a filter instead of deleting them. Filtering preserves the original data and is reversible, which is preferable when you may need to review the excluded rows later.

Frequently Asked Questions

How do I delete a particular row number in VBA?
Set a worksheet object, then use ws.Rows(5).Delete for row 5, replacing the number with the intended worksheet row. Name the worksheet explicitly so the result does not depend on the active tab.

How can I delete a row when a cell contains a certain value?
Use the worksheet’s Range.Find method on the relevant column, check whether the returned range is Nothing, and delete its row if a match exists. Specify exact or partial matching behavior deliberately; the example above uses exact matching and deletes the first match only.

Can I delete a row without deleting the whole worksheet row?
Yes. For a table, use its ListRows(index).Delete method to remove a table data record. If you only want to remove cell contents, use ClearContents rather than Delete.

Why does Ctrl+Z not undo a VBA row deletion?
Running VBA typically clears Excel’s Undo history, so Ctrl+Z cannot reverse the macro’s deletion. Save a separate copy before running code that removes data.

Will this macro run in Excel for the web?
No. Excel for the web does not run VBA macros. Use desktop Excel for Windows or Mac, and save the workbook in a macro-enabled format if the code must be stored in the file.

Related

Try it: the Column Letter to Number: aA is 27, XFD is 16,384. Converts both ways.

More in VBA & macros

Sources: Function behaviour and menu paths: Microsoft Support documentation for Excel. Method & sources

Spotted an error in this guide? Let us know.