View Full Version : [SOLVED:] Help with equation that has several inputs which vary in value.
Itakeyokes
02-13-2018, 11:10 AM
Hi,
I have an equation in VBA as follows:
answer = A * B * C * ((1 - D) ^ (3 / 2) * (1 + E * (1 - F) ^ 3) / G ^ 2)
where A, B, D, E, F & G are defined in a worksheet and are brought in using Worksheets(1).Range("B2") for example. This works fine for the purpose.
However, C and G both have minimum and maximum values. I wish to input them incrementally into the above equation.
For example:
Cmin = 0, Cmax = 6, Increment = 2. Here I have 4 inputs (0, 2, 4, 6)
Gmin = 0, Gmax = 3, Increment = 1. Here I have 4 inputs (0, 1, 2, 3)
This means I will have 16 different solutions to the problem.
I could set up the equation 16 times, but this is not efficient.
How can I incorporate some function, maybe some sort of matrix perhaps, so that running the equation once will result in 16 answers being produced.
Any tips, pointers etc will be much appreciated.
Best Regards,
ITY
mancubus
02-13-2018, 01:11 PM
if G is zero it will throw run-time error 11, "Division by 0"
i have created a UDF to include all C and G values in an array based on min, max and increment numbers.
you should test it with different possible values.
i don't find it reliable even it worked with your example values.
this is the udf:
Function valzArray(min As Long, max As Long, inc As Long)
    Dim i As Long, num As Long
    Dim TempArr As Variant
    
    num = max \ inc
    ReDim TempArr(num)
    
    For i = 0 To num
        TempArr(i) = min + inc * i
    Next
    
    valzArray = TempArr
End Function
it worked with your example numbers 
this is a sample code to test the udf:
Sub test()
    Dim tArr As Variant
    
    tArr = valzArray(0, 3, 1)
    
    For i = LBound(tArr) To UBound(tArr)
        Debug.Print tArr(i)
    Next
End Sub
and this my code for your requirement so far...
Sub vbax_61997_array_elements_input_equation()
    Dim cValz, gValz, answers
    Dim cElements As Long, gElements As Long
    Dim i As Long, j As Long, k As Long
    
    Dim A As Double, B As Double, D As Double, E As Double, F As Double
    
    A = 1
    B = 2
    D = 0.04
    E = 5
    F = 0.06
    
    cValz = valzArray(0, 3, 1)
    gValz = valzArray(0, 6, 2)
    
    cElements = UBound(cValz) + 1
    gElements = UBound(gValz) + 1
    
    ReDim answers(cElements * cElements - 1)
    
    For i = 0 To cElements - 1
        For j = 0 To gElements - 1
            On Error Resume Next
            answers(k) = A * B * cValz(i) * ((1 - D) ^ (3 / 2) * (1 + E * (1 - F) ^ 3) / gValz(j) ^ 2)
            If Err Then
                Err.Clear
                answers(k) = 0 'when G is 0 you'll get RTE 11, division by 0. when this is the case make the answer equal to 0
            End If
            k = k + 1
        Next j
    Next i
    
    Range("F1").Resize(UBound(answers) + 1) = Application.Transpose(answers) 'write the results to worksheet
End Sub
i have used many variables for better understanding...
you may use Range("A1").Value for A, for example
mancubus
02-14-2018, 01:15 AM
change
ReDim answers(cElements * cElements - 1)
to
ReDim answers(cElements * gElements - 1)
Itakeyokes
02-14-2018, 06:49 AM
Thank you very much.
I modify this to meet the needs of the project. but from an initial look over the script it seems to be fit for purpose.
I will update with any progress.
Itakeyokes
02-14-2018, 10:47 AM
As another use of this code I wish to do something similar but with only one set of varying input, i.e d ranging from 5.00E-7 to 2.05E-5 in increments of 5.00-E6
I modified the code as follows, but when using the above values it would run with ' Run-time error '11': Division by zero '  despite the denominator not equalling zero.
Sub array_elements_input_equation()
    Dim dValz, answers
    Dim dElements As Long
    Dim i As Long, k As Long
    
    Dim A As Double, B As Double, C As Double, D As Double
    
    A = Worksheets(1).Range("C4")
    B = Worksheets(1).Range("C5")
    C = Worksheets(1).Range("C6")
    E = Worksheets(1).Range("C7")
    
    dValz = valzArray(1, 10, 1)
    
    dElements = UBound(dValz) + 1
    
    ReDim answers(dElements - 1)
    
    For i = 0 To dElements - 1
            answers(k) = (A * B * C) / (3 * WorksheetFunction.Pi * E * dValz(i))
            If Err Then
                Err.Clear
                answers(k) = 0
            End If
            k = k + 1
    Next i
    
    Range("J4").Resize(UBound(answers) + 1) = Application.Transpose(answers)
End Sub
With larger max, min, and increment values implemented (as shown) it works. 
Any ideas on how to be able to use much smaller values?
mancubus
02-14-2018, 02:34 PM
pls enclose your code with code tags. (see #1 in my sidnature.) 
change the data types to double and integer division \ to division / :
Function valzArrayExp(min As Double, max As Double, inc As Double)
    Dim i As Double, num As Double
    Dim TempArr As Variant
    
    num = max / inc
    ReDim TempArr(num)
    
    For i = 0 To num
        TempArr(i) = min + inc * i
    Next
    
    valzArrayExp = TempArr
End Function
test:
Sub test()
    Dim i As Long
    Dim tArr As Variant
    
    tArr = valzArrayExp(0.0000005, 0.0000205, 0.000005)
    
    For i = LBound(tArr) To UBound(tArr)
        Debug.Print tArr(i)
    Next
End Sub
Itakeyokes
02-15-2018, 05:30 AM
Thank you good sir.
mancubus
02-15-2018, 07:03 AM
you are welcome.
Itakeyokes
02-15-2018, 08:10 AM
I have encountered a further problem.
The final 3 solutions are resulting in errors, ie resulting in a zero value solution.
When solving individually this does not occur.
I edited the first part as the minimum value is no longer 0.
Function valzArray(min As Double, max As Double, inc As Double)
    Dim i As Double, num As Double
    Dim TempArr As Variant
    
    num = (max / inc) - (min / inc)
    ReDim TempArr(num)
    
    For i = 0 To num
        TempArr(i) = min + inc * i
    Next
    
    valzArray = TempArr
End Function
Sub array_elements_input_equation_Image()
    Dim dValz, vValz, answers
    Dim dElements As Double, vElements As Double
    Dim i As Double, j As Double, k As Double
    
    Dim A As Double, B As Double, C As Double, D As Double, E As Double, F As Double, G As Double
    
    A = Worksheets(1).Range("C7") ' value is 2
    B = Worksheets(1).Range("C8") ' value is 3
    C = Worksheets(1).Range("C10") ' value is 5
    D = Worksheets(1).Range("C11") ' value is 6
    E = Worksheets(1).Range("C9") ' value is 4
    F = Worksheets(1).Range("C6") ' value is 11
    G = Worksheets(1).Range("C12") ' value is 7
    
    
    dValz = valzArray(Worksheets(1).Range("F9"), Worksheets(1).Range("F8"), Worksheets(1).Range("F10")) ' (0.0000005, 0.0000205, 0.000005)
    vValz = valzArray(Worksheets(1).Range("F5"), Worksheets(1).Range("F4"), Worksheets(1).Range("F6")) ' (10 , 20, 5)
    
    dElements = UBound(dValz) + 1
    vElements = UBound(vValz) + 1
    
    ReDim answers(dElements * vElements - 1)
    
    For i = 0 To dElements - 1
        For j = 0 To vElements - 1
            On Error Resume Next
            answers(k) = ((A - B) / (A + 2 * B)) * ((C * D ^ 2) / (3 * (WorksheetFunction.Pi) ^ 2 * E * dValz(i) * F ^ 2 * vValz(j)))
            If Err Then   ' an error is occuring for final 3 solutions
                Err.Clear
                answers(k) = 0
            End If
            k = k + 1
        Next j
    Next i
    
    Range("R4").Resize(UBound(answers) + 1) = Application.Transpose(answers)
End Sub
As there is no division by zero the error response part of the code can be removed?
mancubus
02-15-2018, 02:23 PM
Function valzArrayExp(min As Double, max As Double, inc As Double)
    Dim i As Double, num As Double
    Dim TempArr As Variant
    
    num = (max - min) / inc
    ReDim TempArr(num)
    
    i = 0
    Do Until i = num + 1
        TempArr(i) = min + inc * i
        i = i + 1
    Loop
    
    valzArrayExp = TempArr
End Function
Sub array_elements_input_equation_Image()
    Dim dValz, vValz, answers
    Dim dElements As Double, vElements As Double
    Dim i As Double, j As Double, k As Double
    
    Dim A As Double, B As Double, C As Double, D As Double, E As Double, F As Double, G As Double
    
    With Worksheets(1)
        A = .Range("C7") ' value is 2
        B = .Range("C8") ' value is 3
        C = .Range("C10") ' value is 5
        D = .Range("C11") ' value is 6
        E = .Range("C9") ' value is 4
        F = .Range("C6") ' value is 11
        G = .Range("C12") ' value is 7
        dValz = valzArrayExp(.Range("F9"), .Range("F8"), .Range("F10")) ' (0.0000005, 0.0000205, 0.000005)
        vValz = valzArrayExp(.Range("F5"), .Range("F4"), .Range("F6")) ' (10 , 20, 5)
    End With
    
    dElements = UBound(dValz) + 1
    vElements = UBound(vValz) + 1
    
    ReDim answers(dElements * vElements - 1)
    
    For i = 0 To dElements - 1
        For j = 0 To vElements - 1
            answers(k) = ((A - B) / (A + 2 * B)) * ((C * D ^ 2) / (3 * (WorksheetFunction.Pi) ^ 2 * E * dValz(i) * F ^ 2 * vValz(j)))
            If Err Then   ' an error is occuring for final 3 solutions
                Err.Clear
                answers(k) = 0
            End If
            k = k + 1
        Next j
    Next i
    
    Range("R4").Resize(UBound(answers) + 1) = Application.Transpose(answers)
End Sub
Itakeyokes
02-16-2018, 02:08 PM
This solves that issue. 
I have the following code which inputs a list of inputs specified in a column into an equation and then displays the set of solutions in another specified column.
Sub test()
    
        Dim D As Double
    
        lastrow = Cells(Rows.Count, "L").End(xlUp).Row
        inarr = Range(Cells(1, 1), Cells(lastrow, 12))
        For i = 4 To lastrow
            D = inarr(i, 12)
            Cells(i, 16) = 1 + (20 * D) / 5           'example equation
        Next i
    
    End Sub
I have combined this with the code which brings in values incrementally.
My aim is to incorporate both codes into one function so that I can bring in a range of inputs for one part of an equation, whilst also bringing in an input rising incrementally for another part of the same equation.
 Sub array_elements_and_Changing_input_equation_Peclet_Number()
    Dim vValz, answers
    Dim vElements As Double
    Dim i As Double, k As Double
    
    Dim A As Double, D As Double
    
    With Worksheets(1)
        A = .Range("C6")
        vValz = valzArrayExp(.Range("F5"), .Range("F4"), .Range("F6"))
    End With
    
    lastrow = Cells(Rows.Count, "L").End(xlUp).Row
    inarr = Range(Cells(1, 1), Cells(lastrow, 12))
    For i2 = 4 To lastrow
        D = inarr(i2, 12)
    Next i2
    
    vElements = UBound(vValz) + 1
    
    ReDim answers(vElements - 1)
    
    For i = 0 To vElements - 1
            answers(k) = (vValz(i) * A) / D
            If Err Then
                Err.Clear
                answers(k) = 0
            End If
            k = k + 1
    Next i
    
    Range("M4").Resize(UBound(answers) + 1) = Application.Transpose(answers)
End Sub
This does not produce any errors, but it does not run as required.
Thank you.
Itakeyokes
02-17-2018, 07:09 AM
I have solved this issue.
Powered by vBulletin® Version 4.2.5 Copyright © 2025 vBulletin Solutions Inc. All rights reserved.