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: 

Run rule

7 REPLIES 7
SOLVED
Reply
Message 1 of 8
Sketchart_Cad1
261 Views, 7 Replies

Run rule

Hi so i need to run specific rule for every part or assembly drawing from main assembly. I have this main assembly and i want to make rule where it checks if part or assembly has drawing if yes than run drawing rule. is it even possible?

7 REPLIES 7
Message 2 of 8
WCrihfield
in reply to: Sketchart_Cad1

Hi @Sketchart_Cad1.  Possibly, but in order to be able to run an iLogic rule on a drawing, from an assembly, we would have to know how to find those drawings.  There is no 'link', reference, or property in a model file to indicate that there is a drawing for it.  However, the drawing will know about the part, because the drawing has references in it for the models shown within its views.  Similar situations with parts.  They do not know if they are being used in any assemblies, but the assemblies know.  So, if you want someone to help you with some code for interacting with drawings, from an assembly, you must describe how to find the drawing, based on some aspect of the model.  Is the drawing file always located in the same folder as the model file?  Is the drawing file always named exactly the same as the model file?  Or are drawings in a parallel folder, or in a sub-folder, or do the drawing files have some prefix or suffix in their file names, or something else?

 

Edit:  Also, where is this other iLogic rule that you are wanting to run on the drawing, and what is its name (spelling and capitalization are important)?  Is it an 'internal' iLogic rule that is saved within the drawing itself, or is it an external iLogic rule?  What does that rule do to/with the drawing?  If that rule uses the 'ThisApplication.ActiveDocument' phrase to refer to the drawing, then that will most likely fail, because when ran remotely like this, it will be pointing to the main assembly, instead of the drawing, because the main assembly will remain the 'active' document, since we started the rule while it was active.  If that is the case, try changing 'ThisApplication.ActiveDocument' phrase to 'ThisDoc.Document' code phrase instead.  That may at least help this type of scenario work better, but no guarantees about the rest of the code, since I know nothing about it yet.

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

Message 3 of 8
WCrihfield
in reply to: Sketchart_Cad1

Hi @Sketchart_Cad1.  I still do not have the answers I need from you, so I am just going to be making some assumptions here.  I created some iLogic code anyways, because I already had a lot of the code needed for a task like this on hand, and just made some adjustments in a couple places.  The first assumption is that your drawing files are all located in the same exact folder as the model file they are documenting, and that the drawing file names match the file names of the model, with the exception of the file extension, of course.  The second assumption is that the iLogic rule you want to run on those drawings is already located within those drawing files themselves, as an internal iLogic rule, and not just as a single external iLogic rule.  However, I still do not know the name of this rule, so I just put some general text in this code example as the name of the rule, so you will have to at least edit that rule name first, before this rule example has any chance of running correctly.  That rule name is being specified on Line 16 of the code below.

 

I incorporated a 'ProgressBar' into this code example, because I do not know how large your assembly may be, or how many referenced documents it may have, or how many drawing files it may be dealing with.  This ProgressBar will show you the progress being made as it goes, and allows you a way to cancel (stop) the progress, if it is taking way too long, or freezes your computer, or anything like that.  Since I still have no idea what your other rule will be trying to do to these drawings, I have no idea how long that code will take to run on each drawings while this overall process is going on.  I left several lines of comments in this code example, to help you read through it and know what is supposed to be happening.

Sub Main
	'<<< try to get a reference to an assembly.  If that fails, let user know, then exit this rule >>>
	Dim oADoc As AssemblyDocument = TryCast(ThisDoc.Document, Inventor.AssemblyDocument)
	If oADoc Is Nothing Then
		MsgBox("The iLogic rule named '" & iLogicVb.RuleName & "' exited, because no AssemblyDocument was obtained!", _
		vbCritical, "No Assembly Available!")
		Exit Sub 'exit this rule
	End If
	'<<< get access to a collection of all of the referenced documents, at all levels of this assembly >>>
	Dim oAllRefDocs As Inventor.DocumentsEnumerator = oADoc.AllReferencedDocuments
	If oAllRefDocs.Count = 0 Then
		MsgBox("This Assembly Has No Referenced Documents Yet.  Exiting rule.", vbCritical, "No Referenced Documents")
		Exit Sub'exit this rule
	End If
	'<<< CHANGE THIS AS NEEDED >>>
	Dim sRuleName As String = "Name Of iLogic Rule Here"
	
	'initialize the ProgressBar, to give you some feedback while this process runs, and the ability to cancel it
	iSteps = oAllRefDocs.Count
	oProgressBar = ThisApplication.CreateProgressBar(False, iSteps, "Processing Drawings", True)
	oProgressBar.Message = "Initializing process to find drawings and run a rule on them."

	'<<< iterate through each referenced document >>>
	For Each oRefDoc As Inventor.Document In oAllRefDocs
		'<<< run custom function to check / update Progress, and cancel, if needed >>>
		If MonitorProgress() = True Then Exit For
		'<<< formulate full path & file name of the drawing file for this model >>>
		'<<< this will be the same path & file name as the model, but with ".idw" file extension >>>
		Dim sDrawingFile As String = System.IO.Path.ChangeExtension(oRefDoc.FullFileName, ".idw")
		'<<< check if that drawing file exists.  If so, then let user know then skip to next referenced part >>>
		If Not System.IO.File.Exists(sDrawingFile) Then
			Logger.Info("No drawing file was found for the following model file:" & vbCrLf & oRefDoc.FullFileName)
			Continue For 'skip to the next referenced document
		End If
		'<<< open the drawing so we can interact with it >>>
		Dim oDDoc As DrawingDocument = ThisApplication.Documents.Open(sDrawingFile, False)
		'<<< find a specific internal iLogic rule within this drawing document >>>
		Dim oRule As iLogicRule = iLogicVb.Automation.GetRule(oDDoc, sRuleName)
		If oRule Is Nothing Then
			Logger.Debug("Cound not find the internal iLogic rule within the following drawing:" _
			& vbCrLf & sDrawingFile)
			Continue For 'skip to the next referenced document
		End If
		Dim iResult As Integer = iLogicVb.Automation.RunRule(oDDoc, sRuleName)
		'Dim iResult As Integer = iLogicVb.Automation.RunRuleDirect(oRule)
		If iResult <> 0 Then 'value of zero means rule ran (not necessarily that it worked)
			Logger.Debug("There was a problem while running the rule on the following drawing:" _
			& vbCrLf & sDrawingFile)
		End If
		'<<< save this new drawing document to a file >>>
		If oDDoc.RequiresUpdate Then oDDoc.Update2(True)
		If oDDoc.Dirty Then oDDoc.Save2(True) 'True = save dependent documents also, if needed
		'<<< close this saved drawing document >>>
		oDDoc.Close(True) 'True = skip save (we already saved)
	Next oRefDoc 'go to the next referenced document, if any
	oProgressBar.Close
	MsgBox("This iLogic rule has finished its task.", vbInformation, "iLogic")
End Sub

Dim WithEvents oProgressBar As Inventor.ProgressBar
Dim bProgressBarCanceled As Boolean
Dim iSteps As Integer
Dim iStep As Integer

Sub oProgressBar_OnCancel() Handles oProgressBar.OnCancel
	bProgressBarCanceled = True
End Sub

Function MonitorProgress() As Boolean
	If bProgressBarCanceled = True Then
		oProgressBar.Message = "Progress Canceled - Exiting iterations."
		oProgressBar.Close
		Return True
	Else
		If iStep >= iSteps Then
			oProgressBar.Close
			Return True
		Else
			iStep = iStep + 1
			oProgressBar.UpdateProgress()
			oProgressBar.Message = "Processing " & iStep.ToString & " of " & iSteps & " referenced documents."
			Return False
		End If
	End If
End Function

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

EESignature

(Not an Autodesk Employee)

Message 4 of 8
Sketchart_Cad1
in reply to: WCrihfield

Hi thx for answer!

 

Belive it or not but i solved it like this:

 

' Get the current document, which should be an assembly
Dim oAsmDoc As AssemblyDocument
oAsmDoc = ThisApplication.ActiveDocument

' Get the component definition of the assembly
Dim oAsmDef As AssemblyComponentDefinition
oAsmDef = oAsmDoc.ComponentDefinition

' Iterate through all the occurrences in the assembly
Dim oOcc As ComponentOccurrence
For Each oOcc In oAsmDef.Occurrences
' Check if the occurrence is a part
If oOcc.DefinitionDocumentType = DocumentTypeEnum.kPartDocumentObject Then
' Open the part document
Dim oPartDoc As PartDocument
oPartDoc = oOcc.Definition.Document

' Make the part document active
ThisApplication.Documents.Open(oPartDoc.FullFileName, True)

' Get the full file name of the part document
Dim partFileName As String
partFileName = oPartDoc.FullFileName

' Replace the part file extension with .dwg to find the drawing
Dim drawingFileName As String
drawingFileName = System.IO.Path.ChangeExtension(partFileName, "dwg")

' Check if the drawing file exists
If System.IO.File.Exists(drawingFileName) Then
' Open the drawing document
Dim oDrawingDoc As DrawingDocument
oDrawingDoc = ThisApplication.Documents.Open(drawingFileName, True)

' Regenerate all rules in the drawing document
Dim oRules As iLogicRule
For Each oRules In oDrawingDoc.iLogic.Rules
ThisApplication.CommandManager.ControlDefinitions("ilogic.runrule").Execute()
Next
End If
End If
Next

All drawings have same name as drawing.
Also Chat gpt helped. 😄

Message 5 of 8
WCrihfield
in reply to: Sketchart_Cad1

Hi @Sketchart_Cad1.  I am glad to hear that you seem to have found something that is working OK for you.  If you had been able to answer some of my questions, I might have been able to help you more.  For instance, I did not know you were using the ".dwg" file extension for your drawings.  I assumed you were using the ".idw" file extension.  Because of that tiny detail that I was not aware of, my code would not have been able to find your drawing files.  The more good information you put in, usually the better or more accurate of a solution you can get out.

 

Plus, your code example only seems to be looking for the drawings or the parts, not for any sub assemblies.  Your initial post said "every part or assembly", so my code example included both.

 

I also see something near the end of your code that I have never seen before in all the years I have been doing this, and I am wandering what is going on there, if anything.  This block of code below is what I am talking about:

' Regenerate all rules in the drawing document
Dim oRules As iLogicRule
For Each oRules In oDrawingDoc.iLogic.Rules
	ThisApplication.CommandManager.ControlDefinitions("ilogic.runrule").Execute()
Next

First of all, I have never seen a Property named "iLogic" associated with a DrawingDocument API object.  You can see all of its methods and properties by following the link in this sentence, to see its online help page for the Inventor API.  So, I am guessing that part of the code is not working.  Next, I have never seen a CommandDefinition named "ilogic.runrule" in the list of available commands in Inventor.  There are some other similar similar ones in there, but not that one...at least not on my computer.  I am using Inventor Pro 2024.3 on a Windows 11 Dell tower PC.  I have seen several folks posting code here that they got either partially, or entirely from AI systems like ChatGPT, and they almost always contain odd code in them that seems meaningless, or not working properly.  I think their AI systems still have a lot to learn about writing code to automate Inventor for custom tasks.

You can review what I am doing in Lines 38 through 49 of my code example above.  Yes, that area is rather wordy and may contain some stuff that is not always necessary, and it can be done in a couple different ways, but iLogic rule objects themselves can always be found within other documents with some code that starts with "iLogicVb.Automation" phrase of code (which returns a IiLogicAutomation Interface).  After that point, there are a few different properties / methods that can be used, depending on the situation, and your coding style.

 

What version of Inventor are you using?  And can you confirm that the internal iLogic rules within each of those drawings is being ran?  What do those rules do?  Do they give any sort of feedback, like MsgBox(), MessageBox.Show(), Logger lines, or maybe output prints or exported files?

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

Message 6 of 8
NachitoMax
in reply to: Sketchart_Cad1

Hey

 

your code needed a bit of cleanup. ChatGPT never quite gets it right. I have changed your loop from Occurrence to Reference because, lets say in your assembly you have 300 parts, 299 of them are PartA and 1 is PartB. your code will loop 300 times and open / close the occurrence document each time. My code will find 2 parts and only open 2 documents to do the exact the same thing. I also changed the application API ref from

ThisApplication

on each API call to

Dim oApp As InventorApplication = ThisApplication

The difference is 1 API call instead of 4. it makes a difference especially on larger code blocks.

 

Here is your cleaned up version

'create a single reference to the application
Dim oApp As InventorApplication = ThisApplication

' Get the current document, which should be an assembly
Dim oAsmDoc As AssemblyDocument = oApp.ActiveDocument

' Get the component definition of the assembly
Dim oAsmDef As AssemblyComponentDefinition = oAsmDoc.ComponentDefinition

' Get all of the referenced documents.
    Dim oRefDocs As DocumentsEnumerator = oAsmDoc.AllReferencedDocuments

    ' Iterate through the list of documents.
    Dim oRefDoc As Document
    For Each oRefDoc In oRefDocs

        'bail continue with Next if doc isnt a part
        If Not oRefDoc.DocumentType = DocumentTypeEnum.kPartDocumentObject Then
            Continue For   
        End If

        ' Get the full file name of the part document
        Dim partFileName As String = oRefDoc.FullFileName

       ' Make the part document active
        oApp.Documents.Open(oRefDoc.FullFileName, True)

        ' Replace the part file extension with .dwg to find the drawing
        Dim drawingFileName As String = System.IO.Path.ChangeExtension(partFileName, "dwg")

        ' Check if the drawing file exists
        If Not System.IO.File.Exists(drawingFileName) Then
            Continue For
        End If

        Dim oDrawingDoc As DrawingDocument = oApp.Documents.Open(drawingFileName, True)

        ' Regenerate all rules in the drawing document
        For Each oRules As iLogicRule In oDrawingDoc.iLogic.Rules
            oApp.CommandManager.ControlDefinitions("ilogic.runrule").Execute()
        Next
    Next

I changed your check from a True to a False so that the code could bail to the Next. Im not a fan of multi nested code, extrapolation can really slow things down. What i mean by that is

For i As Integer = 1 to 1000
   For j As Integer = 1 to 100
   Next
Next
'100,000 iterations nested



 

I also removed your conversion to a PartDocument as it wasnt needed. You only really need to convert if you are doing something that is feature specific. To convert, you can do a CType cast.

Dim OriginalDoc As Document = oRefDoc
Dim oPartDoc As PartDocument = CType(OriginalDoc, PartDocument)

 

Nacho

Automation & Design Engineer

Inventor Programmer (C#, VB.Net / iLogic)


EESignature


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.


Message 7 of 8
WCrihfield
in reply to: Sketchart_Cad1

Hi @Sketchart_Cad1.  Since there has not been any response to anything I posted in Message 5 earlier, and you seem to have accepted yet another solution which still contains that odd block of code in it that I mentioned did not appear to be valid, I feel like I may need to post additional information here to reinforce some of what I said earlier, and show the 'proper' way to do what you seem to be wanting to do there.

 

Unless you are using Inventor 2025, which I do not have yet, and unless they have just added that DrawingDocument.iLogic.Rules property to the DrawingDocument object in the 2025 version, then that line of code is meaningless and does not work at all.  For many, many years now, if you want to be able to iterate through all of the internal iLogic rules within an Inventor document, you had to do so very similar to the following way:

 

Dim oDoc As Inventor.Document = ThisDoc.Document
Dim iLogicAuto As IiLogicAutomation = iLogicVb.Automation
Dim oRules As IEnumerable = iLogicAuto.Rules(oDoc)
If oRules IsNot Nothing Then
	For Each oRule As iLogicRule In oRules
		If oRule.IsActive Then
			iLogicAuto.RunRuleDirect(oRule)
		End If
	Next oRule
End If

 

In this example above, we always have to use the 'iLogicVb.Automation.Rules() property to get an IEnumerable type collection containing the iLogicRule  objects.  Then, we had to check if that oRules variable (representing the IEnumerable) 'Is Nothing', because if no rule were found, it would be Nothing, instead of just having a count of zero.  Then, we could read/edit the primary settings of each rule &/or or read/edit the text of the rule &/or or run the rule.

 

And if we just want one specific iLogic rule from within an Inventor document, we would have to do it this way:

 

Dim oDoc As Inventor.Document = ThisDoc.Document
Dim iLogicAuto As IiLogicAutomation = iLogicVb.Automation
Dim oRule As iLogicRule = iLogicAuto.GetRule(oDoc, "The Rule's Name Here")
If oRule IsNot Nothing Then
	iLogicAuto.RunRuleDirect(oRule)
End If

 

In this example above, we are using the iLogicVb.Automation.GetRule() method.  That method asks us to specify which Document object to attempt to retrieve the iLogic rule from, and to specify the name of the iLogic rule for it to find.  If it does not find an internal iLogic rule with the specified name, within the specified document, it will not throw an error, but instead will return 'Nothing'.  Because of this, we always need to check of oRule 'Is Nothing', before trying to do something with that variable that may (or may not) represent an iLogic rule object.

 

Now, with the two primary ways of accessing internal iLogic rule objects within documents out of the way, next I must point out the proper way to 'regenerate all rules' in a document.  This is because of the comment in your code just before that block of code states that this is what you intended to happen with the following block of code.  As mentioned in Message 5, the command (ControlDefinition) named "ilogic.runrule" does not exist on my computer, so I suspect that line of code is either simply not doing anything, or is just not doing the right thing.  And if so, I am surprised that it is not throwing an error every time it is encountered (if that line of code even gets encountered at all).  When I try to run this line of code:

 

ThisApplication.CommandManager.ControlDefinitions("ilogic.runrule").Execute()

 

...I get the following error message, which essentially means that it can not find any ControlDefinition with that name among all available ControlDefinitions.

WCrihfield_0-1719922669352.png

 

And just as added information, below is a list of all similar iLogic related commands (ControlDefinitions), which you will notice does not contain that command.

iLogic.About
iLogic.AddForm
iLogic.AddRule
iLogic.AssignName
iLogic.ClearCodeClipboard
iLogic.Configuration
iLogic.DeleteAllRules
iLogic.DeleteName
iLogic.DrawingGenerateCode
iLogic.EditName
iLogic.EditRule
iLogic.EventTriggers
iLogic.FreeILogicMemory
iLogic.HideLabel
iLogic.HideLabels
iLogic.iCopy
ilogic.logwindow
iLogic.PlaceComponent
iLogic.RegenAllRules
iLogic.RuleBrowser
iLogic.ShowLabel
iLogic.ShowLabels
ilogic.treeeditor
iLogic.Trigger
iLogic.XmlExport
iLogic.XmlImport

 

Also, as you can see in this list, if you were truly attempting to 'regenerate all rules', then the proper command name that should be used is "iLogic.RegenAllRules", not "ilogic.runrule".  So, that one line of code could be changes like this:

 

ThisApplication.CommandManager.ControlDefinitions("iLogic.RegenAllRules").Execute()

 

This command would only need to be used once per document, not once for each iLogic rule that exists within a document.  So, it should not be used within a loop of each iLogic rule in a document, because that loop of rules would no longer be needed.  This code will not only run every rule in the document, in the order they appear in the document, but will also fix any 'broken' parameter links, if any are currently broken.

 

The only thing that comes to mind about how the previous two code examples that were accepted as solutions could have possibly worked, is maybe if the rules that needed to run in the drawings were set-up to run automatically by the Event Triggers settings, under the 'After Open Document' event.  And if that was the case, then that whole block of code which seems like it is trying to run or regenerate rules, could simply be deleted (since it isn't doing anything anyways).  But if something was potentially 'broken' in those rules, then you could replace that block of code with that one command I mentioned above, to actually regenerate them.

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

Message 8 of 8
NachitoMax
in reply to: WCrihfield

@WCrihfield 

' Regenerate all rules in the drawing document
        For Each oRules As iLogicRule In oDrawingDoc.iLogic.Rules
            oApp.CommandManager.ControlDefinitions("ilogic.runrule").Execute()
        Next

 

To be fair i didnt even check that part in my response, i assumed the OP had the code working seeing as he declared a solution. Im not in the habit of spoon feeding, just guidance 😁

Nacho

Automation & Design Engineer

Inventor Programmer (C#, VB.Net / iLogic)


EESignature


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.


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

Post to forums  

Technology Administrators


Autodesk Design & Make Report