I can do some basic sortinng using vba however i cannot get things to work when i want to make it dynamic...
what i have done now is set a hard stop at 10k, however the workbooks i need to sort change rapidly in size.
what would be the best approach and why?
i have tried to set the "Range" to Range("a1:B" & lastrow), respectively for each select however this seems to hang and not execute the macro.
ActiveWorkbook.Worksheets("Rapportage").Sort.SortFields.Add2 Key:=Range( _
"A1:BZ1"), SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:= _
xlSortNormal
With ActiveWorkbook.Worksheets("Rapportage").Sort
.SetRange Range("A1:BZ9999")
.Header = xlYes
.MatchCase = False
.Orientation = xlLeftToRight
.SortMethod = xlPinYin
.Apply
End With
Application.CutCopyMode = False
Range("q3", Range("q5 : q9999")).FormulaR1C1 = "=RC[1]+RC[2]"
Rows("5:9999").Select
ActiveWorkbook.Worksheets("Rapportage").Sort.SortFields.Clear
ActiveWorkbook.Worksheets("Rapportage").Sort.SortFields.Add2 Key:=Range( _
"B5:B9999"), SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:= _
xlSortNormal
ActiveWorkbook.Worksheets("Rapportage").Sort.SortFields.Add2 Key:=Range( _
"C5:C9999"), SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:= _
xlSortNormal
ActiveWorkbook.Worksheets("Rapportage").Sort.SortFields.Add2 Key:=Range( _
"F5:F9999"), SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:= _
xlSortNormal
ActiveWorkbook.Worksheets("Rapportage").Sort.SortFields.Add2 Key:=Range( _
"E5:E9999"), SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:= _
xlSortNormal
ActiveWorkbook.Worksheets("Rapportage").Sort.SortFields.Add2 Key:=Range( _
"I5:I9999"), SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:= _
xlSortTextAsNumbers
With ActiveWorkbook.Worksheets("Rapportage").Sort
.SetRange Range("A5:BZ9999")
.Header = xlGuess
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With```
I think your code should look somewhat like the procedure below. Note that the Key defines the column to be sorted on. It's specified by a single cell in it, usually in the first row but I chose the fifth because the first row is excluded from your range - not that VBA or Excel would take offence.
Sub TestSort()
' 041
Dim Cell As Range
Dim SortRng As Range
With ActiveWorkbook.Worksheets("Rapportage")
Set Cell = .Cells(5, 2)
With .Sort.SortFields
.Clear
.Add Key:=Cell, SortOn:=xlSortOnValues, _
Order:=xlAscending, DataOption:=xlSortNormal
.Add Key:=Cell.Offset(, 1), SortOn:=xlSortOnValues, _
Order:=xlAscending, DataOption:=xlSortNormal
.Add Key:=Cell.Offset(, 4), SortOn:=xlSortOnValues, _
Order:=xlAscending, DataOption:=xlSortNormal
.Add Key:=Cell.Offset(, 3), SortOn:=xlSortOnValues, _
Order:=xlAscending, DataOption:=xlSortNormal
.Add Key:=Cell.Offset(, 7), SortOn:=xlSortOnValues, _
Order:=xlAscending, DataOption:=xlSortNormal
End With
Set SortRng = .Range(.Cells(5, "A"), _
.Cells(.Rows.Count, "A").End(xlUp).Offset(, 77))
With .Sort
.SetRange SortRng
.Header = xlNo
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With
End With
End Sub
Specifying the column to sort on is different from specifying the range to be sorted. That enters the code only after the keys have all been set and the actual sorting process is initiated.
Related
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
I recorded a macro for sorting this sheet. how do I replace the hardcoded ranges so that this script works with any number of rows?
Worksheets(1).sort.SortFields. _
Clear
Worksheets(1).sort.SortFields. _
Add2 Key:=Range("A2:A130008"), SortOn:=xlSortOnValues, Order:=xlAscending _
, DataOption:=xlSortNormal
Worksheets(1).sort.SortFields. _
Add2 Key:=Range("B2:B130008"), SortOn:=xlSortOnValues, Order:=xlAscending _
, DataOption:=xlSortNormal
Worksheets(1).sort.SortFields. _
Add2 Key:=Range("C2:C130008"), SortOn:=xlSortOnValues, Order:=xlAscending _
, DataOption:=xlSortNormal
Worksheets(1).sort.SortFields. _
Add2 Key:=Range("D2:D130008"), SortOn:=xlSortOnValues, Order:=xlAscending _
, DataOption:=xlSortNormal
Worksheets(1).sort.SortFields. _
Add2 Key:=Range("E2:E130008"), SortOn:=xlSortOnValues, Order:=xlAscending _
, DataOption:=xlSortNormal
Worksheets(1).sort.SortFields. _
Add2 Key:=Range("P2:P130008"), SortOn:=xlSortOnValues, Order:= _
xlDescending, DataOption:=xlSortNormal
Worksheets(1).sort.SortFields. _
Add2 Key:=Range("Q2:Q130008"), SortOn:=xlSortOnValues, Order:= _
xlDescending, DataOption:=xlSortNormal
With Worksheets(1).sort
.SetRange Range("A1:R130008")
.Header = xlYes
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With
This ought to do the job. Please try it.
Sub StackOverflow()
Dim Rng As Range ' range to sort
With Worksheets(1)
Set Rng = .Range(.Cells(2, "A"), .Cells(.Rows.Count, "A").End(xlUp)) _
.Resize(, .Columns("R").Column)
' .Columns("R").Column = 18 and may be replaced with this number
With .Sort.SortFields
.Clear
' specify the columns to sort on in sequence of priority
.Add2 Key:=Rng.Cells(1), SortOn:=xlSortOnValues, _
Order:=xlAscending, DataOption:=xlSortNormal
.Add2 Key:=Rng.Cells(2), SortOn:=xlSortOnValues, _
Order:=xlAscending, DataOption:=xlSortNormal
.Add2 Key:=Rng.Cells(3), SortOn:=xlSortOnValues, _
Order:=xlAscending, DataOption:=xlSortNormal
.Add2 Key:=Rng.Cells(4), SortOn:=xlSortOnValues, _
Order:=xlAscending, DataOption:=xlSortNormal
.Add2 Key:=Rng.Cells(5), SortOn:=xlSortOnValues, _
Order:=xlAscending, DataOption:=xlSortNormal
.Add2 Key:=Rng.Cells(16), SortOn:=xlSortOnValues, _
Order:=xlAscending, DataOption:=xlSortNormal
.Add2 Key:=Rng.Cells(17), SortOn:=xlSortOnValues, _
Order:=xlAscending, DataOption:=xlSortNormal
End With
With .Sort
.SetRange Rng
.Header = xlYes
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With
End With
End Sub
Note that in .Sort.SetRange the entire range must be specified whereas for setting each of the Keys just one cell is required to identify a column. Since the cells in a range are numbered 1 and up first across and then down the first 18 cell numbers in the range coincide with the column numbers in the underling sheet range. So Key:=Rng.Cells(1) happens to be Worksheets(1).Cells(2, "A") based on how Rng was specified. I chose the shorter syntax but the effect is that the entire range will first be sorted on column A before other keys are applied.
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
I'm trying to create a macro in Excel that will sort spreadsheets by columns A, C and F. I found information online to get me started. Below is the code. The challenge I'm having is, the spreadsheet will contain a different number of rows each day. (The columns will always be the same but the row count will change). The below script will sort my data as long as the spreadsheet does not contain more than 9999 rows (that includes column headings). If I have 10,000 or more rows, the macro fails.
How do I update the below code to allow it to run regardless of the number of rows? Any help you can provide would be appreciated. Thank you
Sub Multi_Sort()
'
' Multi_Sort Macro
'
Dim lngLast As Long
lngLast = Range("A" & Rows.Count).End(xlUp).Row
With Worksheets("Sheet1").Sort
.SortFields.Clear
.SortFields.Add Key:=Range("A1:A1" & lngLast), SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
.SortFields.Add Key:=Range("C1:C1" & lngLast), SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
.SortFields.Add Key:=Range("F1:F1" & lngLast), SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
.SetRange Range("A1:F" & lngLast)
.Header = xlYes
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With
End Sub
I can't replicate your error in Excel 2013, but I'm guessing the extra "1" in your range assignments is the problem (i.e., change =Range("A1:A1" & lngLast) to =Range("A1:A" & lngLast), etc.).
Also, a good practice would be to be explicit in your range calls (include the worksheet).
Sub Multi_Sort()
Dim lngLast As Long
Dim ws As Worksheet
Set ws = ThisWorkbook.Worksheets("Sheet1")
lngLast = ws.Range("A" & .Rows.Count).End(xlUp).Row
With .Sort
.SortFields.Clear
.SortFields.Add Key:=ws.Range("A1:A" & lngLast), SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
.SortFields.Add Key:=ws.Range("C1:C" & lngLast), SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
.SortFields.Add Key:=ws.Range("F1:F" & lngLast), SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
.SetRange ws.Range("A1:F" & lngLast)
.Header = xlYes
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With
End Sub
I have wrote the following code to sort data on my workbook
With gwksSheet
With .Sort
.SortFields.Clear
.SortFields.Add Key:=Columns(glAssetTypeCol), _
SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
.SortFields.Add Key:=Columns(glFundCodeCol), _
SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
.SortFields.Add Key:=Columns(glOberonCol), _
SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
.SetRange Range(Cells(1, 1), Cells(glLastRow, glLastCol))
.Header = xlYes
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With
In the column "glOberonCol" I have numbers (e.g. 2561236) & Text (e.g. 2561236R). When it sorts it sorts the numbers and then the text. I want to sort it so I get 2561236 & 2561236R beside each other. What do I need to do. Appreciate any help.
Thanks,
Ciaran.
Follow the steps bellow:
Create another column
Add formula "=TEXT(RC[-1],"###")"
Copy this value and override the old values forcing Excel to see numbers as strings.
Now you can use your macro or just use Filter button.