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

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")

Related

how to set range for a dynamic area and pasting with filters on in vba

I'm having some trouble with a 2 step problem.
The first part is setting a range to constantly changing data. I've been trying to categorize claims on a worksheet that has data that is being added to the same sheet daily, so the last active cell keeps changing. For instance my issue with the specific line of code is as follows.
Columns(“D:D”).Select
Selection.End(xlDown).Select
ActiveCell.Offset(1).Select
ActiveCell.Offset(0, 91).Select
Range(Selection, Selection.End(xlDown)).Select
Selection.Copy
Columns(“D:D”).Select
Selection.End(xlDown).Select
ActiveCell.Offset(1).Select
ActiveSheet.Paste
ActiveSheet.Range("$A$1:$EE$3000”).AutoFilter Field:=22, Criteria1:= Array( _
"DUPLICATE PAID/CAPTURED CLAIM:MORE CURRENT REFILL EXISTS", _
"REFILL TOO SOON:CLAIM ALREADY PROCESSED FOR STORE, RX, DOS", _
"REFILL TOO SOON:DISPENSED TOO SOON"), Operator:=xlFilterValues
Columns(“A:A”).Select
Selection.End(xlDown).Select
Selection.Copy
ActiveCell.Offset(1).Select
ActiveSheet.Paste
But I'm now recognizing setting the end range to a value of $EE$2007 isn't working. The column of EE will always remain the same, however the row changes.
The second part has to do with filtering. There are around 56 different categories in a separate column, V which then get flagged with a keyword in column A. I've gotten as far as being able to do the filtering portion and copying from the next cell up, but I'm having trouble pasting that keyword down the next which is the next blank cell and down to the last active row, again which all happens in column A. Above is what I have so far.
And this is where I get stuck. I'm new to all this, and am hoping to learn if there is a better way to go about this.
I was able to get to the second part by changing the range from $EE$2007 to $EE$3000 which caused my data to go further, but it is a possibility.
Thanks in advance.

VBA not updating Excel rows referring to other sheets in same workbook when sorting rows alphabetically

I'm having problems, Excel is not updating rows referring to other sheets in same workbook when ordering rows alphabetically.
I have a userform in which there's a button insertCM with this code:
Private Sub insertButton_Click()
ActiveCell.EntireRow.Select
Selection.Insert Shift:=xltoDown
Range("A9:AK9").Copy
Range("A8:AK8").Select
Selection.PasteSpecial Paste:=xlPasteFormulas
Selection.PasteSpecial Paste:=xlPasteFormats
Range("C10").Copy
Range("C8:C9").Select
Selection.PasteSpecial Paste:=xlPasteFormulas
Range("H9:AK9").Copy
Range("H8:AK8").Select
Selection.PasteSpecial Paste:=xlPasteAll
nomCM = Empty
CXinitial = Empty
resteCX = Empty
CCselect = Empty
C4initial = Empty
resteC4 = Empty
compteurCT = Empty
Range("A8").Activate
ActiveCell.RowHeight = 18.6
For i = 2 To ThisWorkbook.Sheets.Count
With Sheets(i).Select
emptyRow = Range("A9").End(xlDown).Offset(0, 2).Row
Range("A9:AL" & emptyRow).Sort _
Key1:=Range("A9"), Order1:=xlAscending
Set SearchRange = Range("A8", Range("A200").End(xlUp))
Set FindRow = SearchRange.Find(nomCM, LookIn:=xlValues, LookAt:=xlWhole)
Range("A" & FindRow.Row).Select
ActiveCell.EntireRow.Activate
End With
Next i
Sheet2.Select
End
End Sub
The userform is used for inserting new clients in several sheets at the same time. Textbox inserts Name, Cost Center, etc., in a blank row and insertButton inserts a new row leaving data inserted in row 8 to go to row 9. After that the code puts all rows alphabetical order so the new client now in row 9 goes to the new one, and cells containing formulas change row numbers.
However some of the sheets have cells containing references to other sheets' cells in the same row. So imagine:
I insert client name "LORUM" "Cost Center 4" and it puts him in row 9 so formula is:
=$C9-COUNTIF($E9:$P9;"CT")+'Sheet5'!$D9
...but when it changes his row to the final one, formula row is:
=$C18-COUNTIF($E18:$P18;"CT")+'Sheet5'!$D9
It does not change row when referring to other sheets.
Any ideas?
It's looks like you've made a good effort, but there are still numerous problems with your code (beside the one line), and I can guarantee that a combination of these issues are preventing your intended outcome.
I can't fix it completely because there are so many bugs that I'm not clear on what you're trying to do, but hopefully this will get you started on the right track...
xlToDown is not a valid reference. You probably mean xlDown
you have a number of undeclared variables and objects, like: i, emptyRow, SearchRange, FindRow, nomCM
you have things (objects?) "set to nothing" that aren't declared or used anywhere: CXinitial, resteCX, CCselect, C4initial, resteC4, compteurCT
your Find statement is looking for nomCM which is empty (and never set), so the Find statement will never find anything.
You should put Option Explicit at the top of every module (especially when learning or troubleshooting). This will prevent issues like the ones above by "forcing" you to properly declare & handle all of your variables, objects, properties, etc.
Near the end, you refer to Sheet2.Select as if Sheet2 is a declared object, instead of using Sheets("Sheet2").Select. I'm not sure why you're selecting the sheet at the very end anyhow.
You have an With..End statement that is doing absolutely nothing since you don't reference it with a . dot anywhere: With Sheets(i).Select .. End With, and also Select isn't used like that.
A mystery End near the end for some reason.
Also, you're unnecessarily doubling up commands like:
ActiveCell.EntireRow.Select
Selection.Insert Shift:=xlDown
..instead of:
ActiveCell.EntireRow.Insert Shift:=xlDown
and another example, all this:
Range("A9:AK9").Copy
Range("A8:AK8").Select
Selection.PasteSpecial Paste:=xlPasteFormulas
Selection.PasteSpecial Paste:=xlPasteFormats
Range("C10").Copy
Range("C8:C9").Select
Selection.PasteSpecial Paste:=xlPasteFormulas
Range("H9:AK9").Copy
Range("H8:AK8").Select
Selection.PasteSpecial Paste:=xlPasteAll
...instead of:
Range("A9:AK9").Copy
Range("A8:AK8").PasteSpecial xlPasteValuesAndNumberFormats
Range("C10").Copy
Range("C8:C9").PasteSpecial Paste:=xlPasteFormulas
Range("H9:AK9").Copy Range("H8:AK8")
All of this would be more clear by Googling the documentation for each command you're unfamiliar with, such as:
Range.Copy Method (Excel)
Range.PasteSpecial Method (Excel)
XlPasteType Enumeration (Excel)
All the ActiveCell and ThisWorkbook references are troublesome but again, I'm not sure what to do with them since I don't know your workbook.
Indentation (and general organization) are very important as well. It may not change the way that the code runs, but it will help you (and others) track down existing & potential issues more easily.
Here is your code cleaned up as best as I could:
Option Explicit 'this line goes at the very top of the module
Private Sub insertButton_Click()
Dim i As Long, emptyRow As Long, SearchRange As Range, FindRow As Range, nomCM
nomCM = Empty
ActiveCell.EntireRow.Insert Shift:=xlDown
Range("A9:AK9").Copy
Range("A8:AK8").PasteSpecial xlPasteValuesAndNumberFormats
Range("C10").Copy
Range("C8:C9").PasteSpecial Paste:=xlPasteFormulas
Range("H9:AK9").Copy Range("H8:AK8")
Range("A8").RowHeight = 18.6
For i = 2 To ThisWorkbook.Sheets.Count
With Sheets(i)
emptyRow = .Range("A9").End(xlDown).Offset(0, 2).Row
.Range("A9:AL" & emptyRow).Sort Key1:=.Range("A9"), Order1:=xlAscending
Set SearchRange = .Range("A8", .Range("A200").End(xlUp))
Set FindRow = SearchRange.Find(nomCM, LookIn:=xlValues, LookAt:=xlWhole)
.Range("A" & FindRow.Row).Select
ActiveCell.EntireRow.Activate
End With
Next i
Sheets("Sheet2").Select
End Sub
as per my test, sorting actually doesn't change other sheet direct references
so you may want to use OFFSET to keep referencing the actual current row index
instead of:
=$C9-COUNTIF($E9:$P9;"CT")+'Sheet5'!$D9
use
=$C9-COUNTIF($E9:$P9;"CT")+ OFFSET('Sheet5'!$D1,ROW()-1,0)
I found a solution:
=INDIRECT(ADDRESS(ROW();4;3;1;"Sheet5"))
Where Row() will always refer to the actual cell's row.
Hope it will help you!

Excel VBA .Autofilter Field:= Affects Wrong Column

I am currently working with some macros and I am puzzled with this piece of VBA code that I recopied. This problem only occurs in this workbook alone and does not occur in other workbooks. The issue is with this line:
sh1.Range("$A$21:$ZZ$10000").AutoFilter Field:=64, Criteria1:="<>"
.AutoFilter Field:=64 Does not actually filter the 64th column. When the macro is run, it affects the 65th column instead.
Sub FilterGate()
Dim sh1 As Worksheet
Dim sh2 As Worksheet
Set sh1 = ActiveWorkbook.Sheets("Program Management")
Set sh2 = ActiveWorkbook.Sheets("Certification")
sh1.Range("$A$21:$ZZ$10000").AutoFilter Field:=64, Criteria1:="<>"
Range("A1").Select
sh2.Range("$A$21:$ZZ$10000").AutoFilter Field:=64, Criteria1:="<>"
Range("A1").Select
End Sub
Why is the autofilter acting as such?
Thanks for the helpful posts everyone! The issue was column A being completely blank. The AutoFilters started from columns B to BO which is what threw off the numbers. Starting the AutoFilters from columns A to BO helped fixed the problem.

VBA Sort method of Range class failed

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.

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