Sort by variable Range - excel

I want code to figure how large a table of data is, then sort it. I assumed that I would declare a variable range once I knew how large the table is and tell Excel to sort first by the variable range "Account" and then "Symbol" and then "Quantity."
The problem occurs with the ActiveWorkbook.Worksheets("Mutual Funds").Sort.SortFields.Add Key:=Range("Account")...
Method Range of Object' Global Failed is my error message. It appears that this is not the correct way to give it a variable range.
Anyone know how to fix this?
Sub Macro1()
'
ActiveWorkbook.Sheets("Mutual Funds").Activate
Range("A12").Select
Do Until IsEmpty(ActiveCell)
ActiveCell.Offset(1).Select
Loop
ActiveCell.Offset(-1).Select
Dim Account As Range
Dim Symbol As Range
Dim Quantity As Range
Dim EntireRange As Range
Set Account = Range(ActiveCell, "A11")
Set Symbol = Range(ActiveCell.Offset(, 9), "J11")
Set Quantity = Range(ActiveCell.Offset(, 7), "H11")
Set EntireRange = Range(ActiveCell, "AS11")
ActiveWorkbook.Worksheets("Mutual Funds").Sort.SortFields.Clear
ActiveWorkbook.Worksheets("Mutual Funds").Sort.SortFields.Add Key:=Range("Account"), SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortTextAsNumbers
ActiveWorkbook.Worksheets("Mutual Funds").Sort.SortFields.Add Key:=Range("Symbol"), SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
ActiveWorkbook.Worksheets("Mutual Funds").Sort.SortFields.Add Key:=Range("Quantity"), SortOn:=xlSortOnValues, Order:=xlDescending, DataOption:=xlSortNormal
With ActiveWorkbook.Worksheets("Mutual Funds").Sort
.SetRange Range("EntireRange")
.Header = xlYes
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With
End Sub

Using Range("Account") to reference a Range variable is wrong.
Just use Account
Other issues:
The Key's need to exclude the header,
Your method of getting the used ranges is highly inefficient.
Here's your code refactored :
Sub Macro1()
Dim wb As Workbook
Dim ws As Worksheet
Dim Account As Range
Dim Symbol As Range
Dim Quantity As Range
Dim EntireRange As Range
Set wb = ActiveWorkbook
Set ws = wb.Sheets("Mutual Funds")
With ws
Set Account = .Range(.Cells(12, 1), .Cells(12, 1).End(xlDown))
End With
Set Symbol = Account.Offset(, 8)
Set Quantity = Account.Offset(, 6)
Set EntireRange = Account.Offset(-1, 0).Resize(Account.Rows.Count + 1, 45)
With ws.Sort ' EntireRange
.SortFields.Clear
.SortFields.Add Key:=Account, SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortTextAsNumbers
.SortFields.Add Key:=Symbol, SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
.SortFields.Add Key:=Quantity, SortOn:=xlSortOnValues, Order:=xlDescending, DataOption:=xlSortNormal
.SetRange EntireRange
.Header = xlYes
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With
End Sub

Related

Getting 1004 ERROR when using double lettered columns (works for single lettered)

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.

Excel Macro: Apply sorting to each sheet

Here is the code that I am using to apply sorting to each page except two. The system is throwing following error.
"select method of range class failed".
Private Sub CommandButton3_Click()
Dim ws1 As Worksheet
For Each ws1 In Worksheets
If ws1.Name <> "Sheet1" And ws1.Name <> "Extra" Then
**ws1.Range("A1:V1000").Select** Something is wrong here I suspect
ActiveWorkbook.Worksheets(ws1).Sort.SortFields.Clear
ActiveWorkbook.Worksheets(ws1).Sort.SortFields.Add Key:=Range("I2:I1000") _
, SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
ActiveWorkbook.Worksheets(ws1).Sort.SortFields.Add Key:=Range("T2:T1000") _
, SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
With ActiveWorkbook.Worksheets(ws1).Sort
.SetRange Range("A1:V1000")
.Header = xlYes
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With
End If
Next ws1
End Sub
Please help.
I would Select the worksheet before Selecting the range. Replace:
ws1.Range("A1:V1000").Select
with:
ws1.Select
Range("A1:V1000").Select
You may not need these Selections if you use .Range() rather than Range() in the code that follows. Also since ws1 is a worksheet object,:
ActiveWorkbook.Worksheets(ws1)
should be replace with:
ActiveWorkbook.Worksheets(ws1.Name)
There may be other problems with code.

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

Sorting a range in Excel with VBA

I have several similar examples that all purport to work, but mine does not. Excel 2013, Office 365.
' Sort the "URLs" worksheet after update
Worksheets("URLs").Activate
lngLastRow = Cells(65536, Range.Column).End(xlUp).Row
Set Range = Worksheets("URLs").Range("A3:E" & lngLastRow)
Worksheets("URLs").Sort.SortFields.Clear
Worksheets("URLs").Sort.SortFields.Add Key:=Range("B4:B" & lngLastRow), _
SortOn:=xlSortOnValues, Order:=xlDescending, DataOption:=xlSortNormal
Worksheets("URLs").Sort.SortFields.Add Key:=Range("A4:A" & lngLastRow), _
SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
With Worksheets("URLs").Sort
.SetRange Range("A3:E" & lngLastRow)
.Header = xlYes
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With
Even when I don't use headers (change Range("A3") to "A4") and manually use an end range ("33" instead of lngLastRow), I get the error "Run-time error '5': Invalid procedure call or argument".
I created this macro using the recorder. I don't know why a recorded macro would not work in a macro.
I have never gotten anything with a ":=" to work. I've always had to work around that, but in this case, I can't figure that out either.
Try this:
' Sort the "URLs" worksheet after update
Sub Macro1()
Worksheets("URLs").Activate
Dim Range As Range
Dim lngLastRow As Long
lngLastRow = Worksheets("URLs").Range("A1048576").End(xlUp).Row
Set Range = Worksheets("URLs").Range("A3:E" & lngLastRow)
Worksheets("URLs").Sort.SortFields.Clear
Worksheets("URLs").Sort.SortFields.Add Key:=Worksheets("URLs").Range("B4:B" & lngLastRow), _
SortOn:=xlSortOnValues, Order:=xlDescending, DataOption:=xlSortNormal
Worksheets("URLs").Sort.SortFields.Add Key:=Worksheets("URLs").Range("A4:A" & lngLastRow), _
SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
With Worksheets("URLs").Sort
.SetRange Worksheets("URLs").Range("A3:E" & lngLastRow)
.Header = xlYes
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With
End Sub

How can I only sort thru the rows with data?

I have a macro that sorts the rows by a specific column, the problem is I'm manually setting the range for the number of rows to sort (i.e. A2:A174) every time I add a new row. How can I change my code so that it sorts all the rows with data only so I don't have to go into the code and change the range every time I add a new row.
Sub SortByName()
SortByName Macro
ActiveWorkbook.Worksheets("Sheet1").Sort.SortFields.Clear
ActiveWorkbook.Worksheets("Sheet1").Sort.SortFields.Add Key:=Range("A2:A174") _
, SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
With ActiveWorkbook.Worksheets("Sheet1").Sort
.SetRange Range("A1:H174")
.Header = xlYes
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With
Range("A1").Select
End Sub
Sub SortByDate()
Thanks so much in advance for your wisdom!
something like this which looks for the last cell in A to mark the range.
Sub SortByName()
Dim ws As Worksheet
Dim rng1 As Range
Set ws = Sheets("Sheet1")
Set rng1 = ws.Range(ws.[a1], Cells(Rows.Count, "A").End(xlUp))
ws.Sort.SortFields.Clear
ws.Sort.SortFields.Add Key:=rng1 _
, SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
With ActiveWorkbook.Worksheets("Sheet1").Sort
.SetRange rng1.Resize(rng1.Rows.Count, 8)
.Header = xlYes
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With
Application.Goto ws.[a1]
End Sub

Resources