I am working on a VBA project that fetches financial data from Bloomberg and calculates returns.
At the moment data for 2020 to 2022 is available.
How can I put a dynamic check in the code that checks data for 2023 is available and if it is then updates the calculation using data from 2021 to 2023? Thank you!!
Following is the code I am using right now:
Function getTotalGrowth(k As Integer)
Dim bbg As New BBG_Function
Dim gdpGrowth As Variant
ReDim indexData(5, 2)
indexData(1, 1) = "ECGDEU 20 Index"
indexData(2, 1) = "ECGDEU 21 Index"
indexData(3, 1) = "ECGDEU 22 Index"
indexData(4, 1) = "XYZ Curncy"
indexData(5, 1) = "ABC Index"
indexData(1, 2) = "ECGDUS 20 Index"
indexData(2, 2) = "ECGDUS 21 Index"
indexData(3, 2) = "ECGDUS 22 Index"
indexData(4, 2) = "XYZ Curncy"
indexData(5, 2) = "ABC Index"
gdpGrowth = ((1 + bbg.BDP(indexData(1, k), "PX_LAST") / 100) * (1 + bbg.BDP(indexData(2, k),
"PX_LAST") / 100) * (1 + bbg.BDP(indexData(3, k), "PX_LAST") / 100) ^ 3) ^ (1 / 5) - 1
End Function
How about this:
Dim y as Long, yStart as Long
if bbg.BDP("ECGDEU 23 Index", "PX_LAST") = 0 then
yStart=20
else
yStart=21
end if
for y=yStart to yStart+2
indexData(1, 1) = "ECGDEU " & y & " Index"
indexData(2, 1) = "ECGDEU " & y & " Index"
...
next
Related
i'm trying to visualize my data that i have stored in a word table. I can call the table data with ThisDocument.Tables(6).Cell(i,j).Range.Text. I tried to copy this data to the datasheet of the word graph, but this was unsuccessful.
Word table with data
The chart has to visualize the amount of currency in a timeline with time on the x-axis and the amount of money on the y-axis. I have allready inserted a chart in my word document but i need to access its datasheet.
Graph in word that i want to show
Does anyone have an example code that i can use to solve this problem?
I'm trying to build my code like this:
Dim graph As Word.Chart
Set graph = ThisDocument.InlineShapes(1).Chart
If Not Len(ThisDocument.Tables(3).Cell(2, 1).Range.Text) = 2 Then
Dim temp As String
For i = 0 To ThisDocument.Tables(3).Rows.Count - 2
graph.ChartData.Workbook.Worksheets(1).Cells(1 + i, 1).Value = Left(ThisDocument.Tables(3).Cell(2 + i, 3).Range.Text, Len(ThisDocument.Tables(3).Cell(2 + i, 3).Range.Text) - 2)
temp = Left(ThisDocument.Tables(3).Cell(2 + i, 4).Range.Text, Len(ThisDocument.Tables(3).Cell(2 + i, 4).Range.Text) - 2)
graph.ChartData.Workbook.Worksheets(1).Cells(1 + i, 2).Value = Right(temp, Len(temp) - 2)
Next i
End If
I'm trying to build my code like this:
Dim graph As Word.Chart
Set graph = ThisDocument.InlineShapes(1).Chart
If Not Len(ThisDocument.Tables(3).Cell(2, 1).Range.Text) = 2 Then
Dim temp As String
For i = 0 To ThisDocument.Tables(3).Rows.Count - 2
graph.ChartData.Workbook.Worksheets(1).Cells(1 + i, 1).Value = Left(ThisDocument.Tables(3).Cell(2 + i, 3).Range.Text, Len(ThisDocument.Tables(3).Cell(2 + i, 3).Range.Text) - 2)
temp = Left(ThisDocument.Tables(3).Cell(2 + i, 4).Range.Text, Len(ThisDocument.Tables(3).Cell(2 + i, 4).Range.Text) - 2)
graph.ChartData.Workbook.Worksheets(1).Cells(1 + i, 2).Value = Right(temp, Len(temp) - 2)
Next i
End If
While running this code to randomize some values I find that the all the cells have the same number. I believe I'm missing a standard concept but I can't seem to wrap my head around the issue.
Randomize
LWeekDay = Int((400 - 150 + 1) * Rnd + 200)
LWeekEnd = Int((600 - 200 + 1) * Rnd + 200)
For Y = 3 To 10
For X = 2 To 8
Cells(Y, X) = LWeekDay
Next X
Next Y
You are currently only calculating LWeekDay once, and then using that value for every cell.
I assume you want to assign a new value every time through the loop:
Randomize
For Y = 3 To 10
For X = 2 To 8
LWeekDay = Int((400 - 150 + 1) * Rnd + 200)
LWeekEnd = Int((600 - 200 + 1) * Rnd + 200)
Cells(Y, X) = LWeekDay
Next X
Next Y
I have issue with an Excel worksheet that contains the formula:
=Spline($D$9:$D$34,$J$9:$J$34,$D43)
Sheet works fine until I open this sheet on network drive and save it on local drive. Then this formula throws #NAME? error. Strange is, that error is gone when I click on line with formula to edit it and press enter (nothing changes in formula).
Have someone met similar issue?
I just found another information. Formula spline is defined in VBA module, not internal in Excel. It looks like. But issue is still here.
Function spline(periodcol As Range, ratecol As Range, x As Range)
Dim period_count As Integer
Dim rate_count As Integer
period_count = periodcol.Rows.Count
rate_count = ratecol.Rows.Count
If period_count <> rate_count Then
spline = "Error: Range count does not match"
GoTo endnow
End If
ReDim xin(period_count) As Single
ReDim yin(period_count) As Single
Dim c As Integer
For c = 1 To period_count
xin(c) = periodcol(c)
yin(c) = ratecol(c)
Next c
Dim n As Integer
Dim i, k As Integer
Dim p, qn, sig, un As Single
ReDim u(period_count - 1) As Single
ReDim yt(period_count) As Single
n = period_count
yt(1) = 0
u(1) = 0
For i = 2 To n - 1
sig = (xin(i) - xin(i - 1)) / (xin(i + 1) - xin(i - 1))
p = sig * yt(i - 1) + 2
yt(i) = (sig - 1) / p
u(i) = (yin(i + 1) - yin(i)) / (xin(i + 1) - xin(i)) - (yin(i) - yin(i - 1)) / (xin(i) - xin(i - 1))
u(i) = (6 * u(i) / (xin(i + 1) - xin(i - 1)) - sig * u(i - 1)) / p
Next i
qn = 0
un = 0
yt(n) = (un - qn * u(n - 1)) / (qn * yt(n - 1) + 1)
For k = n - 1 To 1 Step -1
yt(k) = yt(k) * yt(k + 1) + u(k)
Next k
Dim klo, khi As Integer
Dim h, b, a As Single
klo = 1
khi = n
Do
k = khi - klo
If xin(k) > x Then
khi = k
Else
klo = k
End If
k = khi - klo
Loop While k > 1
h = xin(khi) - xin(klo)
a = (xin(khi) - x) / h
b = (x - xin(klo)) / h
y = a * yin(klo) + b * yin(khi) + ((a ^ 3 - a) * yt(klo) + (b ^ 3 - b) * yt(khi)) * (h ^ 2) / 6
spline = y
endnow:
End Function
Try to add:
Application.Volatile
to your VBA code. Add this just below the Function statement to force a renewed calculation as soon as anything changes.
I have a function that only call the spline function when something happens..in this case when a division is less than zero..the inputs for the function is the same that for the spline function(called CUBIC), the spline was tested and works well when I call it direct! someone can help me?...follows a party of the code
Function NDF6(T As Variant, dias As Variant, taxas As Variant)
If T <= dias(1) Then
NDF6 = taxas(1)
Exit Function
End If
If T >= dias(tam) Then
NDF6 = taxas(tam)
Exit Function
End If
For i = 1 To tam
If T <= dias(i) Then
If taxas(i) / taxas(i - 1) < 0 Then
Call CUBIC(T, dias, taxas)
Else
i0 = ((taxas(i - 1) * dias(i - 1)) / 360) + 1
i1 = ((taxas(i - 1) * dias(i - 1)) / 360) + 1
irel = i1 / i0
i2 = irel ^ ((T - dias(i - 1)) / (dias(i) - dias(i - 1)))
i2rel = i2 * i0
i2real = i2rel - 1
NDF6 = i2real * (360 / T)
End If
Public Function CUBIC(x As Variant, input_column As Variant, output_column As Variant)
The function returns a zero value when I call the cubic function. The inputs are a cell with a value with a value equivalent a day and two arrays(DUONOFF and ONOFF) equivalent a days and rates, I call the function like:
NDF6(512,DUONOFF,ONOFF)
follows the CUBIC function
Public Function CUBIC(x As Variant, input_column As Variant, output_column As Variant)
'Purpose: Given a data set consisting of a list of x values
' and y values, this function will smoothly interpolate
' a resulting output (y) value from a given input (x) value
' This counts how many points are in "input" and "output" set of data
Dim input_count As Integer
Dim output_count As Integer
input_count = input_column.Rows.Count
output_count = output_column.Rows.Count
Next check to be sure that "input" # points = "output" # points
If input_count <> output_count Then
CUBIC = "Something's messed up! The number of indeces number of output_columnues don't match!"
GoTo out
End If
ReDim xin(input_count) As Single
ReDim yin(input_count) As Single
Dim c As Integer
For c = 1 To input_count
xin(c) = input_column(c)
yin(c) = output_column(c)
Next c
values are populated
Dim N As Integer 'n=input_count
Dim i, k As Integer 'these are loop counting integers
Dim p, qn, sig, un As Single
ReDim u(input_count - 1) As Single
ReDim yt(input_count) As Single 'these are the 2nd deriv values
N = input_count
yt(1) = 0
u(1) = 0
For i = 2 To N - 1
sig = (xin(i) - xin(i - 1)) / (xin(i + 1) - xin(i - 1))
p = sig * yt(i - 1) + 2
yt(i) = (sig - 1) / p
u(i) = (yin(i + 1) - yin(i)) / (xin(i + 1) - xin(i)) - (yin(i) - yin(i - 1)) / (xin(i) - xin(i - _1))
u(i) = (6 * u(i) / (xin(i + 1) - xin(i - 1)) - sig * u(i - 1)) / p
Next i
qn = 0
un = 0
yt(N) = (un - qn * u(N - 1)) / (qn * yt(N - 1) + 1)
For k = N - 1 To 1 Step -1
yt(k) = yt(k) * yt(k + 1) + u(k)
Next k
now eval spline at one point
Dim klo, khi As Integer
Dim h, b, a As Single
first find correct interval
klo = 1
khi = N
Do
k = khi - klo
If xin(k) > x Then
khi = k
Else
klo = k
End If
k = khi - klo
Loop While k > 1
h = xin(khi) - xin(klo)
a = (xin(khi) - x) / h
b = (x - xin(klo)) / h
y = a * yin(klo) + b * yin(khi) + ((a ^ 3 - a) * yt(klo) + (b ^ 3 - b) * yt(khi)) * (h ^ 2) _/ 6
CUBIC = y
out:
End Function
In VBA, I can easily pull in an sheet\range into an array, manipulate, then pass back to the sheet\range. I'm having trouble doing this in VB.Net though.
Here's my code.
Rng = .Range("a4", .Cells(.UsedRange.Rows.Count, .UsedRange.Columns.Count))
Dim SheetArray(,) As Object = DirectCast(Rng.Value(Excel.XlRangeValueDataType.xlRangeValueDefault), Object(,))
For X As Integer = 0 To SheetArray.GetUpperBound(0)
If IsNothing(SheetArray(X, 0)) Then Exit For
SheetArray(X, 6) = SheetArray(X, 3)
SheetArray(X, 7) = CDbl(SheetArray(X, 3).ToString) - CDbl(SheetArray(X, 1).ToString) - _
CDbl(SheetArray(X, 7).ToString)
For Y As Integer = 0 To 3
SheetArray(X, Y * 2 + 1) = Math.Round(CDbl(SheetArray(X, Y * 2 + 1).ToString), 3)
Next
If Math.Abs(CDbl(SheetArray(X, 7).ToString)) > 0.1 Then _
.Range(.Cells(X + 1, 1), .Cells(X + 1, 8)).Font.Color = -16776961
Next
I'm getting an error on the first If IsNothing(SheetArray(X, 0)) Then Exit For
line. It is telling me index is out of bounds of the array. Any idea why? The SheetArray object contains the data, but I just am not sure how to get to it.
In the For you have to loop from 0 to Count - 1:
For X As Integer = 0 To SheetArray.GetUpperBound(0) - 1
'...
Next
That will fix your problem.