iLogic create Table within Excel

iLogic create Table within Excel

checkcheck_master
Advocate Advocate
1,906 Views
11 Replies
Message 1 of 12

iLogic create Table within Excel

checkcheck_master
Advocate
Advocate

How can I create a Table within an Excel document through iLogic?

In VBA it works fine but I don't know how to put it to iLogic.
I have this in VBA:

Private Sub CreateTable(ByVal oExcelApp As Excel.Application, ByVal oWB As Workbook, ByVal TableStyle As String)
    Dim oWs As WorkSheet
    Set oWs = oWB.ActiveSheet

    ' Get Last Row and Last Column as numbers
    Dim LR As Long
    Dim LC As Long

    LR = oWs.Cells(oWs.Rows.Count, 1).End(xlUp).row
    LC = oWs.Cells(1, oWs.Columns.Count).End(xlToLeft).column

    ' Create Table
    Dim rng As Range
    Set rng = oWs.Cells(1, 1).Resize(LR, LC)

    oWs.ListObjects.Add xlSrcRange, xllistobjecthasheaders:=xlYes, Destination:=rng
    oWs.ListObjects(1).Name = "Table"
    oWs.ListObjects(1).TableStyle = TableStyle '"TableStyleLight21"

    Set oWs = Nothing
    Set oWB = Nothing
    Set oExcelApp = Nothing

End Sub

 Called by:

Call CreateTable(oExcelApp, oWB1, "TableStyleLight10")

 

0 Likes
Accepted solutions (1)
1,907 Views
11 Replies
Replies (11)
Message 2 of 12

WCrihfield
Mentor
Mentor

Hi @checkcheck_master.  The main difficulty in converting this to iLogic, is how to setup/call out the references/imports, so it knows what Excel and its objects are.  This is done within the 'Header' area of an iLogic rule.  I also often prefer to use a separate custom Function just to 'get' the Excel application object, depending on the situation.  Here is an iLogic rule conversion of your VBA macro, that I have included the header content and the custom Function I like to use.  (The first 3 lines will automatically transfer themselves into the header area.)

 

AddReference "Microsoft.Office.Interop.Excel.dll"
Imports Microsoft.Office.Interop
Imports Microsoft.Office.Interop.Excel
Sub Main
	Dim oExcelApp As Microsoft.Office.Interop.Excel.Application = GetExcel
	Dim oWB1 As Workbook = oExcelApp.ActiveWorkbook
	CreateTable(oExcelApp, oWB1, "TableStyleLight10")
End Sub

Private Sub CreateTable(ByVal oExcelApp As Excel.Application, ByVal oWB As Workbook, ByVal TableStyle As String)
    Dim oWs As WorkSheet = oWB.ActiveSheet
    ' Get Last Row and Last Column as numbers
    Dim LR As Long = oWs.Cells(oWs.Rows.Count, 1).End(xlUp).row
    Dim LC As Long = oWs.Cells(1, oWs.Columns.Count).End(xlToLeft).column
    ' Create Table
    Dim rng As Range = oWs.Cells(1, 1).Resize(LR, LC)
    oWs.ListObjects.Add(xlSrcRange, xllistobjecthasheaders:=xlYes, Destination:=rng)
    oWs.ListObjects(1).Name = "Table"
    oWs.ListObjects(1).TableStyle = TableStyle '"TableStyleLight21"
    oWs = Nothing
    oWB = Nothing
    oExcelApp = Nothing
End Sub

Function GetExcel() As Microsoft.Office.Interop.Excel.Application
	Dim oXL As Microsoft.Office.Interop.Excel.Application
	Try
		'try to find an already running instance of the Excel Application
		oXL = GetObject(, "Excel.Application")
	Catch
		'it wasn't found open, so create an instance of it (start the application)
		oXL = CreateObject("Excel.Application")
		'oXL = New Microsoft.Office.Interop.Excel.Application
	Catch
		MsgBox("Failed to Get/Create an instance of the Excel Application. Exiting.", , "")
		Exit Function
	End Try
	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) 👍.

If you want and have time, I would appreciate your Vote(s) for My IDEAS 💡 or you can Explore My CONTRIBUTIONS

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

0 Likes
Message 3 of 12

checkcheck_master
Advocate
Advocate

Thanks a lot WCrihfield.

 

I can't get it to work.
Tried several things, but no luck.
It crashes in 'Private Sub CreateTable'.
See image of the error message.
Could it be something to do with Excel's language/format?
I use a Dutch language version.
Changed the '1' to 'A' but it's not it.
See code:

AddReference "Microsoft.Office.Interop.Excel.dll"
Imports Microsoft.Office.Interop
Imports Microsoft.Office.Interop.Excel
Sub Main()
		
	' Try to Renumbers Item number:
	' - For Structured BOM only FirstLevel is working now
	' - For PartsOnly BOM it' working
	' - Now two(2) List are created, it's more efficient to create the two Lists in one(1) itteration
	iLogicVb.RunExternalRule("Renumber_and_Sort_BOM_Item_Numbers")

'**************************************************************************************
'You can change the output path by editing CSVpath below
'CSVpath = ("C:\Inventor\") 'If you change the path, remember to keep a \ at the end
'CSVpath = ThisDoc.Path + "\"
'**************************************************************************************

'Adapted from Inventor API Samples by Clint Brown @ClintBrown3D
'iLogic code Originally posted at https://clintbrown.co.uk/bom-export-with-ilogic

oDoc = ThisDoc.ModelDocument
'Ensure that we are in an Assembly file - Exit if not
If oDoc.DocumentType = kPartDocumentObject Then
	MessageBox.Show("You need to be in an Assembly to Export a BOM", "@ClintBrown3D iLogic")
	Return
End If
oDoc = ThisApplication.ActiveDocument
Dim oBOM As BOM
oBOM = oDoc.ComponentDefinition.BOM

'**************************************************************************************
'You can change the output path by editing CSVpath below - by default the path is the same as the assembly file
'CSVpath = ("C:\Inventor\") 'If you change the path, remember to keep a \ at the end
CSVpath = ThisDoc.Path + "\"
MessageBox.Show(CSVpath)
'**************************************************************************************

'Get user input for Export Type:
Dim MyArrayList As New ArrayList
MyArrayList.Add("")
MyArrayList.Add("Structured - All Levels")
MyArrayList.Add("")
MyArrayList.Add("Structured - Single Level")
MyArrayList.Add("")
MyArrayList.Add("Parts Only - (Shows components in a flat list)")

ClintsBoMExporter = InputListBox("Choose a BoM type to Export: " & ClintBrown3D , MyArrayList, d0, Title := "@ClintBrown3D: BoM Export ", ListName := "BoM Type")

If ClintsBoMExporter = "Structured - All Levels" Then :GoTo GoAllLevelsExport : End If
If ClintsBoMExporter = "Structured - Single Level" Then :GoTo GoSingleLevelsExport : End If
If ClintsBoMExporter = "Parts Only - (Shows components in a flat list)" Then : GoTo GoPartExport : End If
If ClintsBoMExporter = "" Then : Return : End If
	
'STRUCTURED BoM ALL LEVELS:
GoAllLevelsExport:
' the structured view to 'all levels'
	oBOM.StructuredViewFirstLevelOnly = False
' Make sure that the structured view is enabled.
	oBOM.StructuredViewEnabled = True
	Dim oStructuredBOMView As BOMView
	oStructuredBOMView = oBOM.BOMViews.Item("Structured")
' Export the BOM view to an Excel file
	Dim BoM As String
	BoM = CSVpath + ThisDoc.FileName(False) + " STRUCTURED BoM ALL LEVELS.xlsx"
    oStructuredBOMView.Export(CSVpath + ThisDoc.FileName(False) + " STRUCTURED BoM ALL LEVELS.xlsx", kMicrosoftExcelFormat)
	'oStructuredBOMView.Export(BoM, kMicrosoftExcelFormat)
GoTo GoLaunch:

'STRUCTURED BoM Single Level 
GoSingleLevelsExport:
	oBOM.StructuredViewFirstLevelOnly = True
	oBOM.StructuredViewEnabled = True
	oStructuredBOMView = oBOM.BOMViews.Item("Structured")
	BoM = CSVpath + ThisDoc.FileName(False) + " STRUCTURED BoM Single Level.xlsx"
   'oStructuredBOMView.Export(CSVpath + ThisDoc.FileName(False) + " STRUCTURED BoM Single Level.xlsx", kMicrosoftExcelFormat)
	oStructuredBOMView.Export(BoM, kMicrosoftExcelFormat)
GoTo GoLaunch:

'PARTS ONLY BoM
GoPartExport:
	oBOM.PartsOnlyViewEnabled = True
	Dim oPartsOnlyBOMView As BOMView
	oPartsOnlyBOMView = oBOM.BOMViews.Item("Parts Only")
	BoM = CSVpath + ThisDoc.FileName(False) + " PARTS ONLY BoM.xlsx"
	oPartsOnlyBOMView.Export(CSVpath + ThisDoc.FileName(False) + " PARTS ONLY BoM.xlsx", kMicrosoftExcelFormat)
	'oStructuredBOMView.Export(BoM, kMicrosoftExcelFormat)
GoTo GoLaunch:

'Get user input - do you want to see the BoM?
GoLaunch :	

'	i = MessageBox.Show("Preview the BOM?", "@ClintBrown3D iLogic", MessageBoxButtons.YesNo)
'	If i = vbYes Then : launchviewer = 1 : Else : launchviewer = 0 : End If 
'	'If launchviewer = 1 Then ThisDoc.Launch(CSVpath + ThisDoc.FileName(False) + ".xlsx")
'	If launchviewer = 1 Then ThisDoc.Launch(CSVpath + ThisDoc.FileName(False) + " STRUCTURED BoM ALL LEVELS.xlsx")
				
		' Define the file to create/open
		'myXLS_File = "C:\Temp\Best_Excel_File_Ever.xls"
		myXLS_File = (CSVpath + ThisDoc.FileName(False) + " STRUCTURED BoM ALL LEVELS.xlsx")
		
		' Get the Inventor user name From the Inventor Options
		myName= ThisApplication.GeneralOptions.UserName
		
		' Define Excel Application object
		'excelApp = CreateObject("Excel.Application")
		Dim ExcelApp As Microsoft.Office.Interop.Excel.Application = GetExcel
				
		' Set Excel to run visibly, change to false if you want to run it invisibly
		excelApp.Visible = True
		' Suppress prompts (such as the compatibility checker)
		excelApp.DisplayAlerts = False
		
		' Check for existing file 
		If Dir(myXLS_File) <> "" Then
		' Workbook exists, open it
		excelWorkbook = excelApp.Workbooks.Open(myXLS_File)
		ExcelSheet = excelWorkbook.Worksheets(1)
		Else
		' Create a new spreadsheet from template
		'excelWorkbook = excelApp.Workbooks.Add (Template: = "C:\Temp\Best_Excel_Template_Ever.xlt")
		End If
		
		'Dim ExcelApp As Microsoft.Office.Interop.Excel.Application = GetExcel
		Dim oWB1 As Workbook = excelApp.ActiveWorkbook
		CreateTable(excelApp, oWB1, "TableStyleLight12")		
		
		' Insert data into Excel.
'		With excelApp
'			.Range("A1").Select
'			.ActiveCell.FormulaR1C1 = "Hello, " & myName
'		End With   		
		
		' Set all of the columns to autofit
		excelApp.Columns.AutoFit		
					
		' Save the file
		'excelWorkbook.SaveAs (myXLS_File)
		
		'' Close the workbook and the Excel Application
		'' Uncomment if you want to close the xls file at the end
		'excelWorkbook.Close
		'excelApp.Quit
		'excelApp = Nothing
		
	End Sub



Private Sub CreateTable(ByVal oExcelApp As Excel.Application, ByVal oWB As Workbook, ByVal TableStyle As String)
    Dim oWs As WorkSheet = oWB.ActiveSheet
    ' Get Last Row and Last Column as numbers
    Dim LR As Long ' = oWs.Cells(oWs.Rows.Count, "A").End(xlUp).row
    Dim LC As Long ' = oWs.Cells(1, oWs.Columns.Count).End(xlToLeft).column
		
        LR = oWs.Rows(oWs.Rows.Count).Row
        LC = oWs.Columns(oWs.Columns.Count).Column
    	
'	'Sub LastRowInOneColumn()
''Find the last used row in a Column: column A in this example
'    Dim LR As Long
'    With ActiveSheet
'        LR = .Cells(.Rows.Count, "A").End(xlUp).Row
'    End With
'    'MsgBox LastRow
''End Sub

''Sub LastColumnInOneRow()
''Find the last used column in a Row: row 1 in this example
'    Dim LC As Integer
'    With ActiveSheet
'        LC = .Cells(1, .Columns.Count).End(xlToLeft).Column
'    End With
'    'MsgBox LastCol
''End Sub	
	
    ' Create Table
    Dim rng As Range = oWs.Cells(1, 1).Resize(LR, LC)
    oWs.ListObjects.Add(xlSrcRange, xllistobjecthasheaders:=xlYes, Destination:=rng)
    oWs.ListObjects(1).Name = "Table"
    oWs.ListObjects(1).TableStyle = TableStyle '"TableStyleLight21"
    oWs = Nothing
    oWB = Nothing
    oExcelApp = Nothing
End Sub

Function GetExcel() As Microsoft.Office.Interop.Excel.Application
	Dim oXL As Microsoft.Office.Interop.Excel.Application
	Try
		'try to find an already running instance of the Excel Application
		oXL = GetObject( "Excel.Application")
	Catch
		'it wasn't found open, so create an instance of it (start the application)
		oXL = CreateObject("Excel.Application")
		'oXL = New Microsoft.Office.Interop.Excel.Application
	Catch
		MsgBox("Failed to Get/Create an instance of the Excel Application. Exiting.", , "")
		Exit Function
	End Try
	Return oXL
End Function
0 Likes
Message 4 of 12

A.Acheson
Mentor
Mentor
Accepted solution

I gave this a shot and couldn't work it out even with multiple stack overflow searches. The options may not be available. 

What does work is simply adding the listobject with no options. It seems all the default options work to create the table. 

oWs.ListObjects.Add()

 I hope that helps. 

If this solved a problem, please click (accept) as solution.‌‌‌‌
Or if this helped you, please, click (like)‌‌
Regards
Alan
0 Likes
Message 5 of 12

fidel.makatiaD5W7V
Alumni
Alumni

Hi @checkcheck_master , find these sample code i made sometimes back that creates an ipart and an excel table for it

Just thought i should put it here even for other readers 

    Public Sub CreateiPart()

        Dim oPartDoc As PartDocument
        oPartDoc = _InvApplication.Documents.Add(DocumentTypeEnum.kPartDocumentObject,
                   _InvApplication.FileManager.GetTemplateFile(DocumentTypeEnum.kPartDocumentObject),
                   True)

        oPartDoc.SaveAs("C:\Temp\APIPart.ipt", False)

        Dim oTG As TransientGeometry
        oTG = _InvApplication.TransientGeometry

        Dim oCompDef As PartComponentDefinition
        oCompDef = oPartDoc.ComponentDefinition

        Dim oPoints(3) As Point2d

        oPoints(0) = oTG.CreatePoint2d(0, 0)
        oPoints(1) = oTG.CreatePoint2d(5, 0)
        oPoints(2) = oTG.CreatePoint2d(5, 5)
        oPoints(3) = oTG.CreatePoint2d(0, 5)

        Dim oSketch As PlanarSketch
        oSketch = oCompDef.Sketches.Add(oCompDef.WorkPlanes(1))

        Dim oLines(3) As SketchLine

        oLines(0) = oSketch.SketchLines.AddByTwoPoints(oPoints(0), oPoints(1))
        oLines(1) = oSketch.SketchLines.AddByTwoPoints(oLines(0).EndSketchPoint, oPoints(2))
        oLines(2) = oSketch.SketchLines.AddByTwoPoints(oLines(1).EndSketchPoint, oPoints(3))
        oLines(3) = oSketch.SketchLines.AddByTwoPoints(oLines(2).EndSketchPoint, oLines(0).StartSketchPoint)

        Dim oProfile As Profile
        oProfile = oSketch.Profiles.AddForSolid

        Dim oExtrude As ExtrudeFeature
        oExtrude = oCompDef.Features.ExtrudeFeatures.AddByDistanceExtent(oProfile, 15,
                        PartFeatureExtentDirectionEnum.kPositiveExtentDirection,
                        PartFeatureOperationEnum.kNewBodyOperation, 0)

        oExtrude.FeatureDimensions(1).Parameter.Name = "Length"
        oExtrude.FeatureDimensions(2).Parameter.Name = "TaperAngle"

        Dim oFactory As iPartFactory
        oFactory = oCompDef.CreateFactory

        Dim oWS As Microsoft.Office.Interop.Excel.Worksheet
        oWS = oFactory.ExcelWorkSheet







        oWS.Cells(1, 1) = "Member<defaultRow>1</defaultRow><filename></filename>"
        oWS.Cells(1, 2) = "Part Number [Project]"
        oWS.Cells(1, 3) = "Length<free>150 mm</free>"
        oWS.Cells(1, 4) = "TaperAngle"

        oWS.Cells(2, 1) = "APIiPart-01"
        oWS.Cells(2, 2) = "APIiPart-01"
        oWS.Cells(2, 3) = "150 mm"
        oWS.Cells(2, 4) = "0 deg"

        oWS.Cells(3, 1) = "APIiPart-02"
        oWS.Cells(3, 2) = "APIiPart-02"
        oWS.Cells(3, 3) = "100 mm"
        oWS.Cells(3, 4) = "5 deg"

        oWS.Cells(4, 1) = "APIiPart-03"
        oWS.Cells(4, 2) = "APIiPart-03"
        oWS.Cells(4, 3) = "50 mm"
        oWS.Cells(4, 4) = "10 deg"

        Dim oWB As Microsoft.Office.Interop.Excel.Workbook
        oWB = oWS.Parent

        oWB.Save()
        oWB.SaveAs("C:\Temp\Test.xls")
        oWB.Close()

        oPartDoc.Update()
        oPartDoc.Save()

    End Sub


Fidel Makatia
Developer Advocate

href=https://help.autodesk.com/view/INVNTOR/2022/ENU/?guid=GUID-0BD48573-7193-4285-87B7-6727555D053E rel= "noopener noreferrer">Inventor 2022 Documentation |
0 Likes
Message 6 of 12

checkcheck_master
Advocate
Advocate

Thank you Fidel for your message.
Although I think this is a different type of Table, your code does look very interesting.
However, I can't get it to work, see screenshots.
Can you tell me how I can get it to work?

0 Likes
Message 7 of 12

checkcheck_master
Advocate
Advocate

Thank you A.Acheson for your response and sorting it out.
Indeed this just works.
I still had hope that:
'Imports Microsoft.Office.Interop.Excel.Constants '
would make a difference, but it wouldn't.

0 Likes
Message 8 of 12

WCrihfield
Mentor
Mentor

Just an additional link about the Worksheet.ListObjects property.  It seems like, to use that resource we may need to include more References and/or Imports.  The online documentation page for that in Microsoft's site only shows it being used by C#, and says that is used by Visual Studio Tools for Office.  It shows the 'Namespace' and the 'Assembly' (.dll file) where it is sourced from.  You might be able to use that info to include its recognition / functionality within the iLogic rule.   I have never tried using that specific property or object type before, so I just left that part of the code alone for now.

 

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

0 Likes
Message 9 of 12

checkcheck_master
Advocate
Advocate
Thanks, good to know.
Apart from that, it is still a challenge for me to program against Excel in iLogic/VB.net.
You can find everything for VBA, but a lot less for VB.net.
The impression is often created that people are talking about VB.net, which turns out to be secretly VBA.

For example, I try to find the Column with header 'Item QTY' through code, but I can't manage it.
This worked fine in VBA using:

' Find column number and letter 'Item QTY'
Dim lQTY As Long
lQTY = FindColumn(oExcelApp, oWB, "Item QTY")
If lQTY = 0 Then
Call MsgBox("Column Item QTY missing.", vbCritical, "ExportBOM")
'Filter = Nothing
Exit Sub 'Function
End If

Private Function FindColumn(ByVal oExcelApp As Excel.Application, ByVal oWB As Workbook, ByVal strColumn As String) As Long
Dim lLastColumn As Long
lLastColumn = oExcelApp.Cells(1, oWB.ActiveSheet.Columns.Count).End(xlToLeft).Columns.column

Dim's As Long
Dim rCells As Range
For s = lLastColumn To 1 Step -1
Set rCells = oExcelApp.Cells(1, s)
If rCells.value = strColumn Then
FindColumn = s
Exit For
End If
Next s
End Function

What else needs to be done in iLogic/VB.net to get this to work?
0 Likes
Message 10 of 12

WCrihfield
Mentor
Mentor

Just from a first glance, without digging into it yet, I can already see two potential problems in the code you just posted.

Dim's As Long

should be like this:

Dim s As Long

and in this next line:

Set rCells = oExcelApp.Cells(1, s)

you need to get rid of the 'Set' keyword at the beginning of the line, because that is pretty much only used in VBA.

I also think it is a little odd to be using the 'Cells' property directly from the Excel.Application object.  Usually that is called from a Worksheet object directly (avoids confusion of which Workbook and which Worksheet it should be focusing on), or from a Range object directly.  Also, within the same line of code (setting the value of 'ILastColumn'), I see a variable being used 'xlToLeft', within the End() call, but I do not see where that variable is being passed to that Function, or where it is being defined before that point within that Function.  So, I don't if that variable has any value/meaning there.  I also see that that Function (FindColumn) is supposed to return a Long type value, but I don't see anywhere within that function where it is supposed to 'Return' any value.  And all the 'Input' variables are ByVal, instead of ByRef, so I don't think a value could be returned that way either.  Also, you generally don't need to use the keyword 'Call' in iLogic.

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

0 Likes
Message 11 of 12

A.Acheson
Mentor
Mentor

*

If this solved a problem, please click (accept) as solution.‌‌‌‌
Or if this helped you, please, click (like)‌‌
Regards
Alan
0 Likes
Message 12 of 12

A.Acheson
Mentor
Mentor

I response to the ipart table question earlier. The original code is missing the correct application object for inventor.
_InvApplication =ThisApplication

 

Link to what this means 

If this solved a problem, please click (accept) as solution.‌‌‌‌
Or if this helped you, please, click (like)‌‌
Regards
Alan
0 Likes