How to create an excel formula for the above equation?
Eg. N = 10, P = 9.4
Thanks!
Try the following user defined function:
Public Function Zigma(N As Long, p As Double) As Double
Dim i As Long
Zigma = N
For i = 1 To N - 1
Zigma = Zigma - (i / N) ^ p
Next i
End Function
This allows you to avoid array formulas.
Here it is as an excel formula:
=A1-SUMPRODUCT((ROW(A1:INDEX(A:A, A1-1))/A1)^A2)
Related
I am getting the error "End If Without Block If" problem in VBA. Followin is my code. Could someone help me find out the mistake I am making?
Function ProjectedProductionPlan(Coverage As Double, Sales As Variant, ProjectedStock As Double) As Double
Dim count As Integer
Dim ResidualBalance As Double
Dim ProjectedPlan As Double
Dim k As Integer
Dim x As Integer
Dim y As Single
Dim s As Single
count = Sales.count
s = 0
ResidualBalance = ProjectedStock
i = 1
If Coverage < 1 Then
ProjectedPlan = (Sales(i) * Coverage) - ResidualBalance
ElseIf Coverage = 1 Then
ProjectedPlan = Sales(i) - ResidualBalance
Else
For k = 1 To count
Do Until k - Coverage > 0
x = k
y = Coverage - x
s = Sales(k) + s
Loop
Exit For
End If
ProjectedPlan = s + (Sales(x + 1) * y)
End Function
As per my comment:
To get rid of the compile error, you'll need to change Exit For into Next to create an actual iteration whereas Exit For is simply a statement within the loop to Exit the loop. Here is MS-documentation on For...Next loops.
However, you also make use of a Do Until...Loop. As I see your code, repairing the above would immediately throw your code in an infinite loop since no variable (neither k nor coverage) get's adjusted. So my suggestion would be to include an IF statement inside your For...Next loop instead. For example like this:
For k = 1 To count
If k - Coverage > 0 Then
Exit For
Else
x = k
y = Coverage - x
s = Sales(k) + s
End If
Next
I've not checked the rest of your code to see if implementing this is actually what you needed.
Small sidenote: using Integer data type variables is only going to bite you at one point. Use Long instead.
How to create an excel formula for the above equation?
Eg. N = 10, P = 9.4
Thanks!
Try the following user defined function:
Public Function Zigma(N As Long, p As Double) As Double
Dim i As Long
Zigma = N
For i = 1 To N - 1
Zigma = Zigma - (i / N) ^ p
Next i
End Function
This allows you to avoid array formulas.
Here it is as an excel formula:
=A1-SUMPRODUCT((ROW(A1:INDEX(A:A, A1-1))/A1)^A2)
I want the function to take a range of cells as an argument and return their product.
Let's assume the following value for cells:
A1=5
A2=2
A3=3
Let's call the function Multiply.
=Multiply(A1:A3) will return 30 (=5×2×3).
What is the code for this? I'm just trying to familiarize myself with the syntax and this will help out a lot.
Edit: figured it out:
Function multiply(rng As Range)
multiplied = 1
For Each cell In rng
multiplied = multiplied * cell.Value
Next
multiply = multiplied
End Function
You can use the VBA version of PRODUCT directly, ie
MsgBox WorksheetFunction.Product([a1:a3])
You can use excel worksheet functions.
The default behaviour of SUMPRODUCT if there is only a single range provided is to return the sum so you can just pass the range to SUMPRODUCT this way:
WorksheetFunction.Sumproduct(**your range goes here**)
OK for =PRODUCT, which does the job (SUMPRODUCT will NOT do what the initial fellow asked).
But, just for fun, using the properties of the math functions EXP and LN we have that if
X = A1*B1*C1 then
LN(X) = LN(A1)+LN(B1)+LN(C1)
and
X = EXP(LN(X)) or
X = EXP(LN(A1)+LN(B1)+LN(C1))
so just put in a cel: =EXP(SUM(LN(A1:C1))) and voilà! (you must use CTRL+SHIFT+ENTER)
If you insist of writing your own function then try the following. It loads all the values into memory first and thus should work faster.
Public Function RngProduct(ByRef r as Range) as Double
Dim vals() as Variant, res as Double
vals = r.Value
Dim i as Long, N as Long
N = r.Rows.Count
res = #1
For i=1 to N
res = res * vals(i,1)
Next i
RngProduct = res
End Function
So I'm calculating basic statistics in my worksheet and it includes code such as:
xxx = Application.worksheetfunction.average(etc etc etc
yyy = Application.worksheetfunction.min(etc etc etc
zzz = Application.worksheetfunction.max(etc etc etc
My question: Is there an RMS equivalent function where I can simply plug it in place of where I have 'average, min, max' functions in that code? And if there isn't then what would be the most efficient means to code in to find RMS solutions?
I hope I've stated the goal clearly enough. I'm curious as to whether or not there is a predefined RMS function for VBA or whether or not I've got to create some sort of user defined function? ~ That of which I'm fairly new to as well so if there isn't a simple line of code to write for this, I'll have to do more reading on UDF's.
EDIT:
I've got around 30,000 rows, and for simplicity's sake: imagine two columns. Column A has the year i.e. 1941 or anything else through 2008. Column B is a numeric value. I'm just trying to put code together that gives decade summaries of Average, Min, Max, and the RMS values.
You can do the average with
=SQRT(SUMSQ(A:A)/COUNTA(range))
or in VBA:
r = (Application.WorksheetFunction.SumSq(Range("A:A")) / Range("A:A").Count) ^ (1 / 2)
A VBA function that accepts arrays (any rank) and ranges with multiple areas (a discontinuous range like A4:B6,C11:D15), or even a union of ranges in a formula. It skips non number datatypes (including dates, boolean, blanks etc).
You can use it in VBA code, or as a UDF in a worksheet formula such as:
"=RMS(A1:A10)" (basic usage)
"=RMS(A1:A10,C1:C10)" (multiple ranges (or arrays for that matter))
"{=RMS({1,2,3,4})}" (array formula entered with Ctrl+shift+enter)
Function RMS(ParamArray args()) As Double
Dim arg, arr, area As Range, ss As Double, n As Long
For Each arg In args
If TypeOf arg Is Range Then
For Each area In arg.Areas
arr = area.value
If VarType(arr) < vbArray Then
queryRmsElements Array(arr), ss, n
Else
queryRmsElements arr, ss, n
End If
Next area
ElseIf VarType(arg) > vbArray Then
queryRmsElements arg, ss, n
Else
Err.Raise 1, "RMS", "Invalid Argument"
End If
Next arg
RMS = (ss / n) ^ 0.5
End Function
Private Sub queryRmsElements(ByRef elements, ByRef ss As Double, ByRef n As Long)
Static element As Variant
'Enumerate to cover rank > 1 (vs. Iterate)
For Each element In elements
Select Case VarType(element)
Case VbVarType.vbByte, _
VbVarType.vbCurrency, _
VbVarType.vbDecimal, _
VbVarType.vbDouble, _
VbVarType.vbInteger, _
VbVarType.vbLong, _
VbVarType.vbSingle
ss = element ^ 2 + ss
n = n + 1
Case Else
End Select
Next element
End Sub
This one worked for me:
Function RMS(Intervalo As Range)
Dim SomaQ As Double
Dim Tamanho As Integer
SomaQ = 0
Tamanho = Intervalo.Count
SomaQ = Application.WorksheetFunction.SumSq(Intervalo)
RMS = Sqr(SomaQ / Tamanho)
End Function
I am trying to find the largest prime divisor of a number x. When x is smaller than 1billion my code works but when it is greater than 1billion it gives an overflow error and debugging highlights the line with Mod in it.
Sub Largest_Divisor()
Dim x As Double
Dim Q As Integer
Q = 0
Dim L() As Double
x = 999999999#
Dim i As Double
For i = 775145 To 3 Step -2
If x Mod i = 0 Then
If IsPrime(i) Then
ReDim Preserve L(Q) As Double
L(Q) = i
Q = Q + 1
End If
End If
Next i
MsgBox (Application.Max(L))
End Sub
I suspect it is when x is larger than about 2 billion, 2,147,483,648 to be precise, that you have trouble.
That is because as per the documentation of mod, at most a long is returned, which ranges in value from -2,147,483,648 to 2,147,483,647 as a 32-bit signed value. It is not explicitly stated in the help documentation, but the arguments of mod are probably coerced to long as well.
A good work around can be to use this function:
Function Modulus(int1 As Double, int2 As Double) As Double
' This function will return int1 Mod int2. It is useful when |int1| exceeds
' 2,147,483,647 as the VBA Mod function will then break.
'
Dim myInt As Integer
myInt = Int(int1 / int2)
Modulus = int1 - (myInt * int2)
Return Modulus
End Function