Reputation: 11
I have a C# console application and Dll. I registered the dll as COM via interop. I used the
I referenced this dll in the VBA code.
I created a list of objects for that class in the console application, converted it to Array and then used Excel.Run
to send the array of user defined objects to VBA code.
I can access properties of the array in VBA like LBound
and UBound
. But I am unable to access each individual object in the array.
The C# code is as follows:
using System;
using System.Runtime.InteropServices;
namespace Save_as_excel_classes
{
[Guid("0BA8F8DE-8F0A-4D7E-9DDB-8AED42943BDA")]
[ComVisible(true)]
[ClassInterface(ClassInterfaceType.AutoDual)]
public class CollClass
{
[ComVisible(true)]
public string NameValue { get; set; }
}
}
The Console App is as follows:
using Microsoft.Office.Interop.Excel;
using Save_as_excel_classes;
using System;
using System.Collections;
using System.Collections.Generic;
using _Excel = Microsoft.Office.Interop.Excel;
namespace ConsoleApp1
{
internal class Program
{
static void Main(string[] args)
{
Application excel = new _Excel.Application();
try
{
string fileName = "D:\\Book2.xlsm";
Workbook wb;
Worksheet ws;
int sheetNumber = 1;
excel.Visible = true;
wb = excel.Workbooks.Open(fileName);
ws = wb.Worksheets[sheetNumber];
ws = wb.Worksheets[sheetNumber];
var collVals = new List<CollClass>();
collVals.Add(new CollClass() { NameValue = "ABC" });
collVals.Add(new CollClass() { NameValue = "DEF" });
collVals.Add(new CollClass() { NameValue = "GHI" });
collVals.Add(new CollClass() { NameValue = "KLM" });
CollClass[] arr = collVals.ToArray();
excel.Run("ThisWorkbook.GetListofObjects1", arr);
}
catch (Exception ex)
{
}
finally
{
excel.Quit();
System.Runtime.InteropServices.Marshal.ReleaseComObject(excel);
System.Runtime.InteropServices.Marshal.FinalReleaseComObject(excel);
}
}
}
}
The VBA side looks like this: I am just trying to set the NameValue
to a cell.
Public Function GetListofObjects1(ByRef objColl() As collClass)
MsgBox "Inside GetListofObjects function" + " Hurray!"
Range("C3").Value = LBound(objColl)
Range("C4").Value = UBound(objColl)
Range("C5").Value = objColl(0).NameValue
End Function
I've searched various questions on StackOverflow and forums but I don't know what I am doing wrong. Every time I run the console application, Excel opens, I get the message box and then crashes and restarts. I also get the exception in the c# console application as follows after the LBound line and the UBound line execute. This only happens for the Range("C5").Value = objColl(0).NameValue
"System.Runtime.InteropServices.COMException: 'Exception occurred. (Exception from HRESULT: 0x80020009 (DISP_E_EXCEPTION))'"
I get the proper NameValue
when I send a single object instead of an array. It's just with the array that all the problems seem to occur.
This probably has a very simple solution but I've been at this for over a day and a half now and I can't seem to figure it out.
Edit:
I added another class CollClassArray
to the dll that will just contain the one CollClass
array. When I pass the object of CollClassArray
through the Run
command and try to access the array inside it I get the error: Wrong number of arguments or invalid use of property near the CollArray(0)
.
Public Function GetListOfObjects1(array as CollClassArray)
Dim objColl as CollClass
Set objColl = array.CollArray(0).NameValue
End Function
Upvotes: 1
Views: 172
Reputation: 11
After researching a bit more, I added mscorlib
as a reference in the VBA code. I used the mscorlib.ArrayList
and was able to access the elements in the ArrayList
.
c# code: with ArrayList
static void Main(string[] args)
{
Application excel = new _Excel.Application();
try
{
string fileName = "D:\\Book2.xlsm";
dynamic wb;
Worksheet ws;
int sheetNumber = 1;
excel.Visible = true;
wb = excel.Workbooks.Open(fileName);
ws = wb.Worksheets[sheetNumber];
var collVals = new List<CollClass>();
collVals.Add(new CollClass() { NameValue = "ABC", NumberValue = 2 });
collVals.Add(new CollClass() { NameValue = "DEF", NumberValue = 4 });
collVals.Add(new CollClass() { NameValue = "GHI", NumberValue = 6 });
collVals.Add(new CollClass() { NameValue = "KLM", NumberValue = 8 });
CollClass[] arr = collVals.ToArray();
ArrayList list = new ArrayList();
list.AddRange(arr);
excel.Run("ThisWorkbook.SetC5", list);
}
catch (Exception ex)
{
}
finally
{
excel.Quit();
System.Runtime.InteropServices.Marshal.ReleaseComObject(excel);
System.Runtime.InteropServices.Marshal.FinalReleaseComObject(excel);
}
}
VBA code:
Public Function setC5(coll As mscorlib.ArrayList)
MsgBox "Inside this function"
Dim count As Integer
Dim coll2(), coll1 As collClass
Dim number As Integer
number = coll.count
Range("C6") = number
Set coll1 = coll(0)
Range("C5").Value = coll1.NameValue
End Function
Upvotes: 0