I have an assembly that has a duplication of the same part.
The part has only the master model state, but I want to be able to add model states to this part via ilogic.
This line creates model states at the assembly level (which I don't need).
oModelState = oDoc.ComponentDefinition.ModelStates.Add(oName) oDoc.ActiveModelState = oName
This is what I am trying to do... vaguely...
Dim oDoc As AssemblyDocument Dim oOcc As ComponentOccurrence
For Each oOcc In Occurrences
'The below line does not work, what is the correct syntax????
oOcc.ComponentDefinition.ModelStates.Add(oName)
next
Any help/advice would be great?
Solved! Go to Solution.
I have an assembly that has a duplication of the same part.
The part has only the master model state, but I want to be able to add model states to this part via ilogic.
This line creates model states at the assembly level (which I don't need).
oModelState = oDoc.ComponentDefinition.ModelStates.Add(oName) oDoc.ActiveModelState = oName
This is what I am trying to do... vaguely...
Dim oDoc As AssemblyDocument Dim oOcc As ComponentOccurrence
For Each oOcc In Occurrences
'The below line does not work, what is the correct syntax????
oOcc.ComponentDefinition.ModelStates.Add(oName)
next
Any help/advice would be great?
Solved! Go to Solution.
Solved by zoe.baker-bushby. Go to Solution.
Solved by JelteDeJong. Go to Solution.
Solved by WCrihfield. Go to Solution.
This might get you closer to your goal.
Dim oADoc As AssemblyDocument = ThisApplication.ActiveDocument
'define the variable "oName"
oName = "ModelState1"
For Each oOcc As ComponentOccurrence In oADoc.ComponentDefinition.Occurrences
If TypeOf oOcc.Definition Is PartComponentDefinition Then
Dim oPDef As PartComponentDefinition = oOcc.Definition
Dim oFound As Boolean = False
For Each oMS As ModelState In oPDef.ModelStates
If oMS.Name = oName Then
oFound = True
Exit For 'found it, so don't create it
End If
Next
If oFound = False Then
'did not find it, so create it
oPDef.ModelStates.Add(oName)
End If
oOcc.ActiveModelState = oName
End If
Next
If this solved your problem, or answered your question, please click ACCEPT SOLUTION.
Or, if this helped you, please click (LIKE or KUDOS) 👍.
If you want and have time, I would appreciate your Vote(s) for My IDEAS :light_bulb: or you can Explore My CONTRIBUTIONS
Wesley Crihfield
(Not an Autodesk Employee)
This might get you closer to your goal.
Dim oADoc As AssemblyDocument = ThisApplication.ActiveDocument
'define the variable "oName"
oName = "ModelState1"
For Each oOcc As ComponentOccurrence In oADoc.ComponentDefinition.Occurrences
If TypeOf oOcc.Definition Is PartComponentDefinition Then
Dim oPDef As PartComponentDefinition = oOcc.Definition
Dim oFound As Boolean = False
For Each oMS As ModelState In oPDef.ModelStates
If oMS.Name = oName Then
oFound = True
Exit For 'found it, so don't create it
End If
Next
If oFound = False Then
'did not find it, so create it
oPDef.ModelStates.Add(oName)
End If
oOcc.ActiveModelState = oName
End If
Next
If this solved your problem, or answered your question, please click ACCEPT SOLUTION.
Or, if this helped you, please click (LIKE or KUDOS) 👍.
If you want and have time, I would appreciate your Vote(s) for My IDEAS :light_bulb: or you can Explore My CONTRIBUTIONS
Wesley Crihfield
(Not an Autodesk Employee)
I see @WCrihfield was just a bit faster than me but here is my approach.
Dim doc As AssemblyDocument = ThisDoc.Document Dim occ As ComponentOccurrence = doc.ComponentDefinition.Occurrences.Item(1) Dim facDoc As PartDocument = occ.Definition.Document If (facDoc.ComponentDefinition.IsModelStateMember) Then facDoc = facDoc.ComponentDefinition.FactoryDocument End If Dim modelStates As ModelStates = facDoc.ComponentDefinition.ModelStates Dim newModelStateName = "YourNameHere" Dim modelState As ModelState = modelStates.Add() modelState.Name = newModelStateName modelState.Activate() occ.ActiveModelState = newModelStateName
if you want to know why I find the factory document first then you can read my blog post on that topic.
Jelte de Jong
Did you find this post helpful? Feel free to Like this post.
Did your question get successfully answered? Then click on the ACCEPT SOLUTION button.
Blog: hjalte.nl - github.com
I see @WCrihfield was just a bit faster than me but here is my approach.
Dim doc As AssemblyDocument = ThisDoc.Document Dim occ As ComponentOccurrence = doc.ComponentDefinition.Occurrences.Item(1) Dim facDoc As PartDocument = occ.Definition.Document If (facDoc.ComponentDefinition.IsModelStateMember) Then facDoc = facDoc.ComponentDefinition.FactoryDocument End If Dim modelStates As ModelStates = facDoc.ComponentDefinition.ModelStates Dim newModelStateName = "YourNameHere" Dim modelState As ModelState = modelStates.Add() modelState.Name = newModelStateName modelState.Activate() occ.ActiveModelState = newModelStateName
if you want to know why I find the factory document first then you can read my blog post on that topic.
Jelte de Jong
Did you find this post helpful? Feel free to Like this post.
Did your question get successfully answered? Then click on the ACCEPT SOLUTION button.
Blog: hjalte.nl - github.com
Both solutions work quite well! Thank you both 😀
Both solutions work quite well! Thank you both 😀
Having some issues running rules/setting parameters on the new active model state
I have used the solution code with minor alterations:
Dim doc As AssemblyDocument = ThisDoc.Document Dim occ As ComponentOccurrence '= doc.ComponentDefinition.Occurrences.Item(1) Dim oName = "COURSE 1 STEEL TANK SHEET:8" For Each occ In doc.ComponentDefinition.Occurrences If occ.Name = oName Then Dim facDoc As PartDocument = occ.Definition.Document If (facDoc.ComponentDefinition.IsModelStateMember) Then facDoc = facDoc.ComponentDefinition.FactoryDocument End If Dim modelStates As ModelStates = facDoc.ComponentDefinition.ModelStates Dim newModelStateName = "N1" Dim modelState As ModelState = modelStates.Add() modelState.Name = newModelStateName modelState.Activate() occ.ActiveModelState = newModelStateName End If Next ilogicVb.RunRule("COURSE 1 STEEL TANK SHEET:8", "ManwayCutOut")
Here it goes through each occurrence and looks for 'COURSE 1 STEEL TANK SHEET:8' which is the occurrence of the part that I want on the different model state. (So part such as COURSE 1 STEEL TANK SHEET:1 will still be set to Master model state.)
The issue is that it will not then run the last line. We get a lovely unspecified error. The rule 'ManwayCutOut' does exist in this part. If I go and delete the new ModelState and have every thing back on Master I can run this one line fine...
Had issues with the following line too
Parameter("COURSE 1 STEEL TANK SHEET:" & BespokeSheet, "ManwayType") = MWAY_TYPE
Which again if I delete the new ModelState and have everything back on Master I can run both the parameter line and the ilogicvb.runrule line.
Tried a different approach with setting everything to the new Model State and then running the issue lines but still get the unspecified error...
Any advise/help??
Having some issues running rules/setting parameters on the new active model state
I have used the solution code with minor alterations:
Dim doc As AssemblyDocument = ThisDoc.Document Dim occ As ComponentOccurrence '= doc.ComponentDefinition.Occurrences.Item(1) Dim oName = "COURSE 1 STEEL TANK SHEET:8" For Each occ In doc.ComponentDefinition.Occurrences If occ.Name = oName Then Dim facDoc As PartDocument = occ.Definition.Document If (facDoc.ComponentDefinition.IsModelStateMember) Then facDoc = facDoc.ComponentDefinition.FactoryDocument End If Dim modelStates As ModelStates = facDoc.ComponentDefinition.ModelStates Dim newModelStateName = "N1" Dim modelState As ModelState = modelStates.Add() modelState.Name = newModelStateName modelState.Activate() occ.ActiveModelState = newModelStateName End If Next ilogicVb.RunRule("COURSE 1 STEEL TANK SHEET:8", "ManwayCutOut")
Here it goes through each occurrence and looks for 'COURSE 1 STEEL TANK SHEET:8' which is the occurrence of the part that I want on the different model state. (So part such as COURSE 1 STEEL TANK SHEET:1 will still be set to Master model state.)
The issue is that it will not then run the last line. We get a lovely unspecified error. The rule 'ManwayCutOut' does exist in this part. If I go and delete the new ModelState and have every thing back on Master I can run this one line fine...
Had issues with the following line too
Parameter("COURSE 1 STEEL TANK SHEET:" & BespokeSheet, "ManwayType") = MWAY_TYPE
Which again if I delete the new ModelState and have everything back on Master I can run both the parameter line and the ilogicvb.runrule line.
Tried a different approach with setting everything to the new Model State and then running the issue lines but still get the unspecified error...
Any advise/help??
Can you post an images of what the other tab of that error message says? Most often the "More Info" tab of those error messages contains more useful information, so I usually advise folks to post an image of the contents of both tabs of any error messages they get, when trying to diagnose the error.
Also, just a tip, but if you just want to work with one specifically named component, you can get it directly by its name (using ItemByName()), without needing to loop through all components, unless that component is at a lower level (below some sub-assemblies). Here is an alternative to the last code you posted that shows how to use this technique.
Dim doc As AssemblyDocument = ThisDoc.Document
oName = "COURSE 1 STEEL TANK SHEET:8"
occ = doc.ComponentDefinition.Occurrences.ItemByName(oName)
Dim facDoc As PartDocument = occ.Definition.Document
oPCD = facDoc.ComponentDefinition
If oPCD.IsModelStateMember Then
facDoc = oPCD.FactoryDocument
End If
oMStates = oPCD.ModelStates
newModelStateName = "N1"
oMState = oMStates.Add(newModelStateName)
oMState.Activate()
occ.ActiveModelState = newModelStateName
iLogicVb.RunRule(oName, "ManwayCutOut")
Wesley Crihfield
(Not an Autodesk Employee)
Can you post an images of what the other tab of that error message says? Most often the "More Info" tab of those error messages contains more useful information, so I usually advise folks to post an image of the contents of both tabs of any error messages they get, when trying to diagnose the error.
Also, just a tip, but if you just want to work with one specifically named component, you can get it directly by its name (using ItemByName()), without needing to loop through all components, unless that component is at a lower level (below some sub-assemblies). Here is an alternative to the last code you posted that shows how to use this technique.
Dim doc As AssemblyDocument = ThisDoc.Document
oName = "COURSE 1 STEEL TANK SHEET:8"
occ = doc.ComponentDefinition.Occurrences.ItemByName(oName)
Dim facDoc As PartDocument = occ.Definition.Document
oPCD = facDoc.ComponentDefinition
If oPCD.IsModelStateMember Then
facDoc = oPCD.FactoryDocument
End If
oMStates = oPCD.ModelStates
newModelStateName = "N1"
oMState = oMStates.Add(newModelStateName)
oMState.Activate()
occ.ActiveModelState = newModelStateName
iLogicVb.RunRule(oName, "ManwayCutOut")
Wesley Crihfield
(Not an Autodesk Employee)
You may also want to post the contents of that other rule you are trying to run, because the error message suggests that the error is in that rule. It may have to do with document references and/or using iLogic snippets that target the 'active' document by default, when you may need to be more specifically targeting the 'local' document instead. When running code from a main assembly, usually that main assembly will remain the 'active' document, until you do something that 'activates' another document to become the 'active' document. This little issue trips tons of folks up, and it can be difficult to diagnose without lots of experience/knowledge about the references/methods being used.
Wesley Crihfield
(Not an Autodesk Employee)
You may also want to post the contents of that other rule you are trying to run, because the error message suggests that the error is in that rule. It may have to do with document references and/or using iLogic snippets that target the 'active' document by default, when you may need to be more specifically targeting the 'local' document instead. When running code from a main assembly, usually that main assembly will remain the 'active' document, until you do something that 'activates' another document to become the 'active' document. This little issue trips tons of folks up, and it can be difficult to diagnose without lots of experience/knowledge about the references/methods being used.
Wesley Crihfield
(Not an Autodesk Employee)
Here is the ManwayCutOut rule:
If ManwayType = 600 Then Feature.IsActive("MWAY600 Centre") = True Feature.IsActive("MWAY600 Holes") = True Feature.IsActive("MWAY600 PCD") = True Feature.IsActive("MWAY800 Centre") = False Feature.IsActive("MWAY800 Holes") = False Feature.IsActive("MWAY800 PCD") = False Feature.IsActive("MWAY900 Centre") = False Feature.IsActive("MWAY900 Holes") = False Feature.IsActive("MWAY800 PCD") = False Else If ManwayType = 800 Then Feature.IsActive("MWAY800 Centre") = True Feature.IsActive("MWAY800 Holes") = True Feature.IsActive("MWAY800 PCD") = True Feature.IsActive("MWAY600 Centre") = False Feature.IsActive("MWAY600 Holes") = False Feature.IsActive("MWAY600 PCD") = False Feature.IsActive("MWAY900 Centre") = False Feature.IsActive("MWAY900 Holes") = False Feature.IsActive("MWAY900 PCD") = False Else If ManwayType = 900 Then Feature.IsActive("MWAY900 Centre") = True Feature.IsActive("MWAY900 Holes") = True Feature.IsActive("MWAY900 PCD") = True Feature.IsActive("MWAY800 Centre") = False Feature.IsActive("MWAY800 Holes") = False Feature.IsActive("MWAY800 PCD") = False Feature.IsActive("MWAY600 Centre") = False Feature.IsActive("MWAY600 Holes") = False Feature.IsActive("MWAY600 PCD") = False End If iLogicVb.UpdateWhenDone = True
With the additional error message tab attached.
Your new code works, just again will not run the:
iLogicVb.RunRule(oName, "ManwayCutOut")
Here is the ManwayCutOut rule:
If ManwayType = 600 Then Feature.IsActive("MWAY600 Centre") = True Feature.IsActive("MWAY600 Holes") = True Feature.IsActive("MWAY600 PCD") = True Feature.IsActive("MWAY800 Centre") = False Feature.IsActive("MWAY800 Holes") = False Feature.IsActive("MWAY800 PCD") = False Feature.IsActive("MWAY900 Centre") = False Feature.IsActive("MWAY900 Holes") = False Feature.IsActive("MWAY800 PCD") = False Else If ManwayType = 800 Then Feature.IsActive("MWAY800 Centre") = True Feature.IsActive("MWAY800 Holes") = True Feature.IsActive("MWAY800 PCD") = True Feature.IsActive("MWAY600 Centre") = False Feature.IsActive("MWAY600 Holes") = False Feature.IsActive("MWAY600 PCD") = False Feature.IsActive("MWAY900 Centre") = False Feature.IsActive("MWAY900 Holes") = False Feature.IsActive("MWAY900 PCD") = False Else If ManwayType = 900 Then Feature.IsActive("MWAY900 Centre") = True Feature.IsActive("MWAY900 Holes") = True Feature.IsActive("MWAY900 PCD") = True Feature.IsActive("MWAY800 Centre") = False Feature.IsActive("MWAY800 Holes") = False Feature.IsActive("MWAY800 PCD") = False Feature.IsActive("MWAY600 Centre") = False Feature.IsActive("MWAY600 Holes") = False Feature.IsActive("MWAY600 PCD") = False End If iLogicVb.UpdateWhenDone = True
With the additional error message tab attached.
Your new code works, just again will not run the:
iLogicVb.RunRule(oName, "ManwayCutOut")
OK. So in this case, the info in that other tab wasn't that helpful after all. But after seeing your other rule, I can instantly see why it is having problems. You are using the unquoted names of local parameters and the Feature.IsActive() iLogic snippet without specifying a target component name or document name. That set-up is usually great for local rules, but when you run that rule remotely, while another document is the 'active' document, it may cause problems. I'm not 100% sure whether the Feature.IsActive() iLogic snippet targets the 'active' document or the 'local' document by default, when you don't specify a component name or document name as the first input variable. I assume it is targeting the 'active' document though. And in this case, the main assembly is still the 'active' document when this rule is getting ran remotely, which may be causing the problem.
There are some alternative ways this rule could be laid out, but it starts to get more complicated when we do.
What I would suggest first, before attempting to rewrite your local rule differently, would be to activate this document just before we use that line of code to run it. That may eliminate the problem. If not, then we may look into rewriting that rule a bit to make it work in this situation.
So...I just slightly tweaked the earlier main code to activate that part document just before the line to run the rule.
Dim doc As AssemblyDocument = ThisDoc.Document
oName = "COURSE 1 STEEL TANK SHEET:8"
occ = doc.ComponentDefinition.Occurrences.ItemByName(oName)
Dim facDoc As PartDocument = occ.Definition.Document
oPCD = facDoc.ComponentDefinition
If oPCD.IsModelStateMember Then
facDoc = oPCD.FactoryDocument
End If
oMStates = oPCD.ModelStates
newModelStateName = "N1"
oMState = oMStates.Add(newModelStateName)
oMState.Activate()
occ.ActiveModelState = newModelStateName
facDoc.Activate
iLogicVb.RunRule(oName, "ManwayCutOut")
're-activate the main assembly afterwards, if needed
'but test both ways, in case more time is needed for the rule to do its thing
'doc.Activate
Wesley Crihfield
(Not an Autodesk Employee)
OK. So in this case, the info in that other tab wasn't that helpful after all. But after seeing your other rule, I can instantly see why it is having problems. You are using the unquoted names of local parameters and the Feature.IsActive() iLogic snippet without specifying a target component name or document name. That set-up is usually great for local rules, but when you run that rule remotely, while another document is the 'active' document, it may cause problems. I'm not 100% sure whether the Feature.IsActive() iLogic snippet targets the 'active' document or the 'local' document by default, when you don't specify a component name or document name as the first input variable. I assume it is targeting the 'active' document though. And in this case, the main assembly is still the 'active' document when this rule is getting ran remotely, which may be causing the problem.
There are some alternative ways this rule could be laid out, but it starts to get more complicated when we do.
What I would suggest first, before attempting to rewrite your local rule differently, would be to activate this document just before we use that line of code to run it. That may eliminate the problem. If not, then we may look into rewriting that rule a bit to make it work in this situation.
So...I just slightly tweaked the earlier main code to activate that part document just before the line to run the rule.
Dim doc As AssemblyDocument = ThisDoc.Document
oName = "COURSE 1 STEEL TANK SHEET:8"
occ = doc.ComponentDefinition.Occurrences.ItemByName(oName)
Dim facDoc As PartDocument = occ.Definition.Document
oPCD = facDoc.ComponentDefinition
If oPCD.IsModelStateMember Then
facDoc = oPCD.FactoryDocument
End If
oMStates = oPCD.ModelStates
newModelStateName = "N1"
oMState = oMStates.Add(newModelStateName)
oMState.Activate()
occ.ActiveModelState = newModelStateName
facDoc.Activate
iLogicVb.RunRule(oName, "ManwayCutOut")
're-activate the main assembly afterwards, if needed
'but test both ways, in case more time is needed for the rule to do its thing
'doc.Activate
Wesley Crihfield
(Not an Autodesk Employee)
Hi thank you for your help so far!
Having issues with this code:
It requires me to have the part open along side the assembly so that it can run:
facDoc.Activate
I can not work with having the part open along side the assembly, so is there anyway around this?
Testing WITH the part open so that the facDoc.Activate line runs still does not solve the run issue of:
iLogicVb.RunRule(oName, "ManwayCutOut")
You mentioned being able to approach this by setting up the "ManwayCutOut" rule so that it can be run remotely, it may be better to try that approach if you have any advice on that?
Any more help/advice would be great
Hi thank you for your help so far!
Having issues with this code:
It requires me to have the part open along side the assembly so that it can run:
facDoc.Activate
I can not work with having the part open along side the assembly, so is there anyway around this?
Testing WITH the part open so that the facDoc.Activate line runs still does not solve the run issue of:
iLogicVb.RunRule(oName, "ManwayCutOut")
You mentioned being able to approach this by setting up the "ManwayCutOut" rule so that it can be run remotely, it may be better to try that approach if you have any advice on that?
Any more help/advice would be great
OK. That's fine. Generally, unless the assembly is in 'Express Mode' all components within the assembly are at least 'initiated', if not fully open (in the background, not visibly). So you usually don't have to open or close any of those documents that are being represented by the components. But I can understand not wanting the other document visibly activated, especially when the code leaves them that way when its done. It can be annoying and might possibly interfere with other operations.
Sure, we can look into changing that other rule as needed for this situation. I created something for you to try. I left several lines of comments in this code for you, just as additional information that may be useful to you. When dealing with parameters, there is a tricky & extremely annoying situation to be aware of, involving the 'units' of any numerical values (other than unit-less). There are several ways of accessing and dealing with parameters, and some return different results than others. When using either the unquoted name of a 'local' parameter in a 'local' rule, and when using the iLogic snippet 'Parameters("parameter_name")', these will both return the true 'document units' value of the parameter directly. But when using either the iLogic snippet 'Parameter.Param("parameter_name").Value', or the normal API way 'Document.ComponentDefinition.Parameters.Item("parameter_name").Value' to get the parameter's value, it will return the 'database units' version of its Value, instead of the 'document units' version of it. I generally prefer to use the API route, then convert the units back as needed, instead of using the iLogic snippets for this task, because it's more reliable, clearer, & better documented. But I would need to know what type of units were being used ahead of time, to convert the units properly within the code.
Here is the new version of that local rule that you can try:
'just using a dummy variable here,
'to preserve automation/triggering behavior of unquoted local parameter
oDV = ManwayType
'get the 'local' part document object (the document this rule is saved within)
Dim oPDoc As PartDocument = ThisDoc.Document
oPDef = oPDoc.ComponentDefinition
'if the parameter is numerical, and not unit-less,
'this will return 'database units' version of the parameter's Value,
'not the 'document units' version of it
'oManwayType = oPDef.Parameters.Item("ManwayType").Value
oDocName = ThisDoc.FileName(True)
'these two will get the 'document units' version of the parameter's Value
'oManwayType = ManwayType 'unquoted parameter name
oManwayType = Parameter(oDocName, "ManwayType")
oFeats = oPDef.Features
If oManwayType = 600 Then
oFeats.Item("MWAY600 Centre").Suppressed = False
oFeats.Item("MWAY600 Holes").Suppressed = False
oFeats.Item("MWAY600 PCD").Suppressed = False
oFeats.Item("MWAY800 Centre").Suppressed = True
oFeats.Item("MWAY800 Holes").Suppressed = True
oFeats.Item("MWAY800 PCD").Suppressed = True
oFeats.Item("MWAY900 Centre").Suppressed = True
oFeats.Item("MWAY900 Holes").Suppressed = True
oFeats.Item("MWAY800 PCD").Suppressed = True
ElseIf oManwayType = 800 Then
oFeats.Item("MWAY800 Centre").Suppressed = False
oFeats.Item("MWAY800 Holes").Suppressed = False
oFeats.Item("MWAY800 PCD").Suppressed = False
oFeats.Item("MWAY600 Centre").Suppressed = True
oFeats.Item("MWAY600 Holes").Suppressed = True
oFeats.Item("MWAY600 PCD").Suppressed = True
oFeats.Item("MWAY900 Centre").Suppressed = True
oFeats.Item("MWAY900 Holes").Suppressed = True
oFeats.Item("MWAY900 PCD").Suppressed = True
ElseIf oManwayType = 900 Then
oFeats.Item("MWAY900 Centre").Suppressed = False
oFeats.Item("MWAY900 Holes").Suppressed = False
oFeats.Item("MWAY900 PCD").Suppressed = False
oFeats.Item("MWAY800 Centre").Suppressed = True
oFeats.Item("MWAY800 Holes").Suppressed = True
oFeats.Item("MWAY800 PCD").Suppressed = True
oFeats.Item("MWAY600 Centre").Suppressed = True
oFeats.Item("MWAY600 Holes").Suppressed = True
oFeats.Item("MWAY600 PCD").Suppressed = True
End If
oPDoc.Update
Wesley Crihfield
(Not an Autodesk Employee)
OK. That's fine. Generally, unless the assembly is in 'Express Mode' all components within the assembly are at least 'initiated', if not fully open (in the background, not visibly). So you usually don't have to open or close any of those documents that are being represented by the components. But I can understand not wanting the other document visibly activated, especially when the code leaves them that way when its done. It can be annoying and might possibly interfere with other operations.
Sure, we can look into changing that other rule as needed for this situation. I created something for you to try. I left several lines of comments in this code for you, just as additional information that may be useful to you. When dealing with parameters, there is a tricky & extremely annoying situation to be aware of, involving the 'units' of any numerical values (other than unit-less). There are several ways of accessing and dealing with parameters, and some return different results than others. When using either the unquoted name of a 'local' parameter in a 'local' rule, and when using the iLogic snippet 'Parameters("parameter_name")', these will both return the true 'document units' value of the parameter directly. But when using either the iLogic snippet 'Parameter.Param("parameter_name").Value', or the normal API way 'Document.ComponentDefinition.Parameters.Item("parameter_name").Value' to get the parameter's value, it will return the 'database units' version of its Value, instead of the 'document units' version of it. I generally prefer to use the API route, then convert the units back as needed, instead of using the iLogic snippets for this task, because it's more reliable, clearer, & better documented. But I would need to know what type of units were being used ahead of time, to convert the units properly within the code.
Here is the new version of that local rule that you can try:
'just using a dummy variable here,
'to preserve automation/triggering behavior of unquoted local parameter
oDV = ManwayType
'get the 'local' part document object (the document this rule is saved within)
Dim oPDoc As PartDocument = ThisDoc.Document
oPDef = oPDoc.ComponentDefinition
'if the parameter is numerical, and not unit-less,
'this will return 'database units' version of the parameter's Value,
'not the 'document units' version of it
'oManwayType = oPDef.Parameters.Item("ManwayType").Value
oDocName = ThisDoc.FileName(True)
'these two will get the 'document units' version of the parameter's Value
'oManwayType = ManwayType 'unquoted parameter name
oManwayType = Parameter(oDocName, "ManwayType")
oFeats = oPDef.Features
If oManwayType = 600 Then
oFeats.Item("MWAY600 Centre").Suppressed = False
oFeats.Item("MWAY600 Holes").Suppressed = False
oFeats.Item("MWAY600 PCD").Suppressed = False
oFeats.Item("MWAY800 Centre").Suppressed = True
oFeats.Item("MWAY800 Holes").Suppressed = True
oFeats.Item("MWAY800 PCD").Suppressed = True
oFeats.Item("MWAY900 Centre").Suppressed = True
oFeats.Item("MWAY900 Holes").Suppressed = True
oFeats.Item("MWAY800 PCD").Suppressed = True
ElseIf oManwayType = 800 Then
oFeats.Item("MWAY800 Centre").Suppressed = False
oFeats.Item("MWAY800 Holes").Suppressed = False
oFeats.Item("MWAY800 PCD").Suppressed = False
oFeats.Item("MWAY600 Centre").Suppressed = True
oFeats.Item("MWAY600 Holes").Suppressed = True
oFeats.Item("MWAY600 PCD").Suppressed = True
oFeats.Item("MWAY900 Centre").Suppressed = True
oFeats.Item("MWAY900 Holes").Suppressed = True
oFeats.Item("MWAY900 PCD").Suppressed = True
ElseIf oManwayType = 900 Then
oFeats.Item("MWAY900 Centre").Suppressed = False
oFeats.Item("MWAY900 Holes").Suppressed = False
oFeats.Item("MWAY900 PCD").Suppressed = False
oFeats.Item("MWAY800 Centre").Suppressed = True
oFeats.Item("MWAY800 Holes").Suppressed = True
oFeats.Item("MWAY800 PCD").Suppressed = True
oFeats.Item("MWAY600 Centre").Suppressed = True
oFeats.Item("MWAY600 Holes").Suppressed = True
oFeats.Item("MWAY600 PCD").Suppressed = True
End If
oPDoc.Update
Wesley Crihfield
(Not an Autodesk Employee)
Hi,
Having issues with this line:
Parameter.Param().Value
See error message images attached
(Is line 47 due to commenting out the previous code for safe keeping)
Little out of my depth here but you are explaining everything clearly so thank you for that.
Hi,
Having issues with this line:
Parameter.Param().Value
See error message images attached
(Is line 47 due to commenting out the previous code for safe keeping)
Little out of my depth here but you are explaining everything clearly so thank you for that.
Oops... I didn't mean to leave that line in there. I was just playing around with the different methods of getting that parameter. Just delete that whole line.
Wesley Crihfield
(Not an Autodesk Employee)
Oops... I didn't mean to leave that line in there. I was just playing around with the different methods of getting that parameter. Just delete that whole line.
Wesley Crihfield
(Not an Autodesk Employee)
Thought it was out of place 🙂
Still having issues with getting the rule to run, definitely need to go back to approaching it from assembly level?
So just to refresh:
We have an assembly with duplications of the same part.
We are selecting part variation 'COURSE 1 STEEL TANK SHEET:8'.
We are creating a new model state within this part called N1.
We are activating this model state on just this variation, the other parts are still set to Master. (All this is successful!)
Then we are wanting to run a rule within COURSE 1 STEEL TANK SHEET:8 while it is on model state N1...
This rule is to unsuppress features so that N1 model state differs from the Master model state.
This can all be done manually but we want to have it all automatic...
This works to create the N1 model state within COURSE 1 STEEL TANK SHEET:8
Dim doc As AssemblyDocument = ThisDoc.Document
oName = "COURSE 1 STEEL TANK SHEET:8"
occ = doc.ComponentDefinition.Occurrences.ItemByName(oName)
Dim facDoc As PartDocument = occ.Definition.Document
oPCD = facDoc.ComponentDefinition
If oPCD.IsModelStateMember Then
facDoc = oPCD.FactoryDocument
End If
oMStates = oPCD.ModelStates
newModelStateName = "N1"
oMState = oMStates.Add(newModelStateName)
oMState.Activate()
occ.ActiveModelState = newModelStateName
However this line will not run (when added at the end):
iLogicVb.RunRule(oName, "ManwayCutOut")
So attempted:
Dim doc As AssemblyDocument = ThisDoc.Document
oName = "COURSE 1 STEEL TANK SHEET:8"
occ = doc.ComponentDefinition.Occurrences.ItemByName(oName)
Dim facDoc As PartDocument = occ.Definition.Document
oPCD = facDoc.ComponentDefinition
If oPCD.IsModelStateMember Then
facDoc = oPCD.FactoryDocument
End If
oMStates = oPCD.ModelStates
newModelStateName = "N1"
oMState = oMStates.Add(newModelStateName)
oMState.Activate()
occ.ActiveModelState = newModelStateName
facDoc.Activate
iLogicVb.RunRule(oName, "ManwayCutOut")
're-activate the main assembly afterwards, if needed
'but test both ways, in case more time is needed for the rule to do its thing
'doc.Activate
But the iLogicVb.RunRule(oName, "ManwayCutOut") still will not run.
And I can not work with having the COURSE 1 STEEL TANK SHEET:8 part visibly active along side the main assembly.
Then we tried changing the ManwayCutOut rule but this doesn't fix it as the call from the higher level rule just does not work.
I tried a test:
iLogicVb.RunRule(oName, "TEST")
Run a rule in COURSE 1 STEEL TANK SHEET:8 while N1 Model State is active where TEST had the following code:
MessageBox.Show("WORKING")
But this will not even run...
So I believe the runrule triggger is not working due to the activity state, so can we make the COURSE 1 STEEL TANK SHEET:8 active without it being visibly active??
I hope this is clear.
Thanks
Thought it was out of place 🙂
Still having issues with getting the rule to run, definitely need to go back to approaching it from assembly level?
So just to refresh:
We have an assembly with duplications of the same part.
We are selecting part variation 'COURSE 1 STEEL TANK SHEET:8'.
We are creating a new model state within this part called N1.
We are activating this model state on just this variation, the other parts are still set to Master. (All this is successful!)
Then we are wanting to run a rule within COURSE 1 STEEL TANK SHEET:8 while it is on model state N1...
This rule is to unsuppress features so that N1 model state differs from the Master model state.
This can all be done manually but we want to have it all automatic...
This works to create the N1 model state within COURSE 1 STEEL TANK SHEET:8
Dim doc As AssemblyDocument = ThisDoc.Document
oName = "COURSE 1 STEEL TANK SHEET:8"
occ = doc.ComponentDefinition.Occurrences.ItemByName(oName)
Dim facDoc As PartDocument = occ.Definition.Document
oPCD = facDoc.ComponentDefinition
If oPCD.IsModelStateMember Then
facDoc = oPCD.FactoryDocument
End If
oMStates = oPCD.ModelStates
newModelStateName = "N1"
oMState = oMStates.Add(newModelStateName)
oMState.Activate()
occ.ActiveModelState = newModelStateName
However this line will not run (when added at the end):
iLogicVb.RunRule(oName, "ManwayCutOut")
So attempted:
Dim doc As AssemblyDocument = ThisDoc.Document
oName = "COURSE 1 STEEL TANK SHEET:8"
occ = doc.ComponentDefinition.Occurrences.ItemByName(oName)
Dim facDoc As PartDocument = occ.Definition.Document
oPCD = facDoc.ComponentDefinition
If oPCD.IsModelStateMember Then
facDoc = oPCD.FactoryDocument
End If
oMStates = oPCD.ModelStates
newModelStateName = "N1"
oMState = oMStates.Add(newModelStateName)
oMState.Activate()
occ.ActiveModelState = newModelStateName
facDoc.Activate
iLogicVb.RunRule(oName, "ManwayCutOut")
're-activate the main assembly afterwards, if needed
'but test both ways, in case more time is needed for the rule to do its thing
'doc.Activate
But the iLogicVb.RunRule(oName, "ManwayCutOut") still will not run.
And I can not work with having the COURSE 1 STEEL TANK SHEET:8 part visibly active along side the main assembly.
Then we tried changing the ManwayCutOut rule but this doesn't fix it as the call from the higher level rule just does not work.
I tried a test:
iLogicVb.RunRule(oName, "TEST")
Run a rule in COURSE 1 STEEL TANK SHEET:8 while N1 Model State is active where TEST had the following code:
MessageBox.Show("WORKING")
But this will not even run...
So I believe the runrule triggger is not working due to the activity state, so can we make the COURSE 1 STEEL TANK SHEET:8 active without it being visibly active??
I hope this is clear.
Thanks
Based on that recap and what you said at the end of 'Message 5', my best guess is that there is a bug preventing us from running local rules (or all rules effecting that document) while a ModelState other than "Master" is active. It kind of sounds familiar...like I've heard about this before somewhere, but I can't remember where. May have been a webinar or something about the current limitations of ModelStates. And it also seems to be blocking your simple call to set the value of the parameter while a ModelState other than "Master" is active. I know that non-Master ModelStates have a table in them that can be edited, similar to an iPart, iAssembly, or iFeature table, that can be edited like a spreadsheet (with Excel or whatever native editor you have). And I know that the ModelStates object has a MemberEditScope property that needs to be set to specify whether changes effect all ModelStates or just the 'active' ModelState. But I honestly have not tried this specific task before yet.
Here's a thought as we explore this idea. I bet we have to first set the MemberEditScope setting to "kEditActiveMember" (without quotes). Then either edit the table, or dig down into the ModelState.FactoryDocument, then into its ComponentDefinition.Parameters.Item("parameter_name").Value to get/set its value only for that one ModelState, when dealing with a Parameter. Similar process for suppressing or un-suppressing a feature only in that one ModelState. Using the API route would look like oModelState.FactoryDocument.ComponentDefinition.Features.Item("feature name").Suppressed = True. We may have to do all of this from that main rule in the assembly, instead of using that local rule within the part document. I'm not 100% sure, though. The process I just stated makes better/clearer sense to me right now though. If we were to edit the table, it might get more complicated, because we won't know how its all laid out to find stuff within, so we would likely have to use a series of loops through rows & columns to find the right cell values to change.
PS. I tested that route on a test assembly and it works. (Digging down into the FactoryDocument to get the Parameters & Featrues, that is.)
Wesley Crihfield
(Not an Autodesk Employee)
Based on that recap and what you said at the end of 'Message 5', my best guess is that there is a bug preventing us from running local rules (or all rules effecting that document) while a ModelState other than "Master" is active. It kind of sounds familiar...like I've heard about this before somewhere, but I can't remember where. May have been a webinar or something about the current limitations of ModelStates. And it also seems to be blocking your simple call to set the value of the parameter while a ModelState other than "Master" is active. I know that non-Master ModelStates have a table in them that can be edited, similar to an iPart, iAssembly, or iFeature table, that can be edited like a spreadsheet (with Excel or whatever native editor you have). And I know that the ModelStates object has a MemberEditScope property that needs to be set to specify whether changes effect all ModelStates or just the 'active' ModelState. But I honestly have not tried this specific task before yet.
Here's a thought as we explore this idea. I bet we have to first set the MemberEditScope setting to "kEditActiveMember" (without quotes). Then either edit the table, or dig down into the ModelState.FactoryDocument, then into its ComponentDefinition.Parameters.Item("parameter_name").Value to get/set its value only for that one ModelState, when dealing with a Parameter. Similar process for suppressing or un-suppressing a feature only in that one ModelState. Using the API route would look like oModelState.FactoryDocument.ComponentDefinition.Features.Item("feature name").Suppressed = True. We may have to do all of this from that main rule in the assembly, instead of using that local rule within the part document. I'm not 100% sure, though. The process I just stated makes better/clearer sense to me right now though. If we were to edit the table, it might get more complicated, because we won't know how its all laid out to find stuff within, so we would likely have to use a series of loops through rows & columns to find the right cell values to change.
PS. I tested that route on a test assembly and it works. (Digging down into the FactoryDocument to get the Parameters & Featrues, that is.)
Wesley Crihfield
(Not an Autodesk Employee)
Got the following to work:
Dim doc As AssemblyDocument = ThisDoc.Document oName = "COURSE 1 STEEL TANK SHEET:8" occ = doc.ComponentDefinition.Occurrences.ItemByName(oName) Dim facDoc As PartDocument = occ.Definition.Document oPCD = facDoc.ComponentDefinition If oPCD.IsModelStateMember Then facDoc = oPCD.FactoryDocument End If oMStates = oPCD.ModelStates newModelStateName = "N1" oMState = oMStates.Add(newModelStateName) oMState.Activate() occ.ActiveModelState = newModelStateName oMState.FactoryDocument.ComponentDefinition.Features.Item("MWAY900 Centre").Suppressed = False oMState.FactoryDocument.ComponentDefinition.Features.Item("MWAY900 Holes").Suppressed = False oMState.FactoryDocument.ComponentDefinition.Features.Item("MWAY900 PCD").Suppressed = False
This does require shifting the ManwayCutOut code into this top level rule, which I can do. It is a workable solution.
However it certainly seems to be the long way to do it, the ilogicvb.runrule trigger should work. I will report this as a possible bug.
Thank you for all of your help, finally have a workable solution! 😀
Got the following to work:
Dim doc As AssemblyDocument = ThisDoc.Document oName = "COURSE 1 STEEL TANK SHEET:8" occ = doc.ComponentDefinition.Occurrences.ItemByName(oName) Dim facDoc As PartDocument = occ.Definition.Document oPCD = facDoc.ComponentDefinition If oPCD.IsModelStateMember Then facDoc = oPCD.FactoryDocument End If oMStates = oPCD.ModelStates newModelStateName = "N1" oMState = oMStates.Add(newModelStateName) oMState.Activate() occ.ActiveModelState = newModelStateName oMState.FactoryDocument.ComponentDefinition.Features.Item("MWAY900 Centre").Suppressed = False oMState.FactoryDocument.ComponentDefinition.Features.Item("MWAY900 Holes").Suppressed = False oMState.FactoryDocument.ComponentDefinition.Features.Item("MWAY900 PCD").Suppressed = False
This does require shifting the ManwayCutOut code into this top level rule, which I can do. It is a workable solution.
However it certainly seems to be the long way to do it, the ilogicvb.runrule trigger should work. I will report this as a possible bug.
Thank you for all of your help, finally have a workable solution! 😀
Hi, zoe.baker-bushby,
recently we were trying to transfer to inventor 2022. I am trying to imitate the suppress and unsuppress operations under LOD by using model state. I really met a lot of difficulties and puzzles.
1. you said you would report some potential bugs to autodesk. Did you report them? did you get any feedback from autodesk? The difficulties you met are bugs or not?
2. have you found any good methods to do suppress and unsuppress locally inside a part or assembly?
thank you in advance.
Hi, zoe.baker-bushby,
recently we were trying to transfer to inventor 2022. I am trying to imitate the suppress and unsuppress operations under LOD by using model state. I really met a lot of difficulties and puzzles.
1. you said you would report some potential bugs to autodesk. Did you report them? did you get any feedback from autodesk? The difficulties you met are bugs or not?
2. have you found any good methods to do suppress and unsuppress locally inside a part or assembly?
thank you in advance.
Hi,
We did report some bugs to autodesk. It has been confirmed that there are issues with moving LOD parts with suppressed parts into 2022. We have rules that suppress/unsuppress parts but due to moving to 2022 these would not run.
We got given a rule to run to delete all iLogic LOD in an assembly, info can be found here:
This then allowed us to resume normally running of our code.
Hope this helps with what you are after.
Hi,
We did report some bugs to autodesk. It has been confirmed that there are issues with moving LOD parts with suppressed parts into 2022. We have rules that suppress/unsuppress parts but due to moving to 2022 these would not run.
We got given a rule to run to delete all iLogic LOD in an assembly, info can be found here:
This then allowed us to resume normally running of our code.
Hope this helps with what you are after.
it is possible to create a similar rule but which allows, within the PART, to create a model state with the same name as the modified parameter (For example, parameter name HEIGHT = 30 MODEL STATUS = 30)
and if it does not exist, create it otherwise activate the already existing one? I think you can also use the way of a list that is updated with each new value.
* I asked the same question also in another discussion but I realized only now that they were discussing in a group environment
it is possible to create a similar rule but which allows, within the PART, to create a model state with the same name as the modified parameter (For example, parameter name HEIGHT = 30 MODEL STATUS = 30)
and if it does not exist, create it otherwise activate the already existing one? I think you can also use the way of a list that is updated with each new value.
* I asked the same question also in another discussion but I realized only now that they were discussing in a group environment
Not completely certain what you are asking but I have put this together:
Dim Doc As PartDocument = ThisDoc.Document oPCD = Doc.ComponentDefinition If oPCD.IsModelStateMember Then Doc = oPCD.FactoryDocument End If oMStates = oPCD.ModelStates newModelStateName = HEIGHT oMState = oMStates.Add(newModelStateName)
Hope that helps 😊
Not completely certain what you are asking but I have put this together:
Dim Doc As PartDocument = ThisDoc.Document oPCD = Doc.ComponentDefinition If oPCD.IsModelStateMember Then Doc = oPCD.FactoryDocument End If oMStates = oPCD.ModelStates newModelStateName = HEIGHT oMState = oMStates.Add(newModelStateName)
Hope that helps 😊
Can't find what you're looking for? Ask the community or share your knowledge.