To copy a row with Excel VBA, specify the source and destination worksheet rows and use Copy Destination. For example, this copies row 2 on a sheet named Data to row 5 on the same sheet, including its formulas and formatting:
Sub CopyOneRow()
' Copy row 2 to row 5 on the Data worksheet.
Worksheets("Data").Rows(2).Copy _
Destination:=Worksheets("Data").Rows(5)
End Sub
Change the sheet name and row numbers to suit your workbook. This approach avoids relying on a selected cell or the clipboard, and is usually the clearest starting point.
What a VBA row copy includes
A worksheet row is the entire horizontal row, not just the cells currently containing data. In current Excel for Microsoft 365, that means 16,384 columns, from A through XFD. Copying a whole row can therefore carry across formulas, values, formatting, data validation, and other cell properties across that row. It can also copy blank cells and formatting far beyond the visible table.
That behavior is useful when the source row is a complete template, but it may be excessive when your table occupies only columns A through F. For a table with a known range, copy only that range instead. For example, the following copies A2:F2 to A5:F5 on Data:
Sub CopyTableRange()
' Copy only the six columns used by the table.
Worksheets("Data").Range("A2:F2").Copy _
Destination:=Worksheets("Data").Range("A5:F5")
End Sub
The destination range’s top-left cell determines where the copied cells begin. The destination must have enough room for the source range. If the source is six columns wide, use a destination range starting at the intended first column; Excel fills the corresponding six cells.
Copy a row to another worksheet
To copy from one sheet to another, qualify both the source and destination. Explicit worksheet references prevent VBA from copying to whichever sheet happens to be active:
Sub CopyRowToAnotherSheet()
' Copy row 2 from Data to row 5 on Archive.
Worksheets("Data").Rows(2).Copy _
Destination:=Worksheets("Archive").Rows(5)
End Sub
Both sheet names must match the worksheet tab names, including spaces. If a sheet is named Monthly Data, write Worksheets("Monthly Data"). A missing or misspelled sheet name causes a run-time error rather than silently choosing another sheet.
For a workbook other than the one containing the macro, qualify the workbook too, such as Workbooks("Report.xlsx").Worksheets("Data"). That workbook must be open, and its name must be correct. In reusable code, assign workbook and worksheet objects to declared variables so the references are easy to inspect and update.
Copy to the next available row
A common task is appending a copied row below existing records. The next example assumes the table is on Data, has headers in row 1, and column A is filled for every record. It finds the next blank cell in column A and copies row 2 there:
Sub CopyToNextRow()
Dim ws As Worksheet
Dim nextRow As Long
Set ws = ThisWorkbook.Worksheets("Data")
' Find the first blank row after the last used cell in column A.
nextRow = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row + 1
' Copy the template row to the next record row.
ws.Rows(2).Copy Destination:=ws.Rows(nextRow)
End Sub
The method using End(xlUp) works upward from the bottom of column A to its last nonblank cell. If A has no records below the header, the result is row 2, which is also the source row in this example. Copying row 2 to itself does not append a new record. To handle an empty table, or to use a different header or template row, add logic that matches your layout.
Choose a column that is reliably populated in each record. If column A sometimes has blanks, it may report a row above the actual end of the table. For data arranged as an Excel Table, consider using the table’s ListRows collection to add a record; that approach is more aligned with structured tables than searching a worksheet column.
Copy values only or preserve formatting
The Copy Destination method copies cell contents and formatting, which is appropriate for duplicating a template. If you need values but not formulas or formatting, assign the source values to the destination directly. With a six-column record in A2:F2 copied to A5:F5, use:
Sub CopyValuesOnly()
Dim ws As Worksheet
Set ws = ThisWorkbook.Worksheets("Data")
' Transfer the evaluated cell values, not formulas or formatting.
ws.Range("A5:F5").Value = ws.Range("A2:F2").Value
End Sub
This assignment does not use the clipboard. Formulas in the source become their current results in the destination; number formats and cell formatting are not transferred. The source and destination ranges should have the same dimensions. If you want formulas but not formats, use a copy operation with PasteSpecial and the xlPasteFormulas option instead.
To copy values using the clipboard-based paste method, copy the source and paste only values:
Sub PasteValuesOnly()
Dim ws As Worksheet
Set ws = ThisWorkbook.Worksheets("Data")
' Copy A2:F2, then paste only values into A5:F5.
ws.Range("A2:F2").Copy
ws.Range("A5:F5").PasteSpecial Paste:=xlPasteValues
Application.CutCopyMode = False
End Sub
Use the direct assignment when you only need values; use PasteSpecial when you need a particular paste type supported by Excel. Setting Application.CutCopyMode to False clears the moving copy outline after the paste.
Copying versus inserting a copied row
Copying into an occupied destination replaces the destination cells. It does not make space or push existing records down. If the goal is to insert a duplicate above an existing row, insert first, then copy into the newly created row. For example, this inserts a worksheet row at position 5 and fills it from row 2:
Sub InsertCopiedRow()
Dim ws As Worksheet
Set ws = ThisWorkbook.Worksheets("Data")
' Insert a blank row before the current row 5.
ws.Rows(5).Insert Shift:=xlDown
' Fill the inserted row from row 2.
ws.Rows(2).Copy Destination:=ws.Rows(5)
End Sub
Insertion shifts existing cells downward and can affect formulas, named ranges, and layouts around the insertion point. If the data is an Excel Table, adding a table row is generally preferable to inserting an entire worksheet row, since a worksheet row may alter unrelated content elsewhere on the sheet.
Run the macro safely
In Excel for Microsoft 365 on Windows, open the Visual Basic Editor with Alt+F11. In the editor, choose Insert > Module, paste the macro into the module, and edit the worksheet names and row references. Return to Excel and run it from Developer > Macros, select the macro, and choose Run. If the Developer tab is hidden, enable it through File > Options > Customize Ribbon and select Developer.
On Mac, Excel supports VBA, but the editor and keyboard shortcuts differ by keyboard and settings. Open the editor from Tools > Macro > Visual Basic Editor, or use the Visual Basic control on the Developer tab where available. Excel for the web can open and edit macro-enabled files, but it cannot create, run, or edit VBA macros; use the desktop Excel app for those actions.
Save a copy of the workbook before running a macro. VBA actions cannot be reversed with Ctrl+Z, and a row copy can overwrite existing data. Macros may also be blocked by Trust Center settings or organizational policy, so only enable or run code from a source you trust. Save code in a macro-enabled workbook such as .xlsm if you need to keep it with the file.
Common errors and how to avoid them
- Wrong active sheet: Code using
ActiveSheet.Rows(2)depends on which sheet is active. Qualify both rows with the intended worksheet to make the target explicit. - Destination overwritten: A copy to an occupied row replaces its cells. Check the destination or insert a row first if existing records must be preserved.
- Unexpectedly large copy:
Rows(2)includes every column. UseRange("A2:F2")when the task concerns only a defined table range. - Incorrect next-row detection: A last-row search based on column A is only dependable if A is consistently populated. Select a stable key column or use table-aware code.
- Protected worksheet: Protection may prevent the macro from writing to the destination. Check the worksheet’s protection settings and follow the workbook owner’s rules before changing them.
- Macro does not run: Confirm that the code is in a standard module, the workbook is saved in a macro-enabled format when necessary, and macros are permitted by the computer’s security policy.
Frequently Asked Questions
How do I copy the current row with VBA? If the active cell is in the row you want, copy it with ActiveCell.EntireRow.Copy Destination:=Worksheets("Data").Rows(5). For a dependable macro, explicitly specify the source worksheet and row instead of relying on the active cell.
How do I copy a row without changing its formatting? Assign a same-sized source range to the destination range with .Value = .Value. This transfers current values, not formulas or formatting. Use a range limited to the columns in your data rather than assigning a whole worksheet row.
Does VBA copy formulas as well as values? Yes. A standard row copy carries formulas, and Excel adjusts relative references according to the destination, as it does when copying cells normally. A values-only assignment transfers the formula’s evaluated result instead.
Can I copy a row to another workbook? Yes, provided both workbooks are open. Qualify the source and destination with their workbook and worksheet names. Check that the destination workbook is writable and that the destination cells will not overwrite information you need.
Can I undo a VBA row copy? Usually not with Ctrl+Z. Running VBA clears Excel’s standard undo history, so save a separate copy before running a macro that changes workbook data.
Choosing the right approach
For a one-off duplicate that should retain formulas and formatting, use Rows(source).Copy Destination:=Rows(target) with explicit worksheet references. For a small table range, copy only its columns. For a values-only transfer, use direct value assignment; for a new record, determine the destination carefully or add a table row. The key decision is whether you mean copy into an existing location, append below the data, or insert and shift existing rows. Those operations have different effects, so make that choice explicit before running the macro.
Related
- Excel Power Query: Open It, Import Data, and Refresh
- Excel Notched Box Plot: What It Shows and How to Make One
- Excel Online Page Break Preview: Limits and Workarounds
Try it: the Column Letter to Number: aA is 27, XFD is 16,384. Converts both ways.
More in VBA & macros
- Excel VBA: How to Delete Column and Cell Ranges SafelyTo delete entire columns with Excel VBA, use a worksheet-qualified range such as ws.Columns("B:D").Delete. To delete only cells…
- Excel VBA: Delete a PivotTable SafelyTo delete a PivotTable with VBA, clear its full report range: use pt.TableRange2.Clear after setting pt to the…
- Excel VBA: How to Open a UserFormIn Excel VBA, open a UserForm by calling its Show method from a macro or another procedure. Use…
- Excel VBA: Center a UserForm on Screen AutomaticallyTo center an Excel VBA UserForm on the screen, set its StartUpPosition property to 2 - CenterScreen before…
- Excel VBA Macro to Send a Worksheet File via TeamsYes—but Excel VBA has no built-in command that sends a worksheet directly to Microsoft Teams. A practical Windows…
- Excel VBA Scroll Bar Form Control: Setup, Uses, and CodeIn Excel for Microsoft 365 on Windows, insert a Form Control scroll bar from Developer > Insert >…
Sources: Function behaviour and menu paths: Microsoft Support documentation for Excel. Method & sources
Spotted an error in this guide? Let us know.