Weighted average rate in VBA - excel

I am quite new to VBA so I am sorry if my question might seems very trivial.
I would love to write a function in VBA which helps to estimate weighted average rate (for loan portfolio, for instance). I wrote the following VBA code:
Function WAIRS(Amount As Range, InterestRate As Range, MatchRange As Range, Match1)
WAIRS = Evaluate("=SUMPRODUCT(--(""" & MatchRange & """ = """ & Match1 & """),""" & Amount & """, """ & InterestRate & """)") /Application.WorksheetFunction.SumIfs(Amount, MatchRange, Match1)
End Function
The problem is that when I run this function in Excel by adding respective function criterias I get an "#VALUE#". I have tried a lot but cannot find out what is wrong. I Would highly appreciate if you can help me.
Thank you in advance.
Best,
Jeyhun

The string you build for Evaluate should (in this case) not include literal double quotes. Instead of quoting the result of a range value
"""" & MatchRange & """"
...you should retrieve the address notation of that range, and use that without wrapping it in quotes:
MatchRange.Address()
If you apply that consistently, it would make the Evaluate part of the formula look like this:
"=SUMPRODUCT(--(" & MatchRange.Address() & " = " & Match1.Address() & "), " & _
Amount.Address() & ", " & InterestRate.Address() & ")"
When range is another sheet:
The above will not work if your ranges are on another sheet. In that case, I would suggest to create this function:
Public Function fullAddr(range As Range)
fullAddr = "'" & range.Parent.Name & "'!" & _
range.Address(External:=False)
End Function
And then in your formula:
"=SUMPRODUCT(--(" & fullAddr(MatchRange) & " = " & fullAddr(Match1) & "), " & _
fullAddr(Amount) & ", " & fullAddr(InterestRate) & ")"

Related

How do I write & in a formula within quotation marks?

Im currently figuring out how to write "&" in a formula so that VBA recognizes it as a string and not as the &-operator.
My formula looks like this:
"=AVERAGEIF(RC[-4]:R[" & Total & "]C[-4],"">""&0.5*MAX(RC[-4]:R[" & Total & "]C[-4]))"
But it should look something like this, as I want to use the variable z instead of 0.5
"=AVERAGEIF(RC[-4]:R[" & Total & "]C[-4],"">"" & Chr(34)& Chr(38) & Chr(34)& z & *MAX(RC[-4]:R[" & Total & "]C[-4]))"
As you see I already tried to write the "" and the & as ASCII but it seems that even this doenst work.
Thanks in advance for your help!
EDIT: The result should look like this:
=AVERAGEIF(C31:C6413;">"&0.5*MAX(C31:C6413))
EDIT: will post another question with the whole code. See here
I wouldn't use Chr(34) for " and Chr(38) for &, they're unnecessary indirection making the code harder to reason about. & doesn't need escaping, and to have a " literal inside a string you escape it by doubling it up, so """" is a string containing a single " character.
Concatenating long strings with escaped double-quotes can be a frustrating experience... what if we broke down the steps, and added a bit of space around operators?
The cognitive load is immediately reduced, and any error in the logic is much easier to spot:
Dim avgSourceRangePart As String
avgSourceRangePart = "RC[-4]:R[" & Total & "]C[-4]"
Dim maxPart As String
maxPart = "MAX(RC[-4]:R[" & Total & "]C[-4])"
Dim avgConditionPart As String
avgConditionPart = """>"" & " & z & " * " & maxPart & ")"
Now the final concatenation looks like this:
"=AVERAGEIF(" & avgSourceRangePart & "; " & avgConditionPart ")"
This should be what you're looking for:
"=AVERAGEIF(RC[-4]:R[" & Total & "]C[-4],"">"" &" & z & "*MAX(RC[-4]:R[" & Total & "]C[-4]))"

Excel VBA .Formula - syntax error adding absolute reference to cell

I have a syntax error in this VBA code:
students.Cells(studentRow, StartColumn).Formula = _
"=If($" & SurnameColumnStr & studentRow & " <> """", if($" & colonnaStr & studentRow & _
" <> """", $" & colonnaStr & " & $" & pointRow & ", 0), """")"
I can't put right this piece of code: $" & colonnaStr & " & $" & pointRow & " (it would be like having "$B$3")
I've tried several ways with no luck.
Any help would be really appreciated.
To get "$B$3" out of colonnaStr (a column reference) and pointRow (a row reference), you will need to use Range.Address.
Using this inside your Formula String:
Range(colonnaStr & pointRow).Address(True, True, xlA1)
Will give you $B$3 as a result.
To learn more about is, read HERE

vba Sumif with variables and R1C1

I'm trying to run the below code and it gives me
Run-Time Error "1004"
Application-defined or Object-defined error
Every Single Time!!
Attached is a snippet of the code, any suggestions what's wrong? (The numbers in the Range(Cells( * ) sections are actually mostly variables in my overall macro, it's pretty complex but I've taken them out for simplicity here)
Code:
'Declare variables
Dim CriteriaRng As String
Dim SumRng As String
Dim Criteria As String
'Set a variable for each of the 3 parts of the SUMIF Formula
CriteriaRng = "'" & Sheets(1).Name & "'!" & Range(Cells(2, 4), Cells(88, 4)).Address
SumRng = "'" & Sheets(1).Name & "'!" & Range(Cells(2, 3), Cells(88, 3)).Address
Criteria = Chr(34) & "=" & Chr(34) & " & RC[-1]"
'Here goes the SUMIF Formula
With Sheets(2).Range(Cells(4, 13), Cells(9, 13))
Debug.Print "So the Whole Formula Should be:" & Chr(13) & "= SUMIF(" & CriteriaRng & ", " & Criteria & ", " & SumRng & ")"
'That was a vain attempt to find out what was wrong with the formula; didn't work though.
.FormulaR1C1 = "= SUMIF(" & CriteriaRng & ", " & Criteria & "," & SumRng & ")"
'Then adds NumberFormat and stuff here, but that isn't relevant to this question.
End With
The error always hits on the line where it's putting in the .FormulaR1C1 = .
Yes, I know I could get the same result using a nested loop, but that would return just the value without the SUMIF formula - I need that formula so the sheet updates when edited (without needing a macro - I'm sending the sheet on to other people who won't have or want any macros, but might need to edit the data).
Can anyone point out to me what is wrong? I'm prepared for it to be something pretty basic - only last week I spent 2 hours figuring out a problem from misspelling 'Columns' !!!
Any and all advice welcome - Many Thanks in advance.

Translate Excel array formula to VBA

I am making a calendar with different events.
For that I have the following formula to lookup multiple hits with multiple conditions:
=IFERROR(INDEX(Returnarray, SMALL(IF(Value1 & Value2=Lookuparray1&Lookuparray2, ROW(Returnarray)-MIN(ROW(Returnarray))+1,""), ROW()-Offset)),""))
I would like to translate this formula to a VBA function, but I can't get it to work.
I tried with Evaluate and with appication.worksheetfunction but no success.
Function MultipleLookup(Offset As Integer, ReturnArray As Range, Value1 As Range, Lookuparray1, Value2 As Range, Lookuparray2 As Range)
MultipleLookup = Evaluate("=IFERROR(INDEX(Returnarray, SMALL(IF(Value1 & Value2=Lookuparray1&Lookuparray2, ROW(Returnarray)-MIN(ROW(Returnarray))+1,""), ROW()-Offset)),""))")
End Function
I also tried to change the formula and use match instead of if but then it only gives me the first match.
Can somebody please help me to make it work?
Would it be possible to have a function with a variable amount of criteria?
Thank you
Your Evaluate function is one entire string right now and it doesn't use the variables. Try something like this:
MultipleLookup = Evaluate("=IFERROR(INDEX(" & Returnarray.Address & ", SMALL(IF(" & Value1.Address & " & " & Value2.Address & "=" & Lookuparray1.Address & "&" & Lookuparray2.Address & ", ROW(" & Returnarray.Address & ")-MIN(ROW(" & Returnarray.Address & "))+1,""), ROW()-" & Offset & ")),""))")

VBA Evaluate - Match

I have a problem with my codes below,
As you can see, I am trying to find the row value of a search. I have 3 different criteria ( they are defined before ) and 3 different ranges ( also defined before ). But I cannot find the rows unfortunately.
Here you can see the codes;
Gorev = Worksheets(WS_All).Cells(p, o).Value
SlideNo = Worksheets(WS_All).Cells(p, 34).Value
Egitim_Adi = Worksheets(WS_All).Cells(2, 3).Value
Check1 = Worksheets(j_WS).Range("A:A") 'Egitim_Adi Kontrolü için'
Check2 = Worksheets(j_WS).Range("B:B") 'SlideNo Kontrolü için'
Check3 = Worksheets(j_WS).Range("C:C") 'Gorev Kontrolü için'
Satir_bul = Evaluate("=Match(" & Egitim_Adi & " & " & SlideNo & " & " & Gorev & ", Check1 & Check2 & Check3, 0)")
I am open to any suggestion..
You have a whole heap of problems there. WorksheetFunction.Match is not going to work because you are trying to replicate an array formula so Evaluate is definitely a better bet, but you need to construct the correct formula string for it. Unless you know whether the contents of the three cells will always be text or numbers, it is easier to just use cell addresses than to worry about enclosing the values in quotes:
Gorev = Cells(p, o).address
SlideNo = Cells(p, 34).address
Egitim_Adi = Cells(2, 3).address
Satir_bul = Worksheets(WS_All).Evaluate("=Match(" & Egitim_Adi & "&" & SlideNo & "&" & Gorev & ", '" & j_WS & "'!A:A&'" & j_WS & "'!B:B&'" & j_WS & "'!C:C, 0)")
If you can limit the ranges rather than using entire columns, you'll get better performance too.
Try it like this:
Satir_bul = WorksheetFunction.Match ( Egitim_Adi & " & " & SlideNo & " & " & Gorev & ", Check1 & Check2 & Check3, 0)
Here is a bit more about Match.
It will not work. You should include Union of the ranges in Match. Read more about Unions here.
You have three strings str1, str2, str3. You have three search areas: rng1, rng2 and rng3. Now, on every range you have to do the following (cell will be range variable):
For Each cell In rng1
'here you determine if one of your strings is contained uisng InStr function
'if the above condition is satisfied, then get the number of a row
Next cell
You'll do this then with rng2 and rng3.

Resources