How do i get autofilter field indicator to indicate the correct column? - vba

I have a spreadsheet w/30 or so columns. My goal is to filter the set based on 1 column and my approach was the specify a range being just that column and then filter that range. I do have autofilters on every column and when i specify a field:=1 excel picks the first column...whcih is outside of my range. So it's always trying to filter on column "A"...not column "U" as desired. Am i mis-understanding how to use this field? i though it was an offset w/in a range.
here's a simple example
Dim r As Range
Dim sheet As Worksheet
Set sheet = ThisWorkbook.Worksheets("test")
sheet.Range("u1:u9").AutoFilter field:=1, Criteria1:="Will"
as an aside...is there a way to get a column number associated with the column letter? for example U --> 21. if so i could select the entire spreadsheet as the range and do an offset of 21

If you are applying filters to one column, you will have to clear the existing filters first.
Your tweaked code would be something like this and it will apply the filter to column U only...
Sub test()
Dim r As Range
Dim sheet As Worksheet
Set sheet = ThisWorkbook.Worksheets("test")
sheet.AutoFilterMode = False
sheet.Range("u1:u9").AutoFilter field:=1, Criteria1:="Will"
End Sub
OR
You may also apply the filters to all the columns and specify the field criteria correctly.
Give this a try...
Sub test2()
Dim r As Range
Dim sheet As Worksheet
Set sheet = ThisWorkbook.Worksheets("test")
Set r = sheet.Range("U1")
sheet.AutoFilterMode = False
sheet.Range("A1").CurrentRegion.AutoFilter field:=r.Column, Criteria1:="Will"
End Sub

Related

VBA search column heading in a sheet and return SUM in another sheet

I would like to get datas from sheet 1 to sheet 2 with reference to the column headings With VBA.
For example:(EXCEL file)
So if I want to find the sum of fun1 person A with criteria 1 the command have to go and find the heading “sum of fun 1” in sheet 1 and choose the datas that are only under criteria 1 and sum it up in sheet 2 cell D5. (By using column heading reference instead of cell reference. The table range is A2 : U80. thanks.
Public Sub Match()
ThisWorkbook.Sheets("Sheet1").Activate
Range("Sheet2!B3") = Application.Sum(Application.Index(Range("A:G"), 0, Application.Match("Crit1" & "Fun1personA", Range("A2:G2"), 0)))
End Sub
I have tried it codes but it failed. i know that i havnt include the Row reference for crit1 , but iam not sure how to apply that to the formula.
Can anyone help me with this ? Thanks in advance
You could do it with a formula.
I'll assume that the table in your example covers the range A1:E10.
First we'll need to find the correct column using a MATCH formula:
=MATCH("Fun2PersonA",$1:$1,0) - this will return 3 as Fun2PersonA is in column C.
Next we need to know how many rows are in the table. Assuming the criteria in column A has no blanks except cell A1 we can use COUNTA:
=COUNTA($A:$A)+1 - this will return 10.
The above two formula will be used a few times within the final result, so will probably be easier to use helper cells to store the results (I'll just call them ColumnRef and LastRowRef for readability rather than actual cell references).
Now to set a reference to the first cell and last cell in column C.
=INDEX($1:$1,,ColumnRef) will reference the header, while =INDEX($1:$1048576,RowRef,ColumnRef) will reference the last cell.
As these can be used as references and not just values =SUM(INDEX($1:$1,,ColumnRef):INDEX($1:$1048576,RowRef,ColumnRef)) will sum everything in that column. It's the same as writing =SUM(C1:C10).
But you want to use SUMIF, so we need to reference the criteria in column A as well.
=INDEX($A:$A,RowRef) will reference the last cell in column A, so $A$1:INDEX($A:$A,RowRef) will reference all values in column A.
Final Formula:
The final step is to stick it all together into your final formula:
=SUMIF($A$1:INDEX($A:$A,RowRef),"Crit1",INDEX($1:$1,,ColumnRef):INDEX($1:$1048576,RowRef,ColumnRef))
This is the same as writing =SUMIF($A$1:$A$10,"Crit1",$C$1:$C$10)
For a VBA solution:
Public Function SumCriteria(FunPerson As String, Criteria As String) As Double
Dim rTable As Range
Dim rCol As Range
Dim rCriteria As Range
Dim LastRow As Long
Dim LastCol As Long
'Update Sheet1 to the sheet name with your table.
With ThisWorkbook.Worksheets("Sheet1")
'You may have to change how to find the last row/column depending
'on any extra data on the sheet.
LastRow = .Cells(Rows.Count, 1).End(xlUp).Row
LastCol = .Cells(1, Columns.Count).End(xlToLeft).Column
Set rTable = .Range(.Cells(1, 1), .Cells(LastRow, LastCol))
'EDIT: You could set your table as below if it's a static size.
'Set rTable = .Range("A2:U80")
'The first statement finds the FunPerson heading
Set rCol = rTable.Rows(1).Find(What:=FunPerson, LookIn:=xlValues, LookAt:=xlWhole)
If Not rCol Is Nothing Then
SumCriteria = Application.WorksheetFunction.SumIf(rTable.Columns(1), Criteria, rTable.Columns(rCol.Column))
Else
SumCriteria = CVErr(xlErrValue)
End If
End With
End Function
This method looks at column A and row 1 to get the dimensions of the table and then uses SUMIF to count the figures.
You can use it as a worksheet formula: =SumCriteria("Fun1PersonA","Crit1")
or within VBA:
Public Sub Test()
Dim a As Double
a = SumCriteria("Fun1PersonA", "Crit1")
End Sub

Highlight unique values based on another range

Column 1 is in Sheet1 and column 2 is in Sheet2. If the value is not found , then highlight that cell. I am trying to do a vlookup comparing two columns. I think the Syntax is incorrect. Please see my code I was trying below:
Option Explicit
Sub VlookupColoums()
' declarations
Dim lookFor As Range
Dim srchRange As Range
Dim I As Long
Dim vtest As Variant
' start
Set lookFor = Sheets("Sheet1").Range("A13").End(xlUp)
Set srchRange = Sheets("Sheet2").Range("A2").End(xlUp)
vtest = Application.VLookup(lookFor.Rows.Count, srchRange.Rows.Count, 2, False)
' process
For I = 1 To lookFor.Rows.Count
If IsError(vtest) Then
srchRange.Interior.Color = 4
Else
Exit Sub
End If
Next I
End Sub
Assuming you have data on Sheet1!A1:A15 and Sheet2!A1:A10.
Also assuming you want to highlight unique cells (ones withouth at least one identical in the other list) on Sheet2.
Basically you want to format all the cells that if counted on the other list comes up with 0. The steps:
Select all the cells to be evaluated on Sheet2
Go to Home/Styles/Conditional Formatting
Select New Rule, then Use a formula to determine...
Enter this formula: =COUNTIF(Sheet1!$A$1:$A$5,A1)=0
Click on the Format button, and set up a formatting for the unique cells
OK
Profit. :)

Hide rows conditionally in excel table with VBA

I need to be able to hide rows in a table if the first column is blank. I need the macro to work on tables in different sheets so I search for the table name first using listobjects, I have no problem getting the table name. I have seen how to accomplish this with a general range of cells, but not within a Table. Any help is appreciated.
I have a similar macro to unhide rows in the table and it works fine because it simiply loops through all rows in the ListObject variable 'MyTable' and does not have the IF statement.
HideBlankTableRows()
Application.ScreenUpdating = False
Dim ws As Worksheet
Dim myTable As ListObject
Dim row As Range
Set ws = ActiveSheet
Set myTable = ws.ListObjects(1)
For Each row In myTable.DataBodyRange
If row.Columns(1, 1).Value = "" Then ' Error is caused by this row
row.Hidden = True
End If
Next
End Sub
Each row In myTable.DataBodyRange will actually loop through each cell in the body of the table, which you probably don't want. Since you're only checking the first column in each row, it would be faster to loop through each row in the table using Each row In myTable.DataBodyRange.Rows.
Also, the Range object doesn't have a Columns property, so you'll have to you can use the Cells property and provide the row and column number of the cell you want to reference (row 1, column 1).
The updated code would be as follows:
For Each row In myTable.DataBodyRange.Rows
If row.Cells(1, 1).Value = "" Then
row.Hidden = True
End If
Next
In addition to the fix provided by JayCal, you can utilise the ListObject properties to reference the column by name:
For Each rw In myTable.ListColumns("ColumnName").DataBodyRange
If rw.Value = vbNullString Then
rw.EntireRow.Hidden = True
End If
Next
You could also use the ListObject AutoFilter method
myTable.Range.AutoFilter Field:=lo.ListColumns("ColumnName").Index, Criteria1:="<>"

First value twice when using unique filtering (VBA)

I have made a very simple Visual Basic script, which uses the advanced filter function in Excel, to copy unique values from a column in one sheet, to a column in a different sheet. It works fine on all values, except the first which appears twice. Can anyone tell me the reason for this glitch? I tried using the filter manually, with the same result.
Sub getUniqueRuns()
Sheets(2).Range("C2:C65536").AdvancedFilter Action:=xlFilterCopy,
CopyToRange:=Sheets(5).Range("A2"), Unique:=True
End Sub
The AdvancedFilter is using the top row of your range as the title and then providing distict values from the rest of the range. As you have provided row 2 as the first row, it is using this as the header and then rows 3 onwards as the data. As a result you are getting duplicates. I suggest you change your ranges to the below which will then copy the heading across.
Sub getUniqueRuns()
Sheets(2).Cells.Clear
Sheets(2).Range("C1:C65536").AdvancedFilter Action:=xlFilterCopy,
CopyToRange:=Sheets(5).Range("A1"), Unique:=True
End Sub
I had the same issue with a script of mine, I resolved it with a .offset(1) to offset the extra row in rgData.
Sub modHouse_Popularity()
'
' modHouse_Popularity Macro
' Select Houses and remove duplicates
'define range
Dim rg As Range
Set rg = ThisWorkbook.Worksheets("Popularity").Range("A2:A500")
'retain header
rg.Offset(1).ClearContents
'define data fields, criteria fields and out put fields
Dim rgData As Range, rgCriteria As Range, rgOutput As Range
Set rgData = ThisWorkbook.Worksheets("Facade requests").Range("Table1[House]").Offset(1)
Set rgCriteria = ThisWorkbook.Worksheets("Popularity").Range("a2")
Set rgOutput = ThisWorkbook.Worksheets("Popularity").Range("a3:a500")
'place data
rgData.AdvancedFilter xlFilterCopy, rgCriteria, rgOutput, True

Creating a parameterized query in Excel with SQL using a cell as a parameter

So in MS Excel I've imported a table from a database in a SQL Server. I want to create a parameterized query where you have two cells. Say these two cells are G1 and G2. G1 takes a parameter/category and G2 takes a value from the parameter/category and queries the table you imported (essentially a WHERE clause that is dynamic from cell input). Can someone show me how to do this?
EDIT: Based on a chat session, we discovered that the first parameter is the column to be searched and the second parameter is the value to filter.
You can do what you want by filtering the table you imported.
Use the code below as your template. Modify it to reference the correct worksheets and ranges.
Sub FilterByParameter()
Dim wb As Workbook
Dim dataSheet As Worksheet
Dim parameterSheet As Worksheet
Dim rng As Range
Dim filterColumn As Long
Dim filterValue As String
Set wb = ThisWorkbook
' sheet that contains your table
Set dataSheet = wb.Sheets("Sheet1")
' sheet that contains your parameters
Set parameterSheet = wb.Sheets("Sheet2")
' range that contains your table, hard-coded here
' but can easily be set dynamically
Set rng = dataSheet.Range("A1:F78")
' get the column you are searching
filterColumn = parameterSheet.Range("G1").Value
' get the value you want to filter on
filterValue = parameterSheet.Range("G2").Value
' turn off autofilters if set
dataSheet.AutoFilterMode = False
' autofilter using your column and filter
rng.AutoFilter field:=filterColumn, Criteria1:=filterValue
' now you can do whatever you want to with the rows
' that remain after the autofilter was applied
End Sub
See Efficient way to delete entire row if... for an example of how to use the visible rows.