Occasional "Object Variable or With block Variable Not Set" Error on ext. iLogic

Occasional "Object Variable or With block Variable Not Set" Error on ext. iLogic

Maxim-CADman77
Advisor Advisor
4,986 Views
24 Replies
Message 1 of 25

Occasional "Object Variable or With block Variable Not Set" Error on ext. iLogic

Maxim-CADman77
Advisor
Advisor

We do have set of external iLogic rules running automatically on Open and Save Inventor Documents with IDC (Inventor Design Checker).

Some (AFAIK only two particular) IPT oriented rules sometimes produce error "Object Variable or With block Variable Not Set".

Here is a bit simplified code of one:

Try

Dim oCompdef As PartComponentDefinition
oCompdef = ThisDoc.Document.ComponentDefinition
Dim oSketch As Sketch

''' Initial argument values
msg = "There were no unused sketches found."
retval = 1

For each oSketch in oCompdef.Sketches	
	If oSketch.HealthStatus <> HealthStatusEnum.kBeyondStopNodeHealth And oSketch.Consumed = False	Then
		msg = "There is at least one unused sketch - " & oSketch.Name	
		retval = 0
Exit For
	End if
Next

RuleArguments.Arguments.Value("ReturnValue") = retval
RuleArguments.Arguments.Value("Description") = msg

Catch
End Try

Trace.WriteLine (retval & "; " & msg)

 

The Error occurs occasionally. I see no relation to particular IPTs. Sometimes it even happens on creating new IPT. Sometimes Inventor reboot helps.

How could I debug such occasional errors?

Please vote for Inventor-Idea Text Search within Option Names

0 Likes
Accepted solutions (1)
4,987 Views
24 Replies
Replies (24)
Message 2 of 25

AlexFielder
Advisor
Advisor
I would simply check that the number of sketches in a part file is > 0, then if it is, proceed with your check (because there will be something to check).

I'm not sure whether you use sketchblocks in your part template file , but that may have a bearing on whether or not Inventor thinks there are sketches in the (new) part file or not - you would have to test two template files, one with a sketchblock, one without to be sure.

I suppose you should also be checking whether the document you are opening is actually a part file because that will cause an error if not (unless you have the trigger for this rule set to "part files only"?).
0 Likes
Message 3 of 25

Maxim-CADman77
Advisor
Advisor

Thank you for the reaction

I've added pre-check for oCompdef.Sketches.Count.

Our template contains neither Skatches nor Sketchblocks.

Trigger of check execution "on IPTs only" does set in IDC-profile.

 

As soon as error is occasional I can't say whether adding pre-check helped.

Would report back in a week (or sooner if get error again).

 

 

Please vote for Inventor-Idea Text Search within Option Names

0 Likes
Message 4 of 25

Maxim-CADman77
Advisor
Advisor

Alas!

Just got again this error.

After restarting Inventor cant reproduce it on that same DOC.

Please vote for Inventor-Idea Text Search within Option Names

0 Likes
Message 5 of 25

AlexFielder
Advisor
Advisor
What does the rule code look like now?
0 Likes
Message 6 of 25

Maxim-CADman77
Advisor
Advisor
Try

Dim oCompdef As PartComponentDefinition
oCompdef = ThisDoc.Document.ComponentDefinition
Dim oSketch As Sketch

''' Initial argument values
msg = "There were no unused sketches found."
retval = 1

If oCompdef.Sketches.Count=0 Then
	msg = "The check is inapplicable (no sketches)."
Else
	For Each oSketch in oCompdef.Sketches
		If oSketch.HealthStatus <> HealthStatusEnum.kBeyondStopNodeHealth And oSketch.Consumed = False Then
			msg = "There is at least one unused sketch ("& oSketch.Name & ")."
			retval = 0
	Exit For
		End if
	Next
End If
 
RuleArguments.Arguments.Value("ReturnValue") = retval
RuleArguments.Arguments.Value("Description") = msg

Catch
End Try

MsgBox (retval & "; " & msg)

Please vote for Inventor-Idea Text Search within Option Names

0 Likes
Message 7 of 25

Maxim-CADman77
Advisor
Advisor

Btw. I begin to think "Try-Catch-End Try" does not suits ideally here.

Somewhere I've seen "On error" construction but I don't know where to find how to use it.

Please vote for Inventor-Idea Text Search within Option Names

0 Likes
Message 8 of 25

Maxim-CADman77
Advisor
Advisor

I've just "work-arounded" another iLogic rule (for checking IDWs) that for some files always generated error 0x80020003 on first run.

The workaround was to move "Try" somewhere in the beginning (it was before arguments output).

The rule then still failed on first run (mutely i.e. without interrupting process to show the error window).

Second run (here we used to auto-run check rules at least twice - on open and on save, also manually if needed) then runs ok.

Not perfect and I'd rather know how to make it's first run be ok but much better then with errors.

But unfortunately this method doesn't work with this rule  (Try is already stands before the main code).

 

Please vote for Inventor-Idea Text Search within Option Names

0 Likes
Message 9 of 25

MjDeck
Autodesk
Autodesk
Accepted solution

It's likely that the line

oCompdef = ThisDoc.Document.ComponentDefinition

is causing the problem. There is no ComponentDefinition property on the Document object. Despite that, the code will usually work by late binding to a PartDocument or AssemblyDocument object. However, it can sometimes fail. We've got a fix for this that should be released soon. To work around it:

Dim partDoc As PartDocument = ThisDoc.Document
oCompDef = partDoc.ComponentDefinition

I'd also recommend moving the code that makes the initial assignment to msg and retval to the top of the rule, outside of the try-catch block.


Mike Deck
Software Developer
Autodesk, Inc.

Message 10 of 25

MjDeck
Autodesk
Autodesk

This has been fixed in the Inventor 2019.2 update. A statement such as 

oCompdef = ThisDoc.Document.ComponentDefinition

should always work in 2019.2.

This is issue INVGEN-11073.


Mike Deck
Software Developer
Autodesk, Inc.

Message 11 of 25

Maxim-CADman77
Advisor
Advisor

Lucky those who are going after us - using our pathway they can go faster and get further 🙂 
(unfortunately our company doesn't have plans to upgrade to 2019 ... mainly because of data-migration challenges).

Please vote for Inventor-Idea Text Search within Option Names

Message 12 of 25

DRoam
Mentor
Mentor

@MjDeck wrote:

This has been fixed in the Inventor 2019.2 update. A statement such as 

oCompdef = ThisDoc.Document.ComponentDefinition

should always work in 2019.2.

This is issue INVGEN-11073.


This is really great to hear, thanks for sharing that, Mike.

 

For those of us stuck pre-2019, is there any other workaround (besides explicitly declaring as PartDocument or AssemblyDocument) that can help Inventor out with the late binding and successfully get the ComponentDefinition property for both assemblies and parts?

0 Likes
Message 13 of 25

MjDeck
Autodesk
Autodesk

@DRoam, that's the only workaround that I know of. Are you running Inventor 2018?


Mike Deck
Software Developer
Autodesk, Inc.

0 Likes
Message 14 of 25

DRoam
Mentor
Mentor

We're currently running Inventor 2017.4.6. Why do you ask, is there a workaround for 2018? We may be upgrading to that in the not-too-distant future.

0 Likes
Message 15 of 25

MjDeck
Autodesk
Autodesk

There's no 2018-specific workaround. I'm asking because we might be able to apply the 2019.2 fix to a 2018 update as well. I'll take a look at that.


Mike Deck
Software Developer
Autodesk, Inc.

0 Likes
Message 16 of 25

DRoam
Mentor
Mentor

Ok, thanks for looking into it.

 

In the meantime, I did some research and learned about the VB function "CType". I'm hoping it may do what we need? I tested it using the following code and it doesn't produce any errors:

 

Dim oAssyDoc As Inventor.AssemblyDocument = ThisDoc.Document
Dim oOccurrences As Inventor.ComponentOccurrences = oAssyDoc.ComponentDefinition.Occurrences

Dim oOcc As Inventor.ComponentOccurrence
Dim oCompDef As Inventor.ComponentDefinition

For Each oOcc In oOccurrences
	'Convert Occurrence's Document object to the appropriate document type, and set oOccDoc equal to it
	Dim oOccDoc As Object
	
	If oOcc.Definition.Document.DocumentType = DocumentTypeEnum.kPartDocumentObject Then
		oOccDoc = CType(oOcc.Definition.Document,Inventor.PartDocument)
	Else If oOcc.Definition.Document.DocumentType = DocumentTypeEnum.kAssemblyDocumentObject Then
		oOccDoc = CType(oOcc.Definition.Document,Inventor.AssemblyDocument)
	End If
	
	'Get occurrence's documents's component definition
	oCompDef = oOccDoc.ComponentDefinition
	
	'Access some properties of the component definition
	oParameters = oCompDef.Parameters
	oBOMStructure = oCompDef.BOMStructure
Next

However, since the late binding error happens randomly, I'm not sure how to confirm if this fixes it or not.

 

Do you think this could fix the late binding issue? Any suggestions on how to test it?

0 Likes
Message 17 of 25

DRoam
Mentor
Mentor

Mike, after doing a bit more research, another (probably better) way would be to declare oOccDoc as an "Inventor.Document" rather than an object, and then use "DirectCast" rather than "CType".

 

According to this Microsoft documentation, DirectCast is an alternative to CType that can be used when one type in the conversion inherits from the other type (which is true in the case of Document and PartDocument/AssemblyDocument), and DirectCast "can provide somewhat better performance than CType".

 

So your thoughts on this as well would be appreciated.

 

As before, I tested this and it ran without errors, but I'm not sure how to confirm if it fixes the random late binding bug or not.

0 Likes
Message 18 of 25

MjDeck
Autodesk
Autodesk

I'm not sure, but it might be safer to keep the oOccDoc as Object even though the performance is slightly worse.

But it does look like, in this particular case, you don't have to explicitly declare the document as a PartDocument or AssemblyDocument. That might be because the document is coming from the ComponentDefinition.Document property, which the API declares as an Object instead of a Document.

Here's a version of your rule that leaves things as Objects if they might be either part or assembly:

Dim oAssyDoc As Inventor.AssemblyDocument = ThisDoc.Document
Dim oOccurrences As Inventor.ComponentOccurrences = oAssyDoc.ComponentDefinition.Occurrences

Dim oOcc As Inventor.ComponentOccurrence
Dim oCompDef As Object

For Each oOcc In oOccurrences
	'Convert Occurrence's Document object to the appropriate document type, and set oOccDoc equal to it
	Dim oOccDoc As Object
	
	If oOcc.Definition.Document.DocumentType = DocumentTypeEnum.kPartDocumentObject Then
		oOccDoc = oOcc.Definition.Document
	Else If oOcc.Definition.Document.DocumentType = DocumentTypeEnum.kAssemblyDocumentObject Then
		oOccDoc = oOcc.Definition.Document
	End If
	
	'Get occurrence's documents's component definition
	oCompDef = oOccDoc.ComponentDefinition
	
	'Access some properties of the component definition
	oParameters = oCompDef.Parameters
	oBOMStructure = oCompDef.BOMStructure
'	MessageBox.Show("parameter count = " & oParameters.Count)
Next

I tested that and it hasn't thrown the error for me yet.

 

I think a valid test is to start a fresh Inventor session and then run the rule in a simple assembly where the first component is a part, and the second (or later) component is a subassembly. That comes close to the following scenario, which is a test that can be used to demonstrate the problem reliably.

  • start a new Inventor session
  • create a new part
  • add and run this single-line rule in the part:
    Dim compDef = ThisDoc.Document.ComponentDefinition
  • create a new assembly
  • add and run that same rule in the assembly

This should always throw an error:
Member not found. (Exception from HRESULT: 0x80020003 (DISP_E_MEMBERNOTFOUND)) 


Mike Deck
Software Developer
Autodesk, Inc.

0 Likes
Message 19 of 25

DRoam
Mentor
Mentor

@MjDeck wrote:

But it does look like, in this particular case, you don't have to explicitly declare the document as a PartDocument or AssemblyDocument. That might be because the document is coming from the ComponentDefinition.Document property, which the API declares as an Object instead of a Document.

 


From what I've experienced, whether or not the error occurs depends on two things:

1. Where the document object "came from" (in other words, how the document was accessed/processed -- possibilities being ThisDoc.Document, or iterating through occurrences, or iterating through referenced documents, etc.)

2. The "recipe" of events that took place prior to trying to access the document object's ComponentDefinition property.

 

On top of that, the recipes that will cause failure are different for each method of accessing the document object. For example, the repro steps at the end of your post will produce the error, but doing as you suggested and iterating through a few newly-created sub-assemblies and parts within an assembly does NOT seem to reproduce the error. However, I have experienced the error upon iterating through sub-components in the past. I'm just not sure what the bad recipe(s) are for reproducing this yet.

 

That said, I've been trying to find a solution that I can use reliably, regardless of prior actions and method of accessing the document object.

 

So far, I've had good luck with this function:

 

 

Function GetCompDef(oDoc As Inventor.Document)
	If oDoc.DocumentType = DocumentTypeEnum.kPartDocumentObject Then
		Return DirectCast(oDoc,Inventor.PartDocument).ComponentDefinition
	Else If oDoc.DocumentType = DocumentTypeEnum.kAssemblyDocumentObject Then
		Return DirectCast(oDoc,Inventor.AssemblyDocument).ComponentDefinition
	End If
End Function

 

 

You would use it in a rule like this:

 

 

'Instead of this:
'oCompDef = oDoc.ComponentDefinition

'Use this:
oCompDef = GetCompDef(oDoc)

 

So far I haven't seen any errors with this, but that could just mean I haven't stumbled upon "right" the series of prior events yet...

Message 20 of 25

MjDeck
Autodesk
Autodesk

I think your GetCompDef function will always work. But it's possible that you won't always be able to access all the members on the oCompDef object that it returns. That's because the PartComponentDefinition interface is different from AssemblyComponentDefinition.
I don't have a test to show this, but I'm mentioning it just in case there might be a problem.


Mike Deck
Software Developer
Autodesk, Inc.

0 Likes