visual basic for application Excel - excel

I have written a code in module 1. I get the correct value for the output. But, When I call it in module 2, the output value is zero. I would be thankful, if anyone can help me.
Module 1:
Sub MuAndVuCalculations()
BeamFlangeWidth = Sheets("MuVu").Range("D7")
BeamFlangeThickness = Sheets("MuVu").Range("D8")
BeamWebHeight = Sheets("MuVu").Range("D9")
M3 = (0.5 * BeamFlangeWidth * BeamWebHeight * BeamWebHeight ^ 2)
End Sub
module 2:
Sub Main()
Call MuAndVuCalculations
M = 5 Debug.Print M3 + M
End Sub
In module 2 I can not see M3 in Immediate window and the output of the M3+5 is 5

You have to declare M3 as public to access from the other function.
Add the first line above your code in module1:
Public M3 As Long 'add this line
Sub MuAndVuCalculations()
BeamFlangeWidth = Sheets("Tabelle1").Range("D7")
BeamFlangeThickness = Sheets("Tabelle1").Range("D8")
BeamWebHeight = Sheets("Tabelle1").Range("D9")
M3 = (0.5 * BeamFlangeWidth * BeamWebHeight * BeamWebHeight ^ 2)
End Sub

Related

Rearrange equation to solve for a different variable

I am looking at VBA code (function) written by someone else.
Here is the code:
Function EuropeanDelta(StrikePrice, MarketPrice, Volatility, InterestRate As Double, PC As String, ValueDate, ExpiryDate As Date, Optional PriceOrYield As String = "P") As Double
Rem Declare our working variables
Dim r As Double
Dim d1 As Double
Dim d2 As Double
Dim t As Double
Dim SqT As Double
Rem End of variable declaration
If PriceOrYield = "Y" Then
MarketPrice = 100 - MarketPrice
StrikePrice = 100 - StrikePrice
If PC = "C" Then
PC = "P"
Else
PC = "C"
End If
End If
Rem Initiase our working variables
t = (ExpiryDate - ValueDate) / 365
SqT = Sqr(t)
r = Application.WorksheetFunction.Ln(1 + InterestRate)
d1 = (Application.WorksheetFunction.Ln(MarketPrice / StrikePrice) + (Volatility * Volatility * 0.5) * t) / (Volatility * SqT)
Rem Quick logic to deal with Calls or Puts
If PC = "C" Then
EuropeanDelta = Exp(-r * t) * Application.WorksheetFunction.NormSDist(d1)
Else
EuropeanDelta = -Exp(-r * t) * Application.WorksheetFunction.NormSDist(-d1)
End If
If PriceOrYield = "Y" Then
EuropeanDelta = EuropeanDelta * -1
End If
End Function
The whole problem is based around the line for "d1". I would like to re-organise to solve for "StrikePrice". I have tried writing it out mathematically and then re-arranging, then swapping back to VBA.
#duffymo is correct, but am giving the answer directly in terms of VBA code
' d1 = (Log(MarketPrice / StrikePrice) + (Volatility * Volatility * 0.5) * t) / (Volatility * Sqr(t))
'
' Volatility * Sqr(t) * d1 = Log(MarketPrice / StrikePrice) + Volatility^2 * t/2
'
' Log(MarketPrice / StrikePrice) = Volatility * Sqr(t) * d1 - Volatility^2 * t/2
'
' MarketPrice / StrikePrice = Exp(Volatility * Sqr(t) * d1 - Volatility^2 * t/2)
'
StrikePrice = MarketPrice / Exp(Volatility * Sqr(t) * d1 - Volatility^2 * t/2)
Other Notes :
For brevity replace Application.WorksheetFunction.Ln() with Log()
There is no need cache SqT = Sqr(t) since it is only used once.
For clarity replace Volatility*Volatility with Volatility^2 as internally it does the same thing.
This is just algebra - high school math.
Take it in steps. Make sure you do the same operation to both sides to make sure that equality still holds.
Here's your starting equation:
d = {ln(m/s) + v*v*t/2}/(v*sqrt(t))
Multiply both sides by the denominator of the RHS:
d*v*sqrt(t) = ln(m/s) + v*v*t/2
Subtract v*v*t/2 from both sides:
(d*v*sqrt(t) - v*v*t/2) = ln(m/s)
Apply the exponential function to both sides, noting that exp(ln(x)) = x:
exp(d*v*sqrt(t) - v*v*t/2) = m/s
Multiply both sides by s:
s*exp(d*v*sqrt(t) - v*v*t/2) = m
Divide both sides by exp(d*v*sqrt(t) - v*v*t/2) to get the desired result:
s = m/exp(d*v*sqrt(t) - v*v*t/2)
Let's see if this function makes sense.
At t = 0 the denominator exp(0) = 1, so the strike price is equal to the market price.
As t -> infinity, we hope that the denominator gets large so s -> zero. L'Hospital's Rule will help here.

Ramanujan Function in VBA

I am trying to achieve the Ramanujan Function by using VBA. The formula is in the picture below.
My code is:
Function ramanuian(n)
left_part = (Application.sqrt(8) / 9801)
Dim temp As Double
temp = 0
For i = 0 To n
middle_part = Application.Fact(4 * i) / Application.Power(Application.Fact(i), 4)
right_part = (1103 + 26930 * i) / Application.Power(396, 4 * i)
ramanuian_reciprocal = middle_part * right_part
temp = temp + ramanuian_reciprocal
Next
ramanuian = 1 / (left_part * temp)
End Function
However, when I run this formula in Excel, it shows me an #Value! error. What is wrong with my code?

VB.Net Chart Equation and R² Value

Goal
I have a chart in Excel and I'm trying to replicate the same chart in VB.Net. I can get the chart data to be inputted correctly. I don't know how to retrieve the equation and R² value in a VB.Net chart control, as shown in my Excel chart.
Current Problem
Here is the data that is gotten in my Excel graph and Vb.Net chart:
' X Y
'0.895, 120.1
'0.978, 160.1
'1.461, 240.1
'1.918, 320.1
'2.343, 400.2
'2.769, 480.2
'3.131, 560.2
'3.493, 640.3
'3.797, 720.3
'4.089, 800.3
I get the following result from this (Excel):
As you can see, I receive a formula y= 203.83x - 62.797 and R²=0.9949
I'm trying to get the same result in Vb.Net but I am unable to find where this data is stored.
Any ideas?
I finally figured out my issue. Here is the clsTrendline.vb that I fetched using the help of multiple people/threads/conversion websites/Excel help on this site.
Public Class Trendline
#Region "Variables"
Private m_Slope As Decimal
Private m_Intercept As Decimal
Private m_Start As Decimal
Private m_End As Decimal
Private m_RSquared As Decimal
#End Region
#Region "Properties"
Public Property Slope() As Decimal
Get
Return m_Slope
End Get
Private Set
m_Slope = Value
End Set
End Property
Public Property Intercept() As Decimal
Get
Return m_Intercept
End Get
Private Set
m_Intercept = Value
End Set
End Property
Public Property Start() As Decimal
Get
Return m_Start
End Get
Private Set
m_Start = Value
End Set
End Property
Public Property [End]() As Decimal
Get
Return m_End
End Get
Private Set
m_End = Value
End Set
End Property
Public Property RSquared As Decimal
Get
Return m_RSquared
End Get
Set(value As Decimal)
m_RSquared = value
End Set
End Property
#End Region
#Region "New..."
Public Sub New(yAxisValues As IList(Of Decimal), xAxisValues As IList(Of Decimal))
Me.New(yAxisValues.[Select](Function(t, i) New Tuple(Of Decimal, Decimal)(xAxisValues(i), t)))
End Sub
Public Sub New(data As IEnumerable(Of Tuple(Of [Decimal], [Decimal])))
Dim cachedData = data.ToList()
Dim n = cachedData.Count
Dim sumX = cachedData.Sum(Function(x) x.Item1)
Dim sumX2 = cachedData.Sum(Function(x) x.Item1 * x.Item1)
Dim sumY = cachedData.Sum(Function(x) x.Item2)
Dim sumY2 = cachedData.Sum(Function(x) x.Item2 * x.Item2)
Dim sumXY = cachedData.Sum(Function(x) x.Item1 * x.Item2)
'b = (sum(x*y) - sum(x)sum(y)/n)
' / (sum(x^2) - sum(x)^2/n)
Slope = (sumXY - ((sumX * sumY) / n)) / (sumX2 - (sumX * sumX / n))
'a = sum(y)/n - b(sum(x)/n)
Intercept = (sumY / n) - (Slope * (sumX / n))
' r = (n * (Exy) - (Ex * Ey)) / (((n * (Ex2) - (Ex) ^ 2) ^ (1 / 2)) * ((n * (Ey2) - (Ey) ^ 2) ^ (1 / 2)))
RSquared = ((n * (sumXY) - (sumX * sumY)) / (((n * (sumX2) - (sumX) ^ 2) ^ (1 / 2)) * ((n * (sumY2) - (sumY) ^ 2) ^ (1 / 2)))) ^ 2
Start = GetYValue(cachedData.Min(Function(a) a.Item1))
[End] = GetYValue(cachedData.Max(Function(a) a.Item1))
End Sub
#End Region
#Region "Methods / Functions"
Public Function GetYValue(xValue As Decimal) As Decimal
Return Intercept + Slope * xValue
End Function
#End Region
End Class
Hopefully this will help someone!

VBA : For loop exiting without returning the value

I have the following piece for code to simulate stock prices using stochastic process
Function varswap1(s0, r0, sigma0, t) As Double
Rnd (-10)
Randomize (999)
Dim i As Integer, j As Integer, r As Double
Dim stock() As Double, dt As Double
Dim per As Integer
per = WorksheetFunction.Round(t * 252, 0)
ReDim stock(per)
stock(1) = s0
dt = 1 / 252
For i = 1 To per
stock(i + 1) = stock(i) * Exp((r0 - 0.5 * sigma0 ^ 2) * dt + sigma0 * Sqr(dt) * WorksheetFunction.NormSInv(Rnd()))
Next
varswap1 = WorksheetFunction.Average(stock)
End Function
In this code, I ran debugging by placing a break point at Next and the entire For loop is working absolutely fine. The problem is after completing the loop the function exits and #VALUE! error is displayed in the cell.
I am not able to figure out what is wrong with this code.
Will be thankful if anyone can help me with it.
Try this:
Const n As Integer = 252
Function varswap1(s0, r0, sigma0, t) As Double
Rnd (-10)
Randomize (999)
Dim i As Integer, j As Integer, r As Double
Dim stock() As Double, dt As Double
Dim per As Integer
per = WorksheetFunction.Round(t * n, 0)
ReDim stock(per)
stock(0) = s0 ' First item in the array has index 0
dt = 1# / n ' Avoid integer division, 1/252 = 0
For i = 1 To per
'Each stock depends on the previous stock value:
stock(i) = stock(i - 1) * Exp((r0 - 0.5 * sigma0 ^ 2) * dt + sigma0 * Sqr(dt) * WorksheetFunction.NormSInv(Rnd()))
Next
varswap1 = WorksheetFunction.Average(stock)
End Function
I saw two issues and one suggestion.
One is the array stock goes from 0..252 but you assign values to 1..253 so it crashes.
Also there is a possible integer division resulting in dt=0.0. I updated the definition to make the intent clear that the division is to be done after the conversion from integer to double. Lastly, I moved the magic number 252 to a constant.

Set VBA macro for Excel to run a series of Linear Equations by taking variable from several rows?

I've got a set of equations which I'd like to be repeated taking variables from the next row down for each of the columns at which each variable is located. I am a beginner, so my coding is probably not to scratch:
Sub Iteration()
Dim al, ab, ae As Double
Dim as1, as2 As Double
'etc
as1 = Range("CG7")
as2 = Range("CG8")
aA1 = Range("BQ7")
'etc
intCounter = 0
For intCounter = 1 To 10000
Let x = ((aN1 * 1000) - (as1 * aA1) + (as2 * aA2)) / (al * fc * ae * ab)
Let x2 = ((aN12 * 1000) - (as12 * aA12) + (as22 * aA22)) / (al2 * fc2 * ae2 * ab2)
Next
Sheets("Sheet1").Range("CJ7").Value = x
End Sub
I've done this for several variables which I've set as the range relative to each variable value. And then for the next row I've had to redo the whole equation and set the variables again for the next row down. Is there any way to set the variables (possibly with a relative cell reference?) which will skip to the cell in the next row for the next calculation? Consider also that there are 36 rows for calculation and about 9 variables!
If I understand you correctly, how about something like this:
Sub Iteration()
Dim al, ab, ae As Double
Dim as1, as2 As Double
'etc
intCounter = 0
For intCounter = 0 To 10000
as1 = Range("CG7").Offset(intCounter)
as2 = Range("CG8").Offset(intCounter)
aA1 = Range("BQ7").Offset(intCounter)
'etc
Let x = ((aN1 * 1000) - (as1 * aA1) + (as2 * aA2)) / (al * fc * ae * ab)
Let x2 = ((aN12 * 1000) - (as12 * aA12) + (as22 * aA22)) / (al2 * fc2 * ae2 * ab2)
Next
Sheets("Sheet1").Range("CJ7").Value = x
End Sub

Resources