Excel VBA - multi level sorting - excel

How do I change the code below to sort in a multi level way? At present, the code sorts the table one column at a time, I want to sort it together as a multi level sort.
Below is what Im trying to achieve:
Here's my code which sorts the table one column at a time:
Range("A4:L" & lastRow).Sort key1:=Range("A4:A" & lastRow), _
order1:=xlAscending, Header:=xlNo
Range("A4:L" & lastRow).Sort key1:=Range("B4:B" & lastRow), _
order1:=xlAscending, Header:=xlNo
Range("A4:L" & lastRow).Sort key1:=Range("C4:C" & lastRow), _
order1:=xlAscending, Header:=xlNo
Range("A4:L" & lastRow).Sort key1:=Range("D4:D" & lastRow), _
order1:=xlAscending, Header:=xlNo
Range("A4:L" & lastRow).Sort key1:=Range("E4:E" & lastRow), _
order1:=xlAscending, Header:=xlNo
How do I change the above to sort everything together?

I always recommend getting rid of the recorded .Sort method in favor of 'only what you need' VBA Sort code. However, there is a problem in that you can only sort a maximum of three sort keys per sort; the solution is to perform two sort operations. Sort the highest ordinals first then the last three primary sort ordinals.
With Worksheets("Sheet1").Range("A4:L" & lastRow)
.Cells.Sort Key1:=.Columns("D"), Order1:=xlAscending, _
Key2:=.Columns("E"), Order2:=xlAscending, _
Orientation:=xlTopToBottom, Header:=xlYes
.Cells.Sort Key1:=.Columns("A"), Order1:=xlAscending, _
Key2:=.Columns("B"), Order2:=xlAscending, _
Key3:=.Columns("C"), Order3:=xlAscending, _
Orientation:=xlTopToBottom, Header:=xlYes
End With
You've mashed together cell addresses with table columns or header labels in hte image so I am not sure if I got the ordinals right. The above will sort with column A as the primary, B as secondary, C as third, D as fourth and E as fifth.

s = ComboBox1.Text
sr = ComboBox1.Text & "4"
Dim xlSort As XlSortOrder
Dim LastRow As Long
With ActiveSheet
LastRow = .Cells(.Rows.Count, "B").End(xlUp).Row
Sheet9.Range("b4:k5002").Sort Key1:=Sheet9.Range(sr), Order1:=xlAscending, Key2:=Sheet9.Range("e4"), Order2:=xlAscending
End With

Related

need to remove duplicated based on adjacent cell values

Remove Duplicated based on the adjacent cell values, with help of VBA
ID|Status
1234|Not Started - Need to be deleted
1234|Completed
3456|Completed
3456|Completed - Need to be deleted
Given your sample data all you have to do is sort by the second column in a ascending order then use Remove Duplicates.
Option Explicit
Sub sortNdedupe()
With Worksheets("sheet4")
With .Range(.Cells(1, "A"), .Cells(.Rows.Count, "B").End(xlUp))
.Cells.Sort Key1:=.Columns(2), Order1:=xlAscending, _
Header:=xlYes
.RemoveDuplicates Columns:=1, Header:=xlYes
End With
End With
End Sub
Select which of the two methods do you prefer and try:
Sub Removeduplicates()
Dim Lastrow As Long
With Worksheets("sheet1")
Lastrow = .Cells(.Rows.Count, "A").End(xlUp).Row
'Remove based on based on ID
With .Range("A1" & ":B" & Lastrow)
.Removeduplicates Columns:=1, Header:=xlYes
End With
'Remove based on ID and Status
With .Range("A1" & ":B" & Lastrow)
.Removeduplicates Columns:=Array(1, 2), Header:=xlYes
End With
End With
End Sub

Want to augment code to paste only values, would like to change range to specific columns

Looking to augment my existing code to paste only values, and would like to change the copy range to select columns only.
Sub CopySort()
Dim dEnd As Integer
Sheets("Sorted").Range("A2:R250").ClearContents
Sheets("Portfolio").Select
Range("a1").Select
dEnd = Selection.End(xlDown).Row
Range("A5:" & "Z" & dEnd).Copy
Sheets("Sorted").Select
Range("A2").Select
ActiveSheet.Paste
Columns("A:R").Sort key1:=Range("A:A"), order1:=xlAscending, Header:=xlYes, _
key2:=Range("F:F"), order2:=xlAscending, Header:=xlYes, _
OrderCustom:=1, MatchCase:=False, _
Orientation:=xlTopToBottom, DataOption1:=xlSortNormal
Application.CutCopyMode = False
End Sub

Sorting not working

In this user form
I have the following code (Ascending is by default TRUE, while Descending is False)
Private Sub OKButton_Click()
Dim rRange As Range
lastRow = Sheets("overview").Range("G1000").End(xlUp).Row
On Error Resume Next
Application.DisplayAlerts = False
Set rRange = Application.InputBox(Prompt:="Please select a cell in the column you want
_to sort", Title:="SPECIFY COLUMN", Type:=8)
Col = rRange.Columns(1).Column
On Error GoTo 0
Application.DisplayAlerts = True
If rRange Is Nothing Then
Exit Sub
Else
If AscendingOption Then
Range("A14:CB" & lastRow).Sort key1:=Range(Col & "14:" & Col & lastRow), Order1:=xlAscending, Header:=xlNo, key2:=Range("C14:C" & lastRow), Order2:=xlAscending, Header:=xlNo
End If
If DescendingOption Then
Range("A14:CB" & lastRow).Sort key1:=Range(Col & "14:" & Col & lastRow), Order1:=xlDescending, key2:=Range("C14:C" & lastRow), Order2:=xlAscending
End If
End If
End Sub
When I click OK nothing happens: not an error message, nor any action.
Can anybody help me finding the error?
Both variables AscendingOption and DescendingOption are not initialized so are set as false. You need to change value of one of them into TRUE to sort. But in current code if both are TRUE, you will sort it twice - firstly ascending and secondly descending. You can reduce code by one variable into:
If AscendingOption Then
Range("A14:CB" & lastRow).Sort key1:=Range(Col & "14:" & Col & lastRow), Order1:=xlAscending, Header:=xlNo, key2:=Range("C14:C" & lastRow), Order2:=xlAscending, Header:=xlNo
Else
Range("A14:CB" & lastRow).Sort key1:=Range(Col & "14", Col & lastRow), Order1:=xlDescending, key2:=Range("C14:C" & lastRow), Order2:=xlAscending
End If
If AscendingOption is true, it sorts in in ascending order, otherwise descending.
This is the version of the code which works fine:
Private Sub OKButton_Click()
Dim rRange As Range
lastRow = Sheets("overview").Range("G1000").End(xlUp).Row
Application.DisplayAlerts = False
Set rRange = Application.InputBox(Prompt:="Please select a cell in the column
_you want to sort", Title:="SPECIFY COLUMN", Type:=8)
Col = rRange.Columns(1).Column
On Error GoTo 0
Application.DisplayAlerts = True
If rRange Is Nothing Then
Exit Sub
Else
If AscendingOption Then
Range("A14:CE" & lastRow).Sort key1:=Range(Cells(14, Col), Cells(lastRow, Col)),
_Order1:=xlAscending, Header:=xlNo, key2:=Range("C14:C" & lastRow),
_Order2:=xlAscending, Header:=xlNo
End If
If DescendingOption Then
Range("A14:CE" & lastRow).Sort key1:=Range(Cells(14, Col), Cells(lastRow, Col)),
_Order1:=xlDescending, Header:=xlNo, key2:=Range("C14:C" & lastRow),
_Order2:=xlAscending, Header:=xlNo
End If
Unload UserForm1
End If
End Sub

Sorting using VBA

I have this code below
Dim Lasteuro As Long
ThisWorkbook.Sheets("Euro Cash").Range("A2:AF").Sort Key1:=Range("T2:T"), Order1:=xlAscending, Key2:=Range("V:V"), Order2:=xlAscending, Header:=xlYes
Lasteuro = Sheets("Euro Cash").Range("a1").End(xlDown).Row
Sheets("Euro Cash").Range("A:U").AutoFilter Field:=17, Criteria1:=Array("LNCCP", "LNLCHSCM"), Operator:=xlFilterValues
'Sec No.'
Sheets("Euro Cash").Range("D2:D" & Lasteuro).Copy
Sheets("Master").Range("K6").PasteSpecial Paste:=xlPasteValues
'Cpty Name'
Sheets("Euro Cash").Range("F2:F" & Lasteuro).Copy
Sheets("Master").Range("L6").PasteSpecial Paste:=xlPasteValues
'Break'
Sheets("Euro Cash").Range("I2:I" & Lasteuro).Copy
Sheets("Master").Range("M6").PasteSpecial Paste:=xlPasteValues
'Age'
Sheets("Euro Cash").Range("P2:P" & Lasteuro).Copy
Sheets("Master").Range("P6").PasteSpecial Paste:=xlPasteValues
Sheets("Euro Cash").ShowAllData
However upon running, I get:
Run-time error '1004' : Method Range of object _Global failed.
I clicked on debug, it highlights this
ThisWorkbook.Sheets("Euro Cash").Range("A2:AF").Sort Key1:=Range("T2:T"), Order1:=xlAscending, Key2:=Range("V:V"), Order2:=xlAscending, Header:=xlYes
So what I did is change Thisworkbook.Sheets to Sheets - still same error..
what should I do?
The use of the Range object within the Range .Sort method is open to interpretation as to what the parent worksheet is.
Dim Lasteuro As Long
With Sheets("Euro Cash")
If .AutoFilterMode Then .AutoFilterMode = False
Lasteuro = .Cells(Rows.Count, 1).End(xlUp).Row
.Range("A:AF").Sort Key1:=.Columns(20), Order1:=xlAscending, _
Key2:=.Columns(22), Order2:=xlAscending, _
Header:=xlYes
.Range("A:U").AutoFilter Field:=17, Criteria1:=Array("LNCCP", "LNLCHSCM"), _
Operator:=xlFilterValues
'Sec No.'
.Range("D2:D" & Lasteuro).Copy
Sheets("Master").Range("K6").PasteSpecial Paste:=xlPasteValues
'Cpty Name'
.Range("F2:F" & Lasteuro).Copy
Sheets("Master").Range("L6").PasteSpecial Paste:=xlPasteValues
'Break'
.Range("I2:I" & Lasteuro).Copy
Sheets("Master").Range("M6").PasteSpecial Paste:=xlPasteValues
'Age'
.Range("P2:P" & Lasteuro).Copy
Sheets("Master").Range("P6").PasteSpecial Paste:=xlPasteValues
If .AutoFilterMode Then .AutoFilterMode = False
End With
Note the use of .Range and not Range. This means that the parent is the one defined in the With ... End With statement. You are only required to indicate the first cell when defining the key.
After looking closer at all of your code (and reviewing the comments provided) I've changed the sort range so that it recognizes the column header labels in row 1.

Operation of filters in VBA

I have very recently started writing in VBA having written in various other languages over the years. I am currently having some strange issues using filters in Excel VBA and wondered if anyone could shed any light on the behaviour I am experiencing.
I would like to filter by dataset by a number of different columns, one at a time, I am doing this by copying my data set to a new sheet and sorting the data there. For the first filter I am using:
Sheets("Temp Data").Range("A:T").ClearContents
Sheets("Main Sheet").Range("A1", "T" & CountLV_Rows).Copy Sheets("Temp Data").Range("A1", "T" & CountLV_Rows)
Sheets("Temp Data").Range("A1", "T" & CountLV_Rows).Sort Key1:=Range("R1"), Order1:=xlAscending, Header:=xlGuess, _
OrderCustom:=1, MatchCase:=False, Orientation:=xlTopToBottom, _
DataOption1:=xlSortNormal
This works successfully. I would now like to filter by the values in Col C INSTEAD, I repeat the above code (including the clearcontents command as I thought that would improve my chances of success... and just swap the Key1 value to C1
For second (hopefully new filter), I used:
`Sheets("Temp Data").Range("A:T").ClearContents
Sheets("Main Sheet").Range("A1", "T" & CountLV_Rows).Copy Sheets("Temp Data").Range("A1", "T" & CountLV_Rows)
'Sort the data so ascending site numbers in column C
Sheets("Temp Data").Range("A1", "T" & CountLV_Rows).Sort Key1:=Range("C1"), Order1:=xlAscending, Header:=xlGuess, _
OrderCustom:=1, MatchCase:=False, Orientation:=xlTopToBottom, _
DataOption1:=xlSortNormal`
However, my data is sorted by column C after it is first sorted by column R...
How can I wipe any previous sorts applied?
Thanks for your help
I think it might have to do with the fact that you aren't qualifying your worksheets and ranges, i.e., explicitly specifying which workbook or worksheet they are in. That's something you always want to do.
I've done that below and it works for me in Excel 2010:
Sub test()
Dim CountLV_Rows As Long
Dim wbActive As Excel.Workbook
Set wbActive = ActiveWorkbook
With wbActive
.Sheets("Temp Data").Range("A:T").ClearContents
CountLV_Rows = .Sheets("Main Sheet").Range("A" & Rows.Count).End(xlUp).Row
.Sheets("Main Sheet").Range("A1", "T" & CountLV_Rows).Copy _
Destination:=.Sheets("Temp Data").Range("A1", "T" & CountLV_Rows)
With .Sheets("Temp Data")
.Range("A1", "T" & CountLV_Rows).Sort Key1:=.Range("R1"), Order1:=xlAscending, Header:=xlGuess, _
OrderCustom:=1, MatchCase:=False, Orientation:=xlTopToBottom, _
DataOption1:=xlSortNormal
.Activate
MsgBox "Sorted by R"
.Range("A1", "T" & CountLV_Rows).Sort Key1:=.Range("C1"), Order1:=xlAscending, Header:=xlGuess, _
OrderCustom:=1, MatchCase:=False, Orientation:=xlTopToBottom, _
DataOption1:=xlSortNormal
End With
End With
End Sub

Resources