In a previous post (Integrating with Excel) I gave a code example of how RE can integrate with Excel. The code was relatively simple. One of the problems with working with Excel is if you embed references to Excel in your project but you are not sure of the version of Excel you will be working with.
The following code sets up the Excel objects so that they can be used throughout the code with convenient intellisense.
Dim objExcel As Excel.Application ' Excel application Dim objBook As Excel.Workbook ' Excel workbook Dim objSheet As Excel.Worksheet ' Excel Worksheet Dim oConstit As New CRecord oConstit.Init REApplication.SessionContext Set objExcel = CreateObject("excel.application") 'Starts the Excel Session Set objBook = objExcel.Workbooks.Open("C:test.xls")
The problem is though in order for this to compile you have to put a reference to Excel in the references. This version will vary depending on the version you are using and the application will crash if your target user has a different version. What can be done about this?
The most obvious choice is to remove the reference to Excel and do everything using late binding. All the objects have to be of type Object and there will be no intellisense. What is more there will be no compile time errors either. The best way around this is to test your code with the references and then remove them before going live.
Dim objExcel As Object Dim objBook As Object Dim objSheet As Object On Error Resume Next Set objExcel = GetObject(, "excel.application") If Err.Number = 429 Then Set objExcel = CreateObject("excel.application") End If On Error GoTo 0 Set objBook = objExcel.Workbooks.Open("C:test.xls")
We define our Excel objects as simply Object. We then use the GetObject function to get an existing instance of Excel (you may want to jump to creating a new one so as not to interfere with other ones). If there is not existing instance we create a new one. We then use the Excel object as we did previously (but have to remember the syntax as we are not prompted now).
So far we have seen how we can use Excel from VB6 code but more and more we want to use RE and .NET. How does this work? The Excel object model is COM based so we have to have an interop to use. Luckily these are available but need to be downloaded and installed (see MSDN article). Even then we still have the same problem with versions. That aside there are some pointers we should remember.
When working with Excel from .NET remember that setting the reference to Nothing
may not be enough for it to be cleaned up. Instead I always call the following method in order to release the objects
Private Sub Kill(ByVal o As Object) Try System.Runtime.InteropServices.Marshal.ReleaseComObject(o) System.Runtime.InteropServices.Marshal.FinalReleaseComObject(o) GC.Collect() Catch Finally o = Nothing End Try End Sub
Also according to one article you should never implicitly reference Excel objects. For example instead of doing the following:
XLSheet.Cells(row, column).BorderAround(1, ColorIndex:=16, Weight:=2)
Do this:
Dim cells As Excel.Range Dim cell As Excel.Range cells = _XLSheet.Cells cell = cells.Item(row, column) cell.BorderAround(1, ColorIndex:=16, Weight:=2) Kill(cell) Kill(cells)
Of course many would say that all this work is simple not worth it. One solution is to do away with COM altogether and generate the Excel file in XML. When you open it up it will open up correctly and then you can save it back in native Excel format. See this article for the code