VBA Sort method of Range class failed - vba

I know there are several threads on this topic but none of the answers have helped resolved this error.
I am trying to sort a table using three keys but receive the error, "Run-time error '1004': Sort method of Range class failed"
I've tried changing "Range("L2")" to ".Range("L2")" and received the error, "Compile error: Invalid or unqualified reference"
I've tried specifying the actual range instead of using columns, I've removed the last two keys and tried just the first, still received the run-time error.
shtData.Activate
shtData.Range(Range("A2"), Range("Z8000").End(xlUp)).Sort _
Key1:=Range("L2"), Order1:=xlAscending, _
Key2:=Range("M2"), Order2:=xlAscending, _
Key3:=Range("B2"), Order3:=xlAscending, _
Header:=xlYes
If you have any suggestions, I'd greatly appreciate it. I had this working yesterday and my excel crashed and did not recover the changes I made, I cannot figure out why I can't get it to work today.

you most probably have no data in "Z" column
if data rows range can be safely sized by column "A" not empty cells then go like follows
Option Explicit
Sub main()
Dim shtData As Worksheet
Set shtData = Worksheets("Data") '<--| some setting of 'shtData'
With shtData
.Range("Z2", .Cells(.Rows.Count, "A").End(xlUp)).Sort _
Key1:=.Range("L2"), Order1:=xlAscending, _
Key2:=.Range("M2"), Order2:=xlAscending, _
Key3:=.Range("B2"), Order3:=xlAscending, _
Header:=xlYes
End With
End Sub

If it is possible you could end up changing amount of columns again in the future, you could do something like.
With shtData
Range(Range("A2"), Cells(Range("A8000").End(xlUp).Row, Range("ZZ2").End(xlLeft).Column)
That way it will automatically size the sort area for however many columns you are using as well as rows.

Related

Run time error 91, Object variable or with block variable not set, lastrow [duplicate]

What I want:
I've got a lot of sheets whith different devices. Let's call one of these sheets "WS1".
And I've got a seperate sheet with all existing devices and the appropriate OS next to it. This one we call "list".
Now I want the other sheets (e.g. the "WS1") to check the "list", find the right device, and copy the right OS into the WS1-sheet.
the manual way would be:
select cell "C3" of WS1 and copy it.
open the "list"-Sheet and find the copied entry
select the cell left to the found entry and copy it
open the WS1 again, select the left cell right next to the active cell and paste the new clipboard (which contains the OS)
select the next cell which is under and on the right side of the active cell.
loop until every device in WS1 is filled with an OS
What I've got so far:
Dim DataObj As New MSForms.DataObject
Dim strCliBoa As String
'strCliBoa = DataObj.GetText
DataObj.GetFromClipboard
Range("C3").Select
Selection.Copy
strCliBoa = DataObj.GetText
Sheets("list").Select
Range("A1").Select
Cells.Find(What:=strCliBoa, After:=ActiveCell, LookIn:=xlFormulas, _
LookAt:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
MatchCase:=True, SearchFormat:=False).Activate
ActiveCell.Offset(0, -1).Select
Selection.Copy
strCliBoa = DataObj.GetText
Sheets("WS1").Select
ActiveCell.Offset(0, -1).Select
ActiveSheet.Paste
ActiveCell.Offset(1, 1).Select
My issue:
"Runtime Error 91: Object variable or with block variable not set"
and it marks the cells.find-method.
Can someone tell me what I'm doing wrong?^^
Thanks in advance!
(oh, almost forgot: I'm using ms excel 2010 on Win7)
If the string you're looking for isn't found you'll get that error. The find function returns "Nothing" if nothing is found
Dim r As Range
Set r = Cells.find(What:=strCliBoa, After:=ActiveCell, LookIn:=xlFormulas, _
LookAt:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
MatchCase:=True, SearchFormat:=False)
If r Is Nothing Then
'handle error
Else
'fill in your code
End If
I'll provide you an answer using the VLOOKUP() function. So Sheet1 contains several devices and I need to find the correct OS. Sheet2 contains the matching between device and OS.
On Sheet1 enter this formula in the cell next to device and pull it down (of course edit to your specific needs).
=VLOOKUP(A2;Sheet2!$A$1:$B$20;2;0)
EDIT: the VLOOKUP function will only work if the OS is in second column. Either switch around the columns or use a helper column at the end to contain the OS.
In the sheet where you have the Device name (WS1) put formula:
=INDEX(List!$A$2:$B$10;MATCH('WS1'!C3;List!$B$2:$B$10;0);1)
Where :
List!$A$2:$B$10 is a range where you have the Devices + OS in the list
'WS1'!C3 is the Device you want to search for in the list ("WS1" in your case)
List!$B$2:$B$10 is the column on Sheet List, where the devices are listed.
Edit 1 - VBA code
If you want to use VBA then use this :
Sub FindDevicePasteOS()
'Find corresponding OS for the device
Dim intRow As Integer
Dim wsht As Worksheet
For Each wsht In Worksheets
If wsht.Name <> "List" Then 'add more sheets you want to exclude using OR (e.g. ... Or wsht.Name <> "Cover Sheet" Then)
For intRow = 3 To wsht.Cells(Rows.Count, 3).End(xlUp).Row 'presuming there is nothing else in the column C below the devices
If Not Worksheets("List").Cells.Find(what:=wsht.Cells(intRow, 3)) Is Nothing Then
wsht.Cells(intRow, 2) = Worksheets("List").Cells.Find(what:=wsht.Cells(intRow, 3)).Offset(0, -1)
End If
Next intRow
End If
Next wsht
End Sub
So I used a psuedo solution where I added the If x is nothing block to the code to skip over the err'd pieces. I was able to process about 80% of the data which is good for me. I still can't understand why Find would return nothing.
Another interesting and maybe related problem occurred in a different computer running the same macro - after I ran into this problem a few times, my computer gave me a blue screen with a 'thread stuck in driver' message. Could they be related? Excel processing to much to fast and get's mixed in the thread processing?
Food for though, I dunno why the find won't just work every-time.
In Sobigen post I had to switch the part LookAt:=xlPart to LookAt:=xlWhole to get it to work because If r Is Nothing Then was throwing an error when it found partial matches. Other than that the code worked great thanks!

Auto sorting and Merging of the cells using vba in excel

I have autosorted two of my rows using VBA in excel.
Private Sub Worksheet_Change(ByVal Target As Range)
On Error Resume Next
If Not Intersect(Target, Range("C:D")) Is Nothing Then
Range("C3").Sort Key1:=Range("C4"), _
Order1:=xlAscending, _
Key2:=Range("D4"), _
Order2:=xlAscending, _
Header:=xlYes, _
OrderCustom:=2, MatchCase:=False, _
Orientation:=xlTopToBottom
End If
End Sub
I have auto sorted column C and D in ascending order.
But when i merge 2 cells in Column J (i.e. J53 and J54) the auto sorting does not work for the Column C and D or the entire sheet we can say.
I want to merge the cells in Column J as well as make Column C and D auto sort using VBA.
NB: similarly i want to sort to 2 cells in Column K as well.
Sorting does not work with merged cells. Except when all merged cells are the same size.
I highly recommend not to use On Error Resume Next without proper error handling. It just makes you blind to any errors but they still occur, you will just never know because the message is suppressed.
That is also why you didn't see the error message telling you exactly this! Remove On Error Resume Next and you will see the error message!
Solution
You can unmerge the cells to sort them, or use a 3ʳᵈ party tool like Kutools: How To Sort Data With Merged Cells In Excel?
Note that this is not the only case why merged cells are evil. Therefore I recommend not to use merged cells at all.
I would unmerge the cells, then sort and then merge again...

unable to get the Specialcells property of the range class for xlcelltypevisible

I have an Excel VBA macro that I run once a week. I have a piece of code that filters out for different data and then copies the remaining cells to a different worksheet
Here is the portion of effected code:
dim data as worksheet
dim sku vp as worksheet
Set skuvp = Workbooks("weekly Brand snapshot report.xlsx").Sheets("SKU VP")
set data = Workbooks("weekly Brand snapshot report.xlsx").Sheets("SKU Data")
data.Range("A1").AutoFilter Field:=4, Criteria1:="Foods", Operator:=xlFilterValues
data.Range("Onsales[[Product]]").SpecialCells(xlCellTypeVisible).Copy Destination:=skuvp.Range("B2")
skuvp.Range("foods").Sort key1:=skuvp.Range("C1"), order1:=xlDescending, Header:=xlYes
data.ShowAllData
data.Range("A1").AutoFilter Field:=4, Criteria1:="Treats", Operator:=xlFilterValues
data.Range("Onsales[[Product]]").SpecialCells(xlCellTypeVisible).Copy Destination:=skuvp.Range("H2")
skuvp.Range("treats").Sort key1:=skuvp.Range("I1"), order1:=xlDescending, Header:=xlYes
data.ShowAllData
data.Range("A1").AutoFilter Field:=3, Criteria1:="Hardgoods", Operator:=xlFilterValues
data.Range("B2:B16354").SpecialCells(xlCellTypeVisible).Copy Destination:=skuvp.Range("N2")
skuvp.Range("hard").Sort key1:=skuvp.Range("O1"), order1:=xlDescending, Header:=xlYes
data.ShowAllData
data.Range("A1").AutoFilter Field:=3, Criteria1:="Specialty", Operator:=xlFilterValues
data.Range("B2:B16354").SpecialCells(xlCellTypeVisible).Copy Destination:=skuvp.Range("T2")
skuvp.Range("spcl").Sort key1:=skuvp.Range("U1"), order1:=xlDescending, Header:=xlYes
data.ShowAllData
Data and skuvp are set as worksheets.
This code ran fine the very first time I ran it. However, it began having an error after that. The error appears on this line:
data.Range("B2:B16354").SpecialCells(xlCellTypeVisible).Copy Destination:=skuvp.Range("N2")
The error it gives is "Unable to get the Specialcells property of the range class."
I originally had the range in that code set the table column "Onsales[[Product]]" as the range like the previous 2 times I used the code but changed it to a set range to see if that would fix the issue.
Why is this code having an error on that line when the same basic code works a few lines earlier?
I've searched stackoverflow and other online sources for a solution without success.
So, from comments it seems that the problem is solved by using .Cells :
data.Range("B2:B16354").SpecialCells(xlCellTypeVisible).Cells.Copy Destination:=skuvp.Range("N2")

Excel 2010 VBA Runtime 1004' PasteSpecial Method of class failed intermittently?

The below section of code works majority of the time but occasionally it will throw an error for
loc.PasteSpecial xlValues
with
Runtime 1004' PasteSpecial Method of class failed
I cant get it to regularly fault either so is hampering me tracking down the cause. Error doesn't happen when stepping through the code.
This method of copy and paste special is used a few times through out the macro.
Other answers for this question seem to be different use cases so I'm struggling to find the issue within my code.
'extracts the cfc data out to its own table if its there.
If Not IsError(Application.Match("CFC", rng1, 0)) Then
wb2.Sheets("Import").Activate
'reset filter to show all data
If (ActiveSheet.AutoFilterMode And ActiveSheet.FilterMode) Or ActiveSheet.FilterMode Then
ActiveSheet.ShowAllData
End If
If ActiveSheet.AutoFilterMode = False Then ActiveSheet.Range("A1:BK1").AutoFilter
ActiveSheet.Range("A1:BK1").AutoFilter Field:=1,
'filters data based on criteria
Criteria1:=Array("*criteria1*"), Operator:=xlFilterValues
ActiveSheet.Range("A1:BK1").AutoFilter Field:=5, Criteria1:=Array("*CFC*"), Operator:=xlFilterValues
'Copys the rows that are visable.
Range("A2:BK" & ActiveSheet.UsedRange.Rows.Count + 1) _
.Cells.SpecialCells(xlCellTypeVisible).Rows.Copy
wb2.Sheets("CFC").Select
'reset filter to show all data
If (ActiveSheet.AutoFilterMode And ActiveSheet.FilterMode) Or ActiveSheet.FilterMode Then
ActiveSheet.ShowAllData
End If
With Range("a:a") 'find the next available row on sheet data using column A
Set loc = .Find(What:="", LookIn:=xlFormulas, _
LookAt:=xlWhole, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
MatchCase:=False)
End With
outputrow = loc.Row 'sets the output row
loc.PasteSpecial xlValues
loc.PasteSpecial xlFormats
End If
Basic fuction is.
Autofilter data based on Criteria on the main data sheet
Copy remaining viable rows
Reset filtering on destination sheet
Find empty row at bottom of table
Paste copied rows to the found location.
I've been trying to sort this for a while now so any help would greatly appreciated.
Only copy the range immediately before you paste it (use a variable to store the range to copy). – Rory
As Rory commented. It was not placing the copy immediately before the paste that was causing the issues.
The copy code was changed to use a sheet reference variable and placed right before the paste and now the macro works as intended 100% of the time. :)
outputrow = loc.Row 'sets the output row
sh1.Range("A2:BK" & sh1.UsedRange.Rows.Count + 1) _
.Cells.SpecialCells(xlCellTypeVisible).Rows.Copy
loc.PasteSpecial xlValues
loc.PasteSpecial xlFormats

Sort a Column in Another Sheet Without Selecting That Sheet

Is it possible to sort columns in another sheet without selecting that sheet?
The problem is while I am running this code, I want this sheet to be hidden and I do not want it to flash over to it when I need to sort the table. Here is my code... This works, but it does obviously select the sheet and shows you the other sheet. Maybe something with 'make active sheet' would work can you do that then say 'make active cell'. I am not sure. Thanks guys.
Application.Worksheets("RawDataLines").Select
Application.Worksheets("RawDataLines").Range("Q5").Select
Application.Worksheets("RawDataLines").Range("A4:R1007").Sort Key1:=Range("Q5"), Order1:=xlAscending, Header:= _
xlGuess, OrderCustom:=1, MatchCase:=False, Orientation:=xlTopToBottom, _
DataOption1:=xlSortNormal
Application.Worksheets("RawDataLines").Range("A5").Select
Application.Worksheets("RawDataLines").Range("A4:R1007").Sort Key1:=Range("A5"), Order1:=xlAscending, Header:= _
xlGuess, OrderCustom:=1, MatchCase:=False, Orientation:=xlTopToBottom, _
DataOption1:=xlSortNormal
This:
Application.Worksheets("RawDataLines").Select
Application.Worksheets("RawDataLines").Range("Q5").Select
Application.Worksheets("RawDataLines").Range("A4:R1007").Sort ...
Could be this:
With Application.Worksheets("RawDataLines")
.Range("A4:R1007").Sort Key1:= .Range("A5")'...
End With
Add ScreenUpdating
Application.ScreenUpdating = False
#Your Code
Application.ScreenUpdating = True
Just make sure that you set the select back to the sheet you want it on prior to setting ScreenUpdating = True
Here the problem comes with the Key1 arguments of VBA sort method. Even though we explicitly pass range with relevant sheet, when it comes to Key1:=Range(…), VBA automatically take ActiveSheet.Range(…).
If We have selected some other sheet instead of the sheets of sort data, VBA shows runtime error.
To fix this problem change the code as Key1:=Your_Sheet_With_Data.Range(Your_Range). For Example, above referred code can be fixed changing the code as
Key1:=Worksheets("RawDataLines").Range("Q5")