Using IFERROR with VLOOKUP - excel

I am adding a formula into a spreadsheet via VBA that uses iferror and vlookup. Below is the code from the VBA
LastRow = Cells(Rows.Count, 1).End(xlUp).Row
Range("O2:o" & LastRow).FormulaR1C1 = "=IFERROR(VLOOKUP(RC1,'Controls'!a:b,2,FALSE),""Missing"")"
But when I look back into the spreadsheet, I find the following formula in the cells
=IFERROR(VLOOKUP($A2,Controls!A:(B),2,FALSE),"Missing")
which always results in a value of "Missing". When I edited the formula in the sheet and removed the parens from the B in the lookup range, the formula resolved correctly by finding the value in the Controls sheet.
I've tried changing the lookup range from A:B to A1:B500, $A$1:$B$500, and $A:$B. I also tried breaking it up and using various concatenations.
My question is ... How can I get VBA to NOT add the parens around the B in my lookup range.

Your problem comes from the fact that you put a regular address (A:B) into a R1C1-Formula. Even if your lookup-range is in another sheet, Excel expect the address in R1C1-notation. Your formula would look like
dim formula as string
formula = "=IFERROR(VLOOKUP(RC1,Controls!C[-14]:C[-13],2,FALSE),""Missing"")"
Range("O2:o" & LastRow).FormulaR1C1 = formula
as this is super ugly, I would suggest you define a name for the range Controls!A:B. Then you can change the formula simply to
formula = "=IFERROR(VLOOKUP(RC1,MyControls,FALSE),""Missing"")"

I think you would need to use .Formula(...) instead of .FormulaR1C1(...) and use uppercase on your string like ...A:B...
Else, you could do the following:
LastRow = Cells(Rows.Count, 1).End(xlUp).Row
Range("O2:o" & LastRow).FormulaR1C1 = "=IFERROR(VLOOKUP(RC1,'Controls'!a:b,2,FALSE),""Missing"")"
Dim cell As Range
For Each cell in Range("O2:O" & LastRow)
cell.Formula = Replace(cell.Formula, "(B)","B")
Next cell

Related

Referencing a dynamic table in VBA in order to autofill a formula (r1c1/a1 style)

I am trying to achieve the following in VBA:
Fill a column from 2nd row to LastRow with a vlookup with the mention that the range of the vlookup is dynamic.
I used Match (see code snippet below) to identify the position of that column and also the last row.
I thought about referencing it in FormulaR1C1 but I have no idea how to reference the range with these variables (esentially the last line of code in my snippet) in either .Formula or .FormulaR1C1
Snippet
LastRowBin = wsbin.Cells(Rows.Count, "B").End(xlUp).Row
Set wsbin = Inputwb.Worksheets("Raport_POS_BIN")
colcopydoi = Application.Match(Search_doi, wsbin.Range("4:4"), 0)
newtgtlastrow = shttgt.Cells(Rows.Count, "A").End(xlUp).Row
/ This would be a formula that works but that doesn't have a dynamic reference for the range.
With shttgt.Range("D2")
.Formula = "=IFNA(VLOOKUP(A2,Input!Z2:AA20500, 2, FALSE),0)"
.AutoFill Destination:=Range("D2:D" & newtgtlastrow)
End With
/Range to use
wsbin.Range(wsbin.Cells(5, colcopydoi), wsbin.Cells(LastRowBin, colcopydoi))
Thank you very much for the help.

Excel VBA Vlookup with Ranges

I have vlookup formula that takes the value of A2 and returns the corresponding match found in my Lookup_Table in cell O2, this lookup continues for the rows underneath.
How would I modify this code to lookup a range of values in A:M, with the results placed in O:AA? Or do I have to manually code each column separately?
With Sheets("Example")
.Range("O2:O" & .Range("A" & Rows.Count).End(xlUp).Row).Formula = _
"=IF(ISERROR(VLOOKUP(A2,'Lookup_Table'!A:H,4,FALSE)),0,VLOOKUP(A2,'Lookup_Table'!A:H,4,FALSE))"
.Range("O2:O" & .Range("A" & Rows.Count).End(xlUp).Row).Value = _
.Range("O2:O" & .Range("A" & Rows.Count).End(xlUp).Row).Value 'Comment out if you'd like to leave the above formula in place
End With
Assuming Lookup_Table = 'Lookup_Table'!A:H, you could try something like:
With worksheets("Cross_Walk") ' Assumes Activeworkbook
.Range("E2:H" & .Range("A" & .Rows.Count).End(xlUp).Row).Formula = _
"=Iferror(VLOOKUP(A2,'Lookup_Table'!$A:$H,4,FALSE),0)"
End With
We assign the formula to range E2:H? where ? is whatever the last row is determined to be.
Excel observes relative and absolute references when assigning the same formula to a range of cells.
So since A2 in the VLOOKUP has a relative row and column reference (no $ signs), it will change to B2 when the formula is entered in F2 -- and so forth for the remaining columns and rows.
Also, if you're going to test whether the result of the VLOOKUP is an error, and then conditionally assign either zero or the matching value, you may as well just use IFERROR in your formula -- rather than performing the VLOOKUP twice.

Unable to give reference for VLOOKUP on special cells

I am trying to you vlookup on the specials where we have N/A in prior column but not able to succeed as cell reference for vlookup is creating or problem and i tried to research it and fix it but couldn't get the right one. Would be helpful if any of you can help me to correct it
N/A can be in any of the cells in column K and once i filter column k with N/A's here and need to vlookup in column L using below formula on the special cells which are filtered but i am facing challenge with giving vlookup reference cell for which i need to your assistance as N/A can be in K2/K16/K20/K50/K80
=IFERROR(VLOOKUP($D16,'BP Scoping'!A:B,2,0),D16)
'Second vlookup not working
With Sheets("Sheet4")
Dim LRW As Long
LRW = .Range("A" & Rows.Count).End(xlUp).Row
.Range("A1").AutoFilter Field:=11, Criteria1:="#N/A"
'need to check for right cells which is missing
'One way tried to use this
.Range(.Range("L2"), Cells(LRW, "L")).SpecialCells(xlCellTypeVisible).Formula = "=iferror(VLOOKUP($D2,'BP Scoping'!A:B,2,0),D2)"
Another way I tried to use this:
.Range("L2:L" & LRW).SpecialCells(xlCellTypeVisible).FormulaR1C1 = "=iferror(VLOOKUP($D2,'BP Scoping'!A:B,2,0),D2)"
Your last effort was getting close but you need to use xlR1C1 referencing, not xlA1 referencing in the formula.
.Range("L2:L" & LRW).SpecialCells(xlCellTypeVisible).FormulaR1C1 = _
"=IFERROR(VLOOKUP(RC4, 'BP Scoping'!C1:C2, 2, FALSE),RC4)"
That should provide the correct references to the values in column D relative to where the formula is placed in column L.
fwiw, you can quickly switch back and forth from xlA1 to xlR1C1 referencing with alt+F,T,F then alt+R.

Have formula to remove all characters to the right of the last char (there might be more then one) problems with vba

The formula =LEFT(A2,FIND("|",SUBSTITUTE(A2,".","|",LEN(A2)-LEN(SUBSTITUTE(A2,".",""))))-1) to remove all characters to the right of the last . (there might be more then one) works if I add it to a cell and copy down.
I can not figure out how add the formula to vba
I have the vba if there is only one .
(the cells to be evaluated are in column A and the output is to column E )
When I add the code ta a module c.Formula = "=LEFT(A2,FIND("|",SUBSTITUTE(A2,".","|",LEN(A2)-LEN(SUBSTITUTE(A2,".",""))))-1)" it highlights in red and error Invalid Character with the | highligthed
Thanks
Sub NotWorking()
Dim c As range
Dim Lastrow As Long
With Sheets("sheet1")
Lastrow = .range("C" & .Rows.Count).End(xlUp).Row
For Each c In .range("E2:E" & Lastrow)
c.Formula = "=LEFT(A2,FIND("|",SUBSTITUTE(A2,".","|",LEN(A2)-LEN(SUBSTITUTE(A2,".",""))))-1)"
Next
.range("E1").Value = "Source"
End With
End Sub
First tip:
when your are usign quotes in formula in VBA, you should use double qoutes. E.g.
instead
Range("E1").Formula="=IF(A1="test",1,2)"
you should use
Range("E1").Formula="=IF(A1=""test"",1,2)"
Second tip:
There is no need to use loop when applying formula. There is a more efficient way to do it.
Next your code
For Each c In .range("E2:E" & Lastrow)
c.Formula = "=LEFT(A2,FIND("|",SUBSTITUTE(A2,".","|",LEN(A2)-LEN(SUBSTITUTE(A2,".",""))))-1)"
Next
gives you formula for E2 : =LEFT(A2,...), and formula for E3 again =LEFT(A2,...) (note in both formulas A2). I think, it's not what you expected. Use this one instead:
.Range("E2:E" & Lastrow).Formula="=LEFT(A2,FIND(""|"",SUBSTITUTE(A2,""."",""|"",LEN(A2)-LEN(SUBSTITUTE(A2,""."",""""))))-1)"
Above code applies formula to entire range. Formula would be adjusted for each row, e.g. formula for E2 would be =LEFT(A2,...), while formula for E3 would be =LEFT(A3,...) and so on.
But, if you need to have the same formula for entire column E (for E2 : =LEFT(A2,...), and for E3 again =LEFT(A2,...)), use absolute/mixed references (with $ sign):
.Range("E2:E" & Lastrow).Formula="=LEFT(A$2,FIND(""|"",SUBSTITUTE(A$2,""."",""|"",LEN(A$2)-LEN(SUBSTITUTE(A$2,""."",""""))))-1)"
In addition to the points #Simoco makes, you need to adjust the cell refernces in order to get the same effect copying a range gives you, as Excel will automatically adjust these for you (unless you use absolute refernces $), whereas VBA won't.
The easiest way to do this is to use the R1C1 version of cell references.
Try this
Sub Working()
Dim rng As Range
With Sheets("sheet1")
Set rng = Range(.Cells(2, 5), .Cells(.Rows.Count, 3).End(xlUp).Offset(, 2))
End With
rng.FormulaR1C1 = "=LEFT(RC1,FIND(""|"",SUBSTITUTE(RC1,""."",""|"",LEN(RC1)-LEN(SUBSTITUTE(RC1,""."",""""))))-1)"
End Sub

Vba Excel Formula for following condition(Circular Referencing)

Hi, i tried to put a formula like ActiveCell.FormulaR1C1 = "=IF(RC[-1]=""India"",RC,"""")" If the country is not India then Check1, Check2 and Check3 should be empty otherwise they should display their own value. when i tried to put that formula the excel has given me circular referencing warning. I just want that formula. Any help would be appreciated greatly.
When a formula refers back to its own cell, either directly or indirectly, it creates a circular reference.
ActiveCell.FormulaR1C1 = "=IF(RC[-1]=""India"",RC,"""")"
You are writing the formula in activecell and the formula says if RC[-1]="India"
and if its true RC which is same as activecell. Hence you are getting the circular reference error.
But if you put this formula in Column E as below it would work.
Range("E2:E" & lastRow).FormulaR1C1 = "=IF(RC[-4]=""India"",RC[-3],"""")"
Alternatively below is simple VBA code.
Sub sample()
Dim lastRow As Long
lastRow = Range("A65000").End(xlUp).Row
For i = 2 To lastRow
If (InStr(1, Cells(i, 1), "India") <= 0) Then
Range("B" & i & ":D" & i).Clear
End If
Next
End Sub
You can't use RC as a result only as this is referencing the current formula.
Option 1: You need to have another cell to be the validated cell, e.g.the following will create a cell to the left one of the current cell:
ActiveCell.Offset(0,1).FormulaR1C1 = "=IF(RC[-2]=""India"",RC[-1],"""")"
Option 2 after comment: If your line of code is only going to clear the current cells value if the left cell is not India then use this:
If ActiveCell.Offset(0,-1).Value <> "India" Then ActiveCell.Value = ""
Option 3: If your default value in RC has to stay but a formula is needed to override it if the value of RC[-1] becomes a not equal to India you must hard code your value in the formula like so:
ActiveCell.FormulaR1C1 = "=IF(RC[-1]=""India"",""" & ActiveCell.Value & ""","""")"

Resources