I have a small estimating worksheet I have made where you type in line items with a description, quantity and price. As it happens you often want to organize your data. In this case I would like to have the ability to move a range of cells up or down the list. (No data is being deleted, just shifting the range up or down) I am simply trying to cut and paste the data up or down one row at a time. I have an Up Arrow and Down Arrow for users to click on to activate the macro, one for up and one for down.
I have successfully written the macro code to make this happen, however it uses the select command and is very slow. I have used the same code before on another project and it was much faster, almost instant, the only difference that I can think of is that I was selecting the the ENTIRE row. In this particular instance I am only wanting to move the data in Columns B thru N. Columns O thru Y have fixed inputs and cannot be moved.
Below is the working code to move the range up.
Sub MoveUp()
Application.ScreenUpdating = False
ActiveSheet.Unprotect 'Unprotects The Sheet
If Not Intersect(ActiveCell, Range("B12:F98")) Is Nothing Then 'Makes sure you are within the correct range, cannot move top row up
Range("B" & ActiveCell.Row & ":" & "N" & ActiveCell.Row).Select 'Selects only area you want to move
Selection.Rows(Selection.Rows.Count + 1).Insert Shift:=xlDown
Selection.Rows(1).Offset(-1).Cut Selection.Rows(Selection.Rows.Count + 1)
Selection.Rows(1).Offset(-1).Delete Shift:=xlUp
Selection.Offset(-1).Select 'This keeps the cell you moved selected so you can keep moving it without having to reselect
Else
MsgBox "You Can't Move That Row Up"
End If
Call ResetRanges 'Resets the named ranges
Call ProtectWorkSheet 'Protects The Sheet
Application.ScreenUpdating = True
End Sub
I wrote an alternative macro without using select, trying to use defined ranges and use offsets to make the shift happen, but it was still just as slow as the above code. Am I missing something?
Sub MoveUpRangeMethod()
Application.ScreenUpdating = False
activerow = ActiveCell.Row
endon = activerow - 1
Set rng = Range("B" & activerow & ":" & "N" & activerow)
Set rng2 = Range("B" & activerow - 1 & ":" & "N" & activerow - 1)
rng3 = ("F" & endon)
rng.Cut
rng2.Insert Shift:=xlDown
Range(rng3).Activate
Application.ScreenUpdating = True
End Sub
Update:
I wrote the macro out another way and it still performs slowly. I think that there is something else behind the scenes causing the slowdown. It could quite possibly be from some bad code I have elsewhere. Below is the new code I tried, again, it works fast in a new sheet, but struggles in the workbook where I need it.
Sub ShiftCellsDown()
Dim ws As Worksheet: Set ws = ThisWorkbook.ActiveSheet
Application.ScreenUpdating = False
Application.Calculation = xlManual
Application.DisplayAlerts = False
ws.Range("B" & ActiveCell.Row - 1 & ":" & "N" & ActiveCell.Row - 1).Insert Shift:=xlDown, CopyOrigin:=xlFormatFromLeftOrAbove
ws.Range("B" & ActiveCell.Row - 1 & ":" & "N" & ActiveCell.Row - 1).Value = ws.Range("B" & ActiveCell.Row + 1 & ":" & "N" & ActiveCell.Row + 1).Value
ws.Range("B" & ActiveCell.Row + 1 & ":" & "N" & ActiveCell.Row + 1).Delete Shift:=xlUp
ws.Range(("F" & ActiveCell.Row - 1)).Activate
Application.DisplayAlerts = True
Application.Calculation = xlCalculationAutomatic
Application.ScreenUpdating = True
End Sub