iLogic to search all parts in an assembly for a sketch, and change the text within the sketch. looking for help with the search sectio

iLogic to search all parts in an assembly for a sketch, and change the text within the sketch. looking for help with the search sectio

ciaran.gibson
Contributor Contributor
480 Views
5 Replies
Message 1 of 6

iLogic to search all parts in an assembly for a sketch, and change the text within the sketch. looking for help with the search sectio

ciaran.gibson
Contributor
Contributor

I am writing some iLogic to open up parts in an assembly and replace the old part number with the new one. The part number is a sketch that contains a text box, and then is extrude cut into the part, which is in the folded model of the part. The following code runs, but it just cant find the sketch. 

 

Sub Main()
Dim oDoc As AssemblyDocument
oDoc = ThisDoc.Document
Dim newPartNumber As String
newPartNumber = InputBox("Enter the new part number:")

Dim isSketchFound As Boolean
isSketchFound = False

MsgBox("Searching for sketch 'Part_Number' in all parts and sub-assemblies...")

For Each oOccurrence In oDoc.ComponentDefinition.Occurrences
    isSketchFound = isSketchFound Or SearchForSketch(oOccurrence, newPartNumber)
Next

If isSketchFound Then
    MsgBox("Sketch 'Part_Number' was found and updated with new part number.")
Else
    MsgBox("Sketch 'Part_Number' was not found in any parts or sub-assemblies.")
End If

MsgBox("Search finished.")
End Sub

Private Function SearchForSketch(ByVal oCompDef As Object, ByVal newPartNumber As String) As Boolean
If TypeOf oCompDef Is PartComponentDefinition Then
For Each oExtrudeFeature In oCompDef.Features.ExtrudeFeatures
If oExtrudeFeature.Profile.Name = "Part_Number" Then
For Each oTextBox In oExtrudeFeature.Profile.Sketch.TextBoxes
oTextBox.Text = newPartNumber
Return True
Next
End If
Next
ElseIf TypeOf oCompDef Is AssemblyComponentDefinition Then
For Each oSubOccurrence In oCompDef.Occurrences
If SearchForSketch(oSubOccurrence.Definition, newPartNumber) Then
Return True
End If
Next
End If
Return False
End Function

This is the code i am using. I know it is possible as an earlier version worked, but only twice out of abut 20 times i ran it. below is the code that worked very temporarily. 

 

Private Sub Main()
Dim oDoc As AssemblyDocument
oDoc = ThisDoc.Document

For Each oOccurrence In oDoc.ComponentDefinition.Occurrences
SearchForSketch(oOccurrence)
Next
End Sub

Private Sub SearchForSketch(ByVal oCompDef As Object)
If TypeOf oCompDef Is PartComponentDefinition Then
For Each oSketch In oCompDef.Sketches
If oSketch.Name = "Part_Number" Then
For Each oTextBox In oSketch.TextBoxes
oTextBox.Text = "New Part Number"
Next
End If
Next
ElseIf TypeOf oCompDef Is AssemblyComponentDefinition Then
For Each oSubOccurrence In oCompDef.Occurrences
SearchForSketch(oSubOccurrence.Definition)
Next
End If
End Sub

Annotation 2023-01-31 094926.png

Annotation 2023-01-31 094956.png

Annotation 2023-01-31 095052.png

   

 

0 Likes
Accepted solutions (1)
481 Views
5 Replies
Replies (5)
Message 2 of 6

WCrihfield
Mentor
Mentor
Accepted solution

Hi @ciaran.gibson.  I do not know if this code below will fix all of the problems or be a complete working solution, but I think this should help you achieve your goals some.  I kept all the code within one main Sub routine, for simplicity sake, but if you want to maintain a separate routine, I may be able to change it that way for you.

There were several things hindering your success in that code above, so I will mention a few of them below.  When declaring a variable for a TextBox within an Inventor sketch, you must declare it as 'Inventor.TextBox', not just 'TextBox', because it gets confused with the 'System.Windows.Forms.TextBox', which is a completely different object.  Also, when defining a Sub or Function routine, use ByRef declaration for items that may need to be changed within that routine, and ByVal for things that you do not want to be changed.  In your example, you were attempting to pass a ComponentOccurrence object into a Function routine that was set up to receive a generic Object, then within that Function routine, you were treating that Object like it was a ComponentDefinition, which is a different Type of object.  There were other little problems too, but try this code below out, and see if it works any better for you.

Sub Main
	If ThisDoc.Document.DocumentType <> DocumentTypeEnum.kAssemblyDocumentObject Then
		MsgBox("This rule only works on an Assembly.", vbCritical,"")
		Exit Sub
	End If
	Dim oADoc As AssemblyDocument = ThisDoc.Document
	Dim oRefDocs As DocumentsEnumerator = oADoc.AllReferencedDocuments
	Dim sNewPN As String = InputBox("Enter the new part number.", "New Part Number", "")
	If sNewPN = "" Then Exit Sub
	For Each oRefDoc As Document In oRefDocs
		If oRefDoc.DocumentType <> DocumentTypeEnum.kPartDocumentObject Then Continue For
		Dim oPDoc As PartDocument = oRefDoc
		Dim oExtFeats As ExtrudeFeatures = oPDoc.ComponentDefinition.Features.ExtrudeFeatures
		If oExtFeats.Count = 0 Then Continue For
		For Each oExtFeat As ExtrudeFeature In oExtFeats
			If oExtFeat.Definition.Profile.Parent.Name <> "Part_Number" Then Continue For
			Dim oSketch As Sketch = oExtFeat.Definition.Profile.Parent
			If oSketch.TextBoxes.Count = 0 Then Continue For
			Dim oTBox As Inventor.TextBox = oSketch.TextBoxes.Item(1)
			Try : oTBox.Text = sNewPN : Catch : End Try
		Next
		If oPDoc.RequiresUpdate Then oPDoc.Update2(True)
	Next 'oRefDoc
	If oADoc.RequiresUpdate Then oADoc.Update2(True)
End Sub

 

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

Message 3 of 6

ciaran.gibson
Contributor
Contributor

ah great thanks so much for the help! i wrote this with snippets of other bits that i didnt understand thank you for explaining it for me also 

0 Likes
Message 4 of 6

Luis_Pacheco_3D
Advocate
Advocate

I don't know if you tried this. Connect the part number with a user parameter through a rule, this user parameter is used in the text box and when you run the rule, that parameter updates automatically in the part and show the correct info.

 

This works only if the parameter to show in the part is the part number of the piece.

Message 5 of 6

WCrihfield
Mentor
Mentor

Good idea @Luis_Pacheco_3D.  That is how most folks set that sort of thing up, when they are planning on needing to change its value regularly, and easily.  If done this way, you would then only have to change the Parameter's value to change the text within the TextBox, within the sketch, then update the part document it is in, to see the changes.  Here is a screenshot of the Format Text dialog box, while editing a TextBox within a sketch, within a part.  As you can see here, I have a text type user parameter named "Part_Number" in my part, and I am inserting a reference to that parameter, using the available dialog tools.  When done this way, that value will stay up-to-date with the parameter's value, instead of being a 'static' value.  Beware though, if you are using ModelStates, there may be a different value in there for each ModelState, so you would have to keep that in mind.

WCrihfield_0-1675177909492.png

 

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

Message 6 of 6

ciaran.gibson
Contributor
Contributor

thank you for your help, i have ended up solving the issue without the use of paramaters, i am trying to make this as fluid as possible, it needs to work for multiple large assemblies and regularly. take a look. 

 

Private Sub Main()
Dim oDoc As AssemblyDocument
oDoc = ThisDoc.Document

For Each oOccurrence In oDoc.ComponentDefinition.Occurrences
SearchForSketch(oOccurrence)
Next
End Sub

Private Sub SearchForSketch(ByVal oOccurrence As ComponentOccurrence)
If TypeOf oOccurrence.Definition Is PartComponentDefinition Then
Dim oPartDoc As PartDocument
oPartDoc = oOccurrence.Definition.Document
Dim fileName As String
fileName = System.IO.Path.GetFileNameWithoutExtension(oPartDoc.FullFileName)

For Each oSketch In oOccurrence.Definition.Sketches
  If oSketch.Name = "Part_Number" Then
    For Each oTextBox In oSketch.TextBoxes
      oTextBox.Text = fileName
    Next
  End If
Next
ElseIf TypeOf oOccurrence.Definition Is AssemblyComponentDefinition Then
For Each oSubOccurrence In oOccurrence.Definition.Occurrences
SearchForSketch(oSubOccurrence)
Next
End If
iLogicVb.UpdateWhenDone = True
End Sub
0 Likes