How to Move a Row to Another Sheet Based on the Cell Value in Excel (2 Methods)

Dataset Overview

Often, we need to move or copy rows based on cell values to different worksheets for various purposes. The cell value can be in any column. Let’s illustrate this with a sample dataset. In the dataset below, we have multiple products listed in column C. Our goal is to move the rows containing the product Cable to another sheet.


Method 1 – Use the Filter Feature

  • Click the Product header (cell C4).
  • Go to Home, select Editing, choose Sort & Filter and click on Filter.

Apply Filter Feature in Excel to Move Row to Another Sheet Based on Cell Value

  • You’ll see drop-down icons next to each header.
  • Select the drop-down icon next to the Product header.
  • Check the box for Cable only.
  • Press OK.

Apply Filter Feature in Excel to Move Row to Another Sheet Based on Cell Value

  • This will display only the rows containing Cable.
  • Select these rows and copy them (Ctrl + C).

Apply Filter Feature in Excel to Move Row to Another Sheet Based on Cell Value

  • Go to the desired sheet.
  • Choose any cell where you want to paste the rows.
  • Press Ctrl + V to paste the rows.

Apply Filter Feature in Excel to Move Row to Another Sheet Based on Cell Value

Read More: Move Row to Bottom in Excel If Cell Contains a Value


Method 2 – Move Rows Using Excel VBA

Excel VBA allows us to perform various operations. In this method, we’ll use VBA codes to move rows to another sheet based on cell value.


2.1 Deleting Original Rows

  • Go to Developer and select Visual Basic.

Move Row to Another Sheet Based on Cell Value with Excel VBA

  • The VBA window will appear.
  • Click Insert and select Module to open a new module window.
  • Paste the following code:
Sub MoveRow_DeleteOriginal()
Dim rg As Range
Dim xc As Range
Dim p As Long
Dim q As Long
Dim r As Long
p = Worksheets("VBA delete original").UsedRange.Rows.Count
q = Worksheets("Sheet1").UsedRange.Rows.Count
If q = 1 Then
If Application.WorksheetFunction.CountA(Worksheets("Sheet1").UsedRange) = 0 Then q = 0
End If
Set rg = Worksheets("VBA delete original").Range("C1:C" & p)
On Error Resume Next
Application.ScreenUpdating = False
 For r = 1 To rg.Count
 If CStr(rg(r).Value) = "Cable" Then
 rg(r).EntireRow.Copy Destination:=Worksheets("Sheet1").Range("A" & q + 1)
 rg(r).EntireRow.Delete
 If CStr(rg(r).Value) = "Cable" Then
 r = r - 1
 End If
 q = q + 1
End If
Next
Application.ScreenUpdating = True
End Sub

Move Row to Another Sheet Based on Cell Value with Excel VBA

NOTE: Customize the code by replacing VBA delete original with your original sheet name and Sheet1 with the target sheet name. Adjust the range (C1:C) to match your desired column containing the cell value. Replace Cable with your specific value. 
  • Save the file and press the F5 key to run the code.
  • The rows with Cable will be deleted, as shown in the figure below.

Move Row to Another Sheet Based on Cell Value with Excel VBA

  • Sheet1 will display the required rows.

Move Row to Another Sheet Based on Cell Value with Excel VBA


2.2 Keeping the Original Rows

If you want to retain the original data, follow these steps to modify the code:

  • Select Developer and select Visual Basic.
  • Click Insert and choose Module to open a new module window.
  • Paste the following code into the module:
Sub MoveRow_KeepOriginal()
Dim rg As Range
Dim xc As Range
Dim p As Long
Dim q As Long
Dim r As Long
p = Worksheets("VBA keep original").UsedRange.Rows.Count
q = Worksheets("Sheet2").UsedRange.Rows.Count
If q = 1 Then
If Application.WorksheetFunction.CountA(Worksheets("Sheet2").UsedRange) = 0 Then q = 0
End If
Set rg = Worksheets("VBA keep original").Range("C1:C10" & p)
On Error Resume Next
Application.ScreenUpdating = False
 For r = 1 To rg.Count
 If CStr(rg(r).Value) = "Cable" Then
 rg(r).EntireRow.Copy Destination:=Worksheets("Sheet2").Range("A" & q + 1)
 q = q + 1
End If
Next
Application.ScreenUpdating = True
End Sub

NOTE: Customize the code by replacing VBA keep original with your original sheet name and Sheet2 with the target sheet name. Adjust the range (C1:C10) to match your desired column containing the cell value. Replace Cable with your specific value.
  • Press F5 to run the code.
  • The rows with Cable will be present in Sheet2, while the original data remains intact.

Read More: How to Move Rows in Excel Without Replacing


Download Practice Workbook

You can download the practice workbook from here:


Related Articles


<< Go Back to Move Rows | Rows in Excel | Learn Excel

Get FREE Advanced Excel Exercises with Solutions!
Aung Shine
Aung Shine

Aung Shine completed his bachelor’s in Electrical and Electronics Engineering from Bangladesh University of Engineering and Technology. It has been almost 2 years since he joined SOFTEKO and actively working on the ExcelDemy project. Currently he works as a Team Leader where he guides his team members to create technical content. He has published 150+ articles and reviewed 50+ articles. He has also solved various user problems before. He has interests in Data Analysis, Power Query, Advanced Excel,... Read Full Bio

33 Comments
  1. Hi,

    I really need a code to move a line from one sheet to another, this code above only deletes the row and its not pulling through to the other sheet?
    Can someone help?

    • Hello ASHLEIGH,
      Thank you for your question. We’re sorry to hear that you’re facing difficulties with the VBA code. In fact, the ExcelDemy team has tested the Excel file and the code with other workbooks following your comment and the code appears to be working correctly.
      However, you can check the following 4 steps.
      1. You can choose any of the two formats according to your need from Method-2. Additionally, read the Notes given after each code. This will help you to understand the code properly.
      2. You must create a worksheet where you want to move the filtered rows.
      3. Set the Input Worksheet and Destination Worksheet names properly with the Range.
      4. In this code, we have selected Cable as filter criteria. So, the rows containing Cable within the given Range will be deleted and it will be moved to your Destination Workbook. So, make sure you have provided the criteria according to your dataset.
      I hope this will solve your issue. If you still face problems, please feel free to comment again or send your workbook through e-mail so that I can check the issue.

  2. Hi, if I want to use different values and different sheets, can I use one module for this? For example: if a cell contains value A, then the row moves from sheet 1 to sheet 2, if it contains value B, then the row moves from sheet 1 to sheet 3. How do I implement this into the code?

    • Reply Lutfor Rahman Shimanto
      Lutfor Rahman Shimanto Apr 13, 2023 at 11:18 AM

      Hello CAR

      Thank you for reaching out to us on our website. You can use a single module to move rows between sheets based on various values. You may do this by using an IF statement inside a FOR loop that iterates through the rows in Sheet1, verifies the value, and then moves the entire row to the proper destination sheet based on the value. The intended code is given below.

      
      Sub MoveRowsInSheetsBasedOnValues()
      
          Dim wsSource As Worksheet, wsDest As Worksheet
          Dim i As Long, lastRow As Long, destRow As Long
          
          Set wsSource = ThisWorkbook.Worksheets("Sheet1")
          lastRow = wsSource.Cells(wsSource.Rows.Count, "B").End(xlUp).Row
          
          Set wsDest = ThisWorkbook.Worksheets("Sheet2")
          destRow = 1
          
          For i = 1 To lastRow
              If wsSource.Cells(i, "B").Value = "A" Then
                  wsSource.Rows(i).Copy wsDest.Rows(destRow)
                  destRow = wsDest.Cells(wsDest.Rows.Count, "B").End(xlUp).Row + 1
              End If
          Next i
          
          Set wsDest = ThisWorkbook.Worksheets("Sheet3")
          destRow = 1
          
          For i = 1 To lastRow
              If wsSource.Cells(i, "B").Value = "B" Then
                  wsSource.Rows(i).Copy wsDest.Rows(destRow)
                  destRow = wsDest.Cells(wsDest.Rows.Count, "B").End(xlUp).Row + 1
              End If
          Next i
          
      End Sub
      

      Regards
      Lutfor Rahman Shimanto

      • Hi again,
        I finally had time to update the code in my spreadsheet, but it doesn’t seem to work. I probably made a mistake somewhere, do you think you could check this code to see if i did something wrong?

        The value that needs to be selected is in column I, from row 3.

        There are multiple values in a dropdown menu in this column, of which 4 values are used in the code:

        If value “1. Cancelled”, then move to sheet “Cancelled Rejected Proposals”
        If value “2. Rejected”, then move to sheet “Cancelled Rejected Proposals”
        If value “9. Projectnumber assigned”, then move to sheet “Projects”
        If value “10. Finished”, then move to sheet “Finished Projects”

        The move from one sheet to another should also be as of row 3, since the first two rows are for titles.

        I hope you can help, thank you so much in advance!

        Sub MoveRowsInSheetsBasedOnValues()

        Dim wsSource As Worksheet, wsDest As Worksheet
        Dim i As Long, lastRow As Long, destRow As Long

        Set wsSource = ThisWorkbook.Worksheets(“Acquisition”)
        lastRow = wsSource.Cells(wsSource.Rows.Count, “I”).End(xlUp).Row

        Set wsDest = ThisWorkbook.Worksheets(“Projects”)
        destRow = 1

        For i = 1 To lastRow
        If wsSource.Cells(i, “I”).Value = “9. Projectnumber assigned” Then
        wsSource.Rows(i).Copy wsDest.Rows(destRow)
        destRow = wsDest.Cells(wsDest.Rows.Count, “I”).End(xlUp).Row + 1
        End If
        Next i

        Set wsDest = ThisWorkbook.Worksheets(“Finished Projects”)
        destRow = 1

        For i = 1 To lastRow
        If wsSource.Cells(i, “I”).Value = “10. Finished” Then
        wsSource.Rows(i).Copy wsDest.Rows(destRow)
        destRow = wsDest.Cells(wsDest.Rows.Count, “I”).End(xlUp).Row + 1
        End If
        Next i

        Set wsDest = ThisWorkbook.Worksheets(“Cancelled Rejected Proposals”)
        destRow = 1

        For i = 1 To lastRow
        If wsSource.Cells(i, “I”).Value = “1. Cancelled” Then
        wsSource.Rows(i).Copy wsDest.Rows(destRow)
        destRow = wsDest.Cells(wsDest.Rows.Count, “I”).End(xlUp).Row + 1
        End If
        Next i

        Set wsDest = ThisWorkbook.Worksheets(“Cancelled Rejected Proposals”)
        destRow = 1

        For i = 1 To lastRow
        If wsSource.Cells(i, “I”).Value = “2. Rejected” Then
        wsSource.Rows(i).Copy wsDest.Rows(destRow)
        destRow = wsDest.Cells(wsDest.Rows.Count, “I”).End(xlUp).Row + 1
        End If
        Next i

        End Sub

        • Lutfor Rahman Shimanto
          Lutfor Rahman Shimanto May 14, 2023 at 2:48 PM

          Hello CAR,

          It is great to see you again. I hope this reply finds you well. As you requested, I have reviewed your code and found some Syntax errors. But overall, the algorithm was close to achieving your goal.

          However, I am introducing a more efficient way of doing the same task with a better algorithm that should be compatible with large datasets.

          EXCEL VBA CODE:

          
          
          Sub MoveRowsInSheetsBasedOnValuesNew()
              
              Dim wsSource As Worksheet, wsDest As Worksheet
              Dim i As Long, lastRow As Long, destRow As Long
              
              Set wsSource = ThisWorkbook.Worksheets("Acquisition")
              lastRow = wsSource.Cells(wsSource.Rows.Count, "I").End(xlUp).Row
              
              
              For i = 3 To lastRow
              
                  If wsSource.Cells(i, "I").Value = "9.Projectnumber assigned" Then
                      
                      Set wsDest = ThisWorkbook.Worksheets("Projects")
                      destRow = wsDest.Cells(wsDest.Rows.Count, "I").End(xlUp).Row + 1
                      
                      wsSource.Rows(i).Copy wsDest.Rows(destRow)
                  
                  ElseIf wsSource.Cells(i, "I").Value = "10.Finished" Then
                      
                      Set wsDest = ThisWorkbook.Worksheets("Finished Projects")
                      destRow = wsDest.Cells(wsDest.Rows.Count, "I").End(xlUp).Row + 1
                      
                      wsSource.Rows(i).Copy wsDest.Rows(destRow)
                  
                  ElseIf wsSource.Cells(i, "I").Value = "1.Cancelled" Then
                      
                      Set wsDest = ThisWorkbook.Worksheets("Cancelled Rejected Proposals")
                      destRow = wsDest.Cells(wsDest.Rows.Count, "I").End(xlUp).Row + 1
                      
                      wsSource.Rows(i).Copy wsDest.Rows(destRow)
                  
                  ElseIf wsSource.Cells(i, "I").Value = "2.Rejected" Then
                      
                      Set wsDest = ThisWorkbook.Worksheets("Cancelled Rejected Proposals")
                      destRow = wsDest.Cells(wsDest.Rows.Count, "I").End(xlUp).Row + 1
                      
                      wsSource.Rows(i).Copy wsDest.Rows(destRow)
                  
                  End If
              
              Next i
              
          End Sub
          
          

          I hope this will achieve your goal. I am also giving you the Solution workbook to help you understand better.

          DOWNLOAD WORKBOOK

          Regards
          Lutfor Rahman Shimanto

        • Hi again,
          You can disregard my question about deleting a row after moving it. I have figured it out myself:

          wsSource.Rows(i).EntireRow.Delete

          I’m so happy, thanks again!

        • Avatar photo
          Shamima Sultana May 14, 2023 at 11:03 AM

          Dear Car,

          You are most welcome.

          Regards
          ExcelDemy

        • Wow, thank you so much! It works like a charm!
          I even adjusted the code for another sheet within the workbook, with different values, and it works perfectly!

          There is only one thing left, and I hope I am not bothering you too much with my questions.
          How do I get these lines to be deleted after they moved to the next sheet? I looked it up online, and found this command, but I feel it’s not complete: EntireRow.Delete

          As you may have noticed, I am new to this VBA, so I really appreciate your help!

      • Thank you for your help!

        • Lutfor Rahman Shimanto
          Lutfor Rahman Shimanto May 11, 2023 at 10:27 AM

          Thank you once again for your trust in us, CAR. Please do not hesitate to reach out if you need further assistance.

          Regards
          Team ExcelDemy

  3. How would i use the code to have different values in the cell for example differen 10 digit numbers all starting with 430

    • Reply Avatar photo
      Rubayed Razib Suprov May 7, 2023 at 11:34 AM

      Greetings Beck,
      Thanks a lot for your question. I am not entirely sure if your question is pertinent to topic of the this article, or if it is just a standalone question. I am giving you a response treating the question as a standalone question.
      To have different values in the cell which is 10 digits long and starts with 430, paste the below code in the code editor, and then press Run.

      
      Sub generate_numbers()
          Dim i As Long
          Dim myrange As Range
          Set myrange = Range("B3:B12")
          For i = 1 To myrange.Cells.Count
              myrange.Cells(i) = "430" & Format(i, "0000000000")
          Next i
      End Sub
      

      After pressing Run, you will notice that the code now put 10 distinct 10-digit values in the worksheet starting with 430.
      Hope this helps, if you have any other question or suggestions,please do not hesitate to comment on this post.

      • How would I adjust the code if I wanted to pull rows that had a value in row K of my spreadsheet and copy to sheet 2?

        • Avatar photo
          Rubayed Razib Suprov Jul 18, 2023 at 1:53 PM

          You an find the solution in the below comment of yours. I have provided a reply with a code and explanation image.

  4. What would I do differently if I had a column that had numbers in some of the rows, and those were the rows I wanted to move to sheet 2. The numbers will vary and I need it to move them if updated during the week.

    • Reply Avatar photo
      Rubayed Razib Suprov Jul 18, 2023 at 12:58 PM

      Greetings Chalon,
      Below I am going to provide a code using which you will be able to move only the rows that have value in the corresponding cells in a specific column. The sheet name here termed as “Destination” and the sheet from where we want to move the cell are named as “Source”. After putting the code in the code editor, press the Run command buton.

      
      Sub MoveRowsBasedOnValue()
          Dim sourceSheet As Worksheet
          Dim destinationSheet As Worksheet
          Dim sourceRange As Range
          Dim cell As Range
          Dim destinationRow As Long
          Set sourceSheet = ThisWorkbook.Worksheets("Move Row") ' Replace "Sheet1" with your actual sheet name
          Set destinationSheet = ThisWorkbook.Worksheets("Destination") ' Replace "Sheet2" with your actual sheet name
          Set sourceRange = sourceSheet.Range("D5:D10") ' Replace "D5:D10" with your actual range
          destinationRow = 1
          For Each cell In sourceRange
              If Not IsEmpty(cell) Then
                  sourceSheet.Rows(cell.Row).Copy Destination:=destinationSheet.Rows(destinationRow)
                  destinationRow = destinationRow + 1
              End If
          Next cell
          Application.CutCopyMode = False
          destinationSheet.UsedRange.Columns.AutoFit
          MsgBox "Rows moved successfully!"
      End Sub

      After running the code,we will see that the rows corresponding to the cell values are now mooved to the destination sheet.

  5. Sometimes I have to run this multiple times for all the rows to move, and even then I can’t get one or two to move. Any ideas?

    • Reply Avatar photo
      Rubayed Razib Suprov Jul 18, 2023 at 1:37 PM

      Greetings Valerie,
      Sorry to hear about your inconvenience. Actually from our side, we are not facing issues while moving the rows. It is working quite well. If you are incorporating this code with another code there might be an issue in the parent dataset or in the sheet name. It will be much easier for us to assist you if you can provide us with your sample code, doing so we can have a look inside the code and try to identify the issue.
      Still for your convenience, we are attaching another code, you can take a look and try y yourself. You need to change the sheets name(source and the destination) and the search value alongside the seourcerange(in which column you want to search the values).

      
      Sub MoveRowsByValue()
          Dim sourceSheet As Worksheet
          Dim destinationSheet As Worksheet
          Dim sourceRange As Range
          Dim destinationRow As Long
          Dim searchValue As Variant
          Dim lastRow As Long
          Dim cell As Range
          Set sourceSheet = ThisWorkbook.Worksheets("VBA delete original")
          Set destinationSheet = ThisWorkbook.Worksheets("Sheet1")
          Set sourceRange = sourceSheet.Range("C:C")
          searchValue = "Cable"
          lastRow = sourceSheet.Cells(sourceSheet.Rows.Count, sourceRange.Column).End(xlUp).Row
          destinationRow = 1
          For Each cell In sourceRange.Cells
              If cell.Value = searchValue Then
                  sourceSheet.Rows(cell.Row).Copy Destination:=destinationSheet.Rows(destinationRow)
                  destinationRow = destinationRow + 1
              End If
              If cell.Row = lastRow Then Exit For
          Next cell
          Application.CutCopyMode = False
          destinationSheet.UsedRange.Columns.AutoFit
          MsgBox "Rows moved successfully!"
      End Sub
  6. Hi i have an issue: it keeps saying ” run-time error “9”: subscript out of range ” and this part is highlighted

    p = Worksheets(“all books”).UsedRange.Rows.Count

    how do i fix this?

    • Hello Hermione,
      Thanks for your comment.
      The “Run-time error ‘9’: Subscript out of range” error typically occurs when VBA code tries to reference a worksheet or object that doesn’t exist in the current workbook. In your case, the error is likely occurring because there is no worksheet named “all books” in your Excel workbook.

      To fix this issue, you need to ensure that the worksheet name you’re trying to reference (“all books”) exactly matches the name of a worksheet in your workbook. If the worksheet name is different or contains typos or extra spaces, you will encounter this error.

      If you have other queries let me know in the comment.
      Regards,
      Sajid Ahmed
      Exceldemy

  7. I have a workbook that is a record of repairs by technician name (which is column D). Sheet 1 is the log with everyone which I want to keep. But I also want to move a copy of that row to the sheet of the individual technician.

    Columns in order are: Date, AE Part Number, Item OEM Serial Number, Technician, Details from Red Tag, PR# if available, Problem Identified by Repair Tech, Detailed Description of Repair Work Performed, Repair Tech Name, Repair Status, Date Repaired

    • Thanks for reaching out.

      Suppose, the technician’s name is Jim. You can follow method 1 of this article to manually copy the row after applying a filter for Jim. Then you can paste it in the sheet for Jim.

      You can also follow sub-method 2.2 of method 2 of this article to apply VBA to perform your task. In the code, you just have to change the sheet names according to your requirement. You should also modify the range to look for the technician name: in your case it’s column D.
      Suppose, the main sheet name is Sheet1 and the destination sheet name is Jim, our technician. The code will be:

      
      Sub MoveRow_KeepOriginal()
      Dim rg As Range
      Dim xc As Range
      Dim p As Long
      Dim q As Long
      Dim r As Long
      p = Worksheets("Sheet1").UsedRange.Rows.Count
      q = Worksheets("Jim").UsedRange.Rows.Count
      If q = 1 Then
      If Application.WorksheetFunction.CountA(Worksheets("Jim").UsedRange) = 0 Then q = 0
      End If
      Set rg = Worksheets("Sheet1").Range("D1:D100" & p)
      On Error Resume Next
      Application.ScreenUpdating = False
       For r = 1 To rg.Count
       If CStr(rg(r).Value) = "Jim" Then
       rg(r).EntireRow.Copy Destination:=Worksheets("Jim").Range("A" & q + 1)
       q = q + 1
      End If
      Next
      Application.ScreenUpdating = True
      End Sub
      

      This code should do the work. You can try this by changing the technician name. Hope this helped.
      Regards,
      Aung
      ExcelDemy

  8. Hi, is there any way that I can get my sheet to continue updating/moving over as I add more data to the original sheet?

    • Hi CELIA!
      To get your sheet to continue updating/moving over as you add more data to the original sheet, you must use a VBA Event. You can follow the steps to do it:
      1. Press Alt + F11 to open the VBA editor.
      2. Right-click on the Sheet1 module, choose “View Code,”
      3. Paste the code into the code window.

      
      Private Sub Worksheet_Change(ByVal Target As Range)
          Dim sourceSheet As Worksheet
          Dim targetSheet As Worksheet
          Dim intersectRange As Range
          Dim cell As Range
       
          ' Set the source and target sheets
          Set sourceSheet = ThisWorkbook.Sheets("Sheet1") ' Change to the name of your source sheet
          Set targetSheet = ThisWorkbook.Sheets("Sheet2") ' Change to the name of your target sheet
       
          ' Set the range of interest (e.g., entire columns A to Z)
          Set intersectRange = Intersect(Target, sourceSheet.Range("A:Z"))
       
          ' Check if the change occurred in the source sheet and the intersected range is not empty
          If Not intersectRange Is Nothing And Target.Parent.Name = sourceSheet.Name Then
              Application.EnableEvents = False ' Disable events to prevent infinite loop
       
              ' Clear the entire target sheet to reflect the changes
              targetSheet.Cells.Clear
       
              ' Copy the entire data from the source sheet to the target sheet
              sourceSheet.UsedRange.Copy targetSheet.Range("A1")
       
              Application.EnableEvents = True ' Enable events
       
          End If
      End Sub
      

      In this code:
      1. The Worksheet_Change event is triggered when changes occur in Sheet1.
      2. The code checks if the change occurred in Sheet1 and if the changed range intersects with the specified range (e.g., columns A to Z).
      3. If the conditions are met, it disables events to prevent infinite loops, clears Sheet2, and then copies the entire data from Sheet1 to Sheet2.
      This way, when you delete items from Sheet1, Sheet2 will be updated to reflect the changes automatically.

      Thanks for Reaching out to us.
      Regards
      Team ExcelDemy

  9. My need is near the same as described in “How to Move Row to Another Sheet Based on Cell Value in Excel”. However, I have three conditions to be true before I want the row moved from worksheet Account to Archive worksheet, then deleted. In the Status column of Account, if a row has Closed or Archive selected AND a button (macro) on a Metrics worksheet is selected, then the actions should occur. Additionally, I would like a prompt in a pop up window saying “Are you sure?” OK / Cancel to confirm the desired action. I’m not sure how to do this. If you can help that would be greatly appreciated. Thx.

    • Reply Lutfor Rahman Shimanto
      Lutfor Rahman Shimanto Jun 11, 2024 at 2:31 PM

      Dear Doug

      Thanks for visiting our blog and sharing an exciting problem. You needed help with some Excel VBA sub-procedures to move rows from the Account sheet to the Archive sheet under specific conditions. You want this to happen only when you click a button on the Metrics sheet and turn it on. The conditions are as follows: if a row in the Account sheet has Closed or Archive in its Status column. You also wanted a pop-up to confirm the action before moving a row. Additionally, the row should be deleted from the Account sheet after moving.

      Don’t worry! I have reviewed your requirements and demonstrated the situation within an Excel file with a suitable dataset. I have solved the problem with the help of some Excel VBA sub-procedures. Please check the following:

      Conditional Row Movement and Deletion with User Prompt using Excel VBA

      Excel VBA Sub-procedures:

      Dim isMacroEnabled As Boolean
      
      Sub MoveRowsBasedOnConditions()
          
          If Not isMacroEnabled Then Exit Sub
          
          Dim wsAccount As Worksheet
          Dim wsArchive As Worksheet
          Dim rg As Range
          Dim cell As Range
          Dim lastRowAccount As Long
          Dim lastRowArchive As Long
          Dim userResponse As VbMsgBoxResult
      
          Set wsAccount = Worksheets("Account")
          Set wsArchive = Worksheets("Archive")
      
          userResponse = MsgBox("Are you sure?", vbOKCancel, "Confirm Action")
          
          If userResponse = vbCancel Then Exit Sub
      
          lastRowAccount = wsAccount.Cells(wsAccount.Rows.Count, "A").End(xlUp).Row
          lastRowArchive = wsArchive.Cells(wsArchive.Rows.Count, "A").End(xlUp).Row + 1
      
          Set rg = wsAccount.Range("A2:A" & lastRowAccount)
          
          For Each cell In rg
          
              If cell.Offset(0, 2).Value = "Closed" Or cell.Offset(0, 2).Value = "Archive" Then
                  
                  cell.EntireRow.Copy Destination:=wsArchive.Range("A" & lastRowArchive)
                  lastRowArchive = lastRowArchive + 1
              
              End If
              
          Next cell
          
          Call DeleteRowsBasedOnCellValue
      
      End Sub
      
      Sub DeleteRowsBasedOnCellValue()
      
          Dim ws As Worksheet
          Dim lastRow As Long
          Dim i As Long
          
          Set ws = Worksheets("Account")
          
          lastRow = ws.Cells(ws.Rows.Count, "C").End(xlUp).Row
          
          For i = lastRow To 2 Step -1
              If ws.Cells(i, 3).Value = "Closed" Or ws.Cells(i, 3).Value = "Archive" Then
                  ws.Rows(i).Delete
                  
              End If
          Next i
      
      End Sub
      
      
      Sub ToggleMacro()
          
          Dim wsMetrics As Worksheet
          Set wsMetrics = Worksheets("Metrics")
          
          isMacroEnabled = Not isMacroEnabled
          
          If isMacroEnabled Then
              wsMetrics.Buttons("btnToggle").Caption = "Macro is ON"
          Else
              wsMetrics.Buttons("btnToggle").Caption = "Macro is OFF"
          End If
      
      End Sub
      
      Sub CreateButton()
          
          Dim wsMetrics As Worksheet
          Dim btn As Button
      
          Set wsMetrics = Worksheets("Metrics")
      
          Set btn = wsMetrics.Buttons.Add(10, 10, 100, 30)
          btn.Name = "btnToggle"
          btn.Caption = "Macro is OFF"
          btn.OnAction = "ToggleMacro"
          
          isMacroEnabled = False
      
      End Sub

      Hopefully, you have found the solution you were looking for. I have attached the solution workbook as well. Good luck.

      DOWNLOAD SOLUTION WORKBOOK

      Regards
      Lutfor Rahman Shimanto
      Excel & VBA Developer
      ExcelDemy

  10. Hello! This blog is super helpful. I have a situation where I have a table of tasks that have different statuses (urgent, in progress, done). I have used the VBA code above to move rows in the table that are marked as ‘done’ to another sheet. I am wondering how to make this automatic? So if I change a row status from ‘in progress’ to ‘done’, I want the row to automatically delete from the current table and move to the next tab of ‘completed tasks’. Thanks for you help!

    • Hello Sophie,

      To automatically moves a row when the status is marked as “done”. You can use the Worksheet_Change event along with the existing code for moving rows.

      Private Sub Worksheet_Change(ByVal Target As Range)
          ' Define the range where the status is located, adjust "C" to your status column
          If Not Intersect(Target, Me.Range("C1:C" & Me.UsedRange.Rows.Count)) Is Nothing Then
              If Target.Value = "done" Then
                  ' Call the MoveRow_DeleteOriginal subroutine when status is "done"
                  Call MoveRow_DeleteOriginal(Target.Row)
              End If
          End If
      End Sub
      
      Sub MoveRow_DeleteOriginal(RowNum As Long)
          Dim rg As Range
          Dim xc As Range
          Dim p As Long
          Dim q As Long
          Dim r As Long
          p = Worksheets("VBA delete original").UsedRange.Rows.Count
          q = Worksheets("Sheet1").UsedRange.Rows.Count
          If q = 1 Then
              If Application.WorksheetFunction.CountA(Worksheets("Sheet1").UsedRange) = 0 Then q = 0
          End If
          
          ' Specify the target row
          Set rg = Worksheets("VBA delete original").Range("C" & RowNum)
          
          ' If the condition is met (e.g., "Cable" or "done"), copy and delete the row
          On Error Resume Next
          Application.ScreenUpdating = False
          If CStr(rg.Value) = "done" Then
              rg.EntireRow.Copy Destination:=Worksheets("Sheet1").Range("A" & q + 1)
              rg.EntireRow.Delete
              q = q + 1
          End If
          Application.ScreenUpdating = True
      End Sub

      This will check the changes in the “Status” column (Column C in this case). If the status changes to “done”, the MoveRow_DeleteOriginal subroutine is triggered. You can modify the range and the condition (Target.Value = “done”) as needed for your specific use case.

      Regards
      ExcelDemy

  11. I successfully used the 2.1 code to move rows from one sheet to one of 6 other sheets depending on the cell value in column Z. However, one of the sheets where the data should move and delete from original, just deletes from the original. I copied the same code for each module. I have rechecked it several times. Why is it doing that? Also, how do I make the VBA run automatically without having to manually run each time?

    Thank you.

    Sub MoveRow_DeleteOriginal()
    Dim rg As Range
    Dim xc As Range
    Dim p As Long
    Dim q As Long
    Dim r As Long
    p = Worksheets(“Intake Unit A-B”).UsedRange.Rows.Count
    q = Worksheets(“Stein E-F”).UsedRange.Rows.Count
    If q = 1 Then
    If Application.WorksheetFunction.CountA(Worksheets(“Stein E-F”).UsedRange) = 0 Then q = 0
    End If
    Set rg = Worksheets(“Intake Unit A-B”).Range(“Z1:Z” & p)
    On Error Resume Next
    Application.ScreenUpdating = False
    For r = 1 To rg.Count
    If CStr(rg(r).Value) = “Stein E-F” Then
    rg(r).EntireRow.Copy Destination:=Worksheets(“Stein E-F”).Range(“A” & q + 1)
    rg(r).EntireRow.Delete
    If CStr(rg(r).Value) = “Stein E-F” Then
    r = r – 1
    End If
    q = q + 1
    End If
    Next
    Application.ScreenUpdating = True
    End Sub

    • Hello M. Conner,

      It seems that the issue you’re facing occurs because when the row is deleted, the loop skips the next row due to the r = r – 1 line, but that condition is inside the If block. Try moving the row deletion and the check for each sheet into separate conditional blocks. For automatic running, you can use the Workbook_Open event or set up a timer to call the macro periodically.

      Here’s a modified approach for your code:
      1. Ensure If CStr(rg(r).Value) for each sheet is checked properly.
      2. For automatic execution, use an event handler like Workbook_Open.

      Let me know if you’d like further assistance!

      Regards
      ExcelDemy

      • So I got it to move and delete to the correct sheet. However, now it is pasting the row in the destination sheet on the header instead of the last row.

        • Avatar photo
          Shamima Sultana Dec 7, 2024 at 10:25 AM

          Hello M. Conner,

          It seems the issue arises from how the last row in the destination sheet is being identified. Instead of directly pasting on the last row, it’s pasting over the header.
          Here’s the updated code incorporating the fix to ensure rows are pasted below the last occupied row in the destination sheet:

          Sub MoveRow_DeleteOriginal()
              Dim rg As Range
              Dim xc As Range
              Dim p As Long
              Dim q As Long
              Dim r As Long
              Dim lastRow As Long
          
              p = Worksheets("Intake Unit A-B").UsedRange.Rows.Count
              q = Worksheets("Stein E-F").UsedRange.Rows.Count
              If q = 1 Then
                  If Application.WorksheetFunction.CountA(Worksheets("Stein E-F").UsedRange) = 0 Then q = 0
              End If
          
              Set rg = Worksheets("Intake Unit A-B").Range("Z1:Z" & p)
              On Error Resume Next
              Application.ScreenUpdating = False
          
              For r = 1 To rg.Count
                  If CStr(rg(r).Value) = "Stein E-F" Then
                      lastRow = Worksheets("Stein E-F").Cells(Rows.Count, 1).End(xlUp).Row + 1
                      rg(r).EntireRow.Copy Destination:=Worksheets("Stein E-F").Rows(lastRow)
                      rg(r).EntireRow.Delete
                      r = r - 1
                  End If
              Next
          
              Application.ScreenUpdating = True
          End Sub
          

          Changes Made:
          1. Identify the Last Row: The code now calculates the last row in the destination sheet dynamically using:
          lastRow = Worksheets(“Stein E-F”).Cells(Rows.Count, 1).End(xlUp).Row + 1

          2. Pasting Rows: Rows are now pasted below the last row to avoid overwriting the header.

          Regards
          ExcelDemy

Leave a reply

Advanced Excel Exercises with Solutions PDF

 

 

ExcelDemy
Logo