Custom order sort - excel

Hi I would like to sort the whole C column based on the values(Critical, high, medium,low). I am running this code on macro enabled worksheet
Here is my code.
Sub run()
Range("C:C").Sort Key1:=Range("C1"), SortOn:=xlSortOnValues, Order:=xlAscending, CustomOrder:="Critical,High,Medium,Low", DataOption:=xlSortNormal
End Sub
It did not work as there is error indicated. No argument. What is the solution to correct this problem? Thank you.

Your custom sort criteria needs to be in an array. Try,
Sub runSortC()
Dim vCustom_Sort As Variant, rr As Long
vCustom_Sort = Array("Critical","High","Medium","Low", Chr(42))
Application.AddCustomList ListArray:=vCustom_Sort
with Range("C:C")
.parent.Sort.SortFields.Clear
'sort on custom order with header
.Cells.Sort Key1:=.Columns(1), Order1:=xlAscending, _
Orientation:=xlTopToBottom, Header:=xlYes, MatchCase:=False, _
OrderCustom:=Application.CustomListCount + 1
.parent.Sort.SortFields.Clear
End With
End Sub
If this is in a public module, a qualified parent worksheet reference would help.

Try:
ActiveWorkbook.Worksheets("Sheet1").Sort.SortFields.Clear
ActiveWorkbook.Worksheets("Sheet1").Sort.SortFields.Add2 Key:=Range("A:A") _
, SortOn:=xlSortOnValues, Order:=xlAscending, CustomOrder:= _
"Critical,High,Medium,Low", DataOption:=xlSortNormal
With ActiveWorkbook.Worksheets("Sheet1").Sort
.SetRange Range("A:A")
.Header = xlNo
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With

Related

How to run a macro by clicking a cell

I am trying to run a macro by clicking in a cell A10. Getting Run-time error '1004': Select method of Range class failed.
"debug" highlights the 4th line down:
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
If Not Intersect(Range("A10"), Target) Is Nothing Then
Sheets("OT Requests & Hours").Select
**Range("B5:AA22").Select**
ActiveWorkbook.Worksheets("OT Requests & Hours").Sort.SortFields.Clear
ActiveWorkbook.Worksheets("OT Requests & Hours").Sort.SortFields.Add2 Key:= _
Range("C5:C22"), SortOn:=xlSortOnValues, Order:=xlDescending, DataOption _
:=xlSortNormal
ActiveWorkbook.Worksheets("OT Requests & Hours").Sort.SortFields.Add2 Key:= _
Range("Z5:Z22"), SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:= _
xlSortNormal
ActiveWorkbook.Worksheets("OT Requests & Hours").Sort.SortFields.Add2 Key:=
Range ("AA5:AA22"), SortOn:=xlSortOnValues, Order:=xlAscending, DataOption _
:=xlSortNormal
With ActiveWorkbook.Worksheets("OT Requests & Hours").Sort
.SetRange Range("B5:AA22")
.Header = xlGuess
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With
Sheets("Sun").Select
Range("A10").Select
ActiveCell.FormulaR1C1 = _
"=IF(AND(R[2]C[4]=""OT"",'OT Requests & Hours'!R[-5]C[2]=""Mid""),'OT Requests & Hours'!R[-5]C[1],"""")"
Range("A11").Select
End If
End Sub
A Worksheet Change: Sorting Another Worksheet
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
Const otName As String = "OT Requests & Hours"
Dim SunCell As Range: Set SunCell = Intersect(Me.Range("A10"), Target)
If SunCell Is Nothing Then Exit Sub
Dim wsOT As Worksheet: Set wsOT = Worksheets(otName)
Dim rgOT As Range: Set rgOT = wsOT.Range("B4:AA22")
With wsOT.Sort
.SortFields.Clear
.SortFields.Add2 Key:=rgOT.Columns(2), SortOn:=xlSortOnValues, _
Order:=xlDescending, DataOption:=xlSortNormal
.SortFields.Add2 Key:=rgOT.Columns(25), SortOn:=xlSortOnValues, _
Order:=xlAscending, DataOption:=xlSortNormal
.SortFields.Add2 Key:=rgOT.Columns(26), SortOn:=xlSortOnValues, _
Order:=xlAscending, DataOption:=xlSortNormal
.SetRange rgOT
.Header = xlYes ' or 'xlNo'; if you know it, don't let Excel guess!
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With
Application.EnableEvents = False ' to not retrigger the event
' Write the formula.
SunCell.FormulaR1C1 = "=IF(AND(R[2]C[4]=""OT"",'" & otName _
& "'!R[-5]C[2]=""Mid""),'" & otName & "'!R[-5]C[1],"""")"
Application.EnableEvents = True
' Select the cell below. This will never allow you to select 'SunCell'!
Application.Goto SunCell.Offset(1)
End Sub

How to sort date data type?

I've been trying to sort dates on A1 but it sorts based on text not the value
Private Sub sortData()
Worksheets(Me.Combobox1.Value).Range("A1:F1", Range("A1:F1").End(xlDown)).Sort
Key1:=Range("A1"), Order1:=xlAscending, Header:=xlYes
End Sub
As #Marcelo Scofano Diniz started to say, when you run into a problem forget about the shortcxuts and go by the book. Here is the book.
Private Sub SortByDate()
Dim Ws As Worksheet
Dim SortRange As Range
Set Ws = Worksheets(Me.ComboBox1.Value)
With Ws
Set SortRange = .Range(.Cells(1, 1), .Cells(.Rows.Count, "A").End(xlUp)) _
.Resize(, 6)
With .Sort.SortFields
.Clear
.Add2 Key:=SortRange.Cells(1), _
SortOn:=xlSortOnValues, _
Order:=xlAscending, _
DataOption:=xlSortNormal
End With
With .Sort
.SetRange SortRange
.Header = xlYes
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With
End With
End Sub
The above code will carry out the sort you say your code won't do. If the dates are true dates they will be sorted by date. If they are fake dates they will be sorted as text. And if you have doubt about any part of the code you can see what is being done and step through it line by line.
Change The Range to Table of Name Tbl
then Create :
Sub Table_Sort(byval FieldNo as Integer)
Tbl.Sort.SortFields.Clear
FieldRange(FieldNo).Select
Tbl.Sort.SortFields.Add _
Key:=FieldRange(FieldNo), SortOn:=xlSortOnValues, Order:= _
xlAscending, DataOption:=xlSortNormal
With Tbl.Sort
.Header = xlYes
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With
End Sub

Is this the cleanest way to code the sorting of a table in Excel?

Here's the code I've written to sort a table based on two columns then deselect the table once that's done. Is there a cleaner way to code this?
Sub SortTable()
' Sorts table
Worksheets("Data").ListObjects("Table").Sort.SortFields. _
Clear
Worksheets("Data").ListObjects("Table").Sort.SortFields. _
Add Key:=Range("Table[Date]"), SortOn:=xlSortOnValues, Order:= _
xlAscending, DataOption:=xlSortNormal
Worksheets("Data").ListObjects("Table").Sort.SortFields. _
Add Key:=Range("Table[Info]"), SortOn:=xlSortOnValues, Order:= _
xlAscending, DataOption:=xlSortNormal
With Worksheets("Data").ListObjects("Table").Sort
.Header = xlYes
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With
' Clears table selection
With Worksheets("Data")
.Activate
.Range("A1").Select
End With
End Sub
If you know the position of the columns to sort, then this method seems to clean things up.
With Sheets("data").ListObjects("Table")
.Range.Sort Key1:=.ListColumns(2), Order1:=xlAscending, _
Key2:=.ListColumns(4), Order2:=xlAscending, _
Orientation:=xlTopToBottom, Header:=xlYes
.Parent.Range("A1").Select
End With
For the above, the Date list column is 2 and Info is 4. If you don't know the column ordinals then you need to reference the columns from the parent worksheet.
With Sheets("data").ListObjects("Table")
.Range.Sort Key1:=.Parent.Range("Table[Date]"), Order1:=xlAscending, _
Key2:=.Parent.Range("Table[Info]"), Order2:=xlAscending, _
Orientation:=xlTopToBottom, Header:=xlYes
.Parent.Range("A1").Select
End With
You can do it tidier by moving your With
Sub SortTable()
' Sorts table
With Worksheets("Data").ListObjects("Table").Sort
With .SortFields
.Clear
.Add Key:=Range("Table[Date]"), SortOn:=xlSortOnValues, Order:= _
xlAscending, DataOption:=xlSortNormal
.Add Key:=Range("Table[Info]"), SortOn:=xlSortOnValues, Order:= _
xlAscending, DataOption:=xlSortNormal
End With
.Header = xlYes
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With
' Clears table selection
With Worksheets("Data")
.Activate
.Range("A1").Select
End With
End Sub

Automatic Multi-level Sorting in VBA

I currently have the following code that works and every time something is typed in, it is automatically sorted by column I
Private Sub Worksheet_Change(ByVal Target As Excel.Range)
If Target.Column = 9 Then
Dim lastRow As Long
lastRow = ActiveSheet.Cells.Find(What:="*", LookIn:=xlValues,
SearchOrder:=xlByRows, SearchDirection:=xlPrevious).Row
Range("A2:I" & lastRow).Sort Key1:=Range("I2:I" & lastRow),
Order1:=xlAscending, Header:=xlNo
End If
End Sub
I want it so that it is primarily sorted by item I, but also secondarily sorted by column A. Any help please?
The starting point for any request like this should be "Fire up the macro recorder, perform a sort, and see what code it spits out".
If you fire up the recorder and add a multilevel sort like so:
...then the Macro Recorder spits out this:
Sub Macro11()
'
' Macro11 Macro
'
'
ActiveWorkbook.Worksheets("Sheet1").Sort.SortFields.Clear
ActiveWorkbook.Worksheets("Sheet1").Sort.SortFields.Add Key:=Range("I2:I16") _
, SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
ActiveWorkbook.Worksheets("Sheet1").Sort.SortFields.Add Key:=Range("A2:A16") _
, SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
With ActiveWorkbook.Worksheets("Sheet1").Sort
.SetRange Range("A1:I16")
.Header = xlYes
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With
End Sub
This gives you a clue as to the syntax you need to add multiple sort keys. Do you need help amending your original code, or is this enough to get you started?

how do I know if my sort worked in excel vba?

I recorded the following macro when sorting data:
Sub sort_sheet_test()
ActiveWindow.ScrollRow = 1
ActiveWindow.ScrollColumn = 1
Range("A1:AB40905").Select
ActiveWorkbook.Worksheets("flurry_an_output.csv").Sort.SortFields.Clear
ActiveWorkbook.Worksheets("flurry_an_output.csv").Sort.SortFields.Add Key:= _
Range("AB2:AB40905"), SortOn:=xlSortOnValues, Order:=xlAscending, _
DataOption:=xlSortNormal
With ActiveWorkbook.Worksheets("flurry_an_output.csv").Sort
.SetRange Range("A1:AB40905")
.Header = xlYes
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With
End Sub
I then wrote my own function to use generically in other sheets...etc:
Function sort_sheet_last_column(sheet_name As String)
Dim rows1 As Long
rows1 = Get_Rows_Generic(sheet_name, 1) ' get the number of rows in the sheet
Dim columns1 As Integer
columns1 = Range(find_last_column(sheet_name)).column ' get the number of columns in the sheet
Dim sort_range As Range
Dim key_range As Range
With Worksheets(sheet_name)
Set sort_range = .Range(.Cells(1, 1), .Cells(rows1, columns1)) ' set up range: the whole used portion of the sheet
Set key_range = .Range(.Cells(1, columns1), .Cells(rows1, columns1))
End With
With Worksheets(sheet_name).Sort
.SortFields.Clear
.SortFields.Add Key:=key_range, SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
.SetRange sort_range
.Header = xlYes
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With
End Function
It seems to reorder the rows based on the right key, but how do I know if my version is 1) working at all (it's hard to know if over 40,000 rows are ordered properly, and 2) how do I know if the rest of the data are in their proper order?
I always use Sheet.Range.Sort not Sheet.Sort
lLastRow = LastUsedRow(shMain)
shMain.Range("A1:W" & lLastRow).SORT Key1:=.Range("B2"), _
Order1:=xlAscending, _
Header:=xlYes, _
OrderCustom:=1, _
MatchCase:=False, _
Orientation:=xlTopToBottom, _
DataOption1:=xlSortNormal
Never had a problem with this sorting the range and you can add Key2,Order2 and DataOption2 to sort by multiple columns

Resources