Selecting a part in an assembly in Inventor drawing using VB code

Selecting a part in an assembly in Inventor drawing using VB code

m.joudivand
Enthusiast Enthusiast
2,431 Views
15 Replies
Message 1 of 16

Selecting a part in an assembly in Inventor drawing using VB code

m.joudivand
Enthusiast
Enthusiast

Hi Community,

I need to select a part in an assembly view in Invnetor drawing. The assembly includes many of that part, located in different areas therefore it takes a considerable time to pick them one by one. Are you able to let me know can it be handled using a VB code? Is it possible to enter a part name and run a code to select all the parts featuring that name?

I need it because I should move the parts to a new layer to change their line style (color, thickness and ...). This means selection mode should be set as "Select Edge Proiority".

Waiting for your help.

Thanks in advance

Mohammad

Accepted solutions (3)
2,432 Views
15 Replies
Replies (15)
Message 2 of 16

wfajber
Contributor
Contributor

Somewhere else in this forum there is this exact example where the author is doing this with parts that are pipe hangers.

 

It identifies the parts in the model, and finds the 2D curves that are in the drawing view that were generated from the 3D model edges, and moves them to a new layer. 

I copied and modified it a bit. I can post it tomorrow if you cannot find the original.

 

 

0 Likes
Message 3 of 16

m.joudivand
Enthusiast
Enthusiast

@wfajber thank you for your reply.

Are you able to paste it here please?
I can try to find the original if you let me what I should search, what the title of that post is.

 

0 Likes
Message 4 of 16

Michael.Navara
Advisor
Advisor
Accepted solution

Here is commented example how to get all drawing curve segments of all instances of part.

 

'Select drawing curve of the part
Dim pick = ThisApplication.CommandManager.Pick(SelectionFilterEnum.kDrawingCurveSegmentFilter, "Pick drawing curve")

'Get assembly occurrene which the selected DrawingCurveSegment belongs to
Dim curveSegment As DrawingCurveSegment = pick
Dim parentCurve As DrawingCurve = curveSegment.Parent
Dim someProxy = parentCurve.ModelGeometry
Dim partOcc As ComponentOccurrence = someProxy.ContainingOccurrence

'Get AssemblyDocument referenced by DrawingView
Dim drawingView As DrawingView = drawingCurve.Parent
Dim viewAsm As AssemblyDocument = drawingView.ReferencedDocumentDescriptor.ReferencedDocument

'Get all occurrences which has the same ComponentDefinition
Dim allInstancesOfPartOcc As ComponentOccurrencesEnumerator = _
viewAsm.ComponentDefinition.Occurrences.AllLeafOccurrences(partOcc.Definition)


'Get all DrawingCurveSegments of each part instance
'and convert them to ObjectCollection
Dim occDrawingCurvesCollection As ObjectCollection = ThisApplication.TransientObjects.CreateObjectCollection()
For Each occ As ComponentOccurrence In allInstancesOfPartOcc
	Dim occDrawingCurves As DrawingCurvesEnumerator = drawingView.DrawingCurves(occ)
	For Each occDrawingCurve As DrawingCurve In occDrawingCurves
		For Each occDrawingCurveSegment As DrawingCurveSegment In occDrawingCurve.Segments
			occDrawingCurvesCollection.Add(occDrawingCurveSegment)
		Next
	Next
Next

'Do something useful with occDrawingCurvesCollection

'Select all DrawingCurveSegments of the occ in the DrawingView
Dim drawingDoc As DrawingDocument = drawingView.Parent.Parent
drawingDoc.SelectSet.SelectMultiple(occDrawingCurvesCollection)

 

0 Likes
Message 5 of 16

m.joudivand
Enthusiast
Enthusiast

Dear @Michael.Navara 

Thank you for the iLogic script, I tried it. and it worked (a screenshot is attached-parts highlighted in red), but I still need to configure a VBA code for this purpose and make the process more standardized because currently using the ilogic code the process needs to be done manually and I want to make it fully automatic.
Using a VB code I want to create a customized icon for this purpose. That my ultimate goal.

Thanks for your great help again.

 

0 Likes
Message 6 of 16

Michael.Navara
Advisor
Advisor

It is possible to create button for iLogic rule (since Inventor 2023) Or you can use some extension for this purpose

For example our add-in XTools or @JelteDeJong has its own free add-in Button Constructor 

 

Or you can convert this code to VBA. You need to split variable definitions and its assignment and use 'Set' keyword appropriately. API calls are the same

0 Likes
Message 7 of 16

m.joudivand
Enthusiast
Enthusiast

Thank you @Michael.Navara for your help, I will definetly try the tools suggested.

0 Likes
Message 8 of 16

wfajber
Contributor
Contributor
Accepted solution
0 Likes
Message 9 of 16

m.joudivand
Enthusiast
Enthusiast

@wfajber thank you for the link, that is accurately addressing my case.

 

0 Likes
Message 10 of 16

m.joudivand
Enthusiast
Enthusiast

Hi @Michael.Navara 

I am trying to convert the ILogic code to an API code but not sure what is the suitable type of "ModelGeometry" here (line ---)

The code is as follows

Option Explicit

Sub PartSelection()


'Select drawing curve of the part
Dim oPick As DrawingCurveSegment
Set oPick = ThisApplication.CommandManager.Pick(SelectionFilterEnum.kDrawingCurveSegmentFilter, "Pick drawing curve")

'Get assembly occurrene which the selected DrawingCurveSegment belongs to
Dim curveSegment As DrawingCurveSegment
Set curveSegment = oPick



Dim parentCurve As DrawingCurve
Set parentCurve = curveSegment.Parent
Dim someProxy As SketchProxy 'changed
Set someProxy = parentCurve.ModelGeometry
Dim partOcc As ComponentOccurrence
Set partOcc = someProxy.ContainingOccurrence

'Get AssemblyDocument referenced by DrawingView
Dim drawingView As drawingView 'needs to be checked
Set drawingView = drawingView.parentCurve.Parent
Dim viewAsm As AssemblyDocument
Set viewAsm = drawingView.ReferencedDocumentDescriptor.ReferencedDocument

'Get all occurrences which has the same ComponentDefinition
Dim allInstancesOfPartOcc As ComponentOccurrencesEnumerator
Set allInstancesOfPartOcc = viewAsm.ComponentDefinition.Occurrences.AllLeafOccurrences(partOcc.Definition)


'Get all DrawingCurveSegments of each part instance
'and convert them to ObjectCollection
Dim occDrawingCurvesCollection As ObjectCollection
Set occDrawingCurvesCollection = ThisApplication.TransientObjects.CreateObjectCollection()

Dim occ As ComponentOccurrence

For Each occ In allInstancesOfPartOcc
    Dim occDrawingCurves As DrawingCurvesEnumerator
    Set occDrawingCurves = drawingView.DrawingCurves(occ)
    
    Dim occDrawingCurve As DrawingCurve
    For Each occDrawingCurve In occDrawingCurves
    
    Dim occDrawingCurveSegment As DrawingCurveSegment
        For Each occDrawingCurveSegment In occDrawingCurve.Segments
            occDrawingCurvesCollection.Add (occDrawingCurveSegment)
        Next
    Next
Next

'Do something useful with occDrawingCurvesCollection

'Select all DrawingCurveSegments of the occ in the DrawingView
Dim drawingDoc As DrawingDocument
Set drawingDoc = drawingView.Parent.Parent
drawingDoc.SelectSet.SelectMultiple (occDrawingCurvesCollection)
End Sub

Could you please check it and let me know what is the appropriate object type for this case?

Thanks

Mohammad

 

0 Likes
Message 11 of 16

wfajber
Contributor
Contributor

Can you clarify your question a little bit? I’m not sure what you are asking.

 

But I can provide a bit more explanation about ModelGeometry, with a perhaps overly simplified explanation of what it happening.  In this routine you’re dealing with different types of entities: Curves and Edges.  The drawing view is like a screen where the model is projected upon. The drawing shows lines and arcs but in fact the drawing is flat and 2D. The lines that are on this 2D drawing are called Curves.  In the 3D world of your model, the model has Edges. The Edges are projected on the drawing view to make the curves.

 

In this routine, your mouse is moving over a drawing, not a model. It is hovering over a drawing view and selecting a drawing curve.  But you want to know what is creating the drawing curve, so you find the ModelGeometry that created the curve. That will be an edge in your model. Then it is just a matter of finding the component occurrence that the edge belongs to.  That is what is happening on line 19 and 20.

 

More accurately, I am not just dealing with edges, but edge proxies. For example, a sphere looks like a circle in a drawing view i.e. a sphere will project  a curve in a drawing view.  But there is no edge to be found on a sphere, it is generating an edgeproxy.

 

Some of the code I have sorts through edges and edge proxies to find the parent part file. But this code does something clever. If I have a curve, it must have come from an edge or an edge proxy. And that edge or edge proxy must have come from a sketch. So line 19 is getting the sketch that created the edge (in the model) that creates the curve (in the drawing view). And sketches belong to a part file so you can find out which part the curve belongs to.

 

Here, since you already have a curve in the drawing view, you get the sketch proxy that created the edge (or edge proxy) and find out which occurrence the sketch proxy belongs to. 

 

Dim someProxy As SketchProxy 'changed
Set someProxy = parentCurve.ModelGeometry
Dim partOcc As ComponentOccurrence
Set partOcc = someProxy.ContainingOccurrence

 

I also notice that you have Strict On. I have noticed that sometimes that setting will give you nuisance warnings about casting types when you you are dealing with specific object types and putting in a collection of generic objects.  The code works fine, so set Strict Off, because I do not need the warning.

 

Lastly, I am not sure of your motivation to use VBA. I have settled on iLogic for many of my tiny coding projects. It is easy to migrate whenever I update Inventor. There are some ilogic functions that greatly simplify common tasks with a single line of code. You can have ilogic assigned to a button on an ilogic form. There are even helper add-ins to allow you to put it on the menu bar.  

0 Likes
Message 12 of 16

m.joudivand
Enthusiast
Enthusiast

Hi @wfajber 

Thanks for your comprehensive explanations.

I figured it out, actually my problem was in defining suitable Object type for the "someProxy" variable.

I defined the object as EdgeProxy which matches the variable's type (see below).

Option Explicit

Sub PartSelection()


'Select drawing curve of the part
Dim oPick As DrawingCurveSegment
Set oPick = ThisApplication.CommandManager.Pick(SelectionFilterEnum.kDrawingCurveSegmentFilter, "Pick drawing curve")

'Get assembly occurrene which the selected DrawingCurveSegment belongs to
Dim curveSegment As DrawingCurveSegment
Set curveSegment = oPick



Dim parentCurve As DrawingCurve
Set parentCurve = curveSegment.Parent
Dim someProxy As EdgeProxy 'changed
Set someProxy = parentCurve.ModelGeometry
Dim partOcc As ComponentOccurrence
Set partOcc = someProxy.ContainingOccurrence

'Get AssemblyDocument referenced by DrawingView
Dim dView As drawingView 'needs to be checked
Set dView = parentCurve.Parent
Dim viewAsm As AssemblyDocument
Set viewAsm = dView.ReferencedDocumentDescriptor.ReferencedDocument

'Get all occurrences which has the same ComponentDefinition
Dim allInstancesOfPartOcc As ComponentOccurrencesEnumerator
Set allInstancesOfPartOcc = viewAsm.ComponentDefinition.Occurrences.AllLeafOccurrences(partOcc.Definition)


'Get all DrawingCurveSegments of each part instance
'and convert them to ObjectCollection
Dim occDrawingCurvesCollection As ObjectCollection
Set occDrawingCurvesCollection = ThisApplication.TransientObjects.CreateObjectCollection()

Dim occ As ComponentOccurrence

For Each occ In allInstancesOfPartOcc
    Dim occDrawingCurves As DrawingCurvesEnumerator
    Set occDrawingCurves = dView.DrawingCurves(occ)
    
    Dim occDrawingCurve As DrawingCurve
    For Each occDrawingCurve In occDrawingCurves
    
    Dim occDrawingCurveSegment As DrawingCurveSegment
        For Each occDrawingCurveSegment In occDrawingCurve.Segments
            occDrawingCurvesCollection.Add (occDrawingCurveSegment)
        Next
    Next
Next

'Do something useful with occDrawingCurvesCollection

'Select all DrawingCurveSegments of the occ in the DrawingView
Dim drawingDoc As DrawingDocument
Set drawingDoc = dView.Parent.Parent

'drawingDoc.SelectSet.SelectMultiple (occDrawingCurvesCollection)

End Sub

 

To be honest, I have problem with defining object types for different purpose since there are many objects in the library. @wfajber are you able to let me know how I can attribute objects to the variables? Is there a pathway to learn it?

To be mentioned the code is not working yet and has some bugs, I need to fix it as well.

Waiting for your helpful reply

Sincerely yours

Mohammad

 

0 Likes
Message 13 of 16

m.joudivand
Enthusiast
Enthusiast
Accepted solution

Here we go, I managed to convert the iLogic code to it's corresponding API version.

Option Explicit

Sub PartSelection()


'Select drawing curve of the part
Dim oPick As DrawingCurveSegment
Set oPick = ThisApplication.CommandManager.Pick(SelectionFilterEnum.kDrawingCurveSegmentFilter, "Pick drawing curve")

'Get assembly occurrene which the selected DrawingCurveSegment belongs to
Dim curveSegment As DrawingCurveSegment
Set curveSegment = oPick



Dim parentCurve As DrawingCurve
Set parentCurve = curveSegment.Parent
Dim someProxy As EdgeProxy 'changed
Set someProxy = parentCurve.ModelGeometry
Dim partOcc As ComponentOccurrence
Set partOcc = someProxy.ContainingOccurrence

'Get AssemblyDocument referenced by DrawingView
Dim dView As drawingView 'needs to be checked
Set dView = parentCurve.Parent
Dim viewAsm As AssemblyDocument
Set viewAsm = dView.ReferencedDocumentDescriptor.ReferencedDocument

'Get all occurrences which has the same ComponentDefinition
Dim allInstancesOfPartOcc As ComponentOccurrencesEnumerator
Set allInstancesOfPartOcc = viewAsm.ComponentDefinition.Occurrences.AllLeafOccurrences(partOcc.Definition)


'Get all DrawingCurveSegments of each part instance
'and convert them to ObjectCollection
Dim occDrawingCurvesCollection As ObjectCollection
Set occDrawingCurvesCollection = ThisApplication.TransientObjects.CreateObjectCollection()

Dim occ As ComponentOccurrence

For Each occ In allInstancesOfPartOcc
    Dim occDrawingCurves As DrawingCurvesEnumerator
    Set occDrawingCurves = dView.DrawingCurves(occ)
    
    Dim occDrawingCurve As DrawingCurve
    For Each occDrawingCurve In occDrawingCurves
    
    Dim occDrawingCurveSegment As DrawingCurveSegment
        For Each occDrawingCurveSegment In occDrawingCurve.Segments
            Call occDrawingCurvesCollection.Add(occDrawingCurveSegment)
        Next
    Next
Next

'Do something useful with occDrawingCurvesCollection

'Select all DrawingCurveSegments of the occ in the DrawingView
Dim drawingDoc As DrawingDocument
Set drawingDoc = dView.Parent.Parent
Call drawingDoc.SelectSet.SelectMultiple(occDrawingCurvesCollection)

End Sub

 

 

0 Likes
Message 14 of 16

wfajber
Contributor
Contributor

@m.joudivand Muhammad I see that you have been waiting for a month for my helpful reply.  😀

 

I did not notice that before. Do you still have a question? 

0 Likes
Message 15 of 16

m.joudivand
Enthusiast
Enthusiast

Dear @wfajber 

Thank you for your messages and help. Currently all is fine with the subroutines 😊

 

0 Likes
Message 16 of 16

anavazquez5LRNJ
Enthusiast
Enthusiast

Is it possible that when I click on the occurrence it gives me the parameter for example length and width of the occurrence is that as far as I can see this is by parts and I do not know if you can select the entire occurrence

0 Likes