- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report
Hi,
I have a feeling this one might be outside of my knowledge base but ill try it out anyway.
I am basically just trying to control the material properties most of my parts all at once. Our products are about 99% stainless steel so ill focus on just that. The issue is we either use type 304L S.S. or 316L S.S. depending on the job. I am trying to create a nice little button to choose either one that will send that information down to all of my parts.
I am hoping that is a nice easy way to go and find all exisiting material properties and IF they are/arent one way, change them to another. I have a feeling however that I am going to have to create a line in a rule for each and every component which will definitely take some time but if thats what I have to do, so be it.
So far I have created my own material library so it consists of ONLY the very few materials we use. Basically the only thing I have figured out how to do so far is create a multi-value list of all of the materials in my library. I can't export the text, and can only reference it at top level assembly. I have no idea how to send that information down to all components.
Any help is immensely appreciated!
Thanks
Sandro
Solved! Go to Solution.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report
' Get the active assembly document.
Dim oAsmDoc As AssemblyDocument
oAsmDoc = ThisApplication.ActiveDocument
' Get the material to assign to all of the parts.
Dim strMaterialName As String
strMaterialName = "YOUR MATERIAL HERE"
Dim oMaterial As Material
On Error Resume Next
' Try to get the material of the specified name.
oMaterial = oAsmDoc.Materials.Item(strMaterialName)
On Error Goto 0
' Iterate through all of the documents refrenced by the assembly.
Dim oDoc As Document
For Each oDoc In oAsmDoc.AllReferencedDocuments
' Check to see if this is a part.
If oDoc.DocumentType = kPartDocumentObject Then
Dim oPartDoc As PartDocument
oPartDoc = oDoc
' Set the material.
oPartDoc.ComponentDefinition.Material = oMaterial
End If
NextThis could be a start for you.
Run in an assembly it will assign all components the same material.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report
That worked almost perfectly. instead of the material name in "your material here" I used the parameter name of the multivalue list so I could control it!.
I wish I had SOME idea about what was going on in this code lol but it works nicely. I do have one problem though that i know this code will cause. This code appears to set ALL parts in the document to that material type. I however need to change groupings of components because we do use small pieces of rubber in our design so i cant have them changing to Stainless Steel. any suggestions?
Thanks!!
Sandro
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report
I guess this means I have a fair bit of customization but If i could figure out how to change one part im sure i could figure out how to change the rest to what i want.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report
Hi,
Not sure I understand what you mean by "If i could figure out how to change one part"
@Anonymous pasted a code that is doing it for lots of parts.
What is missing?
Also, you could check the material name before assigning a new one.
So if all of them are supposed to be 304 or 316, then you could change values only where it is already one of those.
Would that work?
Cheers,

Adam Nagy
Autodesk Platform Services
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report
If I am understanding you correctly, yes I think it would work for me if I could check certain components materials and then If they are one way, Change them to another by my preference per job specifications.
You are right, that code changes the material for lots of parts. All parts actually. If I were to change ALL parts to a certain material, I would then lose the correct material for components that are supposed to be Rubber, or a different grade of stainless than the rest of the assembly.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report
Hi,
If your top assembly has a Multi Value list named e.g. "Metals" then using the following code you could check if the part that your code is checking has a material that is included in the Multi value List.
MultiValue.List returns an ArrayList: https://msdn.microsoft.com/en-us/library/system.collections.arraylist(v=vs.110).aspx and so it has a Contains() method you can use.
values = MultiValue.List("Metals")
If values.Contains("Gold")
MsgBox("has gold")
End If
This way you could check if the part's material is something that you should modify or not.
Cheers,

Adam Nagy
Autodesk Platform Services
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report
Hi Adam,
I am a little confused by the code you posted so I think I am not being clear enough. I have attached a file of one of my models to hopefully explain a little bit better. Please open it and set the view rep to "Default" and the LOD to "iLogic".
I am not sure how the pack and go feature works with regards to Material libraries so I hope I can explain properly.
Please open up the parameters window. You will notice the last 5 parameters are the exact same multivalue liss but with different names (created with a rule). I was hoping to potentially control the materials with these lists but they will be useful for me to explain to you my intentions. I should mention these paramters have nothing to do with the actual model I am attaching.
The first of the last 5 is named "All_Materials" I used this list to simply GET all of the materials available in my custom library.
The next 4 parameters are the actual parameters I need control of. The "Stem_Material" Parameter in reality can either be 304 or 316 S.S. regardless of the rest of the assembly.
The "Pedestal_Material" in reality can either be Galvanized Steel, and 304 or 316 S.S., regardless of the rest of the assembly.
The "Hardware_Material" is for all of the fasnteners and they can either be 304 or 316 regardless of the rest of the assembly.
The "Stainless_Grade" is for what I keep referring to as the "rest of the assembly". I feel this might be the trickiest part. The rest of the assembly is one large assembly made up of a few sub-assembies. It is composed of mostly S.S. but it does have a couple rubber components to it which is why the previously mentioned code that changes all materials does not work the way I want it to. In this large assembly I need to be able to change all of the STEEL to either 304 or 316.
I feel like there has to be as easy way to accomplish this. The reason I created the multivalue lists is because I thought I would simply be able to write a rule that would look something like this
IF Pedestal_Material = "GALVANIZED STEEL" Then
iProperties....Material = "GALVANIZED STEEL"
End if
Please let me know if this makes sense...
Thanks
Sandro
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report
I don't know if this means anything but I was just screwing around with rules and I figured out that using this line:
iProperties.MaterialOfComponent("Rising Stem:1") = Stem_Material
I was able to change the material of that component very easily to exactly what I want. Now, this was only easy because it just so happens this component is ONE part. If this is the only solution to my problem, this means that I will have to create a rule like this which includes EVERY part in my entire assembly which means it will be incredibly time consuming (once). It also means that since suppressed parts will be mentioned, when the rule runs I will probably have some difficulties...
Is any of that correct?
Thanks Sandro
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report
It's quite easy to test what happens if you suppress a component whose material you are trying to change.
And it seems that in that case the material of that component will not get changed.
Is that OK or in your wokflow even suppressed parts' material you should be able to control from the Multi Value List parameter?
If so, then you could go back to the original code, because that should work in that case as well.
The question is how you identify which parts should be controlled by which Multi value List parameter.
If you don't mind handling them one by one in the code then it should be quite easy that could be done based on their exact names: that is something that iLogic seems to expect as well, where you have to provide the exact component name you want to control.
You could also write something that could be more generic: e.g. Stem_Material parameter would only control all documents whose name starts with "Stem", etc

Adam Nagy
Autodesk Platform Services
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report
Yes I decided to give it a test and suppressed components don't cause any issues. They can stay whatever material they are in the background because it doesn't affect my BOM.
I agree with you about the question at hand. I am really trying to avoid creating a rule that lists every single part. Even though I would probably only have to do it once, there are hundreds of small parts and that would be very time consuming.
I am very inexperienced with the API or VBA code, I only have a pretty good handle on the default snippets in iLogic so I dont even know of the option to control parts like you described from pieces of their names. That method seems like it would be perfect however I am nervous thinking about it because i anticipate having to rename everything or having to remember this method when I name new parts.
I have thought about this alot and had a new idea. I haven't tested it yet but do you think I could possibly use the very first code mentioned in this thread to control ALL parts material, but instead of inserting that code at my top level assembly could I insert it into each sub-assembly ensuring all material within that sub-assembly is identical? I feel I could then control the parameter within those sub-assemblies from my top level assembly and not worry about EVERYTHING changing to one material type.
Does this sound like a possible idea? It sounds much better than naming every single part since I only have a handful of sub-assemblies.
Thanks
Sandro
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report
In the sample assembly you attached there were parts also directly under the main assembly - not only under the subassembly.
So you would still need to set the material at the top level assembly as well.
There could be multiple ways of achieving what you need, but you know best how the assemblies and parts will be used, which parts' material should be controlled from where, etc.
Also, are the parts only used from a single assembly? Because once you set the material for them it will be the same in all the assemblies they are being used in. I'm assuming for each assembly you create you copy those parts into the assembly's folder, or something like that?

Adam Nagy
Autodesk Platform Services
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report
Adam,
To be honest with you we have not implemented Inventor into any jobs at our company yet. Right now I am trying to make complete models of all our products. I am creating each product so that it is fully adaptable with iLogic to be any size or configuration that we need to cut down on our design time almost entirely.
This means that I am not too concerned about changing the material type for an assembly that is used in multiple locations that may have a different material than what I am working on at the moment. I am not sure exactly if this is the right direction to be headed but I am not too experienced with Inventor so I figure I'll deal with that when I get there.
For the moment I am uploading the same assembly again but with some important updates to help convey what I am trying to accomplish. I would really appreciate you taking a look at it. I changed the model so that the top level assembly is only composed of sub-assemblies with no stray parts. The top level assembly is composed of three sub-assemblies, If you enter each sub-assembly you will find a rule called "Forum Test" and within it is the code that was given at the beginning of this thread. I tried to control the material is this code from my top level assemblies multi-value lists but was unsuccessful. That code still grabs the material for EVERYTHING in the model even if the rule is placed in a sub-assembly. Please make sure you are on the "iLogic" LOD.
I hope this makes sense and gives you a better understanding at what I am trying to do. I appreciate the help!
Thanks
Sandro
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report
Hi Sandro,
In order to be able to set the material for the derived component, it's best to set its Derived Part Properties so that it's not inheriting the material color from the original part:
You do not even need to modify the iProperties but can simply rely on the Parameter values. I commented out the iProperty parts. I was also wondering in the beginning if it was interfering with things.
In the rules inside the sub assemblies you have to change something. You are using ThisApplication.ActiveDocument, but that will return the top assembly when the rule is called as a result of you changing parameters in the top assembly. You should use ThisDoc.Document instead, which return the document that the rule resides in.
Now all seems fine:
Attached is the modified zip.
Cheers,

Adam Nagy
Autodesk Platform Services
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report
On the code below, why I'm getting an error message of
Error on Line 9 : Type 'm_parameter_Material' is not defined.
I'm also having this target to change all parts within the component as the same material as what I have selected in multivalue list. Or is my parameter Material is creating those problem?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report
Hi @JohnBoySarcia. In this case there are a couple things going on. First of all, unless you are still using Inventor 2016 version, the 'Material' object type no longer exists. That pretty much changed after that year to MaterialAsset object type, and can no longer be used exactly the same way as the old Material object was used. The MaterialAsset object has its own set of methods and properties. At the same time the Render styles also changed to a regular Asset type object. And now you access them through AssemblyDocument.MaterialAssets or PartDocument.MaterialAssets, instead of AssemblyDocument.Materials. And can set the active one for a part through the PartDocument.ActiveMaterial property, which will accept either a MaterialAsset object or regular Asset object as input.
And yes, due to you having the local multi-value parameter named "Material" that is being recognized within your rule as a parameter, that is messing with your ability to 'declare' the oMaterial variable's Type. Some of the old Material & RenderStyle functionality may still be supported, but just to support old code functionality, so you should not use those terms in any new code solutions. A common issue in any type of coding is naming your variable the same spelling and capitalization as the object's Type, which causes confusion and errors.
Edit: My mistake on when the change happened. The change happened between 2013 & 2014 releases. Here is a link to a page describing the changes.
https://help.autodesk.com/view/INVNTOR/2024/ENU/?guid=GUID-2912C0FB-885F-47ED-81C3-AF19584EA9C1
If the link does not work, you can click the Help button in Inventor, then navigate to Programming Interface > Inventor API User's Manual > General Concepts > Materials and Appearances
Wesley Crihfield
(Not an Autodesk Employee)
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report
Thank you for your response, the link shows mostly on appearance as an example and need to pick occurrences prior to change. Would it be possible to have an ilogic code from Autodesk inventor 2022 version to have all material within assembly will be change based on selection? my parameter Material has selection. Also, on those examples the set command doesn't exist on my current version. Thanks
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report
Hi @JohnBoySarcia. Almost all Autodesk provided sample codes are provided in VBA, instead of iLogic, unfortunately. And that 'Set' keyword is used in VBA when setting the value of a variable who's Type is something other than (String, Integer, Double, and similar data types). That keyword is not needed in iLogic rules. There are a few other differences between VBA and vb.net also (iLogic uses vb.net). Both coding languages are pretty similar, and both based on Visual Basic, but VBA is older and not properly maintained anymore, while vb.net is a newer (but not really new) coding language that continues to be maintained.
There is a handy iLogic shortcut snippet that we may be able to use in this situation:
iProperties.Material("ComponentName") = "MaterialName"
I do not recall its 'scope' (if it will only work on top level components, or if it will work on components at all levels), so it may require some testing on your end. The online documentation does not mention its scope. I do not really know if you need this code to only work on top level components, or if you need it to work on all components in all levels of the assembly, so the example code is for the all levels scenario, and is a bit longer. There is another way of changing the 'material' of the parts being referenced by the components, but the other way requires much more lines of Inventor API code, and can get a bit more complicated.
Here is the iLogic rule example code you can try out.
Sub Main
'Material is the name of a multi-value text type user parameter in the assembly
sMaterial = Material
If ThisDoc.Document.DocumentType <> DocumentTypeEnum.kAssemblyDocumentObject Then
MsgBox("An Assembly Document must be active for this rule to work. Exiting.", vbCritical, "")
Exit Sub
End If
Dim oADoc As AssemblyDocument = ThisDoc.Document
Dim oOccs As ComponentOccurrences = oADoc.ComponentDefinition.Occurrences
If oOccs.Count = 0 Then Exit Sub
RecurseComponents(oOccs, AddressOf ProcessComponent)
If oADoc.RequiresUpdate Then oADoc.Update2(True)
MsgBox("This rule's work has finished.", vbInformation, "Job Is Done!")
End Sub
Dim sMaterial As String 'shared among routines
Sub RecurseComponents(oComps As ComponentOccurrences, ComponentProcess As Action(Of ComponentOccurrence))
If oComps Is Nothing OrElse oComps.Count = 0 Then Exit Sub
For Each oComp As ComponentOccurrence In oComps
ComponentProcess(oComp)
If oComp.Suppressed = False AndAlso _
oComp.DefinitionDocumentType = DocumentTypeEnum.kAssemblyDocumentObject Then
RecurseComponents(oComp.SubOccurrences, ComponentProcess)
End If
Next
End Sub
Sub ProcessComponent(oComp As ComponentOccurrence)
If oComp Is Nothing OrElse oComp.Suppressed Then Exit Sub
If TypeOf oComp.Definition Is VirtualComponentDefinition Then Exit Sub
If TypeOf oComp.Definition Is WeldsComponentDefinition Then Exit Sub
Try 'only works on components that reference parts
iProperties.Material(oComp.Name) = sMaterial
Catch oEx As Exception
Logger.Error("Error setting Material of component named: " & oComp.Name _
& vbCrLf & oEx.Message & vbCrLf & oEx.StackTrace & vbCrLf)
End Try
End Sub
If this solved your problem, or answered your question, please click ACCEPT SOLUTION .
Or, if this helped you, please click (LIKE or KUDOS)
.
Wesley Crihfield
(Not an Autodesk Employee)