sort rows in excel programmatically - vb.net

I am fairly new in generating excel reports using vb.net. My problem is I can't seem to properly sort the rows.
What I want to do is sort all the rows including the client name using the total value as the reference. I use interop assembly and this is the code that I've tried but it does not even work properly.
Dim myRange As Excel.Range
myRange = Wsheet.Range("A7:AG17")
myRange.Select()
myRange.Sort(Key1:=myRange.Range("AG7:AG17"), _
Order1:=Excel.XlSortOrder.xlDescending, _
Orientation:=Excel.XlSortOrientation.xlSortRows, _
SortMethod:=Excel.XlSortMethod.xlPinYin, _
DataOption1:=Excel.XlSortDataOption.xlSortNormal)

This doesn't use your ranges, but to sort your data by the totals have you tried recording a macro whilst doing it manually first?
ActiveWorkbook.Worksheets("Sheet1").Sort.SortFields.Clear
ActiveWorkbook.Worksheets("Sheet1").Sort.SortFields.Add Key:=Range("AG8:AG16" _
), SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
With ActiveWorkbook.Worksheets("Sheet1").Sort
.SetRange Range("A7:AG16")
.Header = xlYes
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With

Related

Unable to get the Sort property of the Range class

I'm getting the above error when performing a sort. I've fully qualified all objects and checked that my variables hold the correct values. The error occurs on the first line:
With ws.Columns("A:E").Sort
.SortFields.Clear
.SortFields.Add Key:=ws.Range("A2:A" & oldLastRow), SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
.SetRange ws.Range("A1:E" & oldLastRow)
.Header = xlYes
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With
It doesn't seem to matter how I refer to the range, each of these gives the same error:
With ws.Range("A:E").Sort
With ws.Range("A1:E" & oldLastRow).Sort
There is data in each cell of the range and the columns have headers. What could be causing this problem?
ws.Columns("A:E").Sort is calling the Sort function of a Range which is different from the Sort class of the worksheet:
(hit F2 in the VBA editor to get to that screen)
So your code will likely work if you just remove the .Columns("A:E") of your snippet e.g.:
With ws.Sort
.SortFields.Clear
.SortFields.Add Key:=ws.Range("A2:A" & oldLastRow), SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
.SetRange ws.Range("A1:E" & oldLastRow)
.Header = xlYes
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With
You are already saying what you want to sort with .SetRange ws.Range("A1:E" & oldLastRow) so you can see it is a bit redundant to also have it in the With statement (as well as generating the error).
PS I get
Run-time error '438': Object doesn't support this property or method

excel Vba error 400 when I added sorting to the end of my macro

I Have a relatively long sub that adds data to another sheet in a bunch of columns based on where its coming from. this part of the code works perfectly, however I wanted to sort all the rows in the table up to the last row that was added. the sorting code that I added on to the end works if I hard code what cells to include in the range, but my range will grow each time the sub is run so I tried to make the range include the variable I named for the next empty row (1MaxRows).
When I do this I get an error that says "400", in the past when I have gotten this error it is because i referenced the sheet or workbook wrong, but this time I didn't change any sheet references. The section of my code that gives me this error is as follows:
Columns("A:Q").Select
ActiveWorkbook.Worksheets("Raw Data").Sort.SortFields.Clear
ActiveWorkbook.Worksheets("Raw Data").Sort.SortFields.Add Key:=range("A2:A & lMaxRows" _
), SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
ActiveWorkbook.Worksheets("Raw Data").Sort.SortFields.Add Key:=range("B2:B & lMaxRows" _
), SortOn:=xlSortOnValues, Order:=xlDescending, DataOption:=xlSortNormal
With ActiveWorkbook.Worksheets("Raw Data").Sort
.SetRange range("A1:Q & lMaxRows")
.Header = xlYes
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With
I have tried changing the range codes in a handful of ways but I always either get an overflow error or a 400 error.
Thank you for the help.
You should qualify your Range calls with the correct worksheet, and you also have quotes in the wrong place in your addresses. For example:
Dim ws As Worksheet
Set ws = ActiveWorkbook.Worksheets("Raw Data")
With ws.Sort.SortFields
.Clear
.Add Key:=ws.Range("A2:A" & lMaxRows), SortOn:=xlSortOnValues, _
Order:=xlAscending, DataOption:=xlSortNormal
.Add Key:=ws.Range("B2:B" & lMaxRows), SortOn:=xlSortOnValues, _
Order:=xlDescending, DataOption:=xlSortNormal
End With
With ws.Sort
.SetRange ws.Range("A1:Q" & lMaxRows)
.Header = xlYes
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With
I've assumed you have properly declared and assigned a value to lMaxRows (and note that it is LMAXROWS and not 1MAXROWS with a number at the start.

Select ActiveCell in another sheet

I am working on a project that will sort all the cells in another worksheet based on criteria. I need to activate a cell in another worksheet to make it work. I tried finding a solution but no luck.
I recorded a macro from my workbook and tweaked it a bit so it would fit my need. When I run the code, Runtime Error 1004 appears.
I need a code to replace
SetRange ActiveCell.Offset(-1, 0).Range("A1:AF30436")
Any suggestion will be appreciated.
Here's the code:
Sheets("Source").Select
ActiveWorkbook.Worksheets("Source").Sort.SortFields.Clear
ActiveWorkbook.Worksheets("Source").Sort.SortFields.Add Key:=ActiveCell.Range _
("A1:A30435"), SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:= _
xlSortNormal
With ActiveWorkbook.Worksheets("Source").Sort
.SetRange ActiveCell.Offset(-1, 0).Range("A1:AF30436")
.Header = xlYes
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With
when you record macro, you click on the cell in the second sheet and start the sort routine. Macro correctly recorded this.
however when you are doing this in VBA, the "active cell" could be anything and in most cases you dont need this as long as you know the datarange that you need to work with
dim ws as WorkSheet
set ws = Sheets("Source")
ws.Sort.SortFields.Clear
ws.Sort.SortFields.Add Key:=ws.Range _
("A1:A30435"), SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:= _
xlSortNormal
With ws.Sort
.SetRange Range("A1:AF30436") ' Change here to itended dataset
.Header = xlYes
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With

Sorting multiple sheets - code clean up

Looking for some guidance on sorting columns across multiple sheets.
I have 2 data sets (tab1: ABC and tab2: XYZ).
I'm trying to sort both sheets (range column A to column J) by column A in descending order.
This is what I have so far... it is recorded. I would very much like to clean up my code and also look for better ways to approach sorting by columns. Any help/tips would be appreciated.
Sub sortingcolumns()
Application.Goto Reference:="ABC!A1"
ActiveWorkbook.Worksheets("ABC").sort.SortFields.Clear
ActiveWorkbook.Worksheets("ABC").sort.SortFields.Add Key:=Range("A1"), _
SortOn:=xlSortOnValues, Order:=xlDescending, DataOption:= _
xlSortTextAsNumbers
With ActiveWorkbook.Worksheets("ABC").sort
.SetRange Range("A2:K187")
.Header = xlNo
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With
Application.Goto Reference:="XYZ!RC"
ActiveWorkbook.Worksheets("XYZ").sort.SortFields.Clear
ActiveWorkbook.Worksheets("XYZ").sort.SortFields.Add Key:=Range("A1"), _
SortOn:=xlSortOnValues, Order:=xlDescending, DataOption:= _
xlSortTextAsNumbers
With ActiveWorkbook.Worksheets("XYZ").sort
.SetRange Range("A2:J179")
.Header = xlNo
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With
End Sub
Since you are using "with" you can combine those into one bigger with statement:
With ActiveWorkbook.Worksheets("ABC").sort
.SortFields.Clear
.SortFields.Add Key:=Range("A1"), _
SortOn:=xlSortOnValues, Order:=xlDescending, DataOption:= _
xlSortTextAsNumbers
.SetRange Range("A2:K187")
.Header = xlNo
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With
Also, you can remove the .header, .matchcase, .orientation, .sortmethod if you don't need to sort by those.
call sortingcolumns ActiveWorkbook.worksheets("ABC"), 2, 187
call sortingcolumns ActiveWorkbook.worksheets("XYZ"), 2, 179
Sub sortingcolumns(sht as Worksheet, First as Integer, Last as Integer)
With sht.sort
.sortfields.clear
.sortfields.add Key:=Range("A1"), SortOn:=xlSortOnValues, Order:=xlDescending, _
DataOption:=xlSortTextAsNumbers
.setrange = sht.range("A" & First & ":K" & Last)
.Header = xlNo
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With
End Sub
You could modify it to provide the first and last columns, as well, then you have a nice utility function that can sort any range for you just by passing the appropriate parameters.
I like to fully qualify all objects e.g. ActiveWorkbook becomes Excel.ActiveWorkbook. This is a personal choice.
Also I like to avoid Active... objects so if this code only needs to act on the workbook where the code is stored then switch to ThisWorkbook
With Excel.ThisWorkbook.Worksheets("ABC").sort
.SortFields.Clear
.SortFields.Add _
Key:=Range("A1"), _
SortOn:=Excel.xlSortOnValues, _
Order:=Excel.xlDescending, _
DataOption:= Excel.xlSortTextAsNumbers
.SetRange Range("A2:K187")
.Header = Excel.xlNo
.MatchCase = False
.Orientation = Excel.xlTopToBottom
.SortMethod = Excel.xlPinYin
.Apply
End With
If it needs to act on a separate workbook then use an object variable. For example if the target columns are in a book called foo.xlsx (that we assume is open)
Dim myFooBk As Excel.workbook
Set myFooBk = Excel.workbooks("foo.xlsx")
With myFooBk.Worksheets("ABC").sort
.SortFields.Clear
.SortFields.Add _
Key:=Range("A1"), _
SortOn:=Excel.xlSortOnValues, _
Order:=Excel.xlDescending, _
DataOption:= Excel.xlSortTextAsNumbers
.SetRange Range("A2:K187")
.Header = Excel.xlNo
.MatchCase = False
.Orientation = Excel.xlTopToBottom
.SortMethod = Excel.xlPinYin
.Apply
End With
Also the with could be altered slightly by moving the .Sort inside the clause:
Dim myFooBk As Excel.workbook
Set myFooBk = Excel.workbooks("foo.xlsx")
With myFooBk.Worksheets("ABC")
.sort.SortFields.Clear
.sort.SortFields.Add _
Key:= .Range("A1"), _ '<<more specific now as `.` infront of Range
SortOn:=Excel.xlSortOnValues, _
Order:=Excel.xlDescending, _
DataOption:= Excel.xlSortTextAsNumbers
.sort.SetRange .Range("A2:K187") '<<more specific now as `.` infront of Range
.sort.Header = Excel.xlNo
.sort.MatchCase = False
.sort.Orientation = Excel.xlTopToBottom
.sort.SortMethod = Excel.xlPinYin
.sort.Apply
End With
Yes, you can shorten it substantially:
Sub sortingcolumns()
Worksheets("ABC").Range("A2:K187").sort key1:=Range("A1"), Order1:=xlDescending
Worksheets("XYZ").Range("A2:J179").sort key1:=Range("A1"), Order1:=xlDescending
End sub
I made the following changes:
I used the (old) range.sort construct instead of the (newer) worksheet.sort. With the old construct, you simply identify the range to sort and then apply the .sort method with the appropriate arguments. The newer one is also more flexible but also more complicated to use.
The only arguments you need are key1 and Order1. If you wanted to sort ascending, you could also eliminate the order1 argument; then you'd have just one argument.
If you don't specify an argument, Excel will use the default. All of the arguments in your snippet are the default arguments for the sort method. Therefore you don't need to specify them.

Set range in VBA sort

I am trying to sort data in Excel VBA. My sheet could have a variable amount of data so I am using the Range.End method to find the last row/ column of the sheet. Though, when I try to set the range for the sort it gives me an Object Required error and I am not sure why. I have pasted my code below. Any help would be greatly appreciated.
With Sheet9.Sort
.SetRange (Sheet9.Range("A1").CurrentRegion)
.SortFields.Clear
.SortFields.Add Key:=rng2, SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
.Header = xlYes
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With
EDITED BASED ON COMMENTS:
I entered the below code into a mock spreadsheet that I created and it seems to work fine. The error described in the comments: Sort Reference is not valid indicates that there's possibly an issue in defining the key. Try to use my code (replace with necessary information) and let me know if it works.
Sub Doit()
Set rng2 = Sheet1.Range("A1:A5")
With Sheet1.Sort
.SortFields.Clear
.SortFields.Add Key:=rng2, SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
.SetRange Sheet1.Range("A1").CurrentRegion
.Header = xlYes
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With
End Sub
Based on the ability to use .End for both rows and columns, I assume you have a contiguous data set. If so, instead of complicating matters, simply use:
Range("A1").CurrentRegion to set your range object.
This recognizes the entire dataset that is built around Range("A1")