SilverShaded
Well-known member
- Joined
- Mar 7, 2020
- Messages
- 110
- Programming Experience
- 10+
Hi, i've setup a project that uses .Net 6 and is call from excel VBA. Some of the functions work fine but others are not. Its really not clear to me why they dont work. I've tried everything i can think of many times over.
The interface;
The class;
some function are in other files such as;
The IDL file
The Excel VBA
When i run the VBA "TestTcrit" works fine as does "StreamEnthalpy" but "LiqComponentEnthlapy" give an error saying "Runtime error -2147467261 "Object Reference not set to an instance of an object".
Any possible ideas why?
The interface;
The Interface:
namespace COMThermoClass
{
[Guid(ContractGuids.ServerInterface)]
[ComVisible(true)]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IThermo
{
double TestCritT();
// double LiqEnthalpyReal(object comps, object X, double T, double P, int method);
double StreamEnthalpyReal(object comps, object X, double T, double P, int method);
double StreamTemperatureReal(object comps, object X, double H, double P, int method);
double CritP(double Tb, double SG, int method);
double CritT(double Tb, double SG, int method);
double DistillationPoint(object comps, object X, object SG, object BP, int method, string DistType, string distpoint);
double EnthalpyFormationReal(object comps, object X);
double LiqComponentEnthalpy(string comp, double T, double P, int method);
// double VapComponentEnthalpy(string comp, double T, double P, int method);
}
}
The class;
The class:
namespace COMThermoClass
{
[Guid(ContractGuids.ServerClass)]
[ClassInterface(ClassInterfaceType.None)]
[ComVisible(true)]
public partial class COMThermoClass : IThermo
{
private enumCalcResult cres;
public COMThermoClass()
{
Thermodata data = new Thermodata();
}
public double TestCritT()
{
//Debugger.Launch();
return 99.9;
}
}
}
some function are in other files such as;
Part Partial Class code:
public partial class COMThermoClass
{
public double LiqComponentEnthalpy(string comp, double T, double P, int method)
{
Debugger.Launch();
double res = 0;
BaseComp sc = Thermodata.GetRealComponent((string)comp);
sc.molefraction = 1;
Components cc = new Components();
cc.Add(sc);
cc.T = T;
cc.P = P;
cc.thermo.Enthalpy = (enumEnthalpy)method;
res = ThermodynamicsClass.BulkStreamThermo(cc, cc.P, T, enumMassOrMolar.Molar, enumFluidRegion.Liquid, ref cres).H;
return res;
}
public double StreamEnthalpyReal(object comps, object X, double T, double P, int method)
{
double res;
Components cc = new Components();
cc.T = T;
cc.P = P;
BaseComp sc;
// Debugger.Launch();
string[] c = (string[])comps;
double[] x = (double[])X;
double sum = 0;
for (int i = 0; i < x.Length; i++)
{
sum += x[i];
}
if (sum != 1) // normalise
{
for (int i = 0; i < x.Length; i++)
{
x[i] /= sum;
}
}
cc.thermo.Enthalpy = (enumEnthalpy)method;
for (int i = 0; i < x.Length; i++)
{
sc = Thermodata.GetRealComponent(c[i]);
if (sc == null)
{
System.Windows.Forms.MessageBox.Show("Component " + c[i].ToString() + "Not Found In Database");
}
else
{
sc.molefraction = x[i];
cc.Add(sc);
}
}
BasicPropList bpl = new BasicPropList();
bpl.T.BaseValue = T;
bpl.P.BaseValue = P;
bpl.T.origin = SourceEnum.Input;
bpl.P.origin = SourceEnum.Input;
FlashClass.Flash(cc, bpl, false);
res = cc.BulkEnthalpy();
return res;
}
public double StreamTemperatureReal(object comps, object X, double H, double P, int method)
{
double res;
Components cc = new Components();
cc.P = P;
BaseComp sc;
//Debugger.Launch();
string[] c = (string[])comps;
double[] x = (double[])X;
double sum = 0;
for (int i = 0; i < x.Length; i++)
{
sum += x[i];
}
if (sum != 1) // normalise
{
for (int i = 0; i < x.Length; i++)
{
x[i] /= sum;
}
}
cc.thermo.Enthalpy = (enumEnthalpy)method;
for (int i = 0; i < x.Length; i++)
{
sc = Thermodata.GetRealComponent(c[i]);
if (sc == null)
{
System.Windows.Forms.MessageBox.Show("Component " + c[i].ToString() + "Not Found In Database");
}
else
{
sc.molefraction = x[i];
cc.Add(sc);
}
}
BasicPropList bpl = new BasicPropList();
bpl.H.BaseValue = H;
bpl.P.BaseValue = P;
bpl.H.origin = SourceEnum.Input;
bpl.P.origin = SourceEnum.Input;
FlashClass.Flash(cc, bpl, false);
res = cc.T;
return res;
}
public double StreamComponentEnthalpy(string c, double T, double P, int method)
{
double res;
Components cc = new Components();
cc.T = T;
cc.P = P;
BaseComp sc;
cc.thermo.Enthalpy = (enumEnthalpy)method;
sc = Thermodata.GetRealComponent(c);
if (sc == null)
{
System.Windows.Forms.MessageBox.Show("Component " + c.ToString() + "Not Found In Database");
}
else
{
sc.molefraction = 1;
cc.Add(sc);
}
BasicPropList bpl = new BasicPropList();
bpl.T.BaseValue = T;
bpl.P.BaseValue = P;
bpl.T.origin = SourceEnum.Input;
bpl.P.origin = SourceEnum.Input;
FlashClass.Flash(cc, bpl, false);
res = cc.BulkEnthalpy();
return res;
}
The IDL file
C:
// Generated .IDL file (by the OLE/COM Object Viewer)
//
// typelib filename: COMThermo.tlb
[
uuid(A5996396-7DB2-44B4-BD98-4D769792DE2D),
version(1.0),
custom(90883F05-3D28-11D2-8F17-00A0C9A6286C, "COMThermo, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null")
]
library COMThermo
{
// TLib : mscorlib.dll : {BED7F4EA-1A96-11D2-8F08-00A0C9A6186D}
importlib("mscorlib.tlb");
// TLib : OLE Automation : {00020430-0000-0000-C000-000000000046}
importlib("stdole2.tlb");
// Forward declare all types defined in this typelib
interface ICOMThermo;
[
odl,
uuid(B221E497-C862-4C40-B4E6-5D79E7AB28D5),
version(1.0),
oleautomation,
custom(B10B0742-6D84-415D-894C-798ED2D76C1D, "COMThermo.ICOMThermo")
]
interface ICOMThermo : IUnknown {
[id(0x60020000)]
HRESULT _stdcall TestCritT([out, retval] double* pRetVal);
[id(0x60020001)]
HRESULT _stdcall StreamEnthalpyReal(
[in] VARIANT comps,
[in] VARIANT X,
[in] double T,
[in] double P,
[in] long method,
[out, retval] double* pRetVal);
[id(0x60020002)]
HRESULT _stdcall StreamTemperatureReal(
[in] VARIANT comps,
[in] VARIANT X,
[in] double H,
[in] double P,
[in] long method,
[out, retval] double* pRetVal);
[id(0x60020003)]
HRESULT _stdcall LiqEnthalpyReal(
[in] VARIANT comps,
[in] VARIANT X,
[in] double T,
[in] double P,
[in] long method,
[out, retval] double* pRetVal);
[id(0x60020004)]
HRESULT _stdcall LiqComponentEnthalpy(
[in] BSTR comps,
[in] double T,
[in] double P,
[in] long method,
[out, retval] double* pRetVal);
};
[
uuid(BE532448-9A5A-4273-B93C-0573545D36C4),
version(1.0),
custom(B10B0742-6D84-415D-894C-798ED2D76C1D, "COMThermo.COMThermo")
]
coclass COMThermo {
interface _Object;
[default] interface ICOMThermo;
};
};
The Excel VBA
Excel Code:
Dim test As New COMThermo.COMThermo
Function Test1()
Test1 = test.TestCritT()
End Function
Sub LiqComponentEnthalpy()
Dim res As Double
res = test.LiqComponentEnthalpy("n-Butane", 25 + 273.15, 1#, 5)
'End Function
End Sub
Function StreamEnthalpy(comp As Range, Xfractions As Range, T As Double, P As Double, Method As Integer) As Double
Dim Names() As String
Dim x() As Double
No = comp.Cells.Count
ReDim Names(No - 1)
ReDim x(No - 1)
For i = 1 To No
Names(i - 1) = comp(i).Value
x(i - 1) = Xfractions(i).Value
Next
StreamEnthalpy = test.StreamEnthalpyReal(Names, x, T + 273.15, P, Method)
'End Function
End Function
When i run the VBA "TestTcrit" works fine as does "StreamEnthalpy" but "LiqComponentEnthlapy" give an error saying "Runtime error -2147467261 "Object Reference not set to an instance of an object".
Any possible ideas why?
Last edited: