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: 

Issue Pushing InputListBox Value From Assembly To Frame Generator Members

7 REPLIES 7
SOLVED
Reply
Message 1 of 8
Jonathan.CharltonE35Y2
441 Views, 7 Replies

Issue Pushing InputListBox Value From Assembly To Frame Generator Members

Hello!

I'm currently running Inventor 2022.4.1, Build 492.
All relative service packs and updates installed.


I'm trying to change the materials of all Frame Generator members using ilogic from the assembly level.
I've patched together a block of code that seems to check all the boxes, but I can't figure out how to push the user-selected InputListBox value from the assembly to the individual components.
I've spent hours searching online for the answer, and either can't find it or am to ignorant to recognize it when I did.
Would someone be willing to point out where I'm going wrong, and areas I can improve on?
Please see attached.

Labels (9)
7 REPLIES 7
Message 2 of 8

Hi @Jonathan.CharltonE35Y2 

 

So in your code you are not setting the material at all. You are trying to send a material asset to an iproperty. There is a dedicated ilogic function for material but those snippets do not work great in assembly contexts so the API route is easier in my opinion.  

 

What you need to do is to copy an asset from the asset library to each part then set the active material. 

 

Here is an example of how to do this in a part file.  Ensure you have the same library currently in use. When you are happy it is working for the part. Then transfer this method to the referenced document loop of your assembly. Any question just post up the modified code.

Dim oDoc As PartDocument = ThisApplication.ActiveDocument

    Dim assetLib As AssetLibrary  = ThisApplication.AssetLibraries.Item("Inventor Material Library")
 	
	ThisApplication.ActiveMaterialLibrary = assetLib
   
    Dim MaterialName As String = "Gold"
   
    Try
	Dim localMaterial As MaterialAsset = oDoc.MaterialAssets.Item(MaterialName)
 	Catch
    Dim libMaterial As MaterialAsset = assetLib.MaterialAssets.Item(MaterialName)
	libMaterial.CopyTo(oDoc)
	End Try
	
	oDoc.ActiveMaterial = oDoc.MaterialAssets.Item(MaterialName)
 

 

 

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

@A.Acheson,

 

Thank you for your reply.

 

I've taken the snippet you've provided and added it to my document loop of my assembly and modified it a bit to match what I'm wanting.

I do want the user running the code to select the material library and material name in the assembly environment through the input list boxes created by the block.

The only issue I'm running into is getting the user's selection from the assembly to the part.
However, when I run the newly modified code I'm presented with an error.

Please see attached for the error.

I've also pasted the modified code below. 

I feel like I'm close now, thanks to your contributions (I realized that some of the code I've copied is actually some of your older works).

Sub Main()
	oADOC = ThisDoc.ModelDocument
	If oADOC.DocumentType <> kAssemblyDocumentObject Then
	MessageBox.Show("This rule cannot be executed in this file type.", "iLogic")
	Exit Sub
	End If

	Dim oAsm As AssemblyDocument = ThisDoc.Document
	Dim oTransaction As Transaction = ThisApplication.TransactionManager.StartTransaction(oAsm, "FG Member Material Changer") 'Make this a single transaction

	Dim oAL_List As New ArrayList
		Dim lib_List As New ArrayList

		For Each oAL As AssetLibrary In ThisApplication.AssetLibraries
			If InStr(oAL.DisplayName , "Material") <> 0 Then  
				oAL_List.Add(oAL.DisplayName)
			End If
		Next

		Dim oALSelect As String = InputListBox("Select Asset Library", oAL_List, oAL_List(0), "Change Part Material", "Available Selections")
		If oALSelect Is Nothing Then Exit Sub
		Dim oLib As AssetLibrary =ThisApplication.AssetLibraries(oALSelect)

		For Each libAsset In oLib.MaterialAssets
			lib_List.Add(libAsset.DisplayName)
		Next

		lib_List.Sort

		Dim oLibAssetSel As String = InputListBox("Select Material", lib_List, lib_List(0), "Change Part Material", "Available Selections")
		If oLibAssetSel Is Nothing Then Exit Sub
		

	For Each oDoc As Document In oAsm.AllReferencedDocuments 'Traverse all referenced documents
		If oDoc.DocumentInterests.HasInterest("{AC211AE0-A7A5-4589-916D-81C529DA6D17}") _	'Frame generator component
			AndAlso oDoc.DocumentType = DocumentTypeEnum.kPartDocumentObject _'Part
			AndAlso oDoc.IsModifiable _	'Modifiable (not reference skeleton)
			AndAlso oAsm.ComponentDefinition.Occurrences.AllReferencedOccurrences(oDoc).Count > 0 'Exists in assembly (not derived base component)

				Dim oDoc1 As PartDocument = ThisApplication.ActiveDocument

					Dim assetLib As AssetLibrary  = ThisApplication.AssetLibraries.Item(oLib)
					
					ThisApplication.ActiveMaterialLibrary = assetLib
				
					Dim MaterialName As String = oLibAssetSel
				
					Try
					Dim localMaterial As MaterialAsset = oDoc1.MaterialAssets.Item(MaterialName)
					Catch
					Dim libMaterial As MaterialAsset = assetLib.MaterialAssets.Item(MaterialName)
					libMaterial.CopyTo(oDoc1)
					End Try
					
					oDoc1.ActiveMaterial = oDoc1.MaterialAssets.Item(MaterialName)

				iLogicVb.UpdateWhenDone = True
			
		End If
	Next
	oTransaction.End
End Sub



Message 4 of 8

You might benefit from using the Option Explicit On. This line in the header will spot anything not correctly declared before you run the  code. 

 

The main issue here  is that your declaring a part document variable and setting it to be the active document which in this case is the assembly. Remove this line and use "oDoc" as the document object. 

 

				Dim oDoc1 As PartDocument = ThisApplication.ActiveDocument

 

Duplicate line here where you get the library twice bit on the second line your setting the item Variant as an object rather than an index or string value. See API help here

1.

Dim oLib As AssetLibrary =ThisApplication.AssetLibraries(oALSelect)

2.

					Dim assetLib As AssetLibrary  = ThisApplication.AssetLibraries.Item(oLib)

 

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

Your help is much appreciated.

I've modified the code a bit, namely removing this line entirely, as it was conflicting with some the code above it:

 

Dim oDoc As PartDocument = ThisApplication.ActiveDocument

 

I've also remedied library setting issue by removing the second line:

 

					Dim assetLib As AssetLibrary  = ThisApplication.AssetLibraries.Item(oLib)

 

Now I'm just left with one error, and it is generated whenever the rule runs this line of code:

If I edit out this line, the code runs but doesn't set the material of the Frame Generator components.

 

oDoc.ActiveMaterial = oDoc.MaterialAssets.Item(MaterialName)

 

 

Screenshot 2023-08-09 103510 Member Not Found.jpg

I've been looking around online to see if I can find some documentation on how to clear this Member not found error, but I've not come across much.

 

This is what my block looks like now:

 

Option Explicit On

Sub Main()
	Dim oADOC As Inventor.Document = ThisDoc.ModelDocument
	If oADOC.DocumentType <> kAssemblyDocumentObject Then
	MessageBox.Show("This rule cannot be executed in this file type.", "iLogic")
	Exit Sub
	End If

	Dim oAsm As AssemblyDocument = ThisDoc.Document
	Dim oTransaction As Transaction = ThisApplication.TransactionManager.StartTransaction(oAsm, "FG Member Material Changer") 'Make this a single transaction

	Dim oAL_List As New ArrayList
		Dim lib_List As New ArrayList

		For Each oAL As AssetLibrary In ThisApplication.AssetLibraries
			If InStr(oAL.DisplayName , "Material") <> 0 Then  
				oAL_List.Add(oAL.DisplayName)
			End If
		Next

		Dim oALSelect As String = InputListBox("Select Asset Library", oAL_List, oAL_List(0), "Change Part Material", "Available Selections")
		If oALSelect Is Nothing Then Exit Sub
		Dim oLib As AssetLibrary =ThisApplication.AssetLibraries(oALSelect)

		For Each libAsset In oLib.MaterialAssets
			lib_List.Add(libAsset.DisplayName)
		Next

		lib_List.Sort

		Dim oLibAssetSel As String = InputListBox("Select Material", lib_List, lib_List(0), "Change Part Material", "Available Selections")
		If oLibAssetSel Is Nothing Then Exit Sub
		

	For Each oDoc As Document In oAsm.AllReferencedDocuments 'Traverse all referenced documents
		If oDoc.DocumentInterests.HasInterest("{AC211AE0-A7A5-4589-916D-81C529DA6D17}") _	'Frame generator component
			AndAlso oDoc.DocumentType = DocumentTypeEnum.kPartDocumentObject _'Part
			AndAlso oDoc.IsModifiable _	'Modifiable (not reference skeleton)
			AndAlso oAsm.ComponentDefinition.Occurrences.AllReferencedOccurrences(oDoc).Count > 0 'Exists in assembly (not derived base component)

					Dim MaterialName As String = oLibAssetSel
				
					Try
					Dim localMaterial As MaterialAsset = oDoc.MaterialAssets.Item(MaterialName)
					Catch
					Dim libMaterial As MaterialAsset = oLib.MaterialAssets.Item(MaterialName)
					libMaterial.CopyTo(oDoc)
					End Try
					
					oDoc.ActiveMaterial = oDoc.MaterialAssets.Item(MaterialName)

				iLogicVb.UpdateWhenDone = True
			
		End If
	Next
	oTransaction.End
End Sub

 

 

Message 6 of 8

Patched up a different block by borrowing some code from Andrii's post here to try and do the same thing, but I'm running into the same Member not found error, unfortunately. The error is originating from line 51 of the new block.

 

 

Option Explicit On
Sub Main()
	Dim oAsmDoc As AssemblyDocument = ThisApplication.ActiveDocument
	Dim oOccurrence As ComponentOccurrence
	' Get the material name to apply to all components
	Dim materialName As String = "Stainless Steel"
	Dim oAsset As Asset
	
	Dim oAL_List As New ArrayList
		Dim lib_List As New ArrayList

		For Each oAL As AssetLibrary In ThisApplication.AssetLibraries
			If InStr(oAL.DisplayName , "Material") <> 0 Then  
				oAL_List.Add(oAL.DisplayName)
			End If
		Next

		Dim oALSelect As String = InputListBox("Select Asset Library", oAL_List, oAL_List(0), "Change Part Material", "Available Selections")
		If oALSelect Is Nothing Then Exit Sub
		Dim oLib As AssetLibrary =ThisApplication.AssetLibraries(oALSelect)

		For Each libAsset In oLib.MaterialAssets
			lib_List.Add(libAsset.DisplayName)
		Next

		lib_List.Sort

		Dim oLibAssetSel As String = InputListBox("Select Material", lib_List, lib_List(0), "Change Part Material", "Available Selections")
		If oLibAssetSel Is Nothing Then Exit Sub

	For Each oAssetlib In ThisApplication.AssetLibraries
		For i As Integer = 1 To oAssetlib.MaterialAssets.Count
			If oAssetlib.MaterialAssets.Item(i).DisplayName = materialName Then
				oAsset = oAssetlib.MaterialAssets.Item(i)
				GoTo NextStep
			End If
		Next
	Next
	NextStep :
	If oAsset Is nothing Then Exit Sub
	' Iterate through each component occurrence in the assembly
	For Each oDoc As Document In oAsmDoc.AllReferencedDocuments 'Traverse all referenced documents
		If oDoc.DocumentInterests.HasInterest("{AC211AE0-A7A5-4589-916D-81C529DA6D17}") _	'Frame generator component
			AndAlso oDoc.DocumentType = DocumentTypeEnum.kPartDocumentObject _'Part
			AndAlso oDoc.IsModifiable _	'Modifiable (not reference skeleton)
			AndAlso oAsmDoc.ComponentDefinition.Occurrences.AllReferencedOccurrences(oDoc).Count > 0 'Exists in assembly (not derived base component)
				Dim currentMaterialName As String = oDoc.ActiveMaterial.DisplayName
				If Not String.IsNullOrEmpty(currentMaterialName) Then
					If currentMaterialName <> oAsset.DisplayName Then
						' Set the material for the component occurrence
						oDoc.ActiveMaterial = oAsset
				End If
			End If
		End If
	Next
	' Save the changes
	oAsmDoc.Update()
	oAsmDoc.Save()
End Sub

 

 

 

Message 7 of 8

So what was missing was to open the document and then set the material. Trying to set the material without opening was not working. 

 

Sub Main()
	Dim oADOC As Inventor.Document = ThisDoc.Document
	If oADOC.DocumentType <> kAssemblyDocumentObject Then
		MessageBox.Show("This rule cannot be executed in this file type.", "iLogic")
	Exit Sub
	End If

	Dim oAsm As AssemblyDocument = ThisDoc.Document
	Dim oTransaction As Transaction = ThisApplication.TransactionManager.StartTransaction(oAsm, "FG Member Material Changer") 'Make this a single transaction

	Dim oAL_List As New ArrayList
	Dim lib_List As New ArrayList

	For Each oAL As AssetLibrary In ThisApplication.AssetLibraries
		If InStr(oAL.DisplayName , "Material") <> 0 Then  
			oAL_List.Add(oAL.DisplayName)
		End If
	Next

	Dim oALSelect As String = InputListBox("Select Asset Library", oAL_List, oAL_List(0), "Change Part Material", "Available Selections")
	If oALSelect Is Nothing Then Exit Sub
	
	Dim oLib As AssetLibrary = ThisApplication.AssetLibraries(oALSelect)

	For Each libAsset In oLib.MaterialAssets
		lib_List.Add(libAsset.DisplayName)
	Next

	lib_List.Sort

	Dim oLibAssetSel As String = InputListBox("Select Material", lib_List, lib_List(0), "Change Part Material", "Available Selections")
	If oLibAssetSel Is Nothing Then Exit Sub
		
	For Each oDoc As Document In oAsm.AllReferencedDocuments 'Traverse all referenced documents
		If oDoc.DocumentInterests.HasInterest("{AC211AE0-A7A5-4589-916D-81C529DA6D17}") _	'Frame generator component
			AndAlso oDoc.DocumentType = DocumentTypeEnum.kPartDocumentObject _'Part
			AndAlso oDoc.IsModifiable _	'Modifiable 
			AndAlso oAsm.ComponentDefinition.Occurrences.AllReferencedOccurrences(oDoc).Count > 0 'Exists in assembly (not derived base component)

			Dim oPartDoc As PartDocument  = ThisApplication.Documents.Open(oDoc.FullFileName,False)
		
			Dim libMaterial As MaterialAsset
			Try
			 	libMaterial = oPartDoc.MaterialAssets.Item(oLibAssetSel)
			Catch
				libMaterial = oLib.MaterialAssets.Item(oLibAssetSel)
				libMaterial.CopyTo(oPartDoc)
			End Try
			
			oPartDoc.ActiveMaterial = libMaterial
			oPartDoc.Update
			oPartDoc.Close(True)
			
		End If
	Next
	oTransaction.End
End Sub

 

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

This is exactly what I was looking for, and I can't tell you how thankful I am for your help and patience @A.Acheson.
Is there I any way that I could send you money for a coffee, meal, or the like?

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

Post to forums  

Technology Administrators


Autodesk Design & Make Report