Excel VBA: Sort, then Copy and Paste
All, I need to write a macro that does the following:
On entry data into the last blank cell in column E, sort the entire worksheet by column E in descending order
Once the worksheet is sorted:
2a. Copy the cell to the adjacent cell immediately to the left of the cell into which the data was first entered
2b. Paste the copied data into the first column of the same row from which the data was originally entered
2c. Move the cursor to the adjacent cell immediately to the right of the cell into which the data was first entered
Below, I show the sort on entry code, which works. However, I cannot then get the code to copy, paste, and move correct. My most common problem: after data entry, the rows move, but the cursor stays in the row where the data was first entered. Can anyone help? (I can't even get the indenting right on this post!)
Private Sub Worksheet_Change(ByVal Target As Range)
If Not (Application.Intersect(Worksheets("Sheet1").Range("E:E"), Target) Is Nothing) Then
DoSort
End If开发者_运维问答
End Sub
Private Sub DoSort()
Worksheets("Sheet1").Range("A:E").Sort Key1:=Worksheets("Sheet1").Range("E1"), Order1:=xlDescending, Header:=xlYes
End Sub
Regarding 1, 2a, and 2b: It's more straightforward to do the copying before sorting. That way, the copied value will be sorted along with the rest.
Private Sub Worksheet_Change(ByVal Target As Range)
If Not (Application.Intersect(Worksheets("Sheet1").Range("E:E"), Target) _
Is Nothing) Then
' First copy
Target.Offset(0, -1).Copy Destination:=Target.Offset(0, -4)
' Then sort
DoSort
End If
End Sub
This leaves the question (2c) of how to move the active cell to the appropriate row after the rows have been sorted. Presumably, you want the user to input further data in column F?
Again, the most straightforward solution would be to have this input happen first, and then do the sorting. This would have the added benefit that the user wouldn't have the input row jump around between inputting data in column E and column F. The sorting could even happen just once, after all the data has been entered by the user.
Of course, the above is more a design suggestion than a solution to your specific task 2c. If moving the active cell after sorting is really what you want, then the solution will inevitably be more complicated. Excel's Sort
method does not return an index, to locate your entries after sorting. You will have to make an index / "serial number" yourself and search for it after sorting. This works:
Private Sub Worksheet_Change(ByVal Target As Range)
Dim newIndex As Long
If Not (Application.Intersect(Worksheets("Sheet1").Range("E:E"), Target) _
Is Nothing) Then
' Index the new entry in column B. (You can put the index elsewhere.)
newIndex = WorksheetFunction.Max(Range("B:B")) + 1
Target.Offset(0, -3).Value = newIndex
' Copy the entry.
Target.Offset(0, -1).Copy Destination:=Target.Offset(0, -4)
' Sort
DoSort
' Search for the new index after sorting. Select cell in column 6 (F).
Cells(WorksheetFunction.Match(newIndex, Range("B:B"), 0), 6).Select
End If
End Sub
Making an index is not strictly necessary if all your entries are unique (i.e. no duplicates); you could in principle just search for the entry itself. However, if there can be duplicates, then searching for the entry itself (rather than its index) will be more messy, and may lead to unwanted behaviour unless it's programmed just right. I find it much cleaner to just use an index.
I'd suggest you to save the value that has been entered and search for this value after the sorting.
Notice we may have dup data added into E column, so we'll need to store the other column's information as well until have a reliable key.
So, once you know the value(s) you need to search, find the cell containing the data you added in the column E (that might be in any other row by now, not only in the last one) and use it as an anchor to your other operations.
There are several ways to find a specific entry in a matrix (using Excel or pure VBA, as you wish). If you have problems implementing them, let us know.
Having the cell address (in column E) that contains the value that has just been added, you'll use offset
functions to set adjacent values. Again, if you have problems implementing it, let us know your doubt.
Hope it helps :)
Rgds
精彩评论