Sorting using VBA - excel

I have this code below
Dim Lasteuro As Long
ThisWorkbook.Sheets("Euro Cash").Range("A2:AF").Sort Key1:=Range("T2:T"), Order1:=xlAscending, Key2:=Range("V:V"), Order2:=xlAscending, Header:=xlYes
Lasteuro = Sheets("Euro Cash").Range("a1").End(xlDown).Row
Sheets("Euro Cash").Range("A:U").AutoFilter Field:=17, Criteria1:=Array("LNCCP", "LNLCHSCM"), Operator:=xlFilterValues
'Sec No.'
Sheets("Euro Cash").Range("D2:D" & Lasteuro).Copy
Sheets("Master").Range("K6").PasteSpecial Paste:=xlPasteValues
'Cpty Name'
Sheets("Euro Cash").Range("F2:F" & Lasteuro).Copy
Sheets("Master").Range("L6").PasteSpecial Paste:=xlPasteValues
'Break'
Sheets("Euro Cash").Range("I2:I" & Lasteuro).Copy
Sheets("Master").Range("M6").PasteSpecial Paste:=xlPasteValues
'Age'
Sheets("Euro Cash").Range("P2:P" & Lasteuro).Copy
Sheets("Master").Range("P6").PasteSpecial Paste:=xlPasteValues
Sheets("Euro Cash").ShowAllData
However upon running, I get:
Run-time error '1004' : Method Range of object _Global failed.
I clicked on debug, it highlights this
ThisWorkbook.Sheets("Euro Cash").Range("A2:AF").Sort Key1:=Range("T2:T"), Order1:=xlAscending, Key2:=Range("V:V"), Order2:=xlAscending, Header:=xlYes
So what I did is change Thisworkbook.Sheets to Sheets - still same error..
what should I do?

The use of the Range object within the Range .Sort method is open to interpretation as to what the parent worksheet is.
Dim Lasteuro As Long
With Sheets("Euro Cash")
If .AutoFilterMode Then .AutoFilterMode = False
Lasteuro = .Cells(Rows.Count, 1).End(xlUp).Row
.Range("A:AF").Sort Key1:=.Columns(20), Order1:=xlAscending, _
Key2:=.Columns(22), Order2:=xlAscending, _
Header:=xlYes
.Range("A:U").AutoFilter Field:=17, Criteria1:=Array("LNCCP", "LNLCHSCM"), _
Operator:=xlFilterValues
'Sec No.'
.Range("D2:D" & Lasteuro).Copy
Sheets("Master").Range("K6").PasteSpecial Paste:=xlPasteValues
'Cpty Name'
.Range("F2:F" & Lasteuro).Copy
Sheets("Master").Range("L6").PasteSpecial Paste:=xlPasteValues
'Break'
.Range("I2:I" & Lasteuro).Copy
Sheets("Master").Range("M6").PasteSpecial Paste:=xlPasteValues
'Age'
.Range("P2:P" & Lasteuro).Copy
Sheets("Master").Range("P6").PasteSpecial Paste:=xlPasteValues
If .AutoFilterMode Then .AutoFilterMode = False
End With
Note the use of .Range and not Range. This means that the parent is the one defined in the With ... End With statement. You are only required to indicate the first cell when defining the key.
After looking closer at all of your code (and reviewing the comments provided) I've changed the sort range so that it recognizes the column header labels in row 1.

Related

VBA: How to NOT copy if the filtered data is blank?

I have a set of code to advanced filter Dataset's Column F and H if certain criteria are met, after that the filtered data under Column F to I will be copied to another worksheet's next empty row, in sequence (F & G first, then H & I).
With Worksheets("Sheet3")
.Range("A:K").AutoFilter Field:=6, Criteria:=">=10000000", Operator:=xlAnd, Criteria2:="<=99999999"
.Range("F2:G" & .Cells(.Rows.Count, "F").End(xlUp).Row).Copy
Sheets("Sheet4").Cells(Rows.Count, "A").End(xlUp).Offset(1, 0).PasteSpecial xlPasteValues
.Range("A:K").AutoFilter Field:=8, Criteria:=">=10000000", Operator:=xlAnd, Criteria2:="<=99999999"
.Range("H2:I" & .Cells(.Rows.Count, "H").End(xlUp).Row).Copy
Sheets("Sheet4").Cells(Rows.Count, "A").End(xlUp).Offset(1, 0).PasteSpecial xlPasteValues
End With
*Note: There are headers in first row of this Dataset.
This code works flawlessly when they are values after filtering. When there isn't any values after filtering, VBA does not stop copying, instead it copies the header of Column F, G, H and I, which is not what I wanted.
The outcome should be - Nothing (including header) is copied to Sheet 4 if there isn't any values after filtering. How can I achieve this?
Please, replace the code you show:
With Worksheets("Sheet3")
.Range("A:K").AutoFilter Field:=6, Criteria:=">=10000000", Operator:=xlAnd, Criteria2:="<=99999999"
.Range("F2:G" & .Cells(.Rows.Count, "F").End(xlUp).Row).Copy
Sheets("Sheet4").Cells(Rows.Count, "A").End(xlUp).Offset(1, 0).PasteSpecial xlPasteValues
.Range("A:K").AutoFilter Field:=8, Criteria:=">=10000000", Operator:=xlAnd, Criteria2:="<=99999999"
.Range("H2:I" & .Cells(.Rows.Count, "H").End(xlUp).Row).Copy
Sheets("Sheet4").Cells(Rows.Count, "A").End(xlUp).Offset(1, 0).PasteSpecial xlPasteValues
End With
with this one, which checks if there are visible cells in the range to be copied (except the header):
Dim rngFG As Range, rngHI As Range, lastRow As Long
With Worksheets("Sheet3")
.Range("A:K").AutoFilter field:=6, Criteria:=">=10000000", Operator:=xlAnd, Criteria2:="<=99999999"
lastRow = .cells(.rows.count, "F").End(xlUp).row
On Error Resume Next
Set rngFG = .Range("F2:G" & lastRow).Resize(lastRow - 1).Offset(1).SpecialCells(xlCellTypeVisible)
On Error GoTo 0
If Not rngFG Is Nothing Then 'the range is nothing if no visible cell in it
.Range("F2:G" & lastRow).Copy
Sheets("Sheet4").cells(rows.count, "A").End(xlUp).Offset(1, 0).PasteSpecial xlPasteValues
End If
.Range("A:K").AutoFilter field:=8, Criteria:=">=10000000", Operator:=xlAnd, Criteria2:="<=99999999"
astRow = .cells(.rows.count, "H").End(xlUp).row
On Error Resume Next
Set rngHI = .Range("H2:I" & astRow).Resize(lastRow - 1).Offset(1).SpecialCells(xlCellTypeVisible)
On Error GoTo 0
If Not rngFG Is Nothing Then
.Range("H2:I" & lastRow).Copy
Sheets("Sheet4").cells(rows.count, "A").End(xlUp).Offset(1, 0).PasteSpecial xlPasteValues
End If
End With
It assumes that the header (to be excepted in checking) is on the second row.
Not tested, but it should work. Except the case of a typo somewhere in the code, I think. That's why please, send some feedback after testing it. If something does not work as you need, do not hesitate to explain what and in which circumstances...

Error Handling: Skip autofill formulas if Run-time error '1004' appears

My VBA macro was created to convert several lines of data into a different format. I do this by using various formulas throughout the macro. Typically, the original file that is copied/pasted into the workbook has more than one line of data. However, my test file only has one line of data.
I get a
Run-time error '1004'
when my code hits the Range.Autofill code shown below.
Historically, I have successfully used the On Error Resume Next function to skip the lines of code like this. But, this isn't working for me on this macro for some reason.
Any ideas why? Should I try a different approach, such as a GoTo function instead?
Range("F2").Select
ActiveCell.FormulaR1C1 = _
"=INDEX(ClientReport!C[10],MATCH(RC[-5],ClientReport!C[-1],0))"
Range("E2").Select
ActiveCell.FormulaR1C1 = _
"=INDEX(RawBillingDump!C[38],MATCH(Template!RC[1],RawBillingDump!C[67],0))"
Range("G2").Select
ActiveCell.FormulaR1C1 = _
"=INDEX(ClientReport!C,MATCH(Template!RC[-1],ClientReport!C[9],0))"
Range("I2").Select
ActiveCell.FormulaR1C1 = _
"=INDEX(ClientReport!C[-1],MATCH(Template!RC[-3],ClientReport!C[7],0))"
Range("J2").Select
ActiveCell.FormulaR1C1 = _
"=INDEX(ClientReport!C[-1],MATCH(Template!RC[-4],ClientReport!C[6],0))"
Range("K2").Select
ActiveCell.FormulaR1C1 = _
"=INDEX(ClientReport!C[-1],MATCH(Template!RC[-5],ClientReport!C[5],0))"
Range("L2").Select
ActiveCell.FormulaR1C1 = _
"=INDEX(ClientReport!C[-10],MATCH(Template!RC[-6],ClientReport!C[4],0))"
Range("M2").Select
ActiveCell.FormulaR1C1 = "=INDEX(RawBillingDump!C[38],MATCH(RC[-7],RawBillingDump!C72,0))"
Range("R2").Select
ActiveCell.FormulaR1C1 = "=LEFT(Stage!RC[3],5)"
Range("S2").Select
ActiveCell.FormulaR1C1 = "=IF(Stage!RC[6]=0,"""",Stage!RC[6])"
Range("T2").Select
ActiveCell.FormulaR1C1 = "=IF(Stage!RC[6]=0,"""",Stage!RC[6])"
Range("X2").Select
ActiveCell.FormulaR1C1 = "=INDEX('RawBillingDump'!C[3],MATCH(RC[-6],'RawBillingDump'!C,0))"
On Error Resume Next
'Code snags here, even with On Error Resume Next
Range("B2").AutoFill Destination:=Range("B2:B" & Cells(Rows.Count, "A").End(xlUp).Row)
Range("C2").AutoFill Destination:=Range("C2:C" & Cells(Rows.Count, "A").End(xlUp).Row)
Range("E2").AutoFill Destination:=Range("E2:E" & Cells(Rows.Count, "A").End(xlUp).Row)
Range("F2").AutoFill Destination:=Range("F2:F" & Cells(Rows.Count, "A").End(xlUp).Row)
Range("G2").AutoFill Destination:=Range("G2:G" & Cells(Rows.Count, "A").End(xlUp).Row)
Range("I2").AutoFill Destination:=Range("I2:I" & Cells(Rows.Count, "A").End(xlUp).Row)
Range("J2").AutoFill Destination:=Range("J2:J" & Cells(Rows.Count, "A").End(xlUp).Row)
Range("K2").AutoFill Destination:=Range("K2:K" & Cells(Rows.Count, "A").End(xlUp).Row)
Range("L2").AutoFill Destination:=Range("L2:L" & Cells(Rows.Count, "A").End(xlUp).Row)
Range("m2").AutoFill Destination:=Range("m2:m" & Cells(Rows.Count, "A").End(xlUp).Row)
Range("R2").AutoFill Destination:=Range("R2:R" & Cells(Rows.Count, "A").End(xlUp).Row)
Range("S2").AutoFill Destination:=Range("S2:S" & Cells(Rows.Count, "A").End(xlUp).Row)
Range("T2").AutoFill Destination:=Range("T2:T" & Cells(Rows.Count, "A").End(xlUp).Row)
Range("X2").AutoFill Destination:=Range("X2:X" & Cells(Rows.Count, "A").End(xlUp).Row)

if match found delete from Multiple sheets

Sheet 0 : https://paste.pics/82a491cbc642d6fff555ef70612aec5b
Sheet 1 : https://paste.pics/cafe8628b76e56789cf03b06a923bde8
Sheet 2 : https://paste.pics/2320369d395a22c868b5e439b456ad3a
Sheet 3 : https://paste.pics/9fc84c7f43e1a2819d1537593c44c1f9
If match is found => "SUP" "AL" "AP" then Data should be cleared from all the sheets with one Button click
Button is in "Sheet0" => when clearing data the Headers should not get Cleared
if want to see my excel safe download 100%
https://drive.google.com/file/d/1w0n_srbhF02OhiWzKsB4IWWiwV5nO-Vl/view?usp=sharing
=========================================================================
This is my code where i tried But not working giving error at Ws.Range
Private Sub CommandCreate_new_Click()
Dim Ws As Worksheet
For Each Ws In Sheets(Array("Sheet1","Sheet2","Sheet3"))
Ws.Range ("I9:AM9")
.Cells.Replace what:=UCase("SUP"), Replacement:="", ReplaceFormat:=True
.Cells.Replace what:=UCase("SUP"), Replacement:="", ReplaceFormat:=False
.Cells.Replace what:=UCase("AL"), Replacement:="", ReplaceFormat:=True
.Cells.Replace what:=UCase("AL"), Replacement:="", ReplaceFormat:=False
Next Ws End Sub
========================================================================
Partially Working But not setting the Cell to => No fill Color [As match condition is found data should be deleted and even the cell color should be deleted and set to no fill color]
Private Sub CommandButton1_Click()
Dim Ws As Worksheet
For Each Ws In Sheets(Array("Sheet1", "Sheet2", "Sheet3"))
Ws.Range("A4", Ws.Range("A" & Rows.Count).End(xlUp).Offset(, 1)).ClearContents
Ws.Range("B4", Ws.Range("B" & Rows.Count).End(xlUp).Offset(, 1)).ClearContents
Ws.Range("C4", Ws.Range("C" & Rows.Count).End(xlUp).Offset(, 1)).ClearContents
Ws.Range("D4", Ws.Range("D" & Rows.Count).End(xlUp).Offset(, 1)).ClearContents
Ws.Range("E4", Ws.Range("E" & Rows.Count).End(xlUp).Offset(, 1)).ClearContents
Ws.Range("F4", Ws.Range("F" & Rows.Count).End(xlUp).Offset(, 1)).ClearContents
Ws.Range("G4", Ws.Range("G" & Rows.Count).End(xlUp).Offset(, 1)).ClearContents
Ws.Range("H4", Ws.Range("H" & Rows.Count).End(xlUp).Offset(, 1)).ClearContents
Ws.Range("I4", Ws.Range("I" & Rows.Count).End(xlUp).Offset(, 1)).ClearContents
Ws.Range("J4", Ws.Range("J" & Rows.Count).End(xlUp).Offset(, 1)).ClearContents
Next Ws
End Sub
This is the below output i am getting after running the above partially code
[My output][1]: https://i.stack.imgur.com/6EbRP.png

Excel VBA - multi level sorting

How do I change the code below to sort in a multi level way? At present, the code sorts the table one column at a time, I want to sort it together as a multi level sort.
Below is what Im trying to achieve:
Here's my code which sorts the table one column at a time:
Range("A4:L" & lastRow).Sort key1:=Range("A4:A" & lastRow), _
order1:=xlAscending, Header:=xlNo
Range("A4:L" & lastRow).Sort key1:=Range("B4:B" & lastRow), _
order1:=xlAscending, Header:=xlNo
Range("A4:L" & lastRow).Sort key1:=Range("C4:C" & lastRow), _
order1:=xlAscending, Header:=xlNo
Range("A4:L" & lastRow).Sort key1:=Range("D4:D" & lastRow), _
order1:=xlAscending, Header:=xlNo
Range("A4:L" & lastRow).Sort key1:=Range("E4:E" & lastRow), _
order1:=xlAscending, Header:=xlNo
How do I change the above to sort everything together?
I always recommend getting rid of the recorded .Sort method in favor of 'only what you need' VBA Sort code. However, there is a problem in that you can only sort a maximum of three sort keys per sort; the solution is to perform two sort operations. Sort the highest ordinals first then the last three primary sort ordinals.
With Worksheets("Sheet1").Range("A4:L" & lastRow)
.Cells.Sort Key1:=.Columns("D"), Order1:=xlAscending, _
Key2:=.Columns("E"), Order2:=xlAscending, _
Orientation:=xlTopToBottom, Header:=xlYes
.Cells.Sort Key1:=.Columns("A"), Order1:=xlAscending, _
Key2:=.Columns("B"), Order2:=xlAscending, _
Key3:=.Columns("C"), Order3:=xlAscending, _
Orientation:=xlTopToBottom, Header:=xlYes
End With
You've mashed together cell addresses with table columns or header labels in hte image so I am not sure if I got the ordinals right. The above will sort with column A as the primary, B as secondary, C as third, D as fourth and E as fifth.
s = ComboBox1.Text
sr = ComboBox1.Text & "4"
Dim xlSort As XlSortOrder
Dim LastRow As Long
With ActiveSheet
LastRow = .Cells(.Rows.Count, "B").End(xlUp).Row
Sheet9.Range("b4:k5002").Sort Key1:=Sheet9.Range(sr), Order1:=xlAscending, Key2:=Sheet9.Range("e4"), Order2:=xlAscending
End With

Sorting not working

In this user form
I have the following code (Ascending is by default TRUE, while Descending is False)
Private Sub OKButton_Click()
Dim rRange As Range
lastRow = Sheets("overview").Range("G1000").End(xlUp).Row
On Error Resume Next
Application.DisplayAlerts = False
Set rRange = Application.InputBox(Prompt:="Please select a cell in the column you want
_to sort", Title:="SPECIFY COLUMN", Type:=8)
Col = rRange.Columns(1).Column
On Error GoTo 0
Application.DisplayAlerts = True
If rRange Is Nothing Then
Exit Sub
Else
If AscendingOption Then
Range("A14:CB" & lastRow).Sort key1:=Range(Col & "14:" & Col & lastRow), Order1:=xlAscending, Header:=xlNo, key2:=Range("C14:C" & lastRow), Order2:=xlAscending, Header:=xlNo
End If
If DescendingOption Then
Range("A14:CB" & lastRow).Sort key1:=Range(Col & "14:" & Col & lastRow), Order1:=xlDescending, key2:=Range("C14:C" & lastRow), Order2:=xlAscending
End If
End If
End Sub
When I click OK nothing happens: not an error message, nor any action.
Can anybody help me finding the error?
Both variables AscendingOption and DescendingOption are not initialized so are set as false. You need to change value of one of them into TRUE to sort. But in current code if both are TRUE, you will sort it twice - firstly ascending and secondly descending. You can reduce code by one variable into:
If AscendingOption Then
Range("A14:CB" & lastRow).Sort key1:=Range(Col & "14:" & Col & lastRow), Order1:=xlAscending, Header:=xlNo, key2:=Range("C14:C" & lastRow), Order2:=xlAscending, Header:=xlNo
Else
Range("A14:CB" & lastRow).Sort key1:=Range(Col & "14", Col & lastRow), Order1:=xlDescending, key2:=Range("C14:C" & lastRow), Order2:=xlAscending
End If
If AscendingOption is true, it sorts in in ascending order, otherwise descending.
This is the version of the code which works fine:
Private Sub OKButton_Click()
Dim rRange As Range
lastRow = Sheets("overview").Range("G1000").End(xlUp).Row
Application.DisplayAlerts = False
Set rRange = Application.InputBox(Prompt:="Please select a cell in the column
_you want to sort", Title:="SPECIFY COLUMN", Type:=8)
Col = rRange.Columns(1).Column
On Error GoTo 0
Application.DisplayAlerts = True
If rRange Is Nothing Then
Exit Sub
Else
If AscendingOption Then
Range("A14:CE" & lastRow).Sort key1:=Range(Cells(14, Col), Cells(lastRow, Col)),
_Order1:=xlAscending, Header:=xlNo, key2:=Range("C14:C" & lastRow),
_Order2:=xlAscending, Header:=xlNo
End If
If DescendingOption Then
Range("A14:CE" & lastRow).Sort key1:=Range(Cells(14, Col), Cells(lastRow, Col)),
_Order1:=xlDescending, Header:=xlNo, key2:=Range("C14:C" & lastRow),
_Order2:=xlAscending, Header:=xlNo
End If
Unload UserForm1
End If
End Sub

Resources