How do a create a new Excel file with GoExcel?

How do a create a new Excel file with GoExcel?

harvey_craig2RCUH
Advocate Advocate
2,126 Views
7 Replies
Message 1 of 8

How do a create a new Excel file with GoExcel?

harvey_craig2RCUH
Advocate
Advocate

Hi, 

 

I see open, save and close but how do I create a new Excel file with a line of code in a iLogic rule?

 

Thank you,

Harvey 

0 Likes
Accepted solutions (1)
2,127 Views
7 Replies
Replies (7)
Message 2 of 8

WCrihfield
Mentor
Mentor

Hi @harvey_craig2RCUH.  Good question.  You basically just do not when using iLogic's GoExcel tools.  There are other ways of doing things with Excel in iLogic rules, without using the GoExcel tools, but those are generally much simper to use for basic stuff, and for folks with out much coding experience.  My guess is that the code behind the scenes supporting the functionality of the GoExcel iLogic tool is wanting to be able to dispose of any resources being held in Inventor's memory related to the GoExcel tool once you are done using it.  And if you still have a reference to a new Excel document that was created by the GoExcel tool, there would still be a resource in your control that it would not have any control over.  But I am just guessing.  You would have to ask the folks at Autodesk who designed those tools why they did not include a method for that specific task.  I'm sure they had a good reason for it, I am just not sure what it is.

Those tools primarily provide a simpler/shortcut way of doing basic tasks which need to use some Excel like functionality, and to be able to do it with very little code.  If we have Microsoft Excel installed, we can include some lines in the 'Header' of our rules that will give us access to, and 'Intellisense' support for, the Excel API system, so that we can control Excel using vb.net code.  There are several examples of code like this here on this forum.  Some of those examples include the header lines, and some do not, it all depends on their specific needs, and specific local resources/system.

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

Message 3 of 8

WCrihfield
Mentor
Mentor
Accepted solution

Here is a very short and simple example of an iLogic rule that should:

  • Starting a new instance of the Excel application
  • Creating a new Excel Workbook (Excel document) within that new instance of the Excel application
  • Creating a new Excel Worksheet within that new Workbook
  • Writing 3 column titles
  • Auto-fitting those columns
  • Saving that new document to a new file on disk, in the Temp folder
  • Closing that document
  • Quitting the new Excel application instance.
  • Negating the variables we used, to release those references.

...without using the iLogic GoExcel tools.

AddReference "Microsoft.Office.Interop.Excel.dll"
Imports Microsoft.Office.Interop
Imports Microsoft.Office.Interop.Excel
'Create New instance of the Excel application
Dim oExcel As New Microsoft.Office.Interop.Excel.ApplicationClass
oExcel.DisplayAlerts = False
oExcel.Visible = True
'create new Excel Workbook (document)
Dim oWB As Excel.Workbook = oExcel.Workbooks.Add()
'create new Excel Worksheet (sheet)
Dim oWS As Excel.Worksheet = oWB.Worksheets.Add()
'Create Column Headers by specifying the Cell Address of each cell
oWS.Range("A1").Value = "Column 1"
oWS.Range("B1").Value = "Column 2"
oWS.Range("C1").Value = "Column 3"
'auto-fit the columns
oWS.Columns.AutoFit
'save this new Excel document to a file on disk
oWB.SaveAs("C:\Temp\MyNewExcelFile.xlsx")
'close this Workbook
oWB.Close
'quit the Excel application instance we started
oExcel.Quit
'negate the variables we used, to get rid of system references
oWS = Nothing
oWB = Nothing
oExcel = Nothing

The first 3 lines of code shown above are from the 'Header' of the iLogic rule, and provide recognition of the Excel API objects and methods, which enables the built-in Intellisense system to offer help/hints about those objects when you hover your mouse over them, or type a dot after one of them.  There are multiple ways to do some of these same things that this code is doing, using different code tactics, and not all of them may work well for everyone.  Some folks seem to have more trouble while including those lines in the header, than without them.  But without them, we can not 'declare' any of our variables as any of the Excel API object types, and therefore would be essentially coding 'blind' (without any hints/suggestions/help) when dealing with those variables.  Sometimes the code will still work OK that way (without the references/imports), but you must be pretty knowledgeable about what you are doing to make it work that way.

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

Message 4 of 8

harvey_craig2RCUH
Advocate
Advocate

Once again Wesley, you've come to my rescue. Thank you, your code works great! @WCrihfield 

Harvey

0 Likes
Message 5 of 8

MICHAEL.JONES.AMCE
Advocate
Advocate

We have been trying to create a solution via iLogic using the above approach which would allow the user to select a workbook and then the worksheet from the workbook.

 

Probably just our Office Installs.  Running Microsoft 365 Apps for Business....but it never hurts to see if anyone has any feedback. 🙂

 

Error Message:

Unable to cast COM object of type 'Microsoft.Office.Interop.Excel.ApplicationClass' to interface type 'Microsoft.Office.Interop.Excel._Application'. This operation failed because the QueryInterface call on the COM component for the interface with IID '{000208D5-0000-0000-C000-000000000046}' failed due to the following error: Error loading type library/DLL. (Exception from HRESULT: 0x80029C4A (TYPE_E_CANTLOADLIBRARY)).

 

iLogic Code:

Class ThisRule	
	Public oFileDlg As Inventor.FileDialog = Nothing	
	Public _gbExcelOpen As Boolean = False 		
	Public _oExcel As New Microsoft.Office.Interop.Excel.ApplicationClass
		
Sub Main()		
	If ThisDoc.Document.DocumentType <> DocumentTypeEnum.kPartDocumentObject Then 
		MessageBox.Show("You are not in a part file!", "AMA-iLogic Team")
		Exit Sub
	End If	
		
	Dim _gDoc As PartDocument
	InventorVB.Application.CreateFileDialog(oFileDlg)
	
	_gDoc = ThisApplication.ActiveDocument
	
	Dim curFldr As String = GetFolderPath(_gDoc)
	Logger.Info("Current Drawing Folder:" & curFldr, curFldr)

	Dim xlFileName As String = GetExcelFile(curFldr)
	
	Dim xlWrkShtList As ArrayList	
	Dim UCSWorkbook As Excel.Workbook 	
	UCSWorkbook = XLWorkBook(xlFileName)
	' Logger.Info("Name of workbook :" & UCSWorkbook.FullName)
	
	If UCSWorkbook Is Nothing Then
		MessageBox.Show("Unable to to open Excel file: " & xlFileName, "AMA-iLogic Team")
		Exit Sub
	End If
			
	Dim xlWorkSheets As Excel.Worksheets	
	xlWorkSheets = UCSWorkbook.Worksheets	
	Dim i As Integer 

	For i = 1 To xlWorksheets.Count		
		xlWrkShtList.Add(xlWorkSheets.Item(i).ToString)
		logger.info("Addedworksheet :" & xlWorkSheets.Item(i))		
	Next i
End Sub

Function GetExcelFile(fldr As String ) As String

	oFileDlg.Filter = "Excel Files (*.xlsm)(*.xlsx)|*.xlsm;*.xlsx"
	oFileDlg.InitialDirectory = fldr	
	oFileDlg.ShowOpen()
	GetExcelFile = oFileDlg.FileName
End Function

Function GetFolderPath(pDoc As PartDocument) As String
	Dim FullFileName, ShortName As String 
	Dim FnamePos As Integer 
	FullFileName = pDoc.FullFileName
	Dim DirSep As String = System.IO.Path.DirectorySeparatorChar		
	FnamePos = InStrRev(FullFileName, DirSep, -1)	
	ShortName = Right(FullFileName, Len(FullFileName) -FnamePos)
	GetFolderPath = Left(FullFileName, Len(FullFileName) - Len(ShortName))
End Function

Function XLWorkBook(fn As String) As Excel.Workbook
	Dim fncName As String = "XLWorkBook"

	If fn = "" Then Exit Function
	If System.IO.File.Exists(fn) = False Then Exit Function
	
	Dim bAppStarted As Boolean = False
	
	'_oExcel.DisplayAlerts = False
	'_oExcel.Visible = True 
	
	Dim oWB As Excel.Workbook
	
	Try 
		oWB = _oExcel.Workbooks.Open(fn) 
	Catch 
		MessageBox.Show(fncName & ": (A) Unable to open the Excel workbook " & fn &".", "AMA-iLogic")
	End Try
		
	If oWB Is Nothing Then 
		MessageBox.Show(fncName & ": (B) Unable to open the Excel workbook " & fn &".", "AMA-iLogic")
		Exit Function 
	End If
	
	_gbExcelOpen =  bAppStarted
	Return oWB 

End Function
		
End Class

 

0 Likes
Message 6 of 8

WCrihfield
Mentor
Mentor

Hi @MICHAEL.JONES.AMCE.  The error message you are showing is very common.  It can be confusing getting a reference to the main application object of a different application other than the one you are actively working within.  Some ways seem to work OK for some folks most of the time, and for others only sometimes, while not working at all for yet others.  The 'ApplicationClass' type appears to be for 'internal use only', so I generally do not recommend relying on that one.  But then the regular Application object appears to be an Interface type, instead of a Class type, so you can not use the 'New' keyword to create a new instance of one.  However, we can set a variable to represent an Interface type, then set its value another way, usually through some sort of 'Cast' routine.  Below is another pretty simple routine I have just for getting a reference to an instance of the Excel Application object.  This routine uses a Try...Catch statement while it first attempts to get an already running instance, then if that fails, it tries to create an instance, and casting the object it gets to the Interface type variable.  You can incorporate something like this into your 'Excel' resources.  I also have some that are much more detailed for getting or creating things like a Workbook or a Worksheet, with several inputs and optional inputs.

Imports Microsoft.Office.Interop.Excel
Imports Microsoft.Office.Interop
AddReference "Microsoft.Office.Interop.Excel.dll"
Sub Main
	Dim oExcel As Microsoft.Office.Interop.Excel.Application = GetExcel(True)
	Dim oWB As Microsoft.Office.Interop.Excel.Workbook = Nothing
	Dim oWS As Microsoft.Office.Interop.Excel.Worksheet = Nothing
	If oExcel IsNot Nothing Then
		Logger.Info("Got a reference to an Excel Application instance.")
		oWB = oExcel.ActiveWorkbook
		oWS = oExcel.ActiveSheet
		If oWB IsNot Nothing Then
			Logger.Info("Excel Active Workbook Name = " & oWB.Name)
			oWB = Nothing
		Else
			Logger.Info("No Active Workbook.")
		End If
		If oWS IsNot Nothing Then
			Logger.Info("Excel Active Worksheet Name = " & oWS.Name)
			oWS = Nothing
		Else
			Logger.Info("No Active Worksheet.")
		End If
	Else
		Logger.Debug("No instance of Excel Application obtained!")
	End If
	oExcel = Nothing
End Sub

Function GetExcel(Optional bVisible As Boolean = False) As Excel.Application
	Dim oXL As Microsoft.Office.Interop.Excel.Application
	Dim oObj As Object = Nothing
	Try
		'try to find an already running instance of the Excel Application
		oObj = GetObject(, "Excel.Application")
		oXL = TryCast(oObj, Microsoft.Office.Interop.Excel.Application)
	Catch
		'it wasn't found open, so create an instance of it (start the application)
		oObj = CreateObject("Excel.Application")
		oXL = TryCast(oObj, Microsoft.Office.Interop.Excel.Application)
	End Try
	oObj = Nothing
	If oXL IsNot Nothing Then oXL.Visible = bVisible
	Return oXL
End Function

If this solved your problem, or answered your question, please click ACCEPT SOLUTION .
Or, if this helped you, please click (LIKE or KUDOS) 👍.

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

Message 7 of 8

MICHAEL.JONES.AMCE
Advocate
Advocate

Wesley,

 

Very enlightening and helpful code snippets.

 

Alas, still have the same/similar error message when the sample code is ran.

 

Imports Microsoft.Office.Interop.Excel
Imports Microsoft.Office.Interop
AddReference "Microsoft.Office.Interop.Excel.dll"

 

Sub Main
	Dim oExcel As Microsoft.Office.Interop.Excel.Application = GetExcel(True)
	Dim oWB As Microsoft.Office.Interop.Excel.Workbook = Nothing
	Dim oWS As Microsoft.Office.Interop.Excel.Worksheet = Nothing
	If oExcel IsNot Nothing Then
		Logger.Info("Got a reference to an Excel Application instance.")
		oWB = oExcel.ActiveWorkbook
		oWS = oExcel.ActiveSheet
		If oWB IsNot Nothing Then
			Logger.Info("Excel Active Workbook Name = " & oWB.Name)
			oWB = Nothing
		Else
			Logger.Info("No Active Workbook.")
		End If
		If oWS IsNot Nothing Then
			Logger.Info("Excel Active Worksheet Name = " & oWS.Name)
			oWS = Nothing
		Else
			Logger.Info("No Active Worksheet.")
		End If
	Else
		Logger.Debug("No instance of Excel Application obtained!")
	End If
	oExcel = Nothing
End Sub

Function GetExcel(Optional bVisible As Boolean = False) As Excel.Application
	Dim oXL As Microsoft.Office.Interop.Excel.Application
	Dim oObj As Object = Nothing
	
	Try
		'try to find an already running instance of the Excel Application
		oObj = GetObject(, "Excel.Application")
		oXL = TryCast(oObj, Microsoft.Office.Interop.Excel.Application)
	Catch
		'it wasn't found open, so create an instance of it (start the application)
		oObj = CreateObject("Excel.Application")
		oXL = TryCast(oObj, Microsoft.Office.Interop.Excel.Application)
	End Try
	
	oObj = Nothing
	
	If oXL IsNot Nothing Then 
		oXL.Visible = bVisible
	Else	
		Logger.Debug("Unable to create Excel Object!")
	End If
	
	Return oXL

 

System.InvalidCastException: Unable to cast COM object of type 'Microsoft.Office.Interop.Excel.ApplicationClass' to interface type 'Microsoft.Office.Interop.Excel._Application'. This operation failed because the QueryInterface call on the COM component for the interface with IID '{000208D5-0000-0000-C000-000000000046}' failed due to the following error: Error loading type library/DLL. (Exception from HRESULT: 0x80029C4A (TYPE_E_CANTLOADLIBRARY)).
   at System.StubHelpers.StubHelpers.GetCOMIPFromRCW(Object objSrc, IntPtr pCPCMD, IntPtr& ppTarget, Boolean& pfNeedsRelease)
   at Microsoft.Office.Interop.Excel.ApplicationClass.set_Visible(Boolean RHS)
   at ThisRule.GetExcel(Boolean bVisible) in external rule: ExcelTestForum:line 43
   at ThisRule.Main() in external rule: ExcelTestForum:line 5
   at Autodesk.iLogic.Exec.AppDomExec.ExecRuleInAssembly(Assembly assem)
   at iLogic.RuleEvalContainer.ExecRuleEval(String execRule)

 

I'll see if IT can do a a rebuild/restore on the Office 365 install at work.

 

M.

0 Likes
Message 8 of 8

WCrihfield
Mentor
Mentor

Hi @MICHAEL.JONES.AMCE.  It is like I said...some of these suggestions may work for me, and may work for some others, but may not work for everyone.  I am not always 100% sure why.  Another interesting piece of information is that when I do not have Excel visibly open (manually) then use the 'CreateObject' method, I seem to get an instance of the Excel.ApplicationClass Type, but when I have Excel open visibly (manually) and I use the GetObject method I get an instance of the Excel.Application Type.  But in both cases I do not get any errors, and all Logger statements print to the iLogic Log window as expected.  I am not sure what may be different between my situation and yours.

I am using a Windows 10 Enterprise Dell Precision tower computer, Inventor Professional 2024.0.1, and Microsoft 365 (Version 2312 Build 16.0.17126.20190).  In my iLogic Configuration settings, I have my Excel Options Engine set to COM.

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

0 Likes