VBA function is not saved - excel

I have written my own function for computation have to do very often.
The problem is that when I write it to the xlam file were all my functions are stored
this particular function is not saved. After closing EXCEL and opening it again it is disappeared.
I have nailed the problem down to the decision that is wrong with code. But so far I could not figure out what is wrong with my code.
Here is my code.
Function isotpologues(R_13 As Variant, R_17 As Variant, R_18 As Variant, u_r13 As Variant, u_r17 As Variant, u_r18 As Variant) As Variant()
Dim results As Variant
ReDim results(1 To 11, 1 To 3)
results(1, 1) = "R_12_16_17"
results(2, 1) = "R_12_16_18"
results(3, 1) = "R_12_17_17"
results(4, 1) = "R_12_17_18"
results(5, 1) = "R_12_18_18"
results(6, 1) = "R_13_16_16"
results(7, 1) = "R_13_16_17"
results(8, 1) = "R_13_16_18"
results(9, 1) = "R_13_17_17"
results(10, 1) = "R_13_17_18"
results(11, 1) = "R_13_18_18"
results(1, 2) = 2 * R_17
results(2, 2) = 2 * R_18
results(3, 2) = R_17 ^ 2
results(4, 2) = R_17 * R_18 * 2
results(5, 2) = R_18 * R_18
results(6, 2) = R_13
results(7, 2) = R_13 * R_17 * 2
results(8, 2) = R_13 * R_18 * 2
results(9, 2) = R_13 * R_17 ^ 2
results(10, 2) = R_13 * R_17 * R_18 * 2
results(11, 2) = R_13 * R_18 * R_18
results(1, 3) = 2 * (u_r17) * 2
results(2, 3) = 2 * (u_r18) * 2
results(3, 3) = 2 * (R_17) * (u_r17) * 2
results(4, 3) = (4 * R_17 ^ 2 * u_r18 ^ 2 + 4 * R_18 ^ 2 * u_r17 ^ 2) ^ 0.5 * 2
results(5, 3) = 2 * (R_18) * (u_r18) * 2
results(6, 3) = (u_r13) * 2
results(7, 3) = (4 * R_13 ^ 2 * u_r17 ^ 2 + 4 * R_17 ^ 2 * u_r13 ^ 2) ^ 0.5 * 2
results(8, 3) = (4 * R_13 ^ 2 * u_r18 ^ 2 + 4 * R_18 ^ 2 * u_r13 ^ 2) ^ 0.5 * 2
results(9, 3) = (4 * R_13 ^ 2 * R_17 ^ 2 * u_r17 ^ 2 + R_17 ^ 4 * u_r13 ^ 2) ^ 0.5 * 2
results(10, 3) = (4 * R_13 ^ 2 * R_17 ^ 2 * u_r18 ^ 2 + 4 * R_13 ^ 2 * R_18 ^ 2 * u_r17 ^ 2 + 4 * R_17 ^ 2 * R_18 ^ 2 * u_r13 ^ 2) ^ 0.5 * 2
results(11, 3) = (4 * R_13 ^ 2 * R_18 ^ 2 * u_r18 ^ 2 + R_18 ^ 4 * u_r13 ^ 2) ^ 0.5 * 2
isotpologues = results
End Function

Related

UDF value error for complex itterative function

I want to create an UDF for my excel worksheet. However when I select my input for my UDF I get a value error. Can someone help me?
Code and images below:
code:
Public Function pipediameter(Pth As Double) As Double
Dim D As Double
p = 150
Tv = 30
T = 55
k = 0.000045
vi = 4
a = (1.729 * (10 ^ (-6))) / ((1 + (T / 25)) ^ 1.165)
rho = 988
Cp = 4180
di = 1
i = 1
While i <= 10
v = 4 * Pth / (3.14 * di ^ 2 * Cp * rho * Tv)
Re = v * di / vi
B1 = (0.774 * Log(Re) - 1.41) / (1 + 1.32 * Sqr(k / di))
B2 = ((k * Re) / (3.7 * di)) + (2.51 * B1)
Y = (B1 - ((B1 + (2 * (Log(B2 / Re) / Log(10)))) / (1 + (2.18 / B2)))) ^ (-2)
D = (((8 * Y) / (p * rho)) * ((Pth) / (3.14 * Cp * Tv)) ^ 2) ^ 0.2
di = D
i = i + 1
Wend
pipediameter = D
End Function

Python - Create a new field in Pandas df with result of a scipy function

I have a pandas df that contains fields A, B, and C. I have a scipy minimization function that uses A, B, and C, and returns x. I want to add the value of x as new field for each row in the same df. I have tested the scipy function separately on single values of A, B, and C entered directly as values instead of as df['name'] and it works, returning the value of x. The code does not work when I try to operate on the entire df. Any ideas? Each of A, B, and C are Float64 in the df. Here is the error message:
Here is the code:
from scipy.optimize import minimize_scalar
import math
# set parameters
current_price_per_share = df['share_price']
shares_outstanding_in_millions = df['shares_(diluted)'] / 1000000
owners_income = df['owners_income'] / 1000000
def growth_needed(x, current_price_per_share, shares_outstanding_in_millions, owners_income):
# set growth rates and cost of capital
fcf_growth_1_to_5 = x / 100
fcf_growth_6_to_10 = fcf_growth_1_to_5 / 2 # half the rate of year 1-5
terminal_growth_rate = .03 # constant
cost_of_capital = .1 #constant
# calculate ten years of Free Cash Flow and the Terminal Value
FCF_01 = owners_income * (1 + fcf_growth_1_to_5)
FCF_02 = FCF_01 * (1 + fcf_growth_1_to_5)
FCF_03 = FCF_02 * (1 + fcf_growth_1_to_5)
FCF_04 = FCF_03 * (1 + fcf_growth_1_to_5)
FCF_05 = FCF_04 * (1 + fcf_growth_1_to_5)
FCF_06 = FCF_05 * (1 + fcf_growth_6_to_10)
FCF_07 = FCF_06 * (1 + fcf_growth_6_to_10)
FCF_08 = FCF_07 * (1 + fcf_growth_6_to_10)
FCF_09 = FCF_08 * (1 + fcf_growth_6_to_10)
FCF_10 = FCF_09 * (1 + fcf_growth_6_to_10)
term_value = (FCF_10 * (1 + terminal_growth_rate)) / (cost_of_capital - terminal_growth_rate)
# calcuate the Present Value for each period
PV_01 = FCF_01 * (1 /(( 1 + cost_of_capital) ** 1))
PV_02 = FCF_02 * (1 /(( 1 + cost_of_capital) ** 2))
PV_03 = FCF_03 * (1 /(( 1 + cost_of_capital) ** 3))
PV_04 = FCF_04 * (1 /(( 1 + cost_of_capital) ** 4))
PV_05 = FCF_05 * (1 /(( 1 + cost_of_capital) ** 5))
PV_06 = FCF_06 * (1 /(( 1 + cost_of_capital) ** 6))
PV_07 = FCF_07 * (1 /(( 1 + cost_of_capital) ** 7))
PV_08 = FCF_08 * (1 /(( 1 + cost_of_capital) ** 8))
PV_09 = FCF_09 * (1 /(( 1 + cost_of_capital) ** 9))
PV_10 = FCF_10 * (1 /(( 1 + cost_of_capital) ** 10))
PV_TV = term_value * (1 /(( 1 + cost_of_capital) ** 11))
#sum the Present Values and calculate the value per share
intrinsic_value = PV_01 + PV_02 + PV_03 + PV_04 + PV_05 + PV_06 + PV_07 + PV_08 + PV_09 + PV_10 + PV_TV
intrinsic_value_per_share = intrinsic_value / shares_outstanding_in_millions
# calculate the growth rate in year 1-5 needed to match the current share price
# the square and square root are to force to zero before adding back the growth rate
return ((math.sqrt((intrinsic_value_per_share - current_price_per_share) ** 2)) + x )
res = minimize_scalar(growth_needed, method='bounded', bounds=(-50, 100), args=(current_price_per_share, shares_outstanding_in_millions, owners_income,))
# notice the trailing comma in the Args function to make it a tuple
df['implied_growth'] = res.x / 100

Why function gives #value even though msgbox show right calculated value

I am creating a function that calculate the input from an Excel spreadsheet. However, the function is returning #value!. When I checked via MsgBox and debug Watch, the function is able to calculate a correct value.
Public Function pT_Flash_PR(comp, zComp, Temp, Pres) As Variant
NC = UBound(comp) - LBound(comp) + 1
Dim VapFrac As Variant
ReDim Tc(1 To NC)
ReDim Pc(1 To NC)
ReDim w(1 To NC)
ReDim Keq(1 To NC)
ReDim xComp(1 To NC)
ReDim yComp(1 To NC)
ReDim acrit(1 To NC)
ReDim bCrit(1 To NC)
ReDim Kappa(1 To NC)
ReDim alpha(1 To NC)
ReDim PR_Kij(1 To NC, 1 To NC)
ReDim psi_Liq(1 To NC)
ReDim psi_Vap(1 To NC)
ReDim phi_Liq(1 To NC)
ReDim phi_Vap(1 To NC)
ReDim Keq_New(1 To NC)
ReDim fug_Liq(1 To NC)
ReDim fug_Vap(1 To NC)
Dim ResSum(1 To 2) As Double
comp = Application.Transpose(comp)
zComp = Application.Transpose(zComp)
pSat_coeff_Range = Sheets("Database").Range("c3:L18")
PR_Kij_Database = Sheets("Database").Range("y3:an18")
VapFrac = 0.5
dVapFrac = 0.001
RConst = 8.31446261815324
For j = 1 To NC
For i = 1 To NC
rowNum = Application.Match(comp(i), Worksheets("Database").Range("x3:x18"), 0)
ColNum = Application.Match(comp(j), Worksheets("Database").Range("y2:AN2"), 0)
PR_Kij(i, j) = Application.Index(PR_Kij_Database, rowNum, ColNum)
Tc(i) = Application.WorksheetFunction.VLookup(comp(i), pSat_coeff_Range, 8, False) 'Tc in K
Pc(i) = Application.WorksheetFunction.VLookup(comp(i), pSat_coeff_Range, 9, False) * 1000
w(i) = Application.WorksheetFunction.VLookup(comp(i), pSat_coeff_Range, 10, False)
Keq(i) = Pc(i) / Pres * Exp(5.37 * (1 + w(i)) * (1 - Tc(i) / Temp))
Next
Next
For iter02 = 1 To 100
For iter01 = 1 To 100
For j = 1 To 2
VapFrac = VapFrac + (j - 1) * dVapFrac
For i = 1 To NC
Res = zComp(i) * (Keq(i) - 1) / (1 + VapFrac * (Keq(i) - 1))
ResSum(j) = ResSum(j) + Res
Next
Next
dResSum = 1 / dVapFrac * (ResSum(2) - ResSum(1))
VapFracNew = VapFrac - ResSum(1) / dResSum
Dif = Abs(VapFracNew - VapFrac)
If (Dif < 0.00000001) Then
Exit For
End If
VapFrac = VapFracNew
Next iter01
a_alpha_mixL = 0
bmixL = 0
a_alpha_mixV = 0
bmixV = 0
For i = 1 To NC
xComp(i) = zComp(i) / (1 + VapFrac * (Keq(i) - 1))
yComp(i) = zComp(i) * Keq(i) / (1 + VapFrac * (Keq(i) - 1))
acrit(i) = 0.45724 * RConst ^ 2 * Tc(i) ^ 2 / Pc(i) 'ai = 0.45724*R^2*Tci^2/Pci
bCrit(i) = 0.0778 * RConst * Tc(i) / Pc(i) 'bi = 0.07780*R*Tci/Pci
Kappa(i) = 0.37464 + 1.5422 * w(i) - 0.26992 * w(i) ^ 2 'Kappai = 0.3796 + 1.5422*wi - 0.2699*wi^2
alpha(i) = (1 + Kappa(i) * (1 - (Temp / Tc(i)) ^ 0.5)) ^ 2 'alphai = [1+mi*(1-sqrt(Temp/Tci)]^2
Next
For i = 1 To NC
'Calculation OF a*alpha_mix abd bmix for Liquid
bmixL = bmixL + xComp(i) * bCrit(i)
For j = 1 To NC
a_alpha_mixL = a_alpha_mixL + xComp(i) * xComp(j) * (acrit(i) * acrit(j) * alpha(i) * alpha(j)) ^ 0.5 * (1 - PR_Kij(i, j))
Next
'Calculation OF a*alpha_mix abd bmix for Vapour
bmixV = bmixV + yComp(i) * bCrit(i)
For j = 1 To NC
a_alpha_mixV = a_alpha_mixV + yComp(i) * yComp(j) * (acrit(i) * acrit(j) * alpha(i) * alpha(j)) ^ 0.5 * (1 - PR_Kij(i, j))
Next
Next
'Calculation A AND B constant for Compressibility Equation
ALPR = a_alpha_mixL * Pres / (RConst * Temp) ^ 2
BLPR = bmixL * Pres / (RConst * Temp)
AVPR = a_alpha_mixV * Pres / (RConst * Temp) ^ 2
BVPR = bmixV * Pres / (RConst * Temp)
'Iteration of Compressibility Equation for Liquid Phase
ZLiq = 0
For k = 1 To 100
Z = ZLiq
ZForm = Z ^ 3 + (BLPR - 1) * Z ^ 2 + Z * (ALPR - 3 * BLPR ^ 2 - 2 * BLPR) - (ALPR * BLPR - BLPR ^ 2 - BLPR ^ 3)
dZ = 0.0001
Z = ZLiq + dZ
ZFormdZ = Z ^ 3 + (BLPR - 1) * Z ^ 2 + Z * (ALPR - 3 * BLPR ^ 2 - 2 * BLPR) - (ALPR * BLPR - BLPR ^ 2 - BLPR ^ 3)
ZLiq = Z - ZForm / ((ZFormdZ - ZForm) / dZ)
EpsZLiq = Abs(ZLiq - Z)
If (EpsZLiq < 0.0000001) Then
Exit For
End If
Next
'Iteration of Compressibility Equation for Vapour Phase
ZVap = 1
For k = 1 To 100
Z = ZVap
ZForm = Z ^ 3 + (BVPR - 1) * Z ^ 2 + Z * (AVPR - 3 * BVPR ^ 2 - 2 * BVPR) - (AVPR * BVPR - BVPR ^ 2 - BVPR ^ 3)
dZ = 0.0001
Z = ZVap + dZ
ZFormdZ = Z ^ 3 + (BVPR - 1) * Z ^ 2 + Z * (AVPR - 3 * BVPR ^ 2 - 2 * BVPR) - (AVPR * BVPR - BVPR ^ 2 - BVPR ^ 3)
ZVap = Z - ZForm / ((ZFormdZ - ZForm) / dZ)
EpsZVap = Abs(ZVap - Z)
If (EpsZVap < 0.0000001) Then
Exit For
End If
Next
'Calculation of Fug Coefficent for Liq and Gas
EpsK = 0
For i = 1 To NC
' Calculation of psi Liq for individual compoennt for Fug Coefficient Eq
psi_Liq(i) = 0
For j = 1 To NC
psi_Liq(i) = psi_Liq(i) + xComp(j) * (acrit(i) * acrit(j) * alpha(i) * alpha(j)) ^ 0.5 * (1 - PR_Kij(i, j))
Next
' Calculation of Liquid Fug Coefficient, PhiL for individual component
phi_Liq(i) = Exp(bCrit(i) * (ZLiq - 1) / bmixL - logE(ZLiq - BLPR) - ALPR / 8 ^ 0.5 / (BLPR) * (2 * psi_Liq(i) / a_alpha_mixL - bCrit(i) / bmixL) * logE((ZLiq + BLPR * (1 + 2 ^ 0.5)) / (ZLiq + BLPR * (1 - 2 ^ 0.5))))
Cells(i, 17) = PhiL
' Calculation of psi Vap for individual compoennt for Fug Coefficient Eq
psi_Vap(i) = 0
For j = 1 To NC
psi_Vap(i) = psi_Vap(i) + yComp(j) * (acrit(i) * acrit(j) * alpha(i) * alpha(j)) ^ 0.5 * (1 - PR_Kij(i, j))
Next
' Calculation of Vapour Fug Coefficient, PhiL for individual component
phi_Vap(i) = Exp(bCrit(i) * (ZVap - 1) / bmixV - logE(ZVap - BVPR) - AVPR / 8 ^ 0.5 / (BVPR) * (2 * psi_Vap(i) / a_alpha_mixV - bCrit(i) / bmixV) * logE((ZVap + BVPR * (1 + 2 ^ 0.5)) / (ZVap + BVPR * (1 - 2 ^ 0.5))))
Cells(i, 18) = phiV
'Calculation of new K values
Keq_New(i) = phi_Liq(i) / phi_Vap(i)
fug_Liq(i) = xComp(i) * phi_Liq(i)
fug_Vap(i) = yComp(i) * phi_Vap(i)
'Calculation of summation of difference between new and old K values
EpsK = EpsK + (xComp(i) * phi_Liq(i) / (yComp(i) * phi_Vap(i)) - 1) ^ 2
Next
If (EpsK < 0.000000001) Then
Exit For
End If
Keq = Keq_New
Next iter02
pT_Flash_PR = VapFrac
MsgBox VapFrac
End Function
Sub Test()
comp = Range("g33:g35")
zComp = Range("h33:h35")
Temp = Range("h31") + 273.15
Pres = Range("h32")
VF = pT_Flash_PR(comp, zComp, Temp, Pres)
End Sub
VBA functions work differently if called from within excel cells. In your case (for example) all your parameters are read as Variant() arrays if the function is called from within the VB editor. However, if called from an excel cell they are accepted as Ranges and you therefore get an error when you do something like Lbound(someRange) or .Transpose(someRange). A way around is to check for the caller at the very beginning of your function like this:
'Check if called from an excel cell
If TypeName(Application.Caller) = "Range" Then
If TypeName(comp) = "Range" Then comp = comp.Value
If TypeName(zComp) = "Range" Then zComp = zComp.Value
If TypeName(Temp) = "Range" Then Temp = Temp.Value
If TypeName(Pres) = "Range" Then Pres = Pres.Value
End If
Here I am checking the type of each parameter again to allow for passing literal values.

Z factor iteration using VBA

I created a form button with two subroutines.
1.Pressure Depth Calculations
2. Z factor calculation
Both are iterations. (1) is running properly while (2) does not execute.
Following are the codes:
Sub PressureDepthCalculation()
'Declaring Variables
Dim i, t, row As Integer
t = Range("B5").Value
row = 11
'For Loop
For i = t To 0 Step -100
'Depth caclculation
Range("A" & row).Value = i
'Pressure calculation
Range("B" & row).Value = Range("F5").Value + 0.052 * Range("F6") * i
row = row + 1
Next i
End Sub
Sub ZFactorCalculation()
'Z factor calculation
Dim r1, r2, r3, r4, r5, ppc, tpc, ppr, tpr, fr, dfr, ddfr, rhor As Double
Dim i, row,t As Integer
t = 1
row = 11
Range("D6").Value = 10.731
a1 = 0.3265
a2 = 1.07 * -1
a3 = 0.5339 * -1
a4 = 0.01569
a5 = 0.05165 * -1
a6 = 0.5475
a7 = 0.7361 * -1
a8 = 0.1844
a9 = 0.1056
a10 = 0.6134
a11 = 0.721
For i = t To 100
ppc = (4.6 + (0.1 * Range("H6").Value) - (0.258 * Range("H6").Value ^ 2) * 10.1325 * 14.7)
tpc = (99.3 + (180 * Range("H6").Value) - (6.94 * Range("H6").Value ^ 2) * 1.8)
ppr = 6760 / ppc
tpr = Range("B6").Value / tpc
rhor = 0.27 * ppr / tpr
r1 = (a1 + (a2 / tpr) + (a3 / tpr ^ 3) + (a4 / tpr ^ 4) + (a5 / tpr ^ 5))
r2 = ((0.27 * ppr) / tpr)
r3 = (a6 + (a7 / tpr) + (a8 / tpr ^ 2))
r4 = a9 * ((a7 / tpr) + (a8 / tpr ^ 2))
r5 = (a10 / tpr ^ 3)
fr = (r1 * rhor) - (r2 / rhor) + (r3 * rhor ^ 2) - (r4 * rhor ^ 5) + (r5 * (1 + (a11 * rhor ^ 2))) * (Exp(-a11 * rhor ^ 2)) + 1
dfr = (r1) + (r2 / rhor ^ 2) + (2 * r3 * rhor) - (5 * r4 * rhor ^ 4) + (2 * r5 * rhor * (Exp(-a11 * rhor ^ 2)) * ((1 + (2 * a11 * rhor ^ 3)) - (a11 * rhor ^ 2 * (1 + (a11 * rhor ^ 2)))))
ddfr = rhor - (fr / dfr)
If Abs(rhor - ddfr) <= 0.000000000001 Then
Range("I" & r).Value = (0.27 * ppr) / (rhor * tpr)
Else
rhor = ddfr
End If
Also when in (1) I calculate Range("B"&row).value, I want to use it to calculate ppc in place of 6760 in (2).
It appears that your second loop has no directive to continue the loop.
You can either do:
For i = t To 100 **Step someNumber** 'The -Step- argument was used in loop 1, but was omitted in loop 2
Or this:
For i = t To 100
'the rest of your code here
**Next i** 'will increment i by 1
Welcome to StackOverflow :)

Excel function sheet gives errors

My first attempt at user-defined functions in Excel (Mac) isn't going well. This gives "function or sub undefined":
Function CylArea(d0 As Double, theta As Double, y As Double) As Double
CylArea = Pi() * (d0 ^ 2 / 4 + d0 * Tan(Radians(theta)) * y + Tan(Radians(theta)) ^ 2 * y ^ 2)
End Function
Function CylVolume(d0 As Double, theta As Double, y As Double) As Double
CylVolume = Pi() * (d0 ^ 2 / 4 * y + 1 / 2 * d0 * Tan(Radians(theta)) * y ^ 2 + 1 / 3 * Tan(Radians(theta)) ^ 2 * y ^ 3)
End Function
Function CylAreaDeriv(d0 As Double, theta As Double, y As Double) As Double
CylAreaDeriv = Pi() * (d0 * Tan(Radians(theta)) + 2 * Tan(Radians(theta)) ^ 2 * y)
End Function
Curiously, the Pi in CylVolume is highlighted.
It looks like you are attempting to use Excel functions as you would in a worksheet within VBA code. This will likely not work.
Try changing all instances of Pi() to WorksheetFunction.Pi, all instances of Tan to Math.Tan and all instances of Radians to WorksheetFunction.Radians so that the code looks more like this:
Function CylVolume(d0 As Double, theta As Double, y As Double) As Double
CylVolume = WorksheetFunction.Pi * (d0 ^ 2 / 4 * y + 1 / 2 * d0 * Math.Tan(WorksheetFunction.Radians(theta)) * y ^ 2 + 1 / 3 * Math.Tan(WorksheetFunction.Radians(theta)) ^ 2 * y ^ 3)
End Function

Resources