I am trying to find out how to get a database to automatically sort alphabetically using VBA in column A. Sounds easy, but I have headers in the first 4 rows and want it to sort from line 5 downwards. I have been searching for days to find a code that does this. The nearest I have succeeded is with this code-
Private Sub Worksheet_Change(ByVal Target As Range)
On Error Resume Next
If Not Intersect(Target, Range("A:A")) Is Nothing Then
Range("A1").Sort Key1:=Range("A2"), _
Order1:=xlAscending, Header:=xlYes, _
OrderCustom:=1, MatchCase:=False, _
Orientation:=xlTopToBottom
End If
End Sub
The problem is when I try changing the line
Range("A1").Sort Key1:=Range("A2"), _ to Range("A5").Sort Key1:=Range("A6"), _ when I test it, it still sorts to row 2 and not to row 5 as intended. I know I am missing something, but just cannot see what it is that I am missing!
Please do not misuse OERN (On Error Resume Next). It is like telling the code to Shut up :). Handle the error correctly.
Another interesting read
Is this what you are trying?
Private Sub Worksheet_Change(ByVal Target As Range)
Dim lRow As Long
On Error GoTo Whoa
'~> Find the last row in Col A
lRow = Range("A" & Rows.Count).End(xlUp).Row
'~~> Check if it is greater than row 4
If lRow > 4 Then
Application.EnableEvents = False
'~~> Check if the change happened in the relevant range
If Not Intersect(Target, Range("A5:A" & lRow)) Is Nothing Then
'~~> Sort only the relevant range
Range("A4:A" & lRow).Sort Key1:=Range("A4"), _
Order1:=xlAscending, _
Header:=xlYes, _
OrderCustom:=1, _
MatchCase:=False, _
Orientation:=xlTopToBottom, _
DataOption1:=xlSortNormal
End If
End If
Letscontinue:
Application.EnableEvents = True
Exit Sub
Whoa:
MsgBox Err.Description
Resume Letscontinue
End Sub
Related
Code is as follows:
Private Sub Worksheet_Change(ByVal Target As Range)
On Error Resume Next
If Not Intersect(Target, Range("A:A")) Is Nothing Then
Range("H2").Sort Key1:=Range("A2"), _
Order1:=xlAscending, Header:=xlYes, _
OrderCustom:=1, MatchCase:=False, _
Orientation:=xlTopToBottom
End If
End Sub
Is it possible to increase the scope of the code so that no matter where a date is entered in column A (below the A2 starting parameter) the date and row will be sorted into the correct location? Currently this code only allows the space directly after the final entry to sort.
Example:
Date
Other Info
5/12/2022
""Data
5/18/2022
''Data
5/17/2022
''Data
This produces a chart where the 5/17 will move between the 5/12 and 5/18 as it should
Example2:
Date
Other Info
5/12/2022
""Data
5/18/2022
''Data
--------
--------------
5/17/2022
''Data
This however results in nothing occurring which is what I want to increase the scope for. Is that possible?
Thanks
You could detect the last used row (examining column A) each time the event runs, with something like:
Private Sub Worksheet_Change(ByVal Target As Range)
Dim ws As Worksheet, LastRow As Long
Set ws = ActiveSheet
LastRow = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row
On Error Resume Next
If Not Intersect(Target, Range("A:A")) Is Nothing Then
Range("A2:H" & LastRow).Sort Key1:=Range("A2"), _
Order1:=xlAscending, Header:=xlYes, _
OrderCustom:=1, MatchCase:=False, _
Orientation:=xlTopToBottom
End If
End Sub
However, an easier way would be to just use the Target.Row, as this should suffice in your circumstances:
Private Sub Worksheet_Change(ByVal Target As Range)
On Error Resume Next
If Not Intersect(Target, Range("A:A")) Is Nothing Then
Range("A2:H" & Target.Row).Sort Key1:=Range("A2"), _
Order1:=xlAscending, Header:=xlYes, _
OrderCustom:=1, MatchCase:=False, _
Orientation:=xlTopToBottom
End If
End Sub
Obviously, if your table goes beyond column H, then you'll need to change that.
I have the following code that dos what I want except for being applied to a specific range. In other words, it does sort on multiple columns, and it does auto update when data is changed:
Private Sub Worksheet_Change(ByVal Target As Range)
On Error Resume Next
If Not Intersect(Target, Range("D3:F")) Is Nothing Then
Columns("A:Z").Sort Key1:=Range("F3"), Key2:=Range("E3"), Key3:=Range("D3"), _
Order1:=xlAscending, Order2:=xlAscending, Order3:=xlAscending, Header:=xlYes, _
OrderCustom:=1, MatchCase:=False, _
Orientation:=xlTopToBottom
End If
End Sub
However, what it does is that it is applied to the whole range of "A:Z", whereas I want it to be applied to a specific range only (say, "A3:Z").
I have very limited knowledge of Excel VBAs, and did what I thought was the solution, changing Columns("A:Z").Sort to Columns("A3:Z").Sort, and Range("A3:Z").Sort, but the code stops working after this change.
Any help would be greatly appreciated!
Please, try replacing of
Columns("A3:Z").Sort
with
Range("A3:Z" & Range("A" & Rows.count).End(xlUp).Row).Sort
This will set the range to be sorted like starting from A3 to last cell in column Z:Z, but based on the last cell in column A:A.
Edited:
Your event code should look like this:
Option Explicit
Private Sub Worksheet_Change(ByVal Target As Range)
If Not Intersect(Target, Range("D3:F" & Rows.Count)) Is Nothing Then
Range("B2:Z" & Range("A" & Rows.Count).End(xlUp).Row + 1).Sort Key1:=Range("F2"), Key2:=Range("E2"), Key3:=Range("D2"), _
Order1:=xlAscending, Order2:=xlAscending, Order3:=xlAscending, Header:=xlYes, _
OrderCustom:=1, MatchCase:=False, Orientation:=xlTopToBottom
End If
End Sub
Please, copy the above code instead of yours and test it. When you set the range for the second row, of course, the Keys should be adapted to this row, too. And your code should neve reach the sorting part using Range("D3:F").
Besides all that, you never should use On error resume next until you have a working code and need after that to create a error handler. Otherwise, it only not let you seeing the code real problems/errors...
Edited:
You can also use the next approach (using SortFields):
Private Sub Worksheet_Change(ByVal Target As Range)
If Not Intersect(Target, Range("D3:F" & Rows.Count)) Is Nothing Then
With ActiveSheet
.Sort.SortFields.Clear
.Sort.SortFields.Add2 Key:=Range("F3:F" & Rows.Count) _
, SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
.Sort.SortFields.Add2 Key:=Range("E3:E" & Rows.Count) _
, SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
.Sort.SortFields.Add2 Key:=Range("D3:D" & Rows.Count) _
, SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
With .Sort
.SetRange Range("B2:Z" & Range("B" & Rows.Count).End(xlUp).Row + 1)
.Header = xlYes
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With
End With
End If
End Sub
I think it is obvious that you should choose between one of them. If both of them on the sheet code module, an error will be raised...
In case someone really naïve like me had the same problem, here's what works:
Private Sub Worksheet_Change(ByVal Target As Range)
On Error Resume Next
If Not Intersect(Target, Range("D3:F")) Is Nothing Then
Range("A3", Range("Z3").End(xlDown)).Sort Key1:=Range("F3"), Key2:=Range("E3"), Key3:=Range("D3"), _
Order1:=xlAscending, Order2:=xlAscending, Order3:=xlAscending, Header:=xlNo, _
OrderCustom:=1, MatchCase:=False, _
Orientation:=xlTopToBottom
End If
End Sub
Applying the formula to all the rows below A3
Been trying for days to figure out how to do a two-level auto sort in VBA. I've managed to get a single level auto-sort working, but when I try adding a second level it overrides the first level sorting I did previously. Data is kept in Rows.
Here is what I am trying to set up to autosort
This is the VBA i have written right now for the 1st level or sorting which Sorts the Active? Column
Private Sub Worksheet_Change(ByVal Target As Range)
On Error Resume Next
If Not Intersect(Target, Range("A:A")) Is Nothing Then
Range("A1").Sort key1:=Range("A2"), _
Order1:=xlDescending, Header:=xlYes, _
OrderCustom:=1, MatchCase:=False, _
Orientation:=xlTopToBottom
End If
End Sub
Here's the new formula I wrote thanks to your comments. Seems to work. My problem before was I kept doing Key2 and Order2 as a new If function instead of as part of the previous one.
Private Sub Worksheet_Change(ByVal Target As Range)
If Not Intersect(Target, Range("A:A")) Is Nothing Then
Range("A1").Sort key1:=Range("A2"), _
Order1:=xlDescending, Header:=xlYes, _
OrderCustom:=1, MatchCase:=False, _
key2:=Range("B2"), _
Order2:=xlAscending, Header:=xlYes, _
Orientation:=xlTopToBottom
End If
End Sub
I'm currently using this VBA to sort dates in ascending order. It works well on my first worksheet but i can't seem to get it to apply to additional worksheets. Any help would be much appreciated, thanks!
Private Sub Worksheet_Change(ByVal Target As Range)
'Updateby Extendoffice 20160606
On Error Resume Next
If Application.Intersect(Target, Application.Columns(1)) Is Nothing Then Exit Sub
If Target.Count > 1 Then Exit Sub
Range("A3").Sort Key1:=Range("A4"), Order1:=xlAscending, Header:=xlYes, _
OrderCustom:=1, MatchCase:=False, Orientation:=xlTopToBottom
One Code for All Worksheets
Use the following code in the ThisWorkbook module:
Option Explicit
Private Sub Workbook_SheetChange(ByVal Sh As Object, ByVal Target As Range)
Const Cols As Variant = 1 ' or "A"
Const RangeAddr As String = "A3"
Const Key1Addr As String = "A4"
If Target.Count > 1 Then Exit Sub
If Intersect(Target, Sh.Columns(Cols)) Is Nothing Then Exit Sub
On Error Resume Next
Sh.Range(RangeAddr).Sort Key1:=Sh.Range(Key1Addr), _
Order1:=xlAscending, _
Header:=xlYes, _
OrderCustom:=1, _
MatchCase:=False, _
Orientation:=xlTopToBottom
' While developing, a simple error handler can clarify occurring issues.
' If Err.Number <> 0 Then
' Debug.Print Err.Description
' Else
' Debug.Print "Sheet '" & Sh.Name & "' successfully sorted."
' End If
'On Error GoTo 0
End Sub
I have written a VBA macro which will sort rows based on user inputs. So if an user inputs 1, then the sorting will happen based on a certain condition, if 2 then an another condition and so on. However when I run the code I get the error "Run Time error 1004: Sort method of Range class failed". Can any of the VBA experts help how I can overcome this error. Below is the entire code block :
Public Sub Sortlist()
Dim userinput As String
Dim tryagain As Integer
userinput = InputBox("1 = Sort By Division,2 = Sort by Category, 3 = Sort by Total sales")
If userinput = "1" Then
DivisionSort
ElseIf userinput = "2" Then
CategorySort
ElseIf userinput = "3" Then
TotalSort
Else
tryagain = MsgBox("Incorrect Value.Try again?", vbYesNo)
If tryagain = 6 Then
Sortlist
End If
End If
End Sub
------------------------------------
Sub DivisionSort()
'
' Sort List by Division Ascending
'
'
Selection.Sort Key1:=Range("A4"), Order1:=xlAscending, Header:=xlGuess, _
OrderCustom:=1, MatchCase:=False, Orientation:=xlTopToBottom, _
DataOption1:=xlSortNormal
End Sub
----------------------------------------------
Sub CategorySort()
'
' Sort List by Category Ascending
'
'
Selection.Sort Key1:=Range("B4"), Order1:=xlAscending, Header:=xlGuess, _
OrderCustom:=1, MatchCase:=False, Orientation:=xlTopToBottom, _
DataOption1:=xlSortNormal
End Sub
--------------------------------
Sub TotalSort()
'
' Sort List by Total Sales Ascending
'
'
Selection.Sort Key1:=Range("F4"), Order1:=xlAscending, Header:=xlGuess, _
OrderCustom:=1, MatchCase:=False, Orientation:=xlTopToBottom, _
DataOption1:=xlSortNormal
End Sub
CurrentRegion Saves the Day
Your code was failing when your Selection was out of range. So I created a Sub with one argument called SortRange which uses CurrentRegion to always 'point' to the range.
Option Explicit
Public Sub Sortlist()
Dim userinput As String
Dim tryagain As Integer
userinput = InputBox("1 = Sort By Division,2 = Sort by Category, 3 = Sort by Total sales")
If userinput = "1" Then
DivisionSort
ElseIf userinput = "2" Then
CategorySort
ElseIf userinput = "3" Then
TotalSort
Else
tryagain = MsgBox("Incorrect Value.Try again?", vbYesNo)
If tryagain = 6 Then
Sortlist
End If
End If
End Sub
'------------------------------------
Sub SortRange(rng As Range)
rng.CurrentRegion.Sort Key1:=rng, Order1:=xlAscending, Header:=xlGuess, _
OrderCustom:=1, MatchCase:=False, Orientation:=xlTopToBottom, _
DataOption1:=xlSortNormal
End Sub
'------------------------------------
Sub DivisionSort()
'
' Sort List by Division Ascending
'
SortRange Range("A4")
End Sub
'----------------------------------------------
Sub CategorySort()
'
' Sort List by Category Ascending
'
SortRange Range("B4")
End Sub
'--------------------------------
Sub TotalSort()
'
' Sort List by Total Sales Ascending
'
SortRange Range("F4")
End Sub
I had the same issue when doing an online Excel VBA course. Likely the same course. The error was in the course supplied spreadsheet. I managed to troubleshoot the problem and it was relating to this issue found on the web.
https://learn.microsoft.com/en-us/office/vba/language/reference/user-interface-help/block-if-without-end-if?
So a simpler fix but then my PC rebooted and I lost the macro that I edited and got to work.
I tried the VBasic2008 "Fix" and that works perfectly fine as well.
Just my comments on what I went thru, not trying to persuade or dissuade otherwise.
Barry