Excel VBA - AdvancedFilter - vba

I am trying to filter a range dynamically in VBA and the VBA I am using is not working but I cannot see a logical reason as to why. To explain, I have a range of data in a sheet entitled "Full Stock Report" the size of which will change but I've set it statically in this example... And I'm trying to filter it by a list of criteria held in a range on a sheet initiated "Spitfire Aval Locations", again this is also dynamic but I've set as static again in this example. This sounds simple to me but the below line of code applies a filter but with no results (I have checked I know there are lots that should appear from this filter).
My second question is related, how does this VBA statement dictate which column in the range is being filtered ? (I fear this may be my issue ....)
Sheets("Full Stock Report").Range("A1:F20623").AdvancedFilter Action:=xlFilterInPlace,
CriteriaRange:=Sheets("Spitfire Aval Locations").range("A2:A228"), Unique:=False

Think I've solved this ... essentially AdvancedFilter requires the criteria to be the same format and same column titles as your data set. Not hugeley helpful to me, but I can bodge it to work.
I also have a hunch that AutoFilter with specified criteria might be a better option...

The column to filter on is the first .Range that you call .AdvancedFilter on. The code you posted filters columns A through F. If you wanted to only filter based on values in column A, it would look more like this:
Sheets("Full Stock Report").Range("A1:A20623").AdvancedFilter _
Action:=xlFilterInPlace, _
CriteriaRange:=Sheets("Spitfire Aval Locations").Range("A2:A228"), _
Unique:=False

Related

Autofiltering two columns as an OR function

I am trying to filter two columns in excel to show all the results that deliver today(two separate columns). I have tried multiple ways, however I keep getting results that reflect an "AND" statement. I feel like I am close with.
Sub Playing_Today_v2()
Dim s As String
s = "=" & CStr(Date)
With ActiveSheet.ListObjects("table1").Range
.AutoFilter
.AutoFilter Field:=7, Criteria1:=s
End With
With ActiveSheet.ListObjects("table1").Range
.AutoFilter
.AutoFilter Field:=9, Criteria1:=s
End With
End Sub
Any and all help is greatly appreciated!!
Hello in order to do this via VBA you will first need to understand how to accomplish it manually 2 ways that come to mind are:
Add a helper column to the table
Use an advanced filter
For the helper column add a formula similar to =OR(Col7=TODAY(),Col9=TODAY()) and filter to that column equals true.
For the advanced filter create a 2 x 3 range and populate as follows:
Col7 NAME, Col9 NAME
=Today() ,
, =Today()
As use that as your criteria range to do a OR selection (if you want an AND selection put them on the same line).
Once you have got this working manually it is fairly easy to move to VBA either by adding a new column and adding 1 autofiler similar to your existing code or by using the Range.AdvancedFilter method.
If you get stuck with the code please post a question showing how far you get and someone will be able to help.

1004 error when trying to run a macro that applies to a table

I have an existing table. I want to add a new column next to it, with a formula in it so that the formula adds a new column and fills in all the values.
This is a two-page worksheet. Table1 is on another page than the table we're working with, but has the master data it draws from.
I recorded a macro of the formula I used to produce this, but when I try to run it, I get
Run time error '1004': Application-defined or object-defined error.
The code I'm using is below:
Range("B2").Select
ActiveCell.FormulaR1C1 = "=IF(INDEX(Table1,MATCH([#Listing],Table1[Property],0)," & _
"MATCH(""Status"",Table1[#Headers],0))=""for sale"",""seller""," & _
"IF(INDEX(Table1,MATCH([#Listing],Table1[Property],0)," & _
"MATCH(""Status"",Table1[#Headers],0))=""for lease"",""landlord""," & _
"IF(INDEX(Table1,MATCH([#Listing],Table1[Property],0)," & _
"MATCH(""Status"",Table1[#Headers],0))=""for sale or lease"",""seller / landlord""" & _
"X(Table1,MATCH([#Listing],Table1[Property],0)," & _
"MATCH(""Base Rent/Mo"",Table1[#Headers],0))>0,""landlord"",""seller""))))"
Range("B1").Select
Things I've checked so far:
All the names match (i.e. Table1 is a valid name, and all the headers are correctly named)
The formula works exacly as I want to if I just type it in and hit 'enter'
I've looked for similar issues here, and the most similar seem to be some problems with Pivot tables, but the solutions don't seem to be applicable to my problem
(The reason I'm using VBA for this is that this is one part of a multi-step process that I'm trying to automate to make it simpler to run a complicated report from a large set of data.)
EDIT: Additional fixes I tried:
Moving the master data table to the same sheet as my 'target' table to see if it would work if the two were on the same worksheet. No go.
When you need to use quotes inside quotes like in "MATCH(""Status"", which I suppose you are trying to output Match("Status" try using "MATCH("&Chr(34)&Status&Chr(34)
Chr(34) outputs the " symbol. Otherwise it would return MATCH(Status (without quotes)
There were two separate issues.
First, I was recording the macro and apparently, Excel will not record formulas longer than a certain length properly. This limit is greater than 407 (the longest formula I got to auto capture), but shorter than 467 characters. A similar problem was discussed on this Mr. Excel post. This also was why part of the "INDEX" was missing, as BruceWayne pointed out.
In addition, it was necessary to switch from .FormulaR1C1 to .Formula to get it to work correctly, as R3uK had suggested.
The final code ended up as follows:
Range("B2").Select
ActiveCell.Formula = _
"=IF(INDEX(Table1,MATCH($A2,Table1[Property],0),MATCH(""Status"",Table1[#Headers],0))=""for sale"",""seller"",IF(INDEX(Table1,MATCH($A2,Table1[Property],0),MATCH(""Status"",Table1[#Headers],0))=""for lease"",""landlord"",IF(INDEX(Table1,MATCH($A2,Table1[Property],0),MATCH(""Status"",Table1[#Headers],0))=""for sale or lease"",""seller / landlord"",IF(INDEX(Table1,MATCH($A2,Table1[Property],0),MATCH(""Base Rent/Mo"",Table1[#Headers],0))>0,""landlord"",""seller""))))"
Range("B3").Select

Excel VBA Wrong copy with Advanced Filter

Im trying to get a list of unique data through the Advanced Filter option in Excel.
So, I recorded the macro I wanted to do and I got this as the code:
Sheets("Totaal").Range("A3:A65000").AdvancedFilter Action:=xlFilterCopy, CopyToRange:=Range( _
"D2"), Unique:=True
This should be fine as far as I know because I did this a few times. Problem is, with this one, he only copies the first element to the selected Range. (I tried with actually giving it a range but that didn't change anything).
So, only copying first element not the whole array. If I do it manually it works.
Stumbled onto this one, very interesting problem. I created a test sheet to mimic yours that looked like:
The following code dropped all of the unique entries into col D starting at row 2:
Option Explicit
Sub Test()
Dim TotaalSheet As Worksheet
'set worksheet for easy reference
Set TotaalSheet = ThisWorkbook.Worksheets("Totaal")
'apply the advanced filter to get uniques
With TotaalSheet.Range("A3:A65000")
.AdvancedFilter Action:=xlFilterCopy, CopyToRange:=TotaalSheet.Range("D2"), Unique:=True
End With
End Sub
Here are the results:
nothing is copied if the one of many empty cells on top of the range.

Excel Macro Autofilter issue with variable

I have a table of data with the top row being filters, I have a loop that changes which filter needs to be used inside the loop is the variable filterColumn that is being assigned a new value every time the loop runs through.
when i try to use filterColumn to determine which filter will be 'switched on' i get an error
Autofilter method of Range Class Failed
ActiveSheet.Range("$U$83:$CV$1217").AutoFilter Field:=filterColumn, Criteria1:="<>"
What is the correct syntax in order to use a variable to determine which field the filter is in?
Problem Solved I found the solution. I was referencing the filters columns position in terms of the whole worksheet when in fact I should have been referencing what number it was in the group of filters. For example the filter I wanted to change was in 'CF' which is the 84th column but my the filter I wanted to change is the 64th in the group.
Dim filterColumn As Integer
filterColumn = 2
ActiveSheet.Range("$U$83:$CV$1217").AutoFilter Field:=filterColumn, _
Criteria1:="<>"
EDIT: I tried #HeadofCatering's solution and initially it failed. However I filled in values in the referenced columns and it worked (my solution also failed under reverse conditions - make the column headers blank and it fails).
However this doesn't quite mesh with what I've (and probably you've) seen - you can definitely add filters to columns with blank headers. However one thing was consistent in the failures I saw - the filterColumn referenced a column that was outside of Application.UsedRange. You may want to try verifying that the column you are referencing is actually within Application.UsedRange (easy way: run Application.UsedRange.Select in the Immediate Window and see if your column is selected). Since you are referencing a decent amount of columns, it is possible that there are no values past a certain point (including column headers), and when you specify the column to filter, you are actually specifying something outside of your UsedRange.
An interesting (this is new to me as well) thing to test is taking a blank sheet, filling in values in cells A1 and B1, selecting columns A:G and manually adding AutoFilters - this will only add filters to columns A and B (a related situation can be found if you try to add filters to a completely blank sheet).
Sorry for the babble - chances are this isn't even your problem :)
Old solution (doesn't work when conditions described above are used)
I may be overkilling it, but try setting the sheet values as well (note I used a sample range here):
Sub SOTest()
Dim ws As Worksheet
Dim filterColumn As Integer
' Set the sheet object and declare your variable
Set ws = ActiveSheet
filterColumn = 2
' Now try the filter
ws.Range("$A$1:$E$10").AutoFilter Field:=filterColumn, Criteria1:="<>"
End Sub

Trying to merge columns together in Excel

I appreciate there are a lot of similar questions out there but I've been searching various forums for three days now and not yet found anything which does what I need - so either I'm doing something very strange or my searching skills aren't up to scratch!
I'd really appreciate it if someone could let me know where I'm going wrong, or even link me to a solution which might help as I haven't managed to find one.
I currently have a spreadsheet with six worksheets. Worksheets 2-6 contain data on items which have been sold from different sources. Worksheet 1 currently contains four columns which populate the item data using a macro I've cobbled together into four separate columns. Worksheet 2 contains an 'itemlist' column into which I want to copy the data from each of the four columns in worksheet 2.
I hope this makes sense. At the moment, the code I have is below:
Sub UpdateList()
'Clear the current ranges
Range("PharmacyItems").Clear
Range("PrelabelItems").Clear
Range("RestockItems").Clear
Range("TakehomeItems").Clear
Range("FullItemList").Clear
'Populate control with unique list
Range("PharmacyFullList").AdvancedFilter Action:=xlFilterCopy, CopyToRange:=Range("PharmacyItems"), Unique:=True
Range("PrelabelFullList").AdvancedFilter Action:=xlFilterCopy, CopyToRange:=Range("PrelabelItems"), Unique:=True
Range("RestockFullList").AdvancedFilter Action:=xlFilterCopy, CopyToRange:=Range("RestockItems"), Unique:=True
Range("TakehomeFullList").AdvancedFilter Action:=xlFilterCopy, CopyToRange:=Range("TakehomeItems"), Unique:=True
'Combine the four ranges into one
Range("UniqueLists!$A:$A, UniqueLists!$B:$B, UniqueLists!$C:$C, UniqueLists!$D:$D").Copy Sheets("Drug totals").Range("A2")
'Sort the data
Range("FullItemList").Sort Key1:=Range("FullItemList").Columns(1), Order1:=xlAscending, Orientation:=xlSortColumns, Header:=xlYes, SortMethod:=xlPinYin, DataOption1:=xlSortNormal, DataOption2:=xlSortNormal, DataOption2:=xlSortNormal
End Sub
In order to clarify the above, here is a definition of which range is which:
PharmacyItems, PrelabelItems, RestockItems and TakehomeItems: these are the individual lists which contain the unique items copied from each data worksheet.
FullList: the fulllist of the above four are the source data lists which are not unique lists
FullItemList: the column into which I want all the data from the unique lists to end up
The reason I have a range which specifies each column rather than using a named range is that I was trying to see if this would make it any better as originally it was just giving me a vague and fluffy range issue error. With the columns defined in the range it tells me the size/shape of the destination doesn't match the source.
The exact error is:
Run-time error '1004':
The information cannot be pasted because the Copy area and the paste area are not the same size and shape. Try one of the following:
- click a single cell, and then paste
- select a rectangle that's the same size and shape, and then paste
Can anyone help me? Sadly I'm a SQL Server girl, I'd far rather be pulling data from a database but I'm not allowed on this one!
Thank you in advance
Summer
You can't paste an entire column to a range starting on row 2 (or any other row than 1) because then the last row(s) of the column won't fit on the sheet. That's why Excel says "the Copy area and the paste area are not the same size".
Instead of
Range("UniqueLists!$A:$A, UniqueLists!$B:$B, UniqueLists!$C:$C, UniqueLists!$D:$D").Copy Sheets("Drug totals").Range("A2")
try pasting it starting on the first row.
Range("UniqueLists!A:D").Copy Sheets("Drug totals").Range("A1")
But I'm guessing you don't have data all the way down to the very bottom of your "UniqueLists" sheet? If so, then why are you copying the entire column? Just copy the part you need. Then you'll be able to paste starting on cell "A2". Example:
Range("UniqueLists!A1:D1234").Copy Sheets("Drug totals").Range("A2")
If you don't need the individual unique lists but just want to create a single column of all the unique values then this should work for you (untested though...)
Sub UpdateList()
Range("FullItemList").Clear 'Clear the full item list range
'Populate control with unique list
UniquesToFullItemList Range("PharmacyFullList")
UniquesToFullItemList Range("PrelabelFullList")
UniquesToFullItemList Range("RestockFullList")
UniquesToFullItemList Range("TakehomeFullList")
'Sort the data
Range("FullItemList").Sort Key1:=Range("FullItemList").Columns(1), _
Order1:=xlAscending, Orientation:=xlSortColumns, Header:=xlYes, _
SortMethod:=xlPinYin, DataOption1:=xlSortNormal, DataOption2:=xlSortNormal, _
DataOption2:=xlSortNormal
End Sub
Sub UniquesToFullItemList(rngFrom As Range)
rngFrom.AdvancedFilter Action:=xlFilterCopy, _
CopyToRange:=Sheets("Drug totals").Cells(Rows.Count, 1).End(xlUp).Offset(1, 0), _
Unique:=True
End Sub