I need to just sort the selection I am making in one Excel Datasheet. This book is shared and I am trying to not to avoid the users to use the filter/sort option instead to use this small procedure.
I just tried in many ways to approach it: by macro record, by myself, googling and documenting in any possible way.
Input: Any selection possible in one Excel sheet with headers.
Expected ouptut: Alphabetical sorting of the selection.
Trial 1: Macro recording
Option Explicit
Sub Macro1()
ActiveWorkbook.Worksheets("Raw Data").Sort.SortFields.Clear
ActiveWorkbook.Worksheets("Raw Data").Sort.SortFields.Add Key:=Range( _
"IV71"), SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:= _
xlSortNormal
With ActiveWorkbook.Worksheets("Raw Data").Sort
.SetRange Range("IV72:IZ78")
.Header = xlNo
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With
End Sub
That code works, but obvious, I need to custom for my selection:
Option Explicit
Sub Macro1()
Dim MyRange as Range
Set MyRange = Selection
ActiveWorkbook.Worksheets("Raw Data").Sort.SortFields.Clear
ActiveWorkbook.Worksheets("Raw Data").Sort.SortFields.Add Key:=MyRange, _
SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:= _
xlSortNormal
With ActiveWorkbook.Worksheets("Raw Data").Sort
.SetRange MyRange
.Header = xlNo
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With
End Sub
On that one, I got a 1004 error on .Apply. So I modified to:
Option Explicit
Sub Macro1()
Dim MyRange as Range
Set MyRange = Selection
ActiveWorkbook.Worksheets("Raw Data").Sort.SortFields.Clear
ActiveWorkbook.Worksheets("Raw Data").Sort.SortFields.Add Key:=MyRange, _
SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:= _
xlSortNormal
With ActiveWorkbook.Worksheets("Raw Data").Sort
.SetRange MyRange
.Header = xlNo
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
End With
ActiveWorkbook.Worksheets("Raw Data").Sort.Apply
End Sub
Same result: I got a 1004 error on .Apply
Then I remove the range declaration:
Option Explicit
Sub Macro1()
ActiveWorkbook.Worksheets("Raw Data").Sort.SortFields.Clear
ActiveWorkbook.Worksheets("Raw Data").Sort.SortFields.Add Key:=Selection, _
SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:= _
xlSortNormal
With ActiveWorkbook.Worksheets("Raw Data").Sort
.SetRange Selection
.Header = xlNo
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
End With
ActiveWorkbook.Worksheets("Raw Data").Sort.Apply
End Sub
It is becoming weird... whatever options I try and checked it is reporting error 1004, directly it is not working or it is reporting that the section defined can not be on blank (when it is not). Idea 1 Idea 2 Idea 3 Idea 4 Idea 5 Idea 6 Check 1 Check 2 Check 3 Check 4
My only concern is if, maybe, as Selection is a object, maybe, setting it as range is failing.
One additional detail... This procedure is working just when I select one column... the problem is when I select 2 or more.
Anyone can help me?
I found a solution, anyhow, still I donĀ“t know why I have this problem.
I can not order many columns in a range if I am not splitting in columns separately.
It is not the best one, but works... maybe need some cleaning.
Option Explicit
Sub Macro1()
Dim MyRange As Range
Dim FirstCol As Long
Dim LastCol As Long
Dim FirstRow As Long
Dim LastRow As Long
Dim SelAddress As String
Dim Aux As String
Set MyRange = Selection
SelAddress = Selection.Address
SelAddress = Mid(SelAddress, 2, Len(SelAddress) - InStr(1, SelAddress, "$", vbBinaryCompare))
Aux = Mid(SelAddress, 1, InStr(1, SelAddress, "$", vbBinaryCompare) - 1)
SelAddress = Mid(SelAddress, Len(Aux) + 2, Len(SelAddress) - Len(Aux))
Aux = Aux & Mid(SelAddress, 1, InStr(1, SelAddress, "$", vbBinaryCompare) - 2)
FirstCol = Range(Aux).Column
FirstRow = Range(Aux).Row
SelAddress = Mid(Selection.Address, Len(Aux) + 5, Len(SelAddress) - Len(Aux))
Aux = Mid(SelAddress, 1, InStr(1, SelAddress, "$", vbBinaryCompare) - 1)
SelAddress = Mid(SelAddress, Len(Aux) + 2, Len(SelAddress) - Len(Aux))
Aux = Aux & Mid(SelAddress, InStr(1, SelAddress, "$", vbBinaryCompare) + 1, Len(SelAddress))
LastCol = Range(Aux).Column
LastRow = Range(Aux).Row
For i = FirstCol To LastCol Step 1
Set MyRange = ActiveWorkbook.Worksheets("Raw Data").Range(Cells(FirstRow, i), Cells(LastRow, i))
ActiveWorkbook.Worksheets("Raw Data").Sort.SortFields.Clear
ActiveWorkbook.Worksheets("Raw Data").Sort.SortFields.Add Key:=MyRange, _
SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:= _
xlSortNormal
With ActiveWorkbook.Worksheets("Raw Data").Sort
.SetRange MyRange
.Header = xlNo
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With
Next
End Sub
Hope it helps!
Related
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
I am getting a error when trying to sort these columns. My code for the single lettered columns (ie. "A7") works fine, but when I use "AA7" for instance, there is an error.
Sub SortSectors()
'
' SortSectors Macro
'
'
Dim rng as Range
Set rng = Application.Range("AA7,AA17,AA23,AA33,AA51,AA77,AA101,AA114,AA123,AA131,AA143,AA153,AA178,AA189,AA205,AA212,AA226,AA237,AA241,AA248,AA258,AA263,AA269,AA280,AA292,AA299,AA362,AA376,AA381,AA388,AA404,AA411,AA419,AA427,AA435,AA448,AA467,AA479,AA519,AA545,AA554,AA563,AA573,AA578,AA598")
Dim col As Range
For Each col In rng.Rows
ActiveWorkbook.Worksheets("Sheet1").Sort.SortFields.Clear
ActiveWorkbook.Worksheets("Sheet1").Sort.SortFields.Add Key:=Range("AA" & col.Row), _
SortOn:=xlSortOnValues, Order:=xlDescending, DataOption:=xlSortNormal
Range("AA" & col.Row).Activate
With ActiveWorkbook.Worksheets("Sheet1").Sort
.SetRange ActiveCell.CurrentRegion
.Header = xlGuess
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With
Next col
End Sub
There's a 255-character limit to an address in Range... once you used AA as the column instead of A, you surpassed the limit.
But from your current code, it just looks like you need the rows in question; I'd do something like this (currently untested), using an array of just the row numbers:
Dim rowNums as Variant
rowNums = Array(7, 17, 23, 33, 51, 77) ' and so on
Dim i as Long
For i = LBound(rowNums) to Ubound(rowNums)
With ActiveWorkbook.Worksheets("Sheet1").Sort
.SortFields.Clear
.SortFields.Add Key:=Range("AA" & rowNums(i)), _
SortOn:=xlSortOnValues, Order:=xlDescending, DataOption:=xlSortNormal
.SetRange Range("AA" & rowNums(i))
.Header = xlGuess
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With
Next
Note that you really should qualify what workbook/worksheet each Range is in/on.
i have a macro that sorts all my data based on a custom sort but i want to use it on different worksheets that has different last row "number" if so to speak and i have this code here but i keep getting an error:
and just so that u know i am sorting column O
Sub SortDays()
' SortDays Macro
lRow = Worksheets("Banner Summary").Cells(Rows.Count, "B").End(xlUp).Row
Range("B1").Select
Range("A1:A" & lRow).Select
Range("O2").Activate
ActiveWorkbook.Worksheets("Banner Summary").Sort.SortFields.Clear
ActiveWorkbook.Worksheets("Banner Summary").Sort.SortFields.Add Key:=Range( _
"O2:O" & lRow), SortOn:=xlSortOnValues, Order:=xlAscending, CustomOrder:= _
"M,T,W,R,F", DataOption:=xlSortNormal
With ActiveWorkbook.Worksheets("Banner Summary").Sort
.SetRange Range("A1:A" & lRow)
.Header = xlYes
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With
End Sub
The error is: "The sort reference is not valid. Make sure that...."
it is quite long so any help would be really appreciated, and thnx in advance ^_^
Pass in the worksheet you want to sort:
Sub SortDays(byRef ws)
' SortDays Macro
lRow = ws.Cells(ws.Rows.Count, "B").End(xlUp).Row
'Range("B1").Select
'Range("A1:A" & lRow).Select
'Range("O2").Activate
ws.Sort.SortFields.Clear
ws.Sort.SortFields.Add Key:=Range( _
"O2:O" & lRow), SortOn:=xlSortOnValues, Order:=xlAscending, CustomOrder:= _
"M,T,W,R,F", DataOption:=xlSortNormal
With ws.Sort
.SetRange Range("A1:O" & lRow)
.Header = xlYes
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With
End Sub
Then this will run on any worksheet you pass it (assuming you have defined ws as whichever worksheet you want to use anyway:
Dim ws As Worksheet : Set ws = Workbooks("excelfilename").Worksheets("WhateverSheet")
prior to calling the Sub with SortDays ws
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
The code is from slightly edited macro. I tried to remove the 'messy code', however it is not working. The aim of it is to sort data in column BF from A to Z.
Dim InSheet As Worksheet
Set InSheet = ThisWorkbook.Worksheets("A to Z")
Dim LastRow as Integer
LastRow = InSheet.Cells(Rows.Count, 58).End(xlUp).Row
InSheet.Select
Columns("BF:BF").Select
InSheet.Sort.SortFields.Clear
InSheet.Sort.SortFields.Add Key:=Range( _
"BF1"), SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:= _
xlSortNormal
With InSheet.Sort
.SetRange Range("A1:BF" & LastRow)
.Header = xlGuess
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With
SO I tried this and it is not working:
Dim InSheet As Worksheet
Set InSheet = ThisWorkbook.Worksheets("A to Z")
Dim LastRow as Integer
LastRow = InSheet.Cells(Rows.Count, 58).End(xlUp).Row
InSheet.Columns("BF:BF")
InSheet.Sort.SortFields.Clear
InSheet.Sort.SortFields.Add Key:=Range( _
"BF1"), SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:= _
xlSortNormal
With InSheet.Sort
.SetRange Range("A1:BF" & LastRow)
.Header = xlGuess
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With
Any ideas? I would like to really avoid .select an other stuff as it is hugely decreasing performance.
You can just directly sort the Range with a Key with out the rest of the code you have.
Range("A1:BF" & LastRow).SORT Key1:=Range("BF1"), Order1:=xlAscending_
Header:=xlGuess, OrderCustom:=1, MatchCase:=False, Orientation:= _
xlTopToBottom, DataOption1:=xlSortNormal
I used advice provided by both Steven Martin's answer and Dmitry Pavliv's comment, and this is working pretty well:
Dim InSheet As Worksheet
Set InSheet = ThisWorkbook.Worksheets("A to Z")
Dim LastRow As Integer
LastRow = InSheet.Cells(Rows.Count, 58).End(xlUp).Row
With InSheet.Sort ' sort data from A to Z
.SetRange InSheet.Range("A1:BF" & LastRow)
.Header = xlGuess
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With