VBA Excel: Using an If statement to define an object - excel

I have combined two workbooks into one and would like the macro to work for each worksheet. (I'm fine with having to add to the code each year for it to continue to work, not a problem.) I keep getting a debug code - can you help me?
Sub CustomSort()
Dim tablename As String
If ActiveWorkbook.activeworksheet = ActiveWorkbook.activeworksheet("2021 Data") Then
tablename = Table1
ElseIf ActiveWorkbook.activeworksheet = ActiveWorkbook.activeworksheet("2020 Data") Then
tablename = Table115
Else
MsgBox ("You can't do that")
End If
Range("B2").Select
Selection.AutoFilter
Selection.AutoFilter
ActiveWorkbook.activeworksheet.ListObjects(tablename).Sort.SortFields.Clear
ActiveWorkbook.activeworksheet.ListObjects(tablename).Sort.SortFields.Add2 _
Key:=Range("[Last name]"), SortOn:=xlSortOnValues, Order:= _
xlAscending, DataOption:=xlSortNormal
ActiveWorkbook.activeworksheet.ListObjects(tablename).Sort.SortFields.Add2 _
Key:=Range("[Month ID]"), SortOn:=xlSortOnValues, Order:= _
xlAscending, DataOption:=xlSortNormal
With ActiveWorkbook.activeworksheet.ListObjects(tablename).Sort
.Header = xlYes
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With
End Sub

Related

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

Sort recorded in 2016 generates "Error 438. Object doesn't support this property or method" in 2010

I recorded a macro for a 2 column sort, that works, on Excel 2016.
I get the following error on Excel 2010.
Error 438. Object doesn't support this property or method.
What is not acceptable for the 2010 version of Excel?
Sub SortOpenOrder()
'
' Macro1 Macro
'
'
Range("Table2[[#Headers],[Customer No.]]").Select
Range(Selection, Selection.End(xlToRight)).Select
Range(Selection, Selection.End(xlDown)).Select
ActiveWorkbook.Worksheets("Open Orders").ListObjects("Table2").Sort.SortFields. _
Clear
ActiveWorkbook.Worksheets("Open Orders").ListObjects("Table2").Sort.SortFields. _
Add2 Key:=Range("Table2[Customer No.]"), SortOn:=xlSortOnValues, Order:= _
xlAscending, DataOption:=xlSortNormal
ActiveWorkbook.Worksheets("Open Orders").ListObjects("Table2").Sort.SortFields. _
Add2 Key:=Range("Table2[PO '#]"), SortOn:=xlSortOnValues, Order:= _
xlAscending, DataOption:=xlSortNormal
With ActiveWorkbook.Worksheets("Open Orders").ListObjects("Table2").Sort
.Header = xlYes
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With
Range("Table2[[#Headers],[Customer No.]]").Select
End Sub
The code you have doesn't look like it would bomb on either version of Excel, but refactoring it for better coding practices will surely help (as fabio alluded to).
Try this:
Dim myTable as ListObject
Set myTable = ThisWorkbook.Worksheets("Open Orders").ListObjects("Table2")
With myTable.Sort
With .SortFields
.Clear
.Add Key:=myTable.ListColumns("Customer No.").DataBodyRange, SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
.Add Key:=myTable.ListColumns("PO '#").DataBodyRange, SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
End With
.Header = xlYes
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With

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

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

Resources