I am trying to sort a list order to the order of BMC-, CSR-, MC- and CSR-. This list exist on column B and has data on column C.
Sub telecomsorter()
Dim vCustom_Sort As Variant, rr As Long
vCustom_Sort = Array("BMC-", "CSR-", "MC-", "LC-", Chr(42))
Application.AddCustomList ListArray:=vCustom_Sort
With Worksheets("TELECOM")
LastRow = .Cells(Rows.Count, "B").End(xlUp).Row 'Find the last row for the given table
Range("B13:C" & LastRow).Select
ActiveWorkbook.Worksheets("TELECOM").Sort.SortFields.Clear
ActiveWorkbook.Worksheets("TELECOM").Sort.SortFields.Add2 Key:=Range("B13:B47"), SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
With ActiveWorkbook.Worksheets("TELECOM").Sort
.SetRange Range("B13:C" & LastRow)
.Header = xlYes
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With
End With
End Sub
I want the list to be in the order of:
BMC-
CSR-
MC-
LC-
If there are multiple strings that are the same, then I want to sort according to the order of column C.
Give it a try to this... I removed the array and add the sorting values directly to the Sort properties.
CustomOrder:="BMC-,CSR-,MC-,LC-," & Chr(42) & ""
Option Explicit
Sub telecomsorter()
Dim LastRow As Long
With Worksheets("TELECOM")
LastRow = .Cells(Rows.Count, "B").End(xlUp).Row
Range("B13:C" & LastRow).Select
ActiveWorkbook.Worksheets("TELECOM").Sort.SortFields.Clear
ActiveWorkbook.Worksheets("TELECOM").Sort.SortFields.Add2 Key:=Range( _
"B14:B" & LastRow & ""), SortOn:=xlSortOnValues, Order:=xlAscending, CustomOrder:= _
"BMC-,CSR-,MC-,LC-," & Chr(42) & "", DataOption:=xlSortNormal
ActiveWorkbook.Worksheets("TELECOM").Sort.SortFields.Add2 Key:=Range( _
"C14:C" & LastRow & ""), SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:= _
xlSortNormal
With ActiveWorkbook.Worksheets("TELECOM").Sort
.SetRange Range("B13:C" & LastRow)
.Header = xlYes
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With
End With
End Sub
EDIT: I couldn't figure it out why the LC- always comes before the MC-, so I made a small function to do the workaround... it may not be the ideal solution but it works.
Option Explicit
Sub telecomsorter()
Dim LastRow As Long
Dim First As Long
Dim Last As Long
With Worksheets("TELECOM")
LastRow = .Cells(Rows.Count, "B").End(xlUp).Row
Range("B13:C" & LastRow).Select
ActiveWorkbook.Worksheets("TELECOM").Sort.SortFields.Clear
ActiveWorkbook.Worksheets("TELECOM").Sort.SortFields.Add Key:=Range( _
"B14:B" & LastRow & ""), SortOn:=xlSortOnValues, Order:=xlAscending, CustomOrder:= _
"BMC-*,CSR-*,MC-*,LC-*," & Chr(42) & "", DataOption:=xlSortNormal
With ActiveSheet.Sort
.SetRange Range("B14:C" & LastRow)
.Header = xlNo
.Orientation = xlTopToBottom
.Apply
End With
Call SortSpecial("LC-*", xlDescending)
Call SortSpecial("MC-*", xlAscending)
Call SortSpecial("LC-*", xlAscending)
End With
End Sub
Public Function SortSpecial(ByVal StrVal As String, ByVal SortOrder As XlSortOrder)
Dim First As Long
Dim Last As Long
First = Columns("B").Find(StrVal, , xlValues, , xlRows, xlNext, , , False).Row
Last = Columns("B").Find(StrVal, , xlValues, , xlRows, xlPrevious, , , False).Row
ActiveSheet.Sort.SortFields.Clear
ActiveSheet.Sort.SortFields.Add Key:=Range("B" & First & ":B" & Last), SortOn:=xlSortOnValues, Order:=SortOrder, DataOption:=xlSortNormal
With ActiveSheet.Sort
If SortOrder = xlAscending Then
.SetRange Range("B" & First & ":C" & Last)
Else
Last = ActiveSheet.Cells(Rows.Count, "B").End(xlUp).Row
.SetRange Range("B" & First & ":C" & Last)
End If
.Header = xlNo
.Orientation = xlTopToBottom
.Apply
End With
End Function
Related
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!
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
Sheet1= master field that I am trying to copy the content from the other sheets
Sheet2= Distributor1 Column A has UPC Column B Price Column C Shipping Price
Sheet3= Distributor2 Column A has UPC Column B Price Column C Shipping Price
In Sheet 1 I would like to paste/copy ALL UPC between sheet 2 and sheet 3. If there is a duplicate (comparing UPC) I would like the lesser of the two transferred over (less of the two column B price not worried about shipping).
I have been trying this all day and cannot get it. Tried copying all UPC to Sheet 1 from both sheets marked the duplicates i just can't get it to work so I don't have duplicated products. Any ideas what would be the easier way and a possible solution?
Give this code a shot. It should do what you need.
Sub RemoveDuplicateUPCsAndKeepLowestPrice()
Application.ScreenUpdating = False
Dim Sht1 As Integer
Dim Sht2 As Integer
Dim Sht3 As Integer
Sht2 = WorksheetFunction.CountA(Sheets("Sheet2").Range("A:A"))
Sht3 = WorksheetFunction.CountA(Sheets("Sheet3").Range("A:A"))
Sheets("Sheet1").Range("A:C").ClearContents
Sheets("Sheet1").Range("A1:A" & Sht2 + Sht3).NumberFormat = "#"
Sheets("Sheet1").Range("A1:C" & Sht2).Value = Sheets("Sheet2").Range("A1:C" & Sht2).Value
Sheets("Sheet1").Range("A" & Sht2 + 1 & ":C" & (Sht3 + Sht2 - 1)).Value = Sheets("Sheet3").Range("A2:C" & Sht3).Value
Sheets("Sheet1").Sort.SortFields.Clear
Sheets("Sheet1").Sort.SortFields.Add Key:=Range("A:A"), SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
Sheets("Sheet1").Sort.SortFields.Add Key:=Range("B:B"), SortOn:=xlSortOnValues, Order:=xlDescending, DataOption:=xlSortNormal
With Sheets("Sheet1").Sort
.SetRange Range("A:C")
.Header = xlYes
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With
Sheets("Sheet1").Range("A:C").RemoveDuplicates Columns:=Array(1, 2, 3), Header:=xlYes
Sht1 = WorksheetFunction.CountA(Sheets("Sheet1").Range("A:A"))
For i = 1 To Sht1
If Sheets("Sheet1").Range("A" & i).Value = Sheets("Sheet1").Range("A" & (i + 1)).Value Then
Sheets("Sheet1").Range("A" & i & ":C" & i).ClearContents
End If
Next i
Sheets("Sheet1").Sort.SortFields.Clear
Sheets("Sheet1").Sort.SortFields.Add Key:=Range("A:A"), SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
Sheets("Sheet1").Sort.SortFields.Add Key:=Range("B:B"), SortOn:=xlSortOnValues, Order:=xlDescending, DataOption:=xlSortNormal
With Sheets("Sheet1").Sort
.SetRange Range("A:C")
.Header = xlYes
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With
Application.ScreenUpdating = True
End Sub
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
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