Storing and processing range values in an array - vba

While storing range values as a variant and looping through them i'm having trouble actually changing the value of, for example,
valsf(i, h) = (valsf(i - 1, h) + valsf(i + 1, h)) / 2
It will only change when I make it
Cells(i, h) = (valsf(i - 1, h) + valsf(i + 1, h)) / 2
Why is this?

Related

Issue in using VBA for Finite Difference Method

The question to be done
I have tried this out.
I have created few functions. I am confused in the remaining ones.
I have made the first function and stored the values of upper, lower and main matrix in my spreadsheet.
Function createFEMatrixDirichlet(a, C, Nx, h, dt)
Dim k As Integer
'Main
For k = 0 To Nx - 1
Cells(k + 2, 2).Value = 1 - dt * (((2 * a) / (h * h)) + x)
Next k
'Lower
For k = 0 To Nx - 2
Cells(k + 2, 1).Value = dt * (a / (h * h))
Next k
'Upper
For k = 0 To Nx - 3
Cells(k + 2, 3).Value = dt * (a / (h * h))
Next k
End Function
Nodes are generated similar way.
Function nodeGeneration(xa, xb, Nx, column)
Dim k As Integer
'Find h
h = (xb - xa) / Nx
'Generate Node
For k = 0 To Nx
Cells(k + 2, column).Value = xa + k * h
Next k
End Function
Initial condition are applied:
Function applyInitialCondition(Nx, column)
Dim k As Integer
For k = 0 To Nx
Cells(k + 2, column).Value = ((Cells(k + 2, 4)) + 2) / 2
Next k
End Function
Now to multiply I am a bit confused. My implementation is that I am trying to make the entire matrix and then multiply. However, there is no luck. Some or the other error pops up.
Also, I have no idea on how to implement the FETimeStep and then create a new subroutine to run the entire code.
Any leads?
Sample Input

Generating array of all possible combinations from array regardless of number of elements in VBA

I need to take an input of mins and maxes for multiple variables and generate an array containing each possible combination.
Example: Entering the array
[A min, A max
B min, B max]
should return
[A min, B min
A min, B max
A max, B min
A max, B max]
I was able to do this but only with under 3 variables but can't conveniently expand it. I can't figure out how to make it work for any amount of variables, like if there was a C that also has a max and min.
Does anyone have suggestions?
edit:
If this helps anyone, purpose of this function is to find the extremes of a variable based expression. The first array is generated from the variables included in the expression, then the variables are replaced with values from the second array. So essentially every is calculated to find the highest possible outcome and lowest possible outcome.
So an input that created the first array could have been something like: 'A+B'
Then, for each row in the second array, 'A' and 'B' would be substituted with the instructed value.
Here is a VBA function which can be used to solve one interpretation of your problem:
Function Products(A As Variant) As Variant
'A is assumed to be a 2-column 1-based array
'The function returns another 2-column 1-based array
'Where each successive 4 rows gives the Cartesian product
'of two of the rows of A, with the earlier row
'providing the first element and the latter row the second
Dim i As Long, j As Long, k As Long, n As Long
Dim P As Variant
n = UBound(A, 1)
ReDim P(1 To 2 * n * (n - 1), 1 To 2)
k = 1
For i = 1 To n - 1
For j = i + 1 To n
P(k, 1) = A(i, 1)
P(k, 2) = A(j, 1)
P(k + 1, 1) = A(i, 1)
P(k + 1, 2) = A(j, 2)
P(k + 2, 1) = A(i, 2)
P(k + 2, 2) = A(j, 1)
P(k + 3, 1) = A(i, 2)
P(k + 3, 2) = A(j, 2)
k = k + 4
Next j
Next i
Products = P
End Function
Used like: Range("C1:D12").Value = Products(Range("A1:B3").Value)

How can I write a code to define a range insdide a loop that will change its size?

I need to use two Loops and the easy part is to count how many times does a "submodul" repeats in a defined and known range ("B3","B18"), this means the quantity of elements each submodul has. The difficult part comes when trying to count how many times does a "position" repeats for each different "submodul", this is because the amount of elements of each "submodul" is different so I have to adjust a range in a especial Loop to calculate how many times does a specific element (=Position) repeats within a "submodul".
The specific part that I need help with is the following:
positionrepetition = Application.CountIf(Worksheets("Sheet2").range("cells(3 + x + y - 1, 3)", "cells(3 + x + y - 1 + submodulrepetition,3"), position)
If I can manage to write it in a correct format I believe it will work. The problem is that normally I only use the range function when I know that the range is fixed or known, it doesn´t have to be calculated. I normally write for example: Range("A1","F10").Select
As you can see this is a fixed range, so I imagined that instead of using the format of Range("A1", "F10") I could use the range function with the arguments ("Cells(1,1)","Cells(10,6)"). Please correct me if I´m wrong.
Here is the rest of the code for the Loop.
For x = 0 To numberofparts
If Cells(3 + x, 18) = "1" Then
submodul = Cells(3 + x, 2).Value
submodulrepetition = Application.CountIf(Worksheets("Sheet2").range("B3", "B18"), submodul)
For y = 1 To submodulrepetition
position = Cells(3 + x + y - 1, 3).Value
positionrepetition = Application.CountIf(Worksheets("Sheet2").range("cells(3 + x + y - 1, 3)", "cells(3 + x + y - 1 + submodulrepetition,3"), position)
Next
Else
End If
x = x + submodulrepetition - 1
Next
To explain a little more, all data is gathered from Excel Sheets:
-All Information is gathered from a Excel sheet
-The "submodules" are in column B and they are arranged in numerical order. Every submodul repeats in this column as many elements it has.
-The "positions" (elements of the submodules) are in column C and can also repeat in the same column and even in other "Submodul"s.
All help will be appreciated and I thank you in advance.
Alejandro Farina
Change your line:
positionrepetition = Application.CountIf(Worksheets("Sheet2").Range("cells(3 + x + y - 1, 3)", "cells(3 + x + y - 1 + submodulrepetition,3"), Position)
With :
positionrepetition = Application.CountIf(Worksheets("Sheet2").Range(Cells(3 + x + y - 1, 3), Cells(3 + x + y - 1 + submodulrepetition, 3), Position))
If the Range is going to Change by Column/Row use the following code to get the end of column or row:
Dim GetColEnd, GetRowEnd As Integer
GetColEnd = Sheets("Sheet_Name").Cells(1, .Columns.Count).End(xlToLeft).Column
GetRowEnd = Sheets("Sheet_Name").Cells(Rows.Count, 1).End(xlUp).Row
Use the GetColEnd GetRowEnd in your Range function for flexible Column\Row for example as follows:
Sheets("Sheet_Name").Range(Cells(1,1),Cells(GetRowEnd,GetColEnd)

textbox values won't assign to a variable in vba

I was running tests on my software today and found that some of the values it was producing weren't correct.
I decided to step through the code and noticed that the variables I had assigned to textbox values on my userform when hovered over said empty, even though when hovering over the textbox assigned to it, the value inputted by the user showed.
For Example,
n = BiTimeSteps_TextBox.Value
when hovered over
n = empty
even though
BiTimeSteps_TextBox.Value = 2
when hovered over.
So say I have a formula shortly after that says
d = n*2 ,
n when hovered over says empty and d is made 0 when it shouldn't be.
Someone told me if I switch it around to
BiTimeSteps_TextBox.Value = n
it should be recognised but it is still not.
What could possibly be causing this?
See full code below: (it aims to price options using the binomial tree pricing method)
S = BiCurrentStockPrice_TextBox.Value
X = BiStrikePrice_TextBox.Value
r = BiRisk_Free_Rate_TextBox.Value
T = BiexpTime_TextBox.Value
Sigma = BiVolatility_TextBox.Value
n = BiTimeSteps_TextBox.Value
Dim i, j, k As Integer
Dim p, V, u, d, dt As Double
dt = T / n ' This finds the value of dt
u = Exp(Sigma * Sqr(dt)) 'formula for the up factor
d = 1 - u 'formula for the down factor
'V value of option
'array having the values
Dim bin() As Double 'is a binomial arrays, it stores the value of each node, there is a loop
'work out the risk free probability
p = (1 + r - d) / (u - d)
'probability of going up
ReDim bin(n + 1) As Double
'it redims the array, and n+1 is used because it starts from zero
'------------------------------------------------------------------------------------------------------------------------------
''European Call
If BiCall_CheckBox = True Then
For i = 0 To n 'payoffs = value of option at final time
bin(i + 1) = Application.WorksheetFunction.Max(0, (u ^ (n - i)) * (d ^ i) * S - X)
'It takes the max payoff or 0
Cells(i + 20, n + 2) = bin(i + 1) 'to view payoffs on the isolated column on the right
Next i
End If
'european put
If BiPut_CheckBox = True Then
For i = 0 To n 'payoffs = value of option at final time
bin(i + 1) = Application.WorksheetFunction.Max(0, X - (S * (u * (n - i)) * (d * i)))
' European Put- It takes the max payoff or 0
Cells(i + 20, n + 2) = bin(i + 1) 'to view payoffs on the isolated column on the right
Next i
End If
For k = 1 To n 'backward column loop
For j = 1 To (n - k + 1) 'loop down the column loop
bin(j) = (p * bin(j) + (1 - p) * bin(j + 1)) / (1 + r)
Cells(j + 19, n - k + 2) = bin(j)
'' print the values along the column, view of tree
Next j
Next k
Worksheets("Binomial").Cells(17, 2) = bin(1) ' print of the value V
BiOptionPrice_TextBox = bin(1)

What is wrong in this command "series(diff(f(z), z), z = 1, 2)" in Maple?

Assume f(z) is an arbitrary function of z. In Maple, if we want to get the series expansion of diff(f(z),z) at z=0, we can use
series(diff(f(z), z), z = 0, 2)
The output is "(D(f))(0)+...". However, we cannot obtain the series expansion of diff(f(z),z) at z=1 by
series(diff(f(z), z), z = 1, 2)
The output is "Error, (in PDEtools/useD/diff_to_D) invalid input: diff received z+1, which is not valid for its 2nd argument." What is wrong, and how to get the series expansion of an expression that contains derivatives of a function such as diff(f(z),z)?
It looks like a bug.
Workarounds might include,
series(D(f)(z), z = 1, 2);
/ 2\
D(f)(1) + ##(D, 2)(f)(1) (z - 1) + O\(z - 1) /
or (with a different expansion order option),
MultiSeries:-series(diff(f(z), z), z = 1, 3);
/ 2\
D(f)(1) + ##(D, 2)(f)(1) (z - 1) + O\(z - 1) /