1st VBA code: I am using vlookup formula in VBA, below is the formula I placed in VBA:
Rng.Formula = "=IF(RC" & SeseCol & " ="""","""",IF(LEFT(LOWER(RC" & SeseCol & "),4)=""none"","""",VLOOKUP(LEFT(RC" & SeseCol & ",(FIND("" "",RC" & SeseCol & ",1)-1)),'[HMO Base Rule Picker - Formula.xlsm]BaseRule'!C[-10]:C[-5],2,0)))"
1st VBA output: From the above code I get the below formula in excel which is correct:
=IF($C17 ="","",IF(LEFT(LOWER($C17),4)="none","",VLOOKUP(LEFT($C17,(FIND(" ",$C17,1)-1)),BaseRule!B:G,2,0)))
2nd VBA code: However I wanted make C[-10]:C[-5] to a constant range and tried changing to $B:$G as below VBA code:
Rng.Formula = "=IF(RC" & SeseCol & " ="""","""",IF(LEFT(LOWER(RC" & SeseCol & "),4)=""none"","""",VLOOKUP(LEFT(RC" & SeseCol & ",(FIND("" "",RC" & SeseCol & ",1)-1)),'[HMO Base Rule Picker - Formula.xlsm]BaseRule'!$B:$G,2,0)))"
2nd VBA output: Then I am getting the below formula from the above code which is not working. I am not getting the same as 1st VBA output formula, am I missing something on the 2nd code?
=IF(RC7 ="","",IF(LEFT(LOWER(RC7),4)="none","",VLOOKUP(LEFT(RC7,(FIND(" ",RC7,1)-1)),BaseRule!$B:$G,2,0)))
Use C2:C7 instead in place of C[-10]:C[-5].
Final formula would be:
Rng.FormulaR1C1 = "=IF(RC" & SeseCol & " ="""","""",IF(LEFT(LOWER(RC" & SeseCol & _
"),4)=""none"","""",VLOOKUP(LEFT(RC" & SeseCol & ",(FIND("" "",RC" & SeseCol & _
",1)-1)),'[HMO Base Rule Picker - Formula.xlsm]BaseRule'!C2:C7,2,0)))"
In R1C1 Notation [] brackets are used to indicate relative referencing.
To indicate absolute reference, you just need to indicate the actual column or row number. So for Column B that is C2 which is the 2nd column. For Column G which is the 7th column would be C7.
Also take note that I used FormulaR1C1 property above.
That is the correct property when you're using the R1C1 notation in your formula.
Related
I'm writing a macro to automate some manual processes. One of them is to assign a IF-ISNA-VLOOKUP formula to check an intermediate pivot table. I need to do it in VBA.
That's the currently used formula:
Range("N2").FormulaR1C1 = "=IF(
ISNA(VLOOKUP(RC[-6],'[Workbook.xlsx]Sheet1'!R1C1:R20C18,2,FALSE)),
0,
VLOOKUP(RC[-6],'[Workbook.xlsx]Sheet1'!R1C1:R20C18,2,FALSE))"
The pivot table I need to check is declared as a worksheet variable Wb.WsPivot, I need to access it through the access formula (referring it by it's variable name) or through VBA code (assigning values to cells instead of a formula).
You need to split the string (of the formula) at the points where you want to insert the worksheet name and then use & to concatenate the formula strings and the name of the worksheet:
Range("N2").FormulaR1C1 = "=IF(ISNA(VLOOKUP(RC[-6],'[Workbook.xlsx]" & WsPivot.Name & "'!R1C1:R20C18,2,FALSE)),0,VLOOKUP(RC[-6],'[Workbook.xlsx]" & WsPivot.Name & "'!R1C1:R20C18,2,FALSE))"
To replace the workbook too:
Range("N2").FormulaR1C1 = "=IF(ISNA(VLOOKUP(RC[-6],'[" & Wb.Name & "]" & WsPivot.Name & "'!R1C1:R20C18,2,FALSE)),0,VLOOKUP(RC[-6],'[" & Wb.Name & "]" & WsPivot.Name & "'!R1C1:R20C18,2,FALSE))"
After a query is completed, I am inserting the following formula into the sheet with the query data using the vba code below. All works great on Excel Office365 but if the version of Excel is 2016 standalone the formula fails with a #NAME error as this function is not available in that version. I have some users that are stuck with it.
I know that a formula array could replace this, but I am not sure how to do this and insert it with code, as well as what the most efficient formula is that could replace this one.
=IF(OR(ISERROR(MAXIFS(Consumed!D:D,Consumed!B:B,A2)),
MAXIFS(Consumed!D:D,Consumed!B:B,A2)=0),"",
MAXIFS(Consumed!D:D,Consumed!B:B,A2))
Any help appreciated.
strInsertFormula = "=IF(OR(ISERROR(MAXIFS(Consumed!D:D,Consumed!B:B,A2)),MAXIFS(Consumed!D:D,Consumed!B:B,A2)=0),"""",MAXIFS(Consumed!D:D,Consumed!B:B,A2))"
With Sheet3
.Range("Individual_Bottles").Columns(.Range("EndRng").Offset(0, 1).Column).Insert Shift:=xlToRight
.Range("EndRng").Offset(-1, 1).Cells(1, 1).Value = "Last Drank"
.Range("EndRng").Offset(0, 1).Formula = strInsertFormula
.Range("EndRng").Offset(0, 1).NumberFormat = "yy/mm/dd"
End With
You can use the Excel Array formula =MAX(IF(B:B=A2,D:D,"")) to find the conditional maximum (you can add the extra error checks etc. around this). This will work in all versions from 2016 and earlier.
If you type this into a cell, you do need to press the usual Crtl+Shift+Enter (known as CSE).
If you want to enter this array formula via code, you need to set the FormulaArray property of the range to the above, NOT the Formula property. So your code should read:
.Range("EndRng").Offset(0, 1).FormulaArray = strInsertFormula
where strInsertFormula is the array formula I mentioned above.
#JohnF Well I got it working thanks to John F. I had expected that I would have to use a loop but was hoping not to. In the end I did, as I believe the FillDown method requires the range to be selected and I did not want to do that. Here is the final code
ii = .Range("EndRng").rows.Count
ConsRows = Consumed.Range("Consumed").rows.Count
For i = 1 To ii
strInsertFormula = "=IF(IFERROR(MAX(IF(Consumed!B1:B" & ConsRows & "=" & _
.Range("A1").Offset(i, 0).Address & _
",Consumed!D1:D" & ConsRows & ","""")),0)>0,MAX(IF(Consumed!B1:B" & ConsRows & "=" & _
.Range("A1").Offset(i, 0).Address & _
",Consumed!D1:D" & ConsRows & ","""")),"""")"
.Range("EndRng").Offset(0, 1).Cells(i, 1).FormulaArray = strInsertFormula
Next
End If
I have some trouble applying a FORMULAR1C1 to a range.
This is the code i been using:
Range("AE6:AE" & conter).FormulaR1C1 = "=VLOOKUP(RC[-28],'[" & namebook & "]" & namesheet & "'!C1:C4,4,FALSE)"
where Conter is the number of rows that will applying the formula, namebook is the name of the woorkbook (without path) and namesheet is the name of the sheet that are looking the info for the vlookup.
the reason that i used a variable is that the file update daily and change the name because the date.
When i run this i get the runtime error 1004 what can i solve this? thanks
It's better of you stick with one style of Range.
You want to use FormulaR1C1, and your first VLOOKUP parameter is RC[-28], but the second one you are using C1:C4.
Also, you have a few "extra" ' that needs to be removed.
Modify your code to the line below:
Range("AE6:AE" & conter).FormulaR1C1 = "=VLOOKUP(RC[-28],[" & namebook & "]" & namesheet & "!R1C3:R4C3,4,FALSE)"
I am inserting the following hyperlink as a formula using vba:
ActiveSheet.Range("AD" & ActiveCell.Row).Formula = "=HYPERLINK(""S:\Tasks\" & Range("C" & ActiveCell.Row).Value & "\log.txt"",""View Log"")"
This works fine, however if my value in cell C was to change then my hyperlink becomes invalid and won't work because it has retained the value of the cell at the time in which the formula was entered.
I need a way of making a dynamic reference to my cell C in the event that the value should change then my link will also change.
Can someone please show me how to do this? Thanks in advance
Your code is taking the value from column C and building a string using that value that looks like this:
"S:\Tasks\FolderName\log.txt"
Instead, what you want to do is build the following string:
"S:\Tasks\" & C2 & "\log.txt"
To do that, use this VBA code:
ActiveSheet.Range("AD" & ActiveCell.Row).Formula = "=HYPERLINK(""S:\Tasks\"" & C" & ActiveCell.Row() & " & ""\log.txt"",""View Log"")"
I am using this formula to find the row number of the last valid entry in a sheet:
=SUMPRODUCT(MAX((ROW([A17U.SI.csv]A17U.SI!A:A))*([A17U.SI.csv]A17U.SI!A:A<>"")))
I have a list with several values, including "A17U.SI.csv" and "A17U.SI". Is it possible to reference those with the INDIRECT function?
Also, the reference A:A should not become a string (& A:A), it should remain dynamic so I can drag it to other columns.
Thanks for any input.
=SUMPRODUCT(MAX((ROW(INDIRECT("'[" & A3 & "]" & B3 & "'!" & SUBSTITUTE(ADDRESS(1,COLUMN(),4),"1","") & ":" & SUBSTITUTE(ADDRESS(1,COLUMN(),4),"1",""))))*(INDIRECT("'[" & A3 & "]" & B3 & "'!" & SUBSTITUTE(ADDRESS(1,COLUMN(),4),"1","") &":" & SUBSTITUTE(ADDRESS(1,COLUMN(),4),"1","") )<>"")))
Essentially, you are just needing to make your existing formula dynamic via the INDIRECT function. When using it, you just need to make sure you use the single quotes, brackets, and exclamation point to make the syntax valid. Your goal is simply to reproduce what you had hard-coded in there in your original formula.
The tricky part to your question was actually the need for a dynamic range reference, which makes the formula much uglier because we keep having to include this to get the letters for the range in a way that will be dynamically update:
SUBSTITUTE(ADDRESS(1,COLUMN(),4),"1","")
For example, if you put the above formula on its own in any cell in the A column, it will evaluate to "A". If you could put that in its own cell in the column, then you could simply reference that cell and it would make the formula a bit easier to read. For example, if we put =SUBSTITUTE(ADDRESS(1,COLUMN(),4),"1","") in cell A1, then we could write:
=SUMPRODUCT(MAX((ROW(INDIRECT("'[" & A3 & "]" & B3 & "'!" & A1 & ":" & A1)))*(INDIRECT("'[" & A3 & "]" & B3 & "'!" & A1 &":" & A1 )<>"")))
You asked about the syntax when using INDIRECT in SUMPRODUCT. By the time SUMPRODUCT is involved, if we wrote the INDIRECT part right, it shouldn't be any different syntax than what you already had.