Hi all,
We've had a model that has been bouncing back and forth (Pack n Go) between remote users. At some point there was an error or corrupt file that caused many dialog boxes to occur. Once dealt with, the result was that all iLogic rules had been removed from every single part.
These iLogic rules are essential for processing our CAD data for material allocation and procurement, so we need them back in.
Is it easy enough to do this? Ideally I could have it in a form where, in assembly mode I click the part, then click the button on the form for the iLogic rule I want to write to the part.
Can someone please help me write these codes back to the parts? Unfortunately it's not the same code(s) for every part. It will differ depending on how the part is fabricated and how many details it has. Deciding the code will have to be human input.
Thanks in advance.
Solved! Go to Solution.
Hi all,
We've had a model that has been bouncing back and forth (Pack n Go) between remote users. At some point there was an error or corrupt file that caused many dialog boxes to occur. Once dealt with, the result was that all iLogic rules had been removed from every single part.
These iLogic rules are essential for processing our CAD data for material allocation and procurement, so we need them back in.
Is it easy enough to do this? Ideally I could have it in a form where, in assembly mode I click the part, then click the button on the form for the iLogic rule I want to write to the part.
Can someone please help me write these codes back to the parts? Unfortunately it's not the same code(s) for every part. It will differ depending on how the part is fabricated and how many details it has. Deciding the code will have to be human input.
Thanks in advance.
Solved! Go to Solution.
Solved by WCrihfield. Go to Solution.
Solved by WCrihfield. Go to Solution.
Hi @Cadderman. I'm not 100% sure, but it sounds like this one specific Autodesk published Inventor Add-In may be able to help you out quite a bit with that task. It is called "iLogic Rule Batch Tool", and it is essentially free to download and use too. It can help you re-populate your Inventor documents with local/internal rules, as well as provide a lot of other similar/related functionality.
Wesley Crihfield
(Not an Autodesk Employee)
Hi @Cadderman. I'm not 100% sure, but it sounds like this one specific Autodesk published Inventor Add-In may be able to help you out quite a bit with that task. It is called "iLogic Rule Batch Tool", and it is essentially free to download and use too. It can help you re-populate your Inventor documents with local/internal rules, as well as provide a lot of other similar/related functionality.
Wesley Crihfield
(Not an Autodesk Employee)
If using that add-in is not going to be an option, or does not meet your needs, here are some links to some of my contribution posts that you might find useful, or at least informational/interesting.
Copy All Rules From One Document To Another Using An Exteral iLogic Rule
Copy All iLogic Rules & Event Triggers From One Document To Another Using An External iLogic Rule
External iLogic Rule (or VBA Macro) To Create Local iLogic Rule
and here is one for pushing iProperties to all certain type files in a folder, if that may be of use too
Push (Create/Update) iProperty To All Docs (of Selected Type) Within Specified Folder - iLogic
Wesley Crihfield
(Not an Autodesk Employee)
If using that add-in is not going to be an option, or does not meet your needs, here are some links to some of my contribution posts that you might find useful, or at least informational/interesting.
Copy All Rules From One Document To Another Using An Exteral iLogic Rule
Copy All iLogic Rules & Event Triggers From One Document To Another Using An External iLogic Rule
External iLogic Rule (or VBA Macro) To Create Local iLogic Rule
and here is one for pushing iProperties to all certain type files in a folder, if that may be of use too
Push (Create/Update) iProperty To All Docs (of Selected Type) Within Specified Folder - iLogic
Wesley Crihfield
(Not an Autodesk Employee)
Thanks @WCrihfield for responding so quickly! Unfortunately it looks like I can't use any of the contribution posts as the part numbering system is not descriptive. Picking parts to copy from and to in a windows explorer setting would be difficult this way.
Is there a way to copy ilogic from one part in an assembly to the rest of the parts? I can copy all similar parts and group them into assemblies for the purpose of this exercise if required.
Thanks @WCrihfield for responding so quickly! Unfortunately it looks like I can't use any of the contribution posts as the part numbering system is not descriptive. Picking parts to copy from and to in a windows explorer setting would be difficult this way.
Is there a way to copy ilogic from one part in an assembly to the rest of the parts? I can copy all similar parts and group them into assemblies for the purpose of this exercise if required.
Hi @Cadderman. I did not have a solution like that already made, so I just created this code for that situation. I have not tested it yet myself, so you may want to be careful and test it out on some test files first, just to be sure. Let me know how this works out for you. I included some lines of comments in there to help guide you about what's going on. I'm using the Pick method to allow you to manually select which component will be the source of the rules to be copied. If that is not what you had in mind, we can probably change that part, if necessary.
Sub Main
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
'pick source component with rules to be copied
oObj = ThisApplication.CommandManager.Pick(SelectionFilterEnum.kAssemblyOccurrenceFilter, "Select Source Component.")
If IsNothing(oObj) OrElse (TypeOf oObj Is ComponentOccurrence = False) Then Exit Sub
Dim oSourceOcc As ComponentOccurrence = oObj
'get the document that the component represents
Dim oSourceDoc As Document = oSourceOcc.ReferencedDocumentDescriptor.ReferencedDocument
Dim oAuto As IiLogicAutomation = iLogicVb.Automation
'get the internal/local rules within that source document
Dim oSourceRules = oAuto.Rules(oSourceDoc)
Dim oSourceRule As iLogicRule = Nothing
'loop through all the assembly's referenced documents
'AllReferencedDocuments - looks at all levels of the assembly
'ReferencedDocuments - just looks at top level of assembly
For Each oRefDoc As Document In oADoc.AllReferencedDocuments
'skip the source document, so we don't try to overwrite its rules
If oRefDoc Is oSourceDoc Then Continue For
'if it is not a Part, then skip to next referenced document
If oRefDoc.DocumentType <> DocumentTypeEnum.kPartDocumentObject Then Continue For
'loop through the source rules (if any)
For Each oSourceRule In oSourceRules
Dim oTargetRule As iLogicRule = Nothing
'check if the internal rule already exists in part first
'if not found, this will NOT throw an error, it will just not set a value
oTargetRule = oAuto.GetRule(oRefDoc, oSourceRule.Name)
'if not found, create it
If IsNothing(oTargetRule) Then
oTargetRule = oAuto.AddRule(oRefDoc, oSourceRule.Name, "")
'set text (contents) here so the rule won't immediately run
oTargetRule.Text = oSourceRule.Text
Else 'the rule was found, so make sure its text (contents) is up to date
If oTargetRule.Text <> oSourceRule.Text Then
oTargetRule.Text = oSourceRule.Text
End If
End If
Next 'oSourceRule
'save the referenced document that we copied the rules to
oRefDoc.Save2(False) 'False = skip saving dependent documents
Next 'oRefDoc
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) 👍.
If you want and have time, I would appreciate your Vote(s) for My IDEAS :bulb: or you can Explore My CONTRIBUTIONS
Wesley Crihfield
(Not an Autodesk Employee)
Hi @Cadderman. I did not have a solution like that already made, so I just created this code for that situation. I have not tested it yet myself, so you may want to be careful and test it out on some test files first, just to be sure. Let me know how this works out for you. I included some lines of comments in there to help guide you about what's going on. I'm using the Pick method to allow you to manually select which component will be the source of the rules to be copied. If that is not what you had in mind, we can probably change that part, if necessary.
Sub Main
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
'pick source component with rules to be copied
oObj = ThisApplication.CommandManager.Pick(SelectionFilterEnum.kAssemblyOccurrenceFilter, "Select Source Component.")
If IsNothing(oObj) OrElse (TypeOf oObj Is ComponentOccurrence = False) Then Exit Sub
Dim oSourceOcc As ComponentOccurrence = oObj
'get the document that the component represents
Dim oSourceDoc As Document = oSourceOcc.ReferencedDocumentDescriptor.ReferencedDocument
Dim oAuto As IiLogicAutomation = iLogicVb.Automation
'get the internal/local rules within that source document
Dim oSourceRules = oAuto.Rules(oSourceDoc)
Dim oSourceRule As iLogicRule = Nothing
'loop through all the assembly's referenced documents
'AllReferencedDocuments - looks at all levels of the assembly
'ReferencedDocuments - just looks at top level of assembly
For Each oRefDoc As Document In oADoc.AllReferencedDocuments
'skip the source document, so we don't try to overwrite its rules
If oRefDoc Is oSourceDoc Then Continue For
'if it is not a Part, then skip to next referenced document
If oRefDoc.DocumentType <> DocumentTypeEnum.kPartDocumentObject Then Continue For
'loop through the source rules (if any)
For Each oSourceRule In oSourceRules
Dim oTargetRule As iLogicRule = Nothing
'check if the internal rule already exists in part first
'if not found, this will NOT throw an error, it will just not set a value
oTargetRule = oAuto.GetRule(oRefDoc, oSourceRule.Name)
'if not found, create it
If IsNothing(oTargetRule) Then
oTargetRule = oAuto.AddRule(oRefDoc, oSourceRule.Name, "")
'set text (contents) here so the rule won't immediately run
oTargetRule.Text = oSourceRule.Text
Else 'the rule was found, so make sure its text (contents) is up to date
If oTargetRule.Text <> oSourceRule.Text Then
oTargetRule.Text = oSourceRule.Text
End If
End If
Next 'oSourceRule
'save the referenced document that we copied the rules to
oRefDoc.Save2(False) 'False = skip saving dependent documents
Next 'oRefDoc
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) 👍.
If you want and have time, I would appreciate your Vote(s) for My IDEAS :bulb: or you can Explore My CONTRIBUTIONS
Wesley Crihfield
(Not an Autodesk Employee)
I think this is the solution! I ran it in a test assembly and it copied the code from the source part and wrote it to all the other parts within the assembly.
I can work with this. I will copy all the similar parts into an assembly and then place a template in the assembly to copy from.
This is much easier than copying and pasting the standard way. Thank you so much!!!!
I think this is the solution! I ran it in a test assembly and it copied the code from the source part and wrote it to all the other parts within the assembly.
I can work with this. I will copy all the similar parts into an assembly and then place a template in the assembly to copy from.
This is much easier than copying and pasting the standard way. Thank you so much!!!!
Is there a way to run all the rules once they are written?
Is there a way to run all the rules once they are written?
In a way, yes. I just wasn't sure that was what you wanted, so I set it up in a way that would prevent the rules from immediately running when they were copied over. At the point in the code where I am using the 'AddRule' method, if I had put the Text or contents of the rule in place, instead of an empty String, it would have immediately ran the new rule it was creating. So, I just used an empty String in that location, then set the Rule.Text on the next line of code, which does not trigger the rule to run. I don't know if that is what you had in mind, of if you want a secondary rule to go back through all the components and run the rules after the copy process. Which scenario did you have in mind?
Keep in mind that when running rules in components while the main assembly is open/active, if those rules are not setup properly, they may be trying to target the main assembly, because it will most likely remain the 'active' document while those rules are running. So if those rules use the term 'ThisApplication.ActiveDocument' to specify which document they are to act upon, that will most likely be getting the main assembly. The term 'ThisDoc.Document' is almost always better for use within internal/local rules, because it will default to the 'local' document (the document that the rule is saved within).
Wesley Crihfield
(Not an Autodesk Employee)
In a way, yes. I just wasn't sure that was what you wanted, so I set it up in a way that would prevent the rules from immediately running when they were copied over. At the point in the code where I am using the 'AddRule' method, if I had put the Text or contents of the rule in place, instead of an empty String, it would have immediately ran the new rule it was creating. So, I just used an empty String in that location, then set the Rule.Text on the next line of code, which does not trigger the rule to run. I don't know if that is what you had in mind, of if you want a secondary rule to go back through all the components and run the rules after the copy process. Which scenario did you have in mind?
Keep in mind that when running rules in components while the main assembly is open/active, if those rules are not setup properly, they may be trying to target the main assembly, because it will most likely remain the 'active' document while those rules are running. So if those rules use the term 'ThisApplication.ActiveDocument' to specify which document they are to act upon, that will most likely be getting the main assembly. The term 'ThisDoc.Document' is almost always better for use within internal/local rules, because it will default to the 'local' document (the document that the rule is saved within).
Wesley Crihfield
(Not an Autodesk Employee)
Edit: Delete
@WCrihfield Unfortunately I'm not familiar enough with iLogic to be able to modify the code to include copying event Triggers but you're right - that's what I'm trying to achieve. If the codes can be copied along with their triggers, they will run when all parts are saved.
I have managed to isolate the area you referred to for "AddRule" and "Rule.Text". I have read your response multiple times but it's really not sinking in with me unfortunately 😣 I'll keep trying though. If I don't read from you, thank you for all your assistance so far. That code is brilliant.
@WCrihfield Unfortunately I'm not familiar enough with iLogic to be able to modify the code to include copying event Triggers but you're right - that's what I'm trying to achieve. If the codes can be copied along with their triggers, they will run when all parts are saved.
I have managed to isolate the area you referred to for "AddRule" and "Rule.Text". I have read your response multiple times but it's really not sinking in with me unfortunately 😣 I'll keep trying though. If I don't read from you, thank you for all your assistance so far. That code is brilliant.
Hi @Cadderman. I have created an alternate version of the code I posted above, and this time I moved these two main processes out into their own Sub routines, which can be called to run from within the main routine. The one routine copies the rules from the source document to the target document, and the other routine copies the Event Triggers properties from the source document to the target document.
Sub Main
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
'pick source component with rules to be copied
oObj = ThisApplication.CommandManager.Pick(SelectionFilterEnum.kAssemblyOccurrenceFilter, "Select Source Component.")
If IsNothing(oObj) OrElse (TypeOf oObj Is ComponentOccurrence = False) Then Exit Sub
Dim oSourceOcc As ComponentOccurrence = oObj
'get the document that the component represents
Dim oSourceDoc As Document = oSourceOcc.ReferencedDocumentDescriptor.ReferencedDocument
'loop through all the assembly's referenced documents
'AllReferencedDocuments - looks at all levels of the assembly
'ReferencedDocuments - just looks at top level of assembly
For Each oRefDoc As Document In oADoc.AllReferencedDocuments
'skip the source document, so we don't try to overwrite its rules
If oRefDoc Is oSourceDoc Then Continue For
'if it is not a Part, then skip to next referenced document
If oRefDoc.DocumentType <> DocumentTypeEnum.kPartDocumentObject Then Continue For
'run our custom routines below
CopyAllRules(oSourceDoc, oRefDoc)
CopyAllEventTriggers(oSourceDoc, oRefDoc)
'save the referenced document that we copied the rules to
If oRefDoc.Dirty Then
oRefDoc.Save2(False) 'False = skip saving dependent documents
End If
Next 'oRefDoc
End Sub
Sub CopyAllRules(oSourceDocument As Document, oTargetDocument As Document)
If IsNothing(oSourceDocument) Or IsNothing(oTargetDocument) Then Exit Sub
Dim oAuto As IiLogicAutomation = iLogicVb.Automation
Dim oSourceRules As IEnumerable = oAuto.Rules(oSourceDocument)
Dim oSourceRule As iLogicRule = Nothing
For Each oSourceRule In oSourceRules
Dim oTargetRule As iLogicRule = Nothing
'check if oTargetRule already exists first
'if not found, this will NOT throw an error, it will just not set a value
oTargetRule = oAuto.GetRule(oTargetDocument, oSourceRule.Name)
'if not found, create it
If IsNothing(oTargetRule) Then
oTargetRule = oAuto.AddRule(oTargetDocument, oSourceRule.Name, "")
'set text (contents) here so the rule won't immediately run
oTargetRule.Text = oSourceRule.Text
Else 'the rule was found, so make sure its text (contents) is up to date
If oTargetRule.Text <> oSourceRule.Text Then
oTargetRule.Text = oSourceRule.Text
End If
End If
Next 'oSourceRule
End Sub
Sub CopyAllEventTriggers(oSourceDocument As Document, oTargetDocument As Document)
If IsNothing(oSourceDocument) Or IsNothing(oTargetDocument) Then Exit Sub
Dim oInternalName As String = "{2C540830-0723-455E-A8E2-891722EB4C3E}"
'get Event Triggers PropertySet from source document
Dim oSourceSet As PropertySet = Nothing
If Not oSourceDocument.PropertySets.PropertySetExists(oInternalName, oSourceSet) Then
Exit Sub 'the Event Triggers PropertySet was not found in source document, so exit Sub
End If
If oSourceSet.Count = 0 Then Exit Sub 'it contains zero properties, so exit Sub
'get or create Event Triggers PropertySet within target document
Dim oTargetSet As PropertySet = Nothing
If Not oTargetDocument.PropertySets.PropertySetExists(oInternalName, oTargetSet) Then
'the Event Triggers PropertySet was not found in source document, so create it
oTargetSet = oTargetDocument.PropertySets.Add("_iLogicEventsRules", oInternalName)
End If
'<<<< Could delete target Event Triggers set if found, then create a new one >>>>
For Each oSourceProp As Inventor.Property In oSourceSet
'<<< this is not checking if the property may already exist in the target set >>>
Try
oTargetSet.Add(oSourceProp.Value, oSourceProp.Name, oSourceProp.PropId)
Catch
Logger.Error("Failed to copy property named: " & oSourceProp.Name & vbCrLf & _
"With value: " & oSourceProp.Value & vbCrLf & _
"From source document: " & oSourceDocument.FullFileName & vbCrLf & _
"To target document: " & oTargetDocument.FullFileName)
End Try
Next
End Sub
I'm not sure about the part where you want to run all the rules once all the components are saved, but right now I'm thinking about making that a separate rule that would get ran after this one.
Wesley Crihfield
(Not an Autodesk Employee)
Hi @Cadderman. I have created an alternate version of the code I posted above, and this time I moved these two main processes out into their own Sub routines, which can be called to run from within the main routine. The one routine copies the rules from the source document to the target document, and the other routine copies the Event Triggers properties from the source document to the target document.
Sub Main
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
'pick source component with rules to be copied
oObj = ThisApplication.CommandManager.Pick(SelectionFilterEnum.kAssemblyOccurrenceFilter, "Select Source Component.")
If IsNothing(oObj) OrElse (TypeOf oObj Is ComponentOccurrence = False) Then Exit Sub
Dim oSourceOcc As ComponentOccurrence = oObj
'get the document that the component represents
Dim oSourceDoc As Document = oSourceOcc.ReferencedDocumentDescriptor.ReferencedDocument
'loop through all the assembly's referenced documents
'AllReferencedDocuments - looks at all levels of the assembly
'ReferencedDocuments - just looks at top level of assembly
For Each oRefDoc As Document In oADoc.AllReferencedDocuments
'skip the source document, so we don't try to overwrite its rules
If oRefDoc Is oSourceDoc Then Continue For
'if it is not a Part, then skip to next referenced document
If oRefDoc.DocumentType <> DocumentTypeEnum.kPartDocumentObject Then Continue For
'run our custom routines below
CopyAllRules(oSourceDoc, oRefDoc)
CopyAllEventTriggers(oSourceDoc, oRefDoc)
'save the referenced document that we copied the rules to
If oRefDoc.Dirty Then
oRefDoc.Save2(False) 'False = skip saving dependent documents
End If
Next 'oRefDoc
End Sub
Sub CopyAllRules(oSourceDocument As Document, oTargetDocument As Document)
If IsNothing(oSourceDocument) Or IsNothing(oTargetDocument) Then Exit Sub
Dim oAuto As IiLogicAutomation = iLogicVb.Automation
Dim oSourceRules As IEnumerable = oAuto.Rules(oSourceDocument)
Dim oSourceRule As iLogicRule = Nothing
For Each oSourceRule In oSourceRules
Dim oTargetRule As iLogicRule = Nothing
'check if oTargetRule already exists first
'if not found, this will NOT throw an error, it will just not set a value
oTargetRule = oAuto.GetRule(oTargetDocument, oSourceRule.Name)
'if not found, create it
If IsNothing(oTargetRule) Then
oTargetRule = oAuto.AddRule(oTargetDocument, oSourceRule.Name, "")
'set text (contents) here so the rule won't immediately run
oTargetRule.Text = oSourceRule.Text
Else 'the rule was found, so make sure its text (contents) is up to date
If oTargetRule.Text <> oSourceRule.Text Then
oTargetRule.Text = oSourceRule.Text
End If
End If
Next 'oSourceRule
End Sub
Sub CopyAllEventTriggers(oSourceDocument As Document, oTargetDocument As Document)
If IsNothing(oSourceDocument) Or IsNothing(oTargetDocument) Then Exit Sub
Dim oInternalName As String = "{2C540830-0723-455E-A8E2-891722EB4C3E}"
'get Event Triggers PropertySet from source document
Dim oSourceSet As PropertySet = Nothing
If Not oSourceDocument.PropertySets.PropertySetExists(oInternalName, oSourceSet) Then
Exit Sub 'the Event Triggers PropertySet was not found in source document, so exit Sub
End If
If oSourceSet.Count = 0 Then Exit Sub 'it contains zero properties, so exit Sub
'get or create Event Triggers PropertySet within target document
Dim oTargetSet As PropertySet = Nothing
If Not oTargetDocument.PropertySets.PropertySetExists(oInternalName, oTargetSet) Then
'the Event Triggers PropertySet was not found in source document, so create it
oTargetSet = oTargetDocument.PropertySets.Add("_iLogicEventsRules", oInternalName)
End If
'<<<< Could delete target Event Triggers set if found, then create a new one >>>>
For Each oSourceProp As Inventor.Property In oSourceSet
'<<< this is not checking if the property may already exist in the target set >>>
Try
oTargetSet.Add(oSourceProp.Value, oSourceProp.Name, oSourceProp.PropId)
Catch
Logger.Error("Failed to copy property named: " & oSourceProp.Name & vbCrLf & _
"With value: " & oSourceProp.Value & vbCrLf & _
"From source document: " & oSourceDocument.FullFileName & vbCrLf & _
"To target document: " & oTargetDocument.FullFileName)
End Try
Next
End Sub
I'm not sure about the part where you want to run all the rules once all the components are saved, but right now I'm thinking about making that a separate rule that would get ran after this one.
Wesley Crihfield
(Not an Autodesk Employee)
Can't find what you're looking for? Ask the community or share your knowledge.