Why do blank lines appear after multi-level sorting? - excel

I have a macro that sorts by color, then by date, then again by date.
If I delete a date, instead of just re-sorting, it re sorts and then leaves blank rows where the row from which a date was deleted used to be. I tried adding another sort layer where I sort by color RGB(0,0,0).
Why are the blank rows sitting there?
How do I remove them or make them not appear at all?
If Not Intersect(Target, Range("A:C")) Is Nothing Then
MsgBox ("sorting")
ActiveSheet.Sort.SortFields.Clear
ActiveSheet.Sort.SortFields.Add(Range("C:C"), _
xlSortOnCellColor, _
xlDescending, _
, _
xlSortNormal).SortOnValue.Color = RGB(146, 208, 80)
ActiveSheet.Sort.SortFields.Add2 Key:=Range("C:C"), _
SortOn:=xlSortOnValues, _
Order:=xlDescending, _
DataOption:=xlSortNormal
ActiveSheet.Sort.SortFields.Add2 Key:=Range("B:B"), _
SortOn:=xlSortOnValues, _
Order:=xlDescending, _
DataOption:=xlSortNormal
ActiveSheet.Sort.SortFields.Add2(Range("C:C"), _
xlSortOnCellColor, _
xlDescending, _
, _
xlSortNormal).SortOnValue.Color = RGB(255, 255, 255)
With ActiveSheet.Sort
.SetRange Range("A:C")
.Header = xlYes
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With
End If

I believe I might have an answers to your questions, atleast for the second one I am sure...
Why are the blank rows sitting there?
I can be only guessing since I do not have your source file to check for any irregularities nor your whole macro. If I had to guess, I would say it is either some function in your macro what is causing this or it might also be an issue of how you define sort ranges. You only specify columns and not actual starting cells and also no ending cells. The way I am used to sort data is to dynamically define the exact range.
How do I remove them or make them not appear at all?
Please try the code which I have adjusted based on your data and code you provided:
If Not Intersect(Target, Range("A:C")) Is Nothing Then
MsgBox ("sorting")
With ActiveWorkbook.ActiveSheet
lastRow = .Cells(.Rows.Count, "A").End(xlUp).Row '<-- get last row of data in column "A"
.Sort.SortFields.Clear
.Sort.SortFields.Add(Range("C1:C" & lastRow), _
xlSortOnCellColor, xlDescending, , xlSortNormal).SortOnValue.Color = RGB(146, 208, 80)
.Sort.SortFields.Add Key:=.Range("B1:B" & lastRow), _
SortOn:=xlSortOnValues, Order:=xlDescending, DataOption:=xlSortNormal
.Sort.SortFields.Add Key:=.Range("C1:C" & lastRow), _
SortOn:=xlSortOnValues, Order:=xlDescending, DataOption:=xlSortNormal
.Sort.SortFields.Add(Range("C1:C" & lastRow), _
SortOn:=xlSortOnCellColor, Order:=xlDescending, DataOption:=xlSortNormal).SortOnValue.Color = RGB(255, 255, 255)
With .Sort
.SetRange Range("A1:C" & lastRow)
.Header = xlYes
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With
End With
End If
The main adjustment is declaration of lastRow which adjusts the bottom of the data range (in your situation it should not matter but you might sometimes encounter data where you want to sort until certain row and this will be very helpful. Also lastRow as defined here is very helpful for a whole lot of other macros and helps to set ranges dynamically).
And I have also added the start the data as you can see in Range("C1:C" & lastRow)
I have tested this on a sample data you have provided and it worked as expected. I hope it will work for you exactly as you wanted to.

Related

Sort and ignore leading quotation marks

This VBA code sorts my vinyl collection catalogue by any column by double-clicking the column header.
With my classical vinyl, nearly half of the song titles are in quotes and so when that column is sorted, it alphabetically sorts the titles with quotes first, then the titles without quotes.
Is there a way to add a line of code so that it will ignore the leading quotation marks when sorting so that "ac" comes after ab and so on?
My workaround for now uses a hidden helper column to strip the quotes but I am hoping for a cleaner solution.
Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean)
Dim KeyRange As Range
Dim ColumnCount As Integer
'Clear previous sorts
ActiveSheet.Sort.SortFields.Clear
'Clear contents of hidden helper column
Columns("K").ClearContents
'Copy and Paste songname column to helper column
Range("F:F").Copy Range("K:K")
'Strip quotes from helper column
Application.ScreenUpdating = FALSE
ActiveSheet.Columns("K").Replace What:="""", Replacement:="", LookAt:=xlPart, MatchCase:=False
Application.ScreenUpdating = TRUE
'Set range of header columns that will sort on double-click
ColumnCount = Range("A1:J1").Columns.Count
Cancel = FALSE
If Target.Row = 1 And Target.Column <= ColumnCount Then
Cancel = TRUE
'Get cell address of double-clicked header cell
Set SortColumn = Range(Target.Address)
'Set fill color of currently sorted column header
Rows(1).Interior.Color = xlNone
SortColumn.Interior.ColorIndex = 15
With ActiveSheet
'Sort by hidden column if songname column is double-clicked
If SortColumn = Range("F1") Then
Range("K1").Select
Else
SortColumn.Select
End If
'Sort by selected column followed by album, disc, then track
.Sort.SortFields.Add Key:=Selection, _
SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
.Sort.SortFields.Add Key:=Range("E1"), _
SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
.Sort.SortFields.Add Key:=Range("B1"), _
SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
.Sort.SortFields.Add Key:=Range("C1"), _
SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
End With
With ActiveSheet.Sort
'Set flexible sort range to all data before reaching entirely empty row or column
.SetRange Range("A1").CurrentRegion
.Header = xlYes
.MatchCase = FALSE
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With
End If
End Sub
Excel has always had this issue when sorting data. This is because it uses ASCII character codes to determine sort order (more details here: https://exceljet.net/excel-functions/excel-char-function). Special characters and punctuation have lower ASCII values than alphabet letters, so they get sorted at the top. This is by design.
There's no real way to "ignore" quotation marks when sorting, but one way to get around this is to remove all the quotes from the cells you are trying to sort. You could try adding this code right after your SET statement:
ActiveSheet.KeyRange.Cells.Replace _
What:="""", _
Replacement:="", _
LookAt:=xlPart, _
MatchCase:=False
WARNING!!! This will actually modify all your song titles (it will remove the double quotes from that column), so please back up your file before you try this.
One way is to Add a dummy Column K with F data, clear ", sort, erase column K...
I fixed the code accordingly
Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean)
Dim KeyRange As Range
Dim ColumnCount As Integer
Dim dstRng as Range ' placeholder 2 add column "K"
ActiveSheet.Sort.SortFields.Clear
ColumnCount = Range("A1:J281").Columns.Count
Cancel = False
If Target.Row = 1 And Target.Column <= ColumnCount Then
Cancel = True
Set KeyRange = Range(Target.Address)
Set dstRng = KeyRange.Resize(, 1).Offset(, KeyRange.Columns.Count - 1) 'Added column K
KeyRange.Resize(,1).Offset(,5).copy ' copy column F
dstRng.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
dstRng.Replace What:="""", Replacement:="", LookAt:=xlPart, _
SearchOrder:=xlByColumns, MatchCase:=False, SearchFormat:=False, _
ReplaceFormat:=False
With ActiveSheet ' columns F,B,C >> K,B,C
.Sort.SortFields.Add Key:=KeyRange, _
SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
.Sort.SortFields.Add Key:=Range("K1"), _
SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
.Sort.SortFields.Add Key:=Range("B1"), _
SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
.Sort.SortFields.Add Key:=Range("C1"), _
SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
End With
With ActiveSheet.Sort
.SetRange Range("A1:K281")
.Header = xlYes
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With
dstRng.ClearContents
End If
End Sub
As Always run 1st on a copy, protecting the original Excel file.
NOTES: I have used KeyRange to work on, but there might be a case that some set SrcRng = Range("A1:J281") is needed

VBA Find NAMED column and filter - Nearly working macro

I am struggling to cover everything I need to do in one macro - I asked a similar question here a few hours ago and was answered however unfortunately I needed to add a few functions to my macro so I had to modify it slightly and now I require a tiny tweak that I can't get to work
Sub BoBTEST()
Dim c As Range
For Each c In Range("A1:BR1").Cells
If c.Value = "Plate Name (barcode)" Or c.Value = "Measurement Date" Or c.Value = "Measurement profile" Or c.Value = "pH" Or c.Value = "Count" Or c.Value <= 30 Then
c.EntireColumn.Hidden = False
Else: c.EntireColumn.Hidden = True
End If
Next c
ActiveWorkbook.Worksheets("Sheet1").Sort.SortFields.Clear
ActiveWorkbook.Worksheets("Sheet1").Sort.SortFields.Add2 Key:=Range( _
"AF2:AF1761"), SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:= _
xlSortNormal
ActiveWorkbook.Worksheets("Sheet1").Sort.SortFields.Add2 Key:=Range( _
"AN2:AN1761"), SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:= _
xlSortNormal
ActiveWorkbook.Worksheets("Sheet1").Sort.SortFields.Add2 Key:=Range( _
"J2:J1761"), SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:= _
xlSortNormal
With ActiveWorkbook.Worksheets("Sheet1").Sort
.SetRange Range("A1:BR1761")
.Header = xlYes
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With
Range("A1:BR1761").Select
Range("AT9").Activate
Selection.AutoFilter
Selection.AutoFilter
ActiveSheet.Range("$A$1:$BR$1761").AutoFilter Field:=32, Criteria1:= _
"=Shear Rated(gamma)/dt = 4 1/s", Operator:=xlOr, Criteria2:="="
ActiveSheet.Range("$A$1:$BR$1761").AutoFilter Field:=40, Criteria1:= _
"=Viscosity", Operator:=xlOr, Criteria2:="="
End Sub
Basically what it does so far is takes data which is exported from a robot, hides the columns that I don't want and filters the values that I don't want
The problem is that these columns are dynamic and occasionally move around - the macro is able to hide all of the columns I don't want however I'm struggling to make it search for these columns and then filter, right now it is using a recording I did so it selects e.g. column J and then filters
ActiveWorkbook.Worksheets("Sheet1").Sort.SortFields.Add2 Key:=Range( _
"J2:J1761"), SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:= _
xlSortNormal
However it may not be on column J it might be at K as occasionally more columns are entered when exporting data
Is there any way to tweak the macro to make it so the auto-filter part actually searches for column headers as opposed to doing these functions on e.g. "J2:J2000" etc.
Thanks a lot apologies that it is long winded I wanted to cover everything

Auto Sorting after inputting data using UserForm

I've made a UserForm to input data to specific columns on a worksheet("Endorse"), and it works fine.
After that, I have used a code to automatically sort the sheet based on the the values on Column A, B and C. But the sheet does not sort based on the criteria:
Column A: oldest to recent (date)
Column B: ascending order by: "BSUH (September),Frimley (October),CWH (November),Kingston (December)"
Column C: ascending order by: Allen,Christine,Feri,Hubert,Paula"
here is the code that i have used for the sheet("Endorse"):
Private Sub Worksheet_Change(ByVal Target As Range)
LastRow = Range("L4000").End(xlUp).Row
ActiveWorkbook.Worksheets("Endorsed Candidates").Sort.SortFields.Clear
ActiveWorkbook.Worksheets("Endorsed Candidates").Sort.SortFields.Add Key:= _
Range("A2:A" & LastRow), SortOn:=xlSortOnValues, Order:=xlAscending, DataOption _
:=xlSortNormal
ActiveWorkbook.Worksheets("Endorsed Candidates").Sort.SortFields.Add Key:= _
Range("B2:B" & LastRow), SortOn:=xlSortOnValues, Order:=xlAscending, CustomOrder _
:="BSUH (September),Frimley (October),CWH (November),Kingston (December)", _
DataOption:=xlSortNormal
ActiveWorkbook.Worksheets("Endorsed Candidates").Sort.SortFields.Add Key:= _
Range("C2:C4000"), SortOn:=xlSortOnValues, Order:=xlAscending, CustomOrder _
:="Allen,Christine,Feri,Hubert,Paula", DataOption:=xlSortNormal
With ActiveWorkbook.Worksheets("Endorsed Candidates").Sort
.SetRange Range("A2:L" & LastRow)
.Header = xlGuess
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With
End Sub
Here is the sheet after using the UserForm:
[enter image description here][1]
*ps I can't post an image yet in my question, hope you guys understand. And many thanks to those who could help!

Excel Sorting not working due to Range object

This macro is based off one I recorded, but have tweaked to cope with possible absence of 3 of the 4 sorting criteria. I can't figure out why my Macro works when the range criteria is specific, but not when I'm referencing a single cell and extrapolating.
With this line the sorting works
.SetRange Range("A1:W162")
With this line it doesn't sort.
.SetRange Range("A1").End(xlDown).End(xlToRight)
I've stepped through and can confirm it's selecting the correct range
I don't want use the line with specific cells because future exports will be different sized.
This is the full subroutine (the relevant bit is near the bottom).
Thanks!
Sub SortByScoreAndCost()
Dim Score As Range
Dim Cost As Range
Dim YN As Range
Dim OriginalScore As Range
Set Score = Cells.Find("Score")
Set Cost = Cells.Find("Cost")
Set YN = Cells.Find("Y/N")
Set OriginalScore = Cells.Find("Original Score")
Range("A1").CurrentRegion.Select
ActiveSheet.Sort.SortFields.Clear
ActiveSheet.Sort.SortFields.Add Key:=Range( _
Score.Offset(1, 0), Score.End(xlDown)), SortOn:=xlSortOnValues, Order:=xlDescending, DataOption:= _
xlSortNormal
If Cells.Find("Cost") Is Nothing _
Then
Else: ActiveSheet.Sort.SortFields.Add Key:=Range _
(Cost.Offset(1, 0), Cost.End(xlDown)), SortOn:=xlSortOnValues, Order:=xlDescending, DataOption _
:=xlSortNormal
End If
If Cells.Find("Y/N") Is Nothing _
Then
Else: ActiveSheet.Sort.SortFields.Add Key:=Range _
(YN.Offset(1, 0), YN.End(xlDown)), SortOn:=xlSortOnValues, Order:=xlDescending, DataOption _
:=xlSortNormal
End If
If Cells.Find("Original Score") Is Nothing _
Then
Else: ActiveSheet.Sort.SortFields.Add Key:=Range _
(OriginalScore.Offset(1, 0), Original.End(xlDown)), SortOn:=xlSortOnValues, Order:=xlDescending, DataOption _
:=xlSortNormal
End If
With ActiveSheet.Sort
.SetRange Range("A1:W162") 'works with this line
.SetRange Range("A1").End(xlDown).End(xlToRight) 'doesn't work if replaced with this line
.Header = xlYes
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With
End Sub
Range("A1").End(xlDown).End(xlToRight) refers to a single cell range, not similar to A1:W162. Assuming A1:W162 is the range where all the data on your sheet is. The line refers to W162 only. The Range.End property is explained here and it shows that it does not retain the starting point.
Try Range("A1:"& Range("A1").End(xlDown).End(xlToRight).Address) instead as this should create a range similar to A1:W162. The first part is the string "A1:" and Range("A1).End(xlDown).end(xlToRight).Address returns the string "$W$162" Together they form "A1:$W$162"
With the comment I made on your question in mind I would suggest the code below.
Dim wsData as Worksheet 'Add worksheet variable
Set wsData = ThisworkBook.Worksheets("Name of your data sheet")
With wsData.Sort 'Instead of using ActiveSheet
.SetRange wsData.Range(wsData.Cells(1, 1), wsData.Cells(1, 1).End(xlDown).End(xlToRight))

How to sort filtered data in vba?

I have a worksheet populated with data. I need to filter the data that could only show the info w/in 5 miles. Once the data is filtered to w/in 5 miles, I need to sort the variance column in ascending order. I used a record macro and attempted to incorporate it. The filtering works fine but I get an error saying:
Compile Error: Expected Array
when I run it. Here is a snippet of my code. When the error pops up, the Range is highlighted on the 6th line of code.
.Worksheets("Market Work").Cells.Select
Selection.AutoFilter
.Worksheets("Market Work").Range("$A$1:$Q$" & RowLast2).AutoFilter Field:=5, Criteria1:= _
"w/in 5 miles"
ActiveWorkbook.Worksheets("Market Work").Sort.SortFields.Clear
ActiveWorkbook.Worksheets("Market Work").Sort.SortFields.Add Key:=Range( _
"G2:G112"), SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:= _
xlSortNormal
With ActiveWorkbook.Worksheets("Market Work").Sort
.SetRange Range("A1:Q112")
.Header = xlYes
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With
Following code will help you...
Sheets("Finnet").Select
Sheets("Finnet").AutoFilterMode = False
Sheets("Finnet").Range("A1", Range("XFD1").End(xlToLeft)).Select
Sheets("Finnet").Range(Selection, Range("A" & Rows.Count).End(xlUp)).AutoFilter
Sheets("Finnet").AutoFilter.Sort.SortFields.Add Key:=Range("A1:A" & Range("A" & Rows.Count).End(xlUp).Row), SortOn:=xlSortOnValues, Order:=xlAscending
Sheets("Finnet").AutoFilter.Sort.Header = xlYes
Sheets("Finnet").AutoFilter.Sort.Apply
Sheets("Finnet").AutoFilterMode = False

Resources