My problem with the code below is that because of the select of the range that I have defined I can't run this code successfully while on another Sheet. I know that it's bad practice to use .select and now I know why, it causes so many problems. I'm not sure how to fix this code so that it'll work properly.
Sub Sorting(sorted As Range, keys As Range)
'Range("A1:A4").Select
sorted.Select
Sheets("IDBHour1").Sort.SortFields.Clear
Sheets("IDBHour1").Sort.SortFields.Add Key:=keys, SortOn:=xlSortOnValues, _
Order:=xlAscending, DataOption:=xlSortTextAsNumbers
With Sheets("IDBHour1").Sort
.SetRange sorted
.Header = xlYes
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With
End Sub
You don't need to select in order to sort. How are you passing the ranges in the calling procedure?
My personal preference would be to pass the ranges as strings and then make them into ranges inside the sub. That code runs from anywhere. The IDBHour1 sheet needs neither selection nor activation.
Sub Sorting(sortSheet As String, sorted As String, keys As String)
Dim ws As Worksheet
Dim sortRange As Range
Dim sortKeys As Range
Set ws = ThisWorkbook.Sheets(sortSheet)
Set sortRange = ws.Range(sorted)
Set sortKeys = ws.Range(keys)
ws.Sort.SortFields.Clear
ws.Sort.SortFields.Add Key:=sortKeys, SortOn:=xlSortOnValues, _
Order:=xlAscending, DataOption:=xlSortTextAsNumbers
With ws.Sort
.SetRange sortRange
.Header = xlYes
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With
End Sub
Sub testSort()
Call Sorting("IDBHour1", "A1:A10", "A1")
End Sub
Related
I would like to add the automatic sorting capability to an Excel Table column after entering an item in that column range. The following script is already inserted in the desired Worksheet.
Private Sub WorksheetActivate()
' Sorts table automatically after each entry
Dim WKSeriesList As Sort
Set WKSeriesList = ActiveSheet.ListObjects("KitchenLinesTable").Sort
WKSeriesList.SortFields.Clear
'Clear previous sorting method
With WKSeriesList
.SortFields.Add2 Key:=Range("KitchenLinesTable[[#All],[Kitchen Series]]"), _
SortOn:=xlSortOnValues, Order:=xlAscending
.Header = xlYes
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With
End Sub
The Worksheet_Change event detects any change in column 'Kitchen Series' and calls the sortTable procedure that as some arguments: Table name, Column name, Type of sorting.
Put this code in your sheet module
Private Sub Worksheet_Change(ByVal Target As Range)
If Not Intersect(Target, Range("KitchenLinesTable[[#All],[Kitchen Series]]")) Is Nothing Then
Call sortTable("KitchenLinesTable", "Kitchen Series", xlAscending)
End If
End Sub
Put this code on a standard module
Sub sortTable(tblName As String, colName As String, sOrder As XlSortOrder)
Dim ol As ListObject: Set ol = ActiveSheet.ListObjects(tblName)
Dim olColRng As Range: Set olColRng = ol.ListColumns(colName).DataBodyRange
ol.Sort.SortFields.Clear
ol.Sort.SortFields.Add2 _
Key:=olColRng, _
SortOn:=xlSortOnValues, _
Order:=sOrder, _
DataOption:=xlSortTextAsNumbers
With ol.Sort
.Header = xlYes
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With
End Sub
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 have a number of sheets with the same template where I want to sort the date field. I've been doing it manually but am trying VBA to do it for me. I have the code below which works but it applies to more sheets than I'd like. I am trying to figure out how to stop the macro to stop at a specific sheet and end it there.
Goal: have macro run from sheet 1-10, stop # sheet 10 or if worksheet = Sheet 11 then stop. I am using sheet 1-10, 11 as simple references. I'd insert the specific sheet name.
I found some answers online with -
If ws.Name <> "" Then
end with
but am not sure where to input it within my macro below.
Sub Macro1()
'
' sortbydate2 Macro
'
'
Dim ws As Worksheet
For Each ws In ThisWorkbook.Worksheets
With ws
With .Sort
.SortFields.Clear
.SortFields.Add Key:=Range("A2:a49"), SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
.SetRange ws.Cells
.Header = xlYes
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With
End With
Next ws
End Sub
Thank you,
P1
Manipulate All Worksheets Except...
You can implement an 'exceptions array' where you would preferably
place the names, or the indexes (not recommended) of the unwanted
worksheets.
Then you can use IsError with Application.Match to check if the name of the current worksheet has been found in the 'exceptions array'.
The Code
Option Explicit
Sub Macro1()
'
' sortbydate2 Macro
'
'
Dim Exceptions As Variant
Exceptions = Array("Sheet11", "Sheet12") ' add more or less.
Dim ws As Worksheet
For Each ws In ThisWorkbook.Worksheets
If IsError(Application.Match(ws.Name, Exceptions, 0)) Then
With ws
With .Sort
.SortFields.Clear
.SortFields.Add Key:=Range("A2:a49"), _
SortOn:=xlSortOnValues, _
Order:=xlAscending, _
DataOption:=xlSortNormal
.SetRange ws.Cells
.Header = xlYes
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With
End With
End If
Next ws
End Sub
You could loop through all worksheets within the workbook and apply the filter to all except - something like:
For Each ws In ActiveWorkbook.Worksheets
if ws.Name <> "IDontWantFilters" Then
with ws
....
end with
end if
next ws
I think this should work. I assume once it gets to sheet11 you just want it to stop completly
Sub Macro1()
Dim ws As Worksheet
For Each ws In ThisWorkbook.Worksheets
if ws.name = "Sheet11" then
exit sub
end if
With ws
With .Sort
.SortFields.Clear
.SortFields.Add Key:=Range("A2:a49"), SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
.SetRange ws.Cells
.Header = xlYes
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With
End With
Next ws
End Sub
If you only want to sort the first 10 worksheets, you could do a basic loop to accomplish your task...
Dim ws As Worksheet
For i = 1 To 10
Set ws = Sheets(i)
With ws.Sort
.SortFields.Clear
.SortFields.Add Key:=Range("A2:A49"), SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
.SetRange Sheets(i).Cells
.Header = xlYes
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With
Next i
I am trying to run the macro from sheet1 to sort the column by headers A to Z using VBA in sheet2. Anyone can help me to find it out.
Sub Macro1()
Range("C10:K13").Select
ActiveWorkbook.Worksheets("Sheet2").Sort.SortFields.Clear
ActiveWorkbook.Worksheets("Sheet2").Sort.SortFields.Add Key:=Range("C10:K10") _
, SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
With ActiveWorkbook.Worksheets("Sheet2").Sort
.SetRange Range("C10:K13")
.Header = xlYes
.MatchCase = False
.Orientation = xlLeftToRight
.SortMethod = xlPinYin
.Apply
End With
End Sub
As far as I know you can't sort horizontally so I transformed your range into vertical to sort and return the original value after sorting through the transpose function, this is my approach:
Sub Test()
Dim rng As Range, transposeRng As Range
Set rng = sheets("Sheet2").[C10:K10]: Set transposeRng = sheets("Sheet2").[M6].Resize(rng.Columns.Count, rng.Rows.Count)
transposeRng.Value = Application.Transpose(rng)
ActiveWorkbook.Worksheets("Sheet2").Sort.SortFields.Clear
ActiveWorkbook.Worksheets("Sheet2").Sort.SortFields.Add2 Key:=transposeRng.Columns(1) _
, SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
With ActiveWorkbook.Worksheets("Sheet2").Sort
.SetRange transposeRng
.Header = xlGuess
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With
transposeRng.Clear
rng.Value = Application.Transpose(transposeRng)
End Sub
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