Excel AutoFilter Criteria Variant to string - excel

I'm trying to get an AutoFilter setting as a string.
I set A1:A5 in a worksheet to:
Rows
valA
valB
valC
valD
Then I AutoFilter the worksheet and select Rows values valA, valB, valC. (I.e., I have filtered out Rows value valD.)
I run the following VBA:
Sub CaptureFilters()
With ActiveSheet.AutoFilter.Filters.Item(1)
Cells(1, 3).Value = Join(.Criteria1)
Cells(1, 4).Value = Replace(Join(.Criteria1), "#=", "")
End With
End Sub
Now both worksheet cells C1 and D1 give a #NAME? error, but their formulas show =#valA =#valB =#valC.
VBA shows that .Criteria1 is an Array of Variant/Strings.
How can I get .Criteria1 as a string value in a worksheet cell? In this example I want a cell that contains the string valA valB valC.

Rewrite to
Sub CaptureFilters()
With ActiveSheet.AutoFilter.Filters.Item(1)
Cells(1, 3).Value2 = "'" & Join(.Criteria1)
Cells(1, 4).Value = "'" & Replace(Join(.Criteria1), "#=", "")
End With
End Sub
Otherwise Excel will interpret the string as formula as it starts with a =.
Or you try
Sub CaptureFiltersA()
With ActiveSheet.AutoFilter.Filters.Item(1)
Cells(1, 3).Value2 = Replace(Join(.Criteria1), "=", " ")
Cells(1, 4).Value = Replace(Join(.Criteria1), "=", "")
End With
End Sub
There are four scenarios for a text autofilter – one value, two, and more than two. To handle them all:
Sub CaptureFiltersA()
With ActiveSheet.AutoFilter.Filters.Item(1)
If IsArray(.Criteria1) Then ' CASE: More than two values
Cells(1, 3).Value = Replace(Join(.Criteria1, ","), "=", "")
Else
Cells(1, 3).Value = Replace(.Criteria1, "=", "") ' CASE: One value
If .Count = 2 Then ' CASE: Two values
Cells(1, 3).Value = Cells(1, 3).Value + "," + Replace(.Criteria2, "=", "")
End If
End If
End With
End Sub

Related

Concatenating Rows in For Each/IF Statment

I'm trying to concatenate rows.
The first cell is populated correctly; however, each cell after that is the same as the first cell.
The first cell is FS_Tier_1 , FS_CAP_1_001
The next cell should be FS_Tier_1 , FS_CAP_1_002
The cell after that should be FS_Tier_1 , FS_CAP_1_003, and so on.
Each cell shows FS_Tier_1 , FS_CAP_1_001.
Sub Concatenate_Cap1()
With Worksheets("PD Code Structure")
Dim i As Integer
Dim cell As Range
Dim Rng1 As Range
Set Rng1 = Range("F2:F1006")
i = 2
For Each cell In Rng1
If InStr(Cells(i, 3).Value, "FS_Tier_") And InStr(Cells(i, 8).Value, "FS_CAP_1_") Then
Range("F2:F1006").Formula = Cells(i, 3).Value & " , " & Cells(i, 8).Value
i = i + 1
End If
Next cell
End With
End Sub
You're setting the whole range to the same value here.
Range("F2:F1006").Formula = Cells(i, 3).Value & " , " & Cells(i, 8).Value
Something like this should work:
Sub Concatenate_Cap1()
Dim c As Range, rw As range, v3, v8
For Each c in Worksheets("PD Code Structure").Range("F2:F1006")
v3 = c.EntireRow.cells(3).value
v8 = c.EntireRow.cells(8).value
If InStr(v3, "FS_Tier_") And InStr(v8, "FS_CAP_1_") Then
c.value = v3 & " , " & v8
End If
Next cell
End Sub

Search String and If found then paste value - then loop

I'm trying to build a macro that searches a column for two Strings ("Tip Fee" or "Non-Deal". If it finds this then it pastes a "Y" value in another column. If it doesn't then it pastes "N".
I'm struggling to get it to work and not sure what to do for the "not equal to then "N") part.
Example for just finding "Tip Fee" below:
Sheets("Pipeline simplified").Select
Dim TipFee As String
Dim NonDeal As String
Dim t As Integer
Dim LastRowtip As Long
TipFee = "Tip Fee"
NonDeal = "Non-Deal"
LastRowtip = Cells(Rows.Count, "H").End(xlUp).Row
For t = 7 To LastRowtip
If Cells(t, 8).Value = TipFee Then
Cells(t, 30).Value = "Y"
End If
Next t
Can still use a formula in VBA, that way there's no need to loop. Formula can be made to search for text within the cell, and can also be case insensitive. Then just convert to values afterwards.
Dim ws As Worksheet
Set ws = ActiveWorkbook.Worksheets("Pipeline simplified")
With ws.Range("AD7:AD" & ws.Cells(ws.Rows.Count, "H").End(xlUp).Row)
.Formula = "=IF(OR(ISNUMBER(SEARCH({""Tip Fee"",""Non-Deal""},H7))),""Y"",""N"")"
.Value = .Value
End With
Try this:
If Cells(t, 8).Value = TipFee Or Cells(t, 8).Value = NonDeal Then
Cells(t, 30).Value = "Y"
Else
Cells(t, 30).Value = "N"
End If
Also, check how IF sentence works:
If...Then...Else statement

How do I lookup multiple values from a comma separated cell and average the results in excel?

I'm trying to build a formula that can lookup multiple ISO country codes separated by comma contained in one cell (Cell A2, Image 1) with a reference to a list of country codes and education scoring (Columns F and G, Image 1). Then return the average of the scores of all countries on cell B2. does anyone know if I can build a formula to handle that?
I didn't think you could do this with cell formula, but then I saw this post and came up with this:
=AVERAGE(IF(ISNA(MATCH($F$2:$F$99, TRIM(MID(SUBSTITUTE(A2,",",REPT(" ",99)),(ROW(OFFSET($A$1,,,LEN(A2)-LEN(SUBSTITUTE(A2,",",""))+1))-1)*99+((ROW(OFFSET($A$1,,,LEN(A2)-LEN(SUBSTITUTE(A2,",",""))+1)))=1),99)), 0)), "", $G$2:$G$99 ))
Try pasting into cell B2 as an array formula (Ctrl + Shift + Enter) and fill-down... And don't ask me how it works.
You could try VBA:
Option Explicit
Sub test()
Dim i As Long
Dim strCode As String, strScore As String
Dim rngVlookup As Range
Dim Code As Variant
With ThisWorkbook.Worksheets("Sheet1")
Set rngVlookup = .Range("F2:G34")
For i = 2 To 3
strCode = ""
strScore = ""
strCode = .Range("A" & i).Value
For Each Code In Split(strCode, ",")
If strScore = "" Then
On Error Resume Next
strScore = Application.WorksheetFunction.VLookup(Trim(Code), rngVlookup, 2, False)
Else
On Error Resume Next
strScore = strScore & ", " & Application.WorksheetFunction.VLookup(Trim(Code), rngVlookup, 2, False)
End If
Next Code
With .Range("B" & i)
.Value = strScore
.NumberFormat = "0.000000"
End With
Next i
End With
End Sub

Detect difference between cells where text is the same but text formatting differs

I want to detect if anything about the text is different between two cells.
For example, cells A1 and B1 have the same text but different formatting of the text:
Cell A1: This is my cell.
Cell B1: This is my cell.
The following code does not flag a difference:
'if the text in the cells is different in any way, report a difference
If (ActiveSheet.Cells(1, "A") <> ActiveSheet.Cells(1, "B")) Then
ActiveSheet.Cells(1, "C").Value = DIFFERENT
End If
e.g:
Sub Tester()
Debug.Print SameText(Range("B4"), Range("C4"))
End Sub
'call from VBA or as UDF
Function SameText(rng1 As Range, rng2 As Range) As Boolean
Dim rv As Boolean, c1, c2, x As Long, arr, v
If rng1.Value = rng2.Value Then
rv = True
arr = Array("Underline", "Fontstyle", "Color") '<< for example
For x = 1 To Len(rng1.Value)
Set c1 = rng1.Characters(x, 1).Font
Set c2 = rng2.Characters(x, 1).Font
For Each v In arr
If CallByName(c1, v, VbGet) <> CallByName(c2, v, VbGet) Then
Debug.Print "Mismatch on " & v & " at position " & x, _
rng1.Address, rng2.Address
rv = False
Exit Function
End If
Next
Next x
Else
rv = False
End If
SameText = rv
End Function
I'm not sure whether comparing the cells' .Value(11) XML code will catch every discrepancy you are looking for but it does catch the differences in your example strings' formatting.
With ActiveSheet
Debug.Print .Cells(1, "A").Value(11)
Debug.Print .Cells(1, "B").Value(11)
If .Cells(1, "A").Value(11) <> .Cells(1, "B").Value(11) Then
.Cells(1, "C").Value = "DIFFERENT"
End If
End With
For the unformated cell this element is pretty plain.
...
<Cell><Data ss:Type="String">abcdef</Data></Cell>
...
Not so for the one formatted with bold and strike-through characters.
...
<Cell><ss:Data ss:Type="String" xmlns="http://www.w3.org/TR/REC-html40"><Font
html:Color="#000000">ab</Font><B><S><Font html:Size="8.8000000000000007"
html:Color="#000000">cde</Font></S></B><Font html:Color="#000000">f</Font></ss:Data></Cell>
...
To compare only that <Cell> element,
Dim val11A As String, val11B As String
With ActiveSheet
val11A = Split(Split(.Cells(1, "A").Value(11), "<Cell>")(1), "</Cell>")(0)
val11B = Split(Split(.Cells(1, "B").Value(11), "<Cell>")(1), "</Cell>")(0)
If val11A <> val11B Then
.Cells(1, "C").Value = "DIFFERENT"
End If
End With

Excel Macro: If the final characters in each row of a column is "something", then

I'm trying to concatenate two cells if certain conditions are met in one of the cells.
Specifically: If the final characters in the cells of column D = " XX " then concatenate. I've done something similar to below and get an error each time.
Sub concatenate()
Last = Cells(Rows.Count, 4).End(xlUp).Row
For i = Last To 1 Step -1
If Right(Cells(i, 4), 4) = " XX " Then
'do some stuff to concatenate'
End If
Next i
End Sub
Any help is greatly appreciated.
Here is your reverse loop with some error control added.
Sub concat()
Dim i As Long, l As Long
l = Cells(Rows.Count, 4).End(xlUp).Row
For i = l To 1 Step -1
If Not IsEmpty(Cells(i, 4)) Then
If Not IsError(Cells(i, 4)) Then
If LCase(Right(Cells(i, 4).Value, 4)) = LCase(" XX ") Then
'do some stuff to concatenate'
'maybe...
Cells(i, 4) = Cells(i, 4).Value & " - " & Cells(i, 5).value
Cells(i, 5).clearcontents 'clears value; use Cells(i, 5).clear to clear everything
End If
End If
End If
Next i
End Sub
Running string operations on an empty cell is unnecessary and could conceivably throw an error. Trying to run the same operations on a cell with an error will always throw a Run-time error '13': Type mismatch. You may have other special conditions that need to be accommodated but this should get you started.
Finally, direct string comparisons in VBA are generally case-sensitive; thus the conversion of both to lower case to remove case sensitivity.
Sub concatenate()
Dim myCell As String
Dim i As Integer
lastRow = Worksheets("yourSheet").Cells(Rows.Count, 4).End(xlUp).Row
For i = lastRow To 1 Step -1
myCell = Worksheets("yourSheet").Cells(i, 4).Value
If Right(myCell, 4) = " XX " Then
'do some stuff to concatenate'
End If
Next i
End Sub

Resources