Community
Inventor Programming - iLogic, Macros, AddIns & Apprentice
Inventor iLogic, Macros, AddIns & Apprentice Forum. Share your knowledge, ask questions, and explore popular Inventor topics related to programming, creating add-ins, macros, working with the API or creating iLogic tools.
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Inventor Throwing Error set by Invocation Help

9 REPLIES 9
SOLVED
Reply
Message 1 of 10
ABoaro
931 Views, 9 Replies

Inventor Throwing Error set by Invocation Help

The follow error gets thrown immediately when I try to run the rule.

 

System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.NullReferenceException: Object reference not set to an instance of an object.
   at ThisRule..ctor()
   --- End of inner exception stack trace ---
   at System.RuntimeTypeHandle.CreateInstance(RuntimeType type, Boolean publicOnly, Boolean noCheck, Boolean& canBeCached, RuntimeMethodHandleInternal& ctor, Boolean& bNeedSecurityCheck)
   at System.RuntimeType.CreateInstanceSlow(Boolean publicOnly, Boolean skipCheckThis, Boolean fillCache, StackCrawlMark& stackMark)
   at System.Activator.CreateInstance(Type type, Boolean nonPublic)
   at System.RuntimeType.CreateInstanceImpl(BindingFlags bindingAttr, Binder binder, Object[] args, CultureInfo culture, Object[] activationAttributes, StackCrawlMark& stackMark)
   at System.Activator.CreateInstance(Type type, BindingFlags bindingAttr, Binder binder, Object[] args, CultureInfo culture, Object[] activationAttributes)
   at System.Reflection.Assembly.CreateInstance(String typeName, Boolean ignoreCase, BindingFlags bindingAttr, Binder binder, Object[] args, CultureInfo culture, Object[] activationAttributes)
   at Autodesk.iLogic.Exec.AppDomExec.CreateObjectWithInterface(Assembly a, String interfaceName)
   at Autodesk.iLogic.Exec.AppDomExec.ExecRuleInAssembly(Assembly assem)
   at iLogic.RuleEvalContainer.ExecRuleEval(String execRule)

 

 

The code I try to run is as follows. Can someone help to debug this?

 

'Sub Routing to Define Sub Run Order
Sub Main()
	CreateEmptyDictionary()
	CreateFastenerDictionary()
	CreateVirtualParts()
End Sub

'Public Declarations for use in all functions
Public Dim PartPropertiesFileAddr As String = "04_Part_iProperties.xlsm"
Public Dim FastenerPropertyFileAddr As String = "C:\Downloads\Fastener_Project_Properties.xlsm"
Public Dim oPartDictionary As New Dictionary(Of String, Dictionary(Of String, Integer))
Public Dim oAssy As AssemblyDocument = ThisDoc.Document
Public Dim oAsmCompDef As AssemblyComponentDefinition = oAssy.ComponentDefinition

'Prepopulates the oPartDictionary from an Excel Sheet master
Sub CreateEmptyDictionary
'Find Max Iterations in Parts Sheet
GoExcel.Open(PartPropertiesFileAddr,"Parts")
Dim PartsMaxIterations As Integer = GoExcel.CellValue("F1")

For Rows = 4 To PartsMaxIterations
	'Compare the Material Setting to weed out non-screwed/fastened pieces
	If GoExcel.CellValue("D" & Rows) = "Aluminum" Then
		Dim PartName As String = GoExcel.CellValue("A" & Rows)
		Dim EmptyDictionary As New Dictionary(Of String, Integer)
		oPartDictionary.Add(PartName, EmptyDictionary)
	End If
Next
GoExcel.Close
End Sub

Public Dim oFastDictionary As New Dictionary(Of String, Integer)
Sub CreateFastenerDictionary()
	GoExcel.Open(FastenerPropertyFileAddr, "Fasteners")
	oNumFast = GoExcel.CellValue("J" & 1)
	oNumExtr = GoExcel.CellValue("F" & 1)
	For extrusionID = 4 To NumExtr
		' Holds name of Extrusion in Each Iteration
		UnitExtrusion = GoExcel.CellValue("A" & extrusionID)
		' If the unit has the extrusion checked in excel sheet, then fill out fastener dictionary
		If oPartDictionary.Contains(UnitExtrusion) Then
			For fastenerID = 2 To oNumFast
				'Changes the Character for Clumn
				FastenerCol = "A" + fastenerID - 1
				FastQuantity = GoExcel.CellValue(FastenerCol & fastenerID)
				If FastQuantity <> 0 Then
					' Grab ID of every Fastener that does have a # of parts
					Dim ofastenerName As String = GoExcel.CellValue(FastenerCol & 3)
					oFastDictionary.Add(ofastenerName,FastQuantity)
				End If
			Next
			'Skip to next fastener 
		End If
		'End searching for the part
	Next
	GoExcel.Close
End Sub


'Loop through the assembly to check how many virtual parts are to be made
Sub CreateVirtualParts
'Once the Level 1 Dictionary is created, the FastenerDictionary needs to be generated
Dim i As Integer = 0 ' Holding Index Variable
Dim identity As Matrix = ThisApplication.TransientGeometry.CreateMatrix

' Loop through all the Parts
For Each oOcc As ComponentOccurrence In oAsmCompDef.Occurrences
	'Only look to check if the part itself is not already virtual 
	If Not TypeOf oOcc.Definition Is VirtualComponentDefinition Then
		On Error Resume Next
		oDocFile = oOcc.Definition.Document
		oDocFileName = oDocFile.displayname
		'Set your delimiter
		Delimiter = InStr(oDocFileName, "-")
		Description = Left(oDocFileName, Delimiter - 1)
		' Check if Part Dictionary contains the part for the model
		If oPartDictionary.ContainsKey(Description) Then
			' If it does have the Part, then get the Fastener dictionary and create the number of virtual parts
			' This for loop uses the oOcc to find keys in the map instead of looping through the map
			For Each oFastenerType As String In oPartDictionary(Description).Keys
				For i = 1 To oPartDictionary(Description)(oFastenerType)
				' Loop through each fastener type within the Fastener dictionary ^
				' Virtual Part Parameters
				FastenerName = oFastenerType & ":" & i
				'oProp1 = oFastenerType
				
				'Create a new component occurrence
				Dim oNewOcc As ComponentOccurrence = oAsmCompDef.Occurences	 
				virtOcc = oNewOcc.AddVirtual(FastenerName, identity)
				
				'Create Virtual Component Definition
				Dim oCVirtualCompDef As VirtualComponentDefinition 
				oCVirtualCompDef = oNewOcc.Definition
		        'iProperties.Value(FastenerName & ":1", "Project", "Description") = oProp1
				i = i + 1
				Next
			Next
		End If
	End If
Next
End Sub

 

 

The excel document has the following template:

Fastener_Project_Properties Excel.PNG

 

9 REPLIES 9
Message 2 of 10
omartin
in reply to: ABoaro

At first glance; Public Dim PartPropertiesFileAddr As String = "04_Part_iProperties.xlsm"

looks suspicious is this the correct file you want to use? Also when you are assigning objects to variables it is good to check for null before using them. this will help with debugging or you can use try/catch blocks with a messageBox for these assignment to know exactly where it is failing

Was my reply Helpful ? send a Kudos or accept as solution
Message 3 of 10
ABoaro
in reply to: omartin

I will try the null approach. I am coming from C++ and I am wondering how is NULL checked in VBA.Net specifically.

 

And yes, the Parts Properties excel file is a macro enabled sheet that has code within the sheet to feed information to iLogic. Could it be that iLogic only likes .xls style files?

 

Thank you for a point in a debugging direction.

 

Message 4 of 10
omartin
in reply to: ABoaro

I have not used goExcel myself, but I read it has a lot of finickey behaviour. you can do a small test to ensure that file is being loaded properly with xlsm, otherwise it is some other object that is failng on assignment, you can use is the, "is nothing" to check for null objects

Best Regards

Was my reply Helpful ? send a Kudos or accept as solution
Message 5 of 10
ABoaro
in reply to: omartin

I went ahead and adjusted the format. The sub feature of the set up was what was throwing null exceptions. Now I am getting a similar error but for the Dictionary Definition.

 

I am wondering if you know how to set objects either as NULL or set the dictionary to am empty dictionary. I am hoping after that it should be fixed.

 

But to answer your other point, yes it is an excel file. The path for xlsm is just a type of excel sheet with macros that I programmed into that myself. I haven't had issues with that before. 

Message 6 of 10
omartin
in reply to: ABoaro

As soon as you new up the dictionary, it wont be null, it will be empty and you will be able to add to it, as long as the key you are adding is not null or duplicate.

 

You do not want to set it to null or nothing after it has been new'd up other wise you wont be able to add to it and you will get a null excepton, you just want to clear() it out.

 

Im just looking at the CreateEmptyDictionary() is this where it is failing, what was the error message it may leave some clues

 

Was my reply Helpful ? send a Kudos or accept as solution
Message 7 of 10
ABoaro
in reply to: omartin

After tediously going line by line and commenting out and determining what works, I found that the invocation error was fixed when I did the following change:

Dim EmptyDictionary As New Dictionary(Of String, Integer)

to this:

 

Dim EmptyDictionary = New Dictionary(Of String, Integer)

The null error appeared to have gone away with this fix. Unsure how this differs from the first declaration of the empty dictionary.  

 

My next error occurs when I am looping through the excel columns. GoExcel seems to only like character indices when getting a specific value. I get an error message about looping through the columns:

 

System.ArgumentException: Argument 'Limit' is Nothing.
at Microsoft.VisualBasic.CompilerServices.ObjectFlowControl.ForLoopControl.ForLoopInitObj(Object Counter, Object Start, Object Limit, Object StepValue, Object& LoopForResult, Object& CounterResult)
at ThisRule.Main()
at Autodesk.iLogic.Exec.AppDomExec.ExecRuleInAssembly(Assembly assem)
at iLogic.RuleEvalContainer.ExecRuleEval(String execRule)

 

Not sure if you can help with that at least. I know you are weary of Excel. 

Message 8 of 10
omartin
in reply to: ABoaro

I pretty sure the 'limit' is what your for loop is counting to, seems like it is not being set, if you are getting a value from the f1 column it may need to be converted to integer first. I dont have access to inventor right now so im just going off the top
Was my reply Helpful ? send a Kudos or accept as solution
Message 9 of 10
ABoaro
in reply to: omartin

I have provided the updated code below that has fixed all the bugs I was having. I needed to convert some of the cell types from Excel to strings and others to numbers to ensure my looping worked. 

 

Although, taking you suggestion, I may steer away from Excel come the future.

'Public Declarations for use in all functions
 Dim PartPropertiesFileAddr As String = "W:\Projects-Walters-Wolf\2019\19-04_MSCM_Samm\4-Production_Drawings\19-04_Part_iProperties.xlsm"
 Dim FastenerPropertyFileAddr As String = "C:\Users\aboaro\Downloads\Fastener_Project_Properties.xlsm"
 Dim oPartDictionary = New Dictionary(Of String, Dictionary(Of String, Integer))
 Dim oAssy As AssemblyDocument = ThisDoc.Document
 Dim oAsmCompDef As AssemblyComponentDefinition = oAssy.ComponentDefinition
 Dim List = New String(){"B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T","U", "V", "W", "X", "Y", "Z", "AA", "AB", "AC", "AD", "AE", "AF", "AG", "AH", "AI", "AJ", "AK", "AL", "AM"}
 
'Find Max Iterations in Parts Sheet
GoExcel.Open(PartPropertiesFileAddr,"Parts")
Dim PartsMaxIterations As Integer = GoExcel.CellValue("F1")
For Rows = 4 To PartsMaxIterations
	'Compare the Material Setting to weed out non-screwed/fastened pieces
	If GoExcel.CellValue("D" & Rows) = "Aluminum" Then
		Dim PartName As String = GoExcel.CellValue("A" & Rows)
		Dim EmptyDictionary As New Dictionary(Of String, Integer)
		oPartDictionary.Add(PartName, EmptyDictionary)
	End If
Next
GoExcel.Close

Dim oFastDictionary As New Dictionary(Of String, Integer)
GoExcel.Open(FastenerPropertyFileAddr, "Fasteners")
	
Dim oNumFast As Integer = GoExcel.CellValue("J" & 1)
Dim oNumExtr As Integer = GoExcel.CellValue("K" & 1)
	'Row number matched to specific Extrusion
	For extrusionID = 4 To oNumExtr
		' Holds name of Extrusion in Each Iteration
		Dim oUnitExtrusion As String = GoExcel.CellValue("A" & extrusionID)
		' If the unit has the extrusion checked in excel sheet, then fill out fastener dictionary
		If oPartDictionary.Keys.Contains(oUnitExtrusion) Then
			For fastenerID = 2 To List.Length
				' Selects Column Letter
				FastenerCol = List(fastenerID - 2)
				'Number of Fasteners
				FastQuantity = GoExcel.CellValue(FastenerCol & extrusionID)
				
				If FastQuantity <> 0 Then
					' Grab ID of every Fastener that does have a # of parts
					Dim ofastenerName As String = CStr(GoExcel.CellValue(FastenerCol & 3))
					'MsgBox(ofastenerName) -> show fastener name
					'MsgBox(FastQuantity) -> show Fastener Quantity
					'Add fastener to the fastener dictionary for specific part
					oFastDictionary.Add(ofastenerName, FastQuantity)
	
				End If
			Next ' End Fastener Check
			oPartDictionary(oUnitExtrusion) = oFastDictionary
			oFastDictionary = New Dictionary(Of String, Integer)
		End If
		'End searching for the part
	Next
	GoExcel.Close



'Loop through the assembly to check how many virtual parts are to be made
'Once the Level 1 Dictionary is created, the FastenerDictionary needs to be generated
'Dim i As Integer = 0 ' Holding Index Variable


'' Loop through all the Parts
For Each oOcc As ComponentOccurrence In oAsmCompDef.Occurrences
	'Only look to check if the part itself is not already virtual 
	If Not TypeOf oOcc.Definition Is VirtualComponentDefinition Then
		On Error Resume Next
		Dim identity As Matrix = ThisApplication.TransientGeometry.CreateMatrix
		oDocFile = oOcc.Definition.Document
		oDocFileName = oDocFile.displayname
		'Set your delimiter
		Delimiter = InStr(oDocFileName, "-")
		Description = Left(oDocFileName, Delimiter - 1)
		MsgBox(Description)
		' Check if Part Dictionary contains the part for the model
		If oPartDictionary.ContainsKey(Description) Then
			' If it does have the Part, then get the Fastener dictionary and create the number of virtual parts
			' This for loop uses the oOcc to find keys in the map instead of looping through the map
			MsgBox(oPartDictionary(Description).Keys.Count)
			For Each oFastenerType As String In oPartDictionary(Description).Keys
				'MsgBox(oPartDictionary(Description)(oFastenerType))
				For i = 0 To oPartDictionary(Description)(oFastenerType)
'				' Loop through each fastener type within the Fastener dictionary ^
'				' Virtual Part Parameters
				FastenerName = oFastenerType & ":" & (i + 1)
				'oProp1 = oFastenerType
				
'				'Create a new component occurrence
				Dim oNewOcc As ComponentOccurrence 
				oNewOcc = oAsmCompDef.Occurrences.AddVirtual(FastenerName, identity) 
				Dim oCVirtualCompDef As VirtualComponentDefinition 
				oCVirtualCompDef = oNewOcc.Definition 
				
				'Create Virtual Component Definition
				'Dim oCVirtualCompDef As VirtualComponentDefinition 
				'oCVirtualCompDef = oNewOcc.Definition
		        'iProperties.Value(FastenerName & ":1", "Project", "Description") = oProp1
'				i = i + 1
				Next
			Next
		End If
	End If
Next

 

Message 10 of 10
omartin
in reply to: ABoaro

Glad to hear it all worked out!  some times you got to do what ya got to do and now you know more things to look out for.

you can look in to creating excel as an object and then using the native excel commands, I find this more predictable.

Cheers

Was my reply Helpful ? send a Kudos or accept as solution

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk Design & Make Report