Store value from custom function

smpatty08

Board Regular
Joined
May 16, 2014
Messages
155
I have a custom function that finds the coefficients of a quadratic equation and I am trying to find a way to declare as variable. Here is what I tried so far. I have a version of this macro that works, but it does so by manipulating the worksheet. I am trying to make all the calculation happen using arrays and then create a finished table at the end.

Code:
Sub Macro4()
Dim XArray, YArray As Variant
Dim StdCount, QuadA, QuadB, QuadC As Double


    StdCount = 8
    XArray = Range(Cells(5, 11), Cells(4 + StdCount, 11)).Value2
    YArray = Range(Cells(5, 6), Cells(4 + StdCount, 6)).Value2
    
    QuadA = Application.WorksheetFunction.QuadCoef(XArray, YArray, "a")
End Sub

Does anybody know a way to do this?
 

Excel Facts

Who is Mr Spreadsheet?
Author John Walkenbach was Mr Spreadsheet until his retirement in June 2019.
Should have put the custom function code

Code:
Function QuadCoef(x As Range, y As Range, coef As String) As DoubleDim XArray1() As Double
Dim YArray1() As Double
Dim cyarray() As Variant
Dim cxarray() As Variant
Dim rMax As Integer
Dim crMax As Integer


rMax = x.Count
crMax = rMax - WorksheetFunction.CountBlank(x)


ReDim XArray1(1 To crMax, 1 To 3) As Double
ReDim YArray1(1 To crMax, 1 To 1) As Double


'set values to array
cxarray() = x.Value
cyarray() = y.Value


'fill y and x array
Dim i As Integer
Dim T As Integer
T = 1
For i = 1 To rMax
       If IsNumeric(cxarray(i, 1)) = True And IsEmpty(cxarray(i, 1)) = False Then
          XArray1(T, 2) = cxarray(i, 1)
          YArray1(T, 1) = cyarray(i, 1)
          T = T + 1
          Else
          T = T
      End If
Next i


' Fill the first column of XArray1 with 1
For i = 1 To crMax
    XArray1(i, 1) = 1
Next i


'' fill 3rd column with x^2 in x array
For i = 1 To crMax
    XArray1(i, 3) = XArray1(i, 2) * XArray1(i, 2)
Next i


Dim j As Integer, m As Integer, N As Integer
Dim bArray, pArray, piArray
Dim qArray, xtArray
 
' Dimension the arrays:
ReDim xtArray(1 To 3, 1 To crMax) As Double
ReDim pArray(1 To 3, 1 To 3) As Double
ReDim piArray(1 To 3, 1 To 3) As Double
ReDim qArray(1 To 3, 1 To 1) As Double
ReDim bArray(1 To 3, 1 To 1) As Double


Call Transpose(XArray1, crMax, 3, xtArray)
Call Multiply(xtArray, 3, crMax, XArray1, 3, pArray)
Call Invert(pArray, 3, piArray)
Call Multiply(xtArray, 3, crMax, YArray1, 1, qArray)
Call Multiply(piArray, 3, 3, qArray, 1, bArray)


' Determines coefficient output
Select Case coef
  Case "c", "C"
      QuadCoef = bArray(1, 1)
  Case "b", "B"
      QuadCoef = bArray(2, 1)
  Case "a", "A"
      QuadCoef = bArray(3, 1)
  Case Else
  MsgBox " Select a,b, or c as coefficient)"
End Select


End Function
Sub Multiply(M1, r1, C1, M2, c2, MOut)
' Computes the product of two matrices: MOut = M1 times M2
'   r1: number of rows in M1
'   c1: number of columns in M1
'   c2: number of columns in M2
' M2 must have c1 rows
' MOut will have r1 rows and c2 columns
Dim j As Integer
Dim i As Long, k As Long


For i = 1 To r1
    For j = 1 To c2
        MOut(i, j) = 0
        For k = 1 To C1
            MOut(i, j) = MOut(i, j) + M1(i, k) * M2(k, j)
        Next k
    Next j
Next i


End Sub
Sub Transpose(m, r, c, MT)
' Computes the transpose MT of matrix M
'   r: number of rows in M
'   c: number of columns in M
' MT will have c rows and r columns
Dim i As Long, j As Long


For i = 1 To c
    For j = 1 To r
        MT(i, j) = m(j, i)
    Next j
Next i


End Sub
Sub Invert(m, nrc, MInv)
' The square input and output matrices are M and MInv
' respectively; nrc is the number of rows and columns in
' M and MInv
Dim i As Integer, icol As Integer, irow As Integer
Dim j As Integer, k As Integer, L As Integer, LL As Integer
Dim big As Double, dummy As Double
Dim N As Integer, pivinv As Double
Dim u As Double


N = nrc + 1
ReDim bb(1 To N, 1 To N) As Double
ReDim ipivot(1 To N) As Double
ReDim index(1 To N) As Double
ReDim indexr(1 To N) As Double
ReDim indexc(1 To N) As Double
u = 1


' Copy the input matrix in order to retain it
For i = 1 To nrc
    For j = 1 To nrc
        MInv(i, j) = m(i, j)
    Next j
Next i


' The following is the Gauss-Jordan elimination routine
' GAUSSJ from J. C. Sprott, "Numerical Recipes: Routines
' and Examples in BASIC", Cambridge University Press,
' Copyright (C)1991 by Numerical Recipes Software. Used by
' permission. Use of this routine other than as an integral
' part of the present book requires an additional license
' from Numerical Recipes Software. Further distribution is
' prohibited. The routine has been modified to yield
' double-precision results.
For j = 1 To nrc
    ipivot(j) = 0
Next j
For i = 1 To nrc
    big = 0
    For j = 1 To nrc
      If ipivot(j) <> u Then
        For k = 1 To nrc
          If ipivot(k) = 0 Then
            If Abs(MInv(j, k)) >= big Then
              big = Abs(MInv(j, k))
              irow = j
              icol = k
            End If
            ElseIf ipivot(k) > 1 Then Exit Sub
          End If
        Next k
      End If
    Next j
    ipivot(icol) = ipivot(icol) + 1
    If irow <> icol Then
        For L = 1 To nrc
            dummy = MInv(irow, L)
            MInv(irow, L) = MInv(icol, L)
            MInv(icol, L) = dummy
        Next L
        For L = 1 To nrc
            dummy = bb(irow, L)
            bb(irow, L) = bb(icol, L)
            bb(icol, L) = dummy
        Next L
    End If
    indexr(i) = irow
    indexc(i) = icol
    If MInv(icol, icol) = 0 Then Exit Sub
    pivinv = u / MInv(icol, icol)
    MInv(icol, icol) = u
    For L = 1 To nrc
        MInv(icol, L) = MInv(icol, L) * pivinv
        bb(icol, L) = bb(icol, L) * pivinv
    Next L
    For LL = 1 To nrc
        If LL <> icol Then
            dummy = MInv(LL, icol)
            MInv(LL, icol) = 0
            For L = 1 To nrc
                MInv(LL, L) = MInv(LL, L) - MInv(icol, L) * dummy
                bb(LL, L) = bb(LL, L) - bb(icol, L) * dummy
            Next L
        End If
    Next LL
Next i
For L = nrc To 1 Step -1
    If indexr(L) <> indexc(L) Then
        For k = 1 To nrc
            dummy = MInv(k, indexr(L))
            MInv(k, indexr(L)) = MInv(k, indexc(L))
            MInv(k, indexc(L)) = dummy
        Next k
    End If
Next L
Erase indexc, indexr, ipivot


End Sub
Function QuadCalc(a As Double, b As Double, c As Double, y As Double) As Double


QuadCalc = (-b + Sqr((b ^ 2) - (4 * a * (c - y)))) / (2 * a)


End Function
 
Upvote 0

Forum statistics

Threads
1,223,908
Messages
6,175,306
Members
452,633
Latest member
DougMo

We've detected that you are using an adblocker.

We have a great community of people providing Excel help here, but the hosting costs are enormous. You can help keep this site running by allowing ads on MrExcel.com.
Allow Ads at MrExcel

Which adblocker are you using?

Disable AdBlock

Follow these easy steps to disable AdBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the icon in the browser’s toolbar.
2)Click on the "Pause on this site" option.
Go back

Disable AdBlock Plus

Follow these easy steps to disable AdBlock Plus

1)Click on the icon in the browser’s toolbar.
2)Click on the toggle to disable it for "mrexcel.com".
Go back

Disable uBlock Origin

Follow these easy steps to disable uBlock Origin

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back

Disable uBlock

Follow these easy steps to disable uBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back
Back
Top