How to apply External iLogic rule to all opened documents

How to apply External iLogic rule to all opened documents

Anonymous
Not applicable
4,408 Views
16 Replies
Message 1 of 17

How to apply External iLogic rule to all opened documents

Anonymous
Not applicable

I am looking to speed up the process of finishing a large batch of drawings. Many of our drawings require dxfs to be created. I have a code below that works great for each drawing individually, but still requires you to open each drawing and run it. Is it possible, even if the drawings are not in the same folder, to run this external rule on all open drawings? 

 

Also, here is a link that almost gets what I want, but it creates the same dxf over and over again for X amount of drawings I have opened.

https://forums.autodesk.com/t5/inventor-customization/execute-ilogic-for-all-open-documents/td-p/771...

 

 

'This iLogic rule will grab an excluded from count sheet and recognize it as a DXF. It will automatically save it as a .dxf file
'and place it in the legacy folder, also renaming the sheet to Part Number + DXF. Rev will be inputted by the user.
'A dialog Box will appear To let the user know To update To Vault.
'*******************************************************************************************************************************************
Sub Main()
	'this makes sure you're in a drawing
	Try
		Dim ThisApp = ThisApplication
		Dim TransObj As TransientObjects = ThisApp.TransientObjects
		oDoc = ThisDoc.Document
		If oDoc.DocumentType <> 12292 Then '12292 = kDrawingDocument object
			MessageBox.Show("This Rule must be run from within a Drawing Document.", "Incorrect Document Type")
			Exit Sub
		End If
		Catch
		MessageBox.Show("Error Getting Document Information" & vbCr & "Is the current Document Saved?", "Document Error")
	End Try
	
oFileName = ThisDoc.FileName(False) 'without extension

       oDXFAddIn = ThisApplication.ApplicationAddIns.ItemById("{C24E3AC4-122E-11D5-8E91-0010B541CD80}")

oDocument = ThisApplication.ActiveDocument oContext = ThisApplication.TransientObjects.CreateTranslationContext
oContext.Type = IOMechanismEnum.kFileBrowseIOMechanism oOptions = ThisApplication.TransientObjects.CreateNameValueMap
oDataMedium = ThisApplication.TransientObjects.CreateDataMedium 'Define the drawing
Dim oDrawing As DrawingDocument oDrawing = ThisDoc.Document Dim oSheet As Sheet Dim lPos As Long Dim rPos As Long Dim sLen As Long Dim sSheetName As String Dim sSheetNumber As Integer '] 'Set the default response oRevNum = "REV-XX" 'gets the drawing revision number If iProperties.Value("Project", "Revision Number") = "" Then oRevBlock = 0 Else oRevBlock = iProperties.Value("Project", "Revision Number") End If '************************************************************ 'for future use, if Rev blocks are properly utilized 'oRevNum = iProperties.Value("Project","Revision Number") '************************************************************ 'step through each drawing sheet For Each oSheet In oDrawing.Sheets 'Only grab sheets that are exluded from count and rename the sheet If oSheet.ExcludeFromCount = True Then 'Response for the rev as inputted by the user If oRevNum = "REV-XX" oRevNum = InputBox("Please enter ''REV-XX'' for your dxfs" & vbCrLf & vbCrLf & "Dialog title shows drawing revision number" _ & ", please check that number against the revision block", oSheet.Name & " DWG REV = " & oRevBlock, "REV-0" & oRevBlock) End If 'This block will check for errors '[ 'Exits rule if no input is given If oRevNum = "" Then Return ElseIf oRevNum = " REV-XX" 'Lets the user know that REV-XX is not an acceptable answer MessageBox.Show("REV-XX is not a valid revision number", "REV Number not valid, please try again") Return End If oSheet.activate Dim oDrawingView As DrawingView oDrawingView = oSheet.DrawingViews(1) If oDrawingView.ReferencedDocumentDescriptor.ReferencedDocumentType = kAssemblyDocumentObject '"{E60F81E1-49B3-11D0-93C3-7E0706000000}" messagebox.Show("Do not use a weldment as a dxf view!! Ending rule...") 'This just catches anyone using weldments to create dxfs which causes more problems than it solves Exit Sub Else oModelName = oDrawingView.ReferencedDocumentDescriptor.ReferencedDocument.DisplayName oDesc = iProperties.Value(oModelName, "Project", "Part Number") & " " & oRevNum & " DXF" oSheet.Name = oDesc End If '] 'Checks if user has renamed DXFs properly 'If Left(oSheet.Name,Len(oSheet.Name) - Len(oSheet.Name) + 5) = ThisDoc.FileName(False) ActiveSheet = ThisDrawing.Sheet(oSheet.Name) 'find the sheetname length sLen = Len(oSheet.Name) 'creates the sheet name for saving
sSheetName = Left(oSheet.Name, sLen - 4) 'get DXF target folder path oFolder = "D:\Working Folder\Legacy\DXF (CONTROLLED)" 'Set the DXF target file name oDataMedium.FileName = oFolder & "\" & sSheetName & ".dxf" 'This is ensure latest up to date DXF and prompt the user of the existing DXF If System.IO.File.Exists(oFolder & "\" & sSheetName & ".dxf") Then System.IO.File.Delete( oFolder & "\" & sSheetName & ".dxf") MessageBox.Show("Earlier DXF will be overwritten! ", "Inventor") End If 'Publish document oDXFAddIn.SaveCopyAs(oDocument, oContext, oOptions, oDataMedium) ' Else ' Messagebox.Show("The DXF Sheet is named incorrectly. Please name sheets per iLogic instructions") ' End If End If Next End Sub

 

 

0 Likes
Accepted solutions (2)
4,409 Views
16 Replies
Replies (16)
Message 2 of 17

mcgyvr
Consultant
Consultant

What about just setting that rule to run on one of the events in the "Drawings" tab of the events trigger dialog box?

Then each time you "before save", "close", "after save" or whatever a drawing a DXF will be created or whatever your rule does..

Eventrigger.PNG



-------------------------------------------------------------------------------------------
Inventor 2023 - Dell Precision 5570

Did you find this reply helpful ? If so please use the Accept Solution button below.
Maybe buy me a beer through Venmo @mcgyvr1269
Message 3 of 17

Anonymous
Not applicable

@mcgyvr  That would prove an excellent solution, however, I wish to avoid that for two reasons. 

 

1) Load times for drawings can get excessive.

2) The Legacy folder is regularly cleaned out and tightly controlled with latest revisions. 

 

Hence why I want to run this iLogic in controlled batches. Your solution may be the route I go if no other solutions are possible.

0 Likes
Message 4 of 17

MjDeck
Autodesk
Autodesk

@Anonymous , in your drawing export rule, replace this line:

oDocument = ThisApplication.ActiveDocument

with this:

oDocument = ThisDoc.Document

ThisDoc.Document will give you the document that the rule is running in. That might not be the active document.

If you make that change, then the code from the other post should work.
(If it doesn't, please post a copy of the code you're using.)


Mike Deck
Software Developer
Autodesk, Inc.

Message 5 of 17

Anonymous
Not applicable

@MjDeck Thank you for your response. Your solution makes a lot of sense to me. I made the changes and unfortunately I am running into the same problem. Drawing A will get its .dxfs exported repeatedly (depends on how many drawings I have opened). I will repost the code I am currently using with your changes.

 

Dim addIn As ApplicationAddIn
Dim addIns As ApplicationAddIns
addIns = ThisApplication.ApplicationAddIns
    For Each addIn In addIns
        If InStr(addIn.DisplayName, "iLogic") > 0 Then
                        addIn.Activate
            Dim iLogicAuto As Object
            iLogicAuto = addIn.Automation
            Exit For
        End If
    Next
 
  Dim oDoc As Document
For Each oDoc In ThisApplication.Documents.VisibleDocuments

  If oDoc Is Nothing Then
    MsgBox("Missing Inventor Document")
    Exit Sub
  End If

Try
		Dim ThisApp = ThisApplication
		Dim TransObj As TransientObjects = ThisApp.TransientObjects
		oDoc = Thisdoc.Document
		If oDoc.DocumentType <> 12292 Then '12292 = kDrawingDocument object
			MessageBox.Show("This Rule must be run from within a Drawing Document.", "Incorrect Document Type")
			Exit Sub
		End If
		Catch
		MessageBox.Show("Error Getting Document Information" & vbCr & "Is the current Document Saved?", "Document Error")
	End Try
	
oFileName = ThisDoc.FileName(False) 'without extension

       oDXFAddIn = ThisApplication.ApplicationAddIns.ItemById("{C24E3AC4-122E-11D5-8E91-0010B541CD80}")

       oDocument = ThisDoc.Document

       oContext = ThisApplication.TransientObjects.CreateTranslationContext

       oContext.Type = IOMechanismEnum.kFileBrowseIOMechanism

       oOptions = ThisApplication.TransientObjects.CreateNameValueMap

       oDataMedium = ThisApplication.TransientObjects.CreateDataMedium

       'Define the drawing
       Dim oDrawing As DrawingDocument

      oDrawing = ThisDoc.Document

       Dim oSheet As Sheet

       Dim lPos As Long

       Dim rPos As Long

       Dim sLen As Long

       Dim sSheetName As String

       Dim sSheetNumber As Integer
']

'Set the default response       
oRevNum = "REV-XX"

'gets the drawing revision number
If iProperties.Value("Project", "Revision Number") = "" Then
	oRevBlock = 0
	Else
	oRevBlock = iProperties.Value("Project", "Revision Number")
End If

'************************************************************
'for future use, if Rev blocks are properly utilized
	'oRevNum = iProperties.Value("Project","Revision Number")
'************************************************************

 'step through each drawing sheet
        For Each oSheet In oDrawing.Sheets

'Only grab sheets that are exluded from count and rename the sheet
If oSheet.ExcludeFromCount = True Then

'Response for the rev as inputted by the user
If oRevNum = "REV-XX"
oRevNum = InputBox("Please enter ''REV-XX'' for your dxfs" & vbCrLf & vbCrLf & "Dialog title shows drawing revision number" _
& ", please check that number against the revision block", oSheet.Name & " DWG REV = " & oRevBlock, "REV-0" & oRevBlock)
End If

'This block will check for errors
'[
'Exits rule if no input is given
If oRevNum = "" Then
	Return
ElseIf oRevNum = " REV-XX" 'Lets the user know that REV-XX is not an acceptable answer
	MessageBox.Show("REV-XX is not a valid revision number", "REV Number not valid, please try again")
	Return
End If

	oSheet.activate
	Dim oDrawingView As DrawingView 
    	oDrawingView = oSheet.DrawingViews(1)
		If oDrawingView.ReferencedDocumentDescriptor.ReferencedDocumentType = kAssemblyDocumentObject '"{E60F81E1-49B3-11D0-93C3-7E0706000000}"
			messagebox.Show("Do not use a weldment as a dxf view!! Ending rule...") 'This just catches anyone using weldments to create dxfs which causes more problems than it solves
			Exit Sub
			Else
	oModelName = oDrawingView.ReferencedDocumentDescriptor.ReferencedDocument.DisplayName
	oDesc = iProperties.Value(oModelName, "Project", "Part Number") & " " & oRevNum & " DXF"
	oSheet.Name = oDesc 
	End If
 
']

'Checks if user has renamed DXFs properly
'If Left(oSheet.Name,Len(oSheet.Name) - Len(oSheet.Name) + 5) = ThisDoc.FileName(False)

ActiveSheet = ThisDrawing.Sheet(oSheet.Name)

              'find the sheetname length	  
			   sLen = Len(oSheet.Name)

               'creates the sheet name for saving
               sSheetName = Left(oSheet.Name, sLen - 4)
 

    		   'get DXF target folder path
                oFolder = "D:\Working Folder\Legacy\DXF (CONTROLLED)"

 
               'Set the DXF target file name
                oDataMedium.FileName = oFolder & "\" & sSheetName & ".dxf"
				
'This is ensure latest up to date DXF and prompt the user of the existing DXF
If System.IO.File.Exists(oFolder & "\" & sSheetName & ".dxf") Then
    System.IO.File.Delete( oFolder & "\" & sSheetName & ".dxf")
    MessageBox.Show("Earlier DXF will be overwritten! ", "Inventor")
End If
               'Publish document
               oDXFAddIn.SaveCopyAs(oDocument, oContext, oOptions, oDataMedium)

	   End If
	   

       Next

'if the drawing has sheets excluded from count, then display a message that the DXFs have been saved locally and prompt to update.
If oSheet.ExcludeFromCount = True Then
MessageBox.Show("DXFs SAVED TO LEGACY FOLDER" & vbCrLf & "PLEASE UPDATE TO VAULT", "Please update Vault", MessageBoxButtons.OK, MessageBoxIcon.Information)
End If

oDoc.Activate
Next

It should be noted that I tried closing the drawing before oDoc.Activate to force the next drawing to be active, but I get an error saying it can't find the document (unknown document).

0 Likes
Message 6 of 17

MjDeck
Autodesk
Autodesk

You combined the rule that loops over the visible documents and runs a rule in each one with the rule you want to run. But in this case it will work, because you're using all API and no iLogic functions. Or rather, the iLogic functions you're using have easy API equivalents.

 To fix your rule, get rid of ThisDoc.Document. You want to change documents, and ThisDoc.Document always remains the same.
Delete this line:

oDoc = Thisdoc.Document

Change this line:

oFileName = ThisDoc.FileName(False) 'without extension

to

oFileName = System.IO.Path.GetFileNameWithoutExtension(oDoc.FullFileName)

Change this line:

oDocument = ThisDoc.Document

to

oDocument = oDoc

Change this line:

oDrawing = ThisDoc.Document

to

oDrawing = oDoc

Delete this line:

ActiveSheet = ThisDrawing.Sheet(oSheet.Name)

That should be enough to make it work. You can also get rid of the addin code at the top:

Dim addIn As ApplicationAddIn
Dim addIns As ApplicationAddIns
addIns = ThisApplication.ApplicationAddIns
    For Each addIn In addIns
        If InStr(addIn.DisplayName, "iLogic") > 0 Then
                        addIn.Activate
            Dim iLogicAuto As Object
            iLogicAuto = addIn.Automation
            Exit For
        End If
    Next

Mike Deck
Software Developer
Autodesk, Inc.

Message 7 of 17

Anonymous
Not applicable

@MjDeck This is what I was looking for! As of right now the code always start with the first drawing (far left window) and works its way through consecutive drawings. This was not what the code was doing beforehand, which it took whatever drawing was active and exported that one repeatedly. However, I have a new issue which breaks the code. After completing the first drawing and moving to the second, it gives me an error:

 

"iProperties:The document named 'xxxxx.ipt' was not found."

 

EDIT: to clarify, 'xxxxx.ipt' is the part on the second drawing that is being made into a dxf. the error occurs in document 'firstdrawing.idw'. I assume its searching for the second drawing's parts inside the first drawing?

 

Is this because the file naming refers to the active sheets and their components? Thank you for all your help so far.

0 Likes
Message 8 of 17

MjDeck
Autodesk
Autodesk
Accepted solution

My mistake. I didn't notice that you're using the iProperties function. That's an iLogic function and it only works in the document from which the rule is running.

To do this without more complicated code changes, you need to create a separate external rule. It doesn't need much code, just:

For Each doc As Document In ThisApplication.Documents.VisibleDocuments
	If doc.DocumentType = DocumentTypeEnum.kDrawingDocumentObject Then
		iLogicVb.Automation.RunExternalRule(doc, "Export Drawing")
	End If
Next

Replace "Export Drawing" with the name of your main rule.
Then in your main rule, replace the line:

For Each oDoc In ThisApplication.Documents.VisibleDocuments

with:

oDoc = ThisDoc.Document

and get rid of the Next at the bottom of the rule.


Mike Deck
Software Developer
Autodesk, Inc.

Message 9 of 17

Anonymous
Not applicable

This works flawlessly now! I have learned a lot, thank you so much for your help. This saves me quite a headache a plenty of time too.

0 Likes
Message 10 of 17

rsilvers
Explorer
Explorer

I'm still struggling getting this to work properly. I've modified the iLogic alittle to focus on just going thru each of the open drawings and save them as .dwg. My problem is the saveas file name is always the same for every drawing that opens.

 

Dim oDoc As Document

For Each oDoc In ThisApplication.Documents.VisibleDocuments

If oDoc Is Nothing Then
MsgBox("Missing Inventor Document")
Exit Sub
End If

Try
Dim ThisApp = ThisApplication
Dim TransObj As TransientObjects = ThisApp.TransientObjects
If oDoc.DocumentType <> 12292 Then '12292 = kDrawingDocument object
MessageBox.Show("This Rule must be run from within a Drawing Document.", "Incorrect Document Type")
Exit Sub
End If
Catch
MessageBox.Show("Error Getting Document Information" & vbCr & "Is the current Document Saved?", "Document Error")
End Try

oFileName = System.IO.Path.GetFileNameWithoutExtension(oDoc.FullFileName) 'without extension

'MessageBox.Show(oFileName, "Title")

oDoc.SaveAs(ThisDoc.ChangeExtension(".dwg") , True)
MessageBox.Show(oFileName & ".dwg Saved!! " & vbCrLf & vbCrLf & ThisDoc.Path , "Save As")
oDoc.Activate
Next

0 Likes
Message 11 of 17

MjDeck
Autodesk
Autodesk
Accepted solution

@rsilvers , ThisDoc always refers back to the document from which the rule is run. So the line that contains ThisDoc.ChangeExtension is causing the problem. You can replace it with this:

oDoc.SaveAs(System.IO.Path.ChangeExtension(oDoc.FullFileName, ".dwg") , True)

Another unrelated change to make the code more readable:

If oDoc.DocumentType <> DocumentTypeEnum.kDrawingDocumentObject Then

Mike Deck
Software Developer
Autodesk, Inc.

Message 12 of 17

rsilvers
Explorer
Explorer

That worked perfect. I realized the ThisDoc.Document wasn't right but didn't know what to change it to. Thank you!

0 Likes
Message 13 of 17

forbillian
Advocate
Advocate

Thanks MJDeck - I got some useful info from your posts - thanks for that.

 

I am having a similar issue when exporting all open drawings to DXF when I loop through them and run the DXF Export Rule.  Only the drawing open at the time of the rule execution is saved over and over.

 

Due to time constraints I have had to add a close active document line at the end of the DXF Export rule

so after opening a dozen drawing at a time I can run the rule and loop through them that way.

 

 

 

I am not sure if I need to Edit the Syntax  for the DXF  SaveCopyas line.

 

 

Call DXFAddIn.SaveCopyAs(oDocument, context, oOptions, oDataMedium) 

or is using display name (example below) a better way of the file the way to ensure the Export honours the actual open drawing?

..........................................................................................

Dim oAsmDoc As AssemblyDocument

oAsmDoc = ThisApplication.ActiveDocument

oAsmName = Left(oAsmDoc.DisplayName, Len(oAsmDoc.DisplayName) -4)

......................................................................................

 

Any assistance would be invaluable

 

 

 

 

0 Likes
Message 14 of 17

MjDeck
Autodesk
Autodesk

@forbillian , please post the rule you're using. If you're using one rule to run another, please post both rules.


Mike Deck
Software Developer
Autodesk, Inc.

Message 15 of 17

forbillian
Advocate
Advocate

Hi MJdeck,

 

The rule is basically using the Code in this thread but instead of saving each open drawing I am trying to apply another rule for this example 'delete views & BOM on each open drawing'.  It loops through the open docs & shows the display name but it doesn't apply the DeleteViewsBOM rule.  See below.

 

Sub Main()
		
Dim oDoc As Document

For Each oDoc In ThisApplication.Documents.VisibleDocuments

If oDoc Is Nothing Then
MsgBox("Missing Inventor Document")
Exit Sub
End If

Try
Dim ThisApp = ThisApplication
Dim TransObj As TransientObjects = ThisApp.TransientObjects
If oDoc.DocumentType <> 12292 Then '12292 = kDrawingDocument object
MessageBox.Show("This Rule must be run from within a Drawing Document.", "Incorrect Document Type")
Exit Sub
End If
Catch
MessageBox.Show("Error Getting Document Information" & vbCr & "Is the current Document Saved?", "Document Error")
End Try

oFileName = System.IO.Path.GetFileNameWithoutExtension(oDoc.FullFileName) 'without extension

'MessageBox.Show(oFileName, "Title")

'oDoc.SaveAs(ThisDoc.ChangeExtension(".dwg") , True)

Call DeleteViewsBOM()

MessageBox.Show(oFileName)

oDoc.Activate


'iLogicVb.RunExternalRule("DeleteDrawingsViewsOrBOM")


Next

End Sub

Private Sub DeleteViewsBOM()

Dim oDrawingDoc As DrawingDocument
oDrawingDoc = ThisApplication.ActiveDocument
    
Dim oSheet As Sheet
oSheet = oDrawingDoc.ActiveSheet

'Detect if the template has a parts list
Try 
Dim oPartslistCheck As PartsList
oPartslistCheck = oSheet.PartsLists(1)
partslistpresent=True
Catch
partslistpresent=False
End Try

	If partslistpresent=True
	    
	    'Delete the current parts list
	    Dim oPartsList As PartsList
	    oPartsList = oDrawingDoc.ActiveSheet.PartsLists.Item(1)
	    oPartsList.Delete
	    
	End If
	
	Dim doc As DrawingDocument = ThisDoc.Document
		
	For Each view As DrawingView In doc.ActiveSheet.DrawingViews
		view.Delete
	Next
	
	'ThisDoc.Save

	
	
'	ThisApplication.CommandManager.ControlDefinitions.Item("VaultCheckinTop").Execute2(False)

'	'CHECKIN AUTO WITHOUT COMMENT
'	System.Windows.Forms.SendKeys.SendWait(Chr(9) & vbCrLf)
	
	
'	ThisApplication.ActiveDocument.Close(True)
	

End Sub
0 Likes
Message 16 of 17

MjDeck
Autodesk
Autodesk

Since you want the rule to operate on all documents, you can't use ThisDoc.Document. You might be able to use ThisApplication.ActiveDocument if you activate each document in turn, but that's usually not required. You already have the document you want in the oDoc variable from the For loop. To use it, make these changes:
Replace:

Call DeleteViewsBOM()

with:

Call DeleteViewsBOM(oDoc)

Replace:

Private Sub DeleteViewsBOM()

Dim oDrawingDoc As DrawingDocument
oDrawingDoc = ThisApplication.ActiveDocument

with:

Private Sub DeleteViewsBOM(oDoc As Document)

Dim oDrawingDoc As DrawingDocument = oDoc

Replace:

	Dim doc As DrawingDocument = ThisDoc.Document
		
	For Each view As DrawingView In doc.ActiveSheet.DrawingViews

with:

For Each view As DrawingView In oDrawingDoc.ActiveSheet.DrawingViews

 


Mike Deck
Software Developer
Autodesk, Inc.

Message 17 of 17

forbillian
Advocate
Advocate

Thankyou so much Mike.

That has saved me hours & helped me on the coding journey.

 

I am getting an error exception every  4 or 5 drawings but I am confident I can work that out.

 

I will post the updated code once it runs completely for anyone else that has experienced this issue.

 

Thankyou again.

0 Likes