iLogic to purge styles

iLogic to purge styles

Anonymous
Not applicable
3,385 Views
15 Replies
Message 1 of 16

iLogic to purge styles

Anonymous
Not applicable

Hello fellow Inventor users, 😀

 

I was looking for a way to purge the styles of all the files I work with.

I couldn't find a finished code, so I started tinkering.

 

I came up with the following:

Dim oThisDoc As Document
oThisDoc = ThisDoc.Document

DocType = oThisDoc.DocumentType

Select Case DocType.ToString

'---File is a Drawing---

	Case "kDrawingDocumentObject"

		Dim oDoc As DrawingDocument
		oDoc = ThisDrawing.Document
		Dim oStyles As Styles
		oStyles = oDoc.StylesManager.Styles

		' Info: StyleLocation
		' 51201	=	both (library and local)
		' 51202	=	local
		' 51203	=	library

		DelStyles = True
		DelLoops = 0

		While DelStyles = True And DelLoops < 100 
			DelCounter = 0
			For Each oStyle In oStyles
				' Only delete unused styles saved in 'local' or 'both'
				If oStyle.StyleLocation.ToString <> "51203" And Not oStyle.InUse Then
					oStyle.Delete
					DelCounter += 1
				End If
			Next
			If DelCounter = 0 Then DelStyles = False
			DelLoops += 1
		End While

' ---File is a part or assembly---

	Case "kPartDocumentObject", "kAssemblyDocumentObject"

		Dim oStylesMan As StylesManager
		oStylesMan = ThisApplication.StylesManager
		Dim oDoc As Document
		oDoc = ThisApplication.ActiveDocument
		Dim oAsset As Asset

		' Info: AssetType
		'	99073	 = 	appearances
		'	99074	 = 	materials

		' Materials first
		For Each oAsset In oDoc.Assets
			If oAsset.AssetType = 99074 And Not oAsset.IsUsed Then
				oAsset.Delete
			End If
		Next

		' Then appearances
		For Each oAsset In oDoc.Assets
			If oAsset.AssetType = 99073 And Not oAsset.IsUsed Then
				oAsset.Delete
			End If
		Next

End Select

The code works flawlessly for drawings, but in parts or assemblies I always get an error, saying the active file is not a drawing.

 

Can someone figure out my mistake?

 

Many thanks in advance 😀

0 Likes
Accepted solutions (2)
3,386 Views
15 Replies
Replies (15)
Message 2 of 16

HermJan.Otterman
Advisor
Advisor

why not use the Task scheduler to purge files?

If this answers your question then please select "Accept as Solution"
Kudo's are also appreciated Smiley Wink

Succes on your project, and have a nice day

Herm Jan


0 Likes
Message 3 of 16

Anonymous
Not applicable

Because we work with many different styles simultaneously.

 

The Task scheduler would have to go over our data over and over again.

 

By using an iLogic attached to an Event Trigger we grab the problem by its root.

0 Likes
Message 4 of 16

JelteDeJong
Mentor
Mentor
Accepted solution

I did not test this iLogic rule very good but you can give it a try.

Dim doc As Document = ThisApplication.ActiveDocument
If (doc.DocumentType = DocumentTypeEnum.kDrawingDocumentObject) Then
    Dim dDoc As DrawingDocument = doc
    Dim styles As Styles = dDoc.StylesManager.Styles
    For Each styl As Style In styles
        If (styl.InUse = False And styl.StyleLocation <> StyleLocationEnum.kLibraryStyleLocation) Then
            styl.Delete()
        End If
    Next
ElseIf (doc.DocumentType = DocumentTypeEnum.kPartDocumentObject Or doc.DocumentType = DocumentTypeEnum.kAssemblyDocumentObject) Then
    For Each asset As Asset In doc.Assets
        If (asset.IsUsed = False) Then
            If (asset.AssetType = AssetTypeEnum.kAssetTypeMaterial Or
                    asset.AssetType = AssetTypeEnum.kAssetTypeAppearance) Then
                asset.Delete()
            End If
        End If
    Next
End If

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.

EESignature


Blog: hjalte.nl - github.com

Message 5 of 16

Anonymous
Not applicable

It seems to work fine in drawings, but in parts and in assemblies it doesn't do anything.

I tried to find the problem, but I couldn't.

0 Likes
Message 6 of 16

WCrihfield
Mentor
Mentor

This is a very similar code, but is a little more sepperated out.  You can give it a try, though to see if it works for you.

Dim oDoc As Document = ThisApplication.ActiveDocument
If oDoc.DocumentType = DocumentTypeEnum.kDrawingDocumentObject Then
	For Each oStyle As Style In ThisDrawing.Document.StylesManager.Styles
		If oStyle.StyleLocation <> StyleLocationEnum.kLibraryStyleLocation Then
			If oStyle.InUse = False Then
				oStyle.Delete
			End If
		End If
	Next
ElseIf oDocType = DocumentTypeEnum.kPartDocumentObject Then
	Dim oPdoc As PartDocument = ThisApplication.ActiveDocument
	For Each oAsset As Asset In oPdoc.Assets
		If oAsset.IsUsed = False Then
			If oAsset.AssetType = AssetTypeEnum.kAssetTypeMaterial Then
				oAsset.Delete
			ElseIf oAsset.AssetType = AssetTypeEnum.kAssetTypeAppearance Then
				oAsset.Delete
			End If
		End If
	Next
ElseIf oDoc.DocumentType = DocumentTypeEnum.kAssemblyDocumentObject Then
	For Each oAsset As Asset In ThisAssembly.Document.Assets
		If oAsset.IsUsed = False Then
			If oAsset.AssetType = AssetTypeEnum.kAssetTypeMaterial Then
				oAsset.Delete
			ElseIf oAsset.AssetType = AssetTypeEnum.kAssetTypeAppearance Then
				oAsset.Delete
			End If
		End If
	Next
End If

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

0 Likes
Message 7 of 16

WCrihfield
Mentor
Mentor

Also, if any of your models and/or solid bodies are using a different appearance than the default one for the selected material, you may need to delete the appearances before you delete the materials (Part Documents), because often the appearance is a sub-asset of the Material asset.  So you won't be able to delete the material, even if you aren't using it, if its associated appearance is being used.  See the following code.

Dim oDoc As Document = ThisApplication.ActiveDocument
If oDoc.DocumentType = DocumentTypeEnum.kDrawingDocumentObject Then
	For Each oStyle As Style In ThisDrawing.Document.StylesManager.Styles
		If oStyle.StyleLocation <> StyleLocationEnum.kLibraryStyleLocation Then
			If oStyle.InUse = False Then
				oStyle.Delete
			End If
		End If
	Next
ElseIf oDocType = DocumentTypeEnum.kPartDocumentObject Then
	Dim oPdoc As PartDocument = ThisApplication.ActiveDocument
	For Each oAppAsset As Asset In oPdoc.AppearanceAssets
		If oAppAsset.IsReadOnly = False AndAlso
			oAppAsset.IsUsed = False Then
			oAppAsset.Delete
		End If
	Next
	For Each oMatAsset As MaterialAsset In oPdoc.MaterialAssets
		If oMatAsset.AppearanceAsset.IsUsed = False Then
			If oMatAsset.AppearanceAsset.IsReadOnly = False AndAlso
			oMatAsset.AppearanceAsset.IsUsed = False Then
				oMatAsset.AppearanceAsset.Delete
			End If
			If oMatAsset.IsReadOnly = False AndAlso
				oMatAsset.IsUsed = False Then
				oMatAsset.Delete
			End If
		End If
	Next
ElseIf oDoc.DocumentType = DocumentTypeEnum.kAssemblyDocumentObject Then
	For Each oAppAsset As Asset In ThisAssembly.Document.AppearanceAssets
		If oAppAsset.IsReadOnly = False AndAlso
			oAppAsset.IsUsed = False Then
			oAppAsset.Delete
		End If
	Next
	For Each oMatAsset As MaterialAsset In ThisAssembly.Document.MaterialAssets
		If oMatAsset.AppearanceAsset.IsUsed = False Then
			If oMatAsset.AppearanceAsset.IsReadOnly = False AndAlso
			oMatAsset.AppearanceAsset.IsUsed = False Then
				oMatAsset.AppearanceAsset.Delete
			End If
			If oMatAsset.IsReadOnly = False AndAlso
				oMatAsset.IsUsed = False Then
				oMatAsset.Delete
			End If
		End If
	Next
End If

If the previous code doesn't work, try this one.

Let me know if this works for you.

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

0 Likes
Message 8 of 16

WCrihfield
Mentor
Mentor

I was a little too quick to repost that last time. If forgot to delete the redundant If IsUsed and End If lines.

Here's the corrected version.

Dim oDoc As Document = ThisApplication.ActiveDocument
If oDoc.DocumentType = DocumentTypeEnum.kDrawingDocumentObject Then
	For Each oStyle As Style In ThisDrawing.Document.StylesManager.Styles
		If oStyle.StyleLocation <> StyleLocationEnum.kLibraryStyleLocation Then
			If oStyle.InUse = False Then
				oStyle.Delete
			End If
		End If
	Next
ElseIf oDocType = DocumentTypeEnum.kPartDocumentObject Then
	Dim oPdoc As PartDocument = ThisApplication.ActiveDocument
	For Each oAppAsset As Asset In oPdoc.AppearanceAssets
		If oAppAsset.IsReadOnly = False AndAlso
		oAppAsset.IsUsed = False Then
			oAppAsset.Delete
		End If
	Next
	For Each oMatAsset As MaterialAsset In oPdoc.MaterialAssets
		If oMatAsset.AppearanceAsset.IsReadOnly = False AndAlso
		oMatAsset.AppearanceAsset.IsUsed = False Then
			oMatAsset.AppearanceAsset.Delete
		End If
		If oMatAsset.IsReadOnly = False AndAlso
			oMatAsset.IsUsed = False Then
			oMatAsset.Delete
		End If
	Next
ElseIf oDoc.DocumentType = DocumentTypeEnum.kAssemblyDocumentObject Then
	For Each oAppAsset As Asset In ThisAssembly.Document.AppearanceAssets
		If oAppAsset.IsReadOnly = False AndAlso
		oAppAsset.IsUsed = False Then
			oAppAsset.Delete
		End If
	Next
	For Each oMatAsset As MaterialAsset In ThisAssembly.Document.MaterialAssets
		If oMatAsset.AppearanceAsset.IsReadOnly = False AndAlso
		oMatAsset.AppearanceAsset.IsUsed = False Then
			oMatAsset.AppearanceAsset.Delete
		End If
		If oMatAsset.IsReadOnly = False AndAlso
		oMatAsset.IsUsed = False Then
			oMatAsset.Delete
		End If
	Next
End If

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

Message 9 of 16

Anonymous
Not applicable
Accepted solution

I did some more testing and I finally could find the problem.

 

For some reason materials are only purged properly, after executing the code twice.

 

Here the final code:

 

Dim doc As Document = ThisApplication.ActiveDocument
If (doc.DocumentType = DocumentTypeEnum.kDrawingDocumentObject) Then
    Dim dDoc As DrawingDocument = doc
    Dim styles As Styles = dDoc.StylesManager.Styles
    For Each styl As Style In styles
        If (styl.InUse = False And styl.StyleLocation <> StyleLocationEnum.kLibraryStyleLocation) Then
            styl.Delete()
        End If
    Next
ElseIf (doc.DocumentType = DocumentTypeEnum.kPartDocumentObject Or doc.DocumentType = DocumentTypeEnum.kAssemblyDocumentObject) Then
    For Each asset As Asset In doc.Assets
        If (asset.IsUsed = False) Then
            If (asset.AssetType = AssetTypeEnum.kAssetTypeMaterial Or
                    asset.AssetType = AssetTypeEnum.kAssetTypeAppearance) Then
                asset.Delete()
            End If
        End If
    Next
End If

'---Execute twice---

If (doc.DocumentType = DocumentTypeEnum.kDrawingDocumentObject) Then
    Dim dDoc As DrawingDocument = doc
    Dim styles As Styles = dDoc.StylesManager.Styles
    For Each styl As Style In styles
        If (styl.InUse = False And styl.StyleLocation <> StyleLocationEnum.kLibraryStyleLocation) Then
            styl.Delete()
        End If
    Next
ElseIf (doc.DocumentType = DocumentTypeEnum.kPartDocumentObject Or doc.DocumentType = DocumentTypeEnum.kAssemblyDocumentObject) Then
    For Each asset As Asset In doc.Assets
        If (asset.IsUsed = False) Then
            If (asset.AssetType = AssetTypeEnum.kAssetTypeMaterial Or
                    asset.AssetType = AssetTypeEnum.kAssetTypeAppearance) Then
                asset.Delete()
            End If
        End If
    Next
End If
Message 10 of 16

WCrihfield
Mentor
Mentor

You could try the plan I explained earlier and try looping through and deleting all the Appearances first.

Then loop through to delete all the Materials secondly.  Or vise-versa.  Maybe doing this will eliminate having to run the whole rule twice.  It's worth a try.

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

0 Likes
Message 11 of 16

DeerSpotter
Collaborator
Collaborator

you noticed something that I thought I was going crazy in noticing.

hope the Developers can fix this.

Image and video hosting by TinyPic
..........................................................................................................................
Did you find this reply helpful ? If so please use the Accept as Solution or Kudos button below.
..........................................................................................................................


See My LinkedIn Profile
0 Likes
Message 12 of 16

WCrihfield
Mentor
Mentor

 

How about a quick & simple little VBA Macro button to click, that will do all of this using Inventor's built-in tool, just for purging unused styles.

Insert this simple VBA code into a Module under your VBA Editor's ApplicationProject (gets stored in the default application project .ivb file, so it will always be available).

 

Sub PurgeStyles()
    Dim oCDs As ControlDefinitions
    Set oCDs = ThisApplication.CommandManager.ControlDefinitions
    Dim oPurgeStyles As ControlDefinition
    Set oPurgeStyles = oCDs.Item("PurgeStylesCmd")
    Call oPurgeStyles.Execute2(False)
    Call AppActivate(ThisApplication.Caption)
    Call SendKeys("{TAB}{TAB}{TAB}{TAB}{TAB}{ }{TAB}{TAB}{TAB}{ENTER}{ENTER}", True)
    Call ThisApplication.UserInterfaceManager.DoEvents
End Sub

 

Granted, you sometimes have to click the button more than once to fully get rid of all purge-able stuff, but it works really fast this way.

What this does is activate the built-in Purge tool (located on the Manage tab / Styles and Standards panel), then uses the Tab keyboard key 5 times to navigate to the "Yes to All" button, then uses the Space key to click that button, then uses the Tab key 3 more times to get to the "OK" button, then uses the Enter key once (which clicks the OK button), then a second time (which says OK to the possible warning message that often pops-up warning you if the styles you're deleting have been modified locally, and you may loose those modifications).  But if you aren't using those styles, you don't need them, and that's why we're Purging them.

 

I hope this helps.
If this solves your problem, or answers your questions, please click 'Accept As Solution".
Or, if this helps you reach your goal, please click 'LIKES" 👍.

 

Also, if you're interested, here are a few of the 'Ideas' I'd like to get implemented.
If you agree with any of them, please vote for them.

  • Add more capabilities to the 'Customize' dialog box (exe. Add Tab & Add Panel) Click Here
  • Constrain & Dimension Images In Assembly Sketches & Drawing Sketches (TitleBlocks & SketchedSymbols) Click Here
  • Save Section View Status In DesignViewRepresentation (So It Can Be Used In The Drawing) Click Here
  • Add SolidBodies Folder In iLogic Rule Editor Model Tab Click Here
  • Convert All Views To Raster Before Autosave Stores To 'OldVersions' Folder Click Here
  • SetDesignViewRepresentation - Fix limitations for DrawingView of a Part Click Here
  • Create DocumentSubTypeEnum Click Here
  • Add kRevisionTag or kDrawingRevisionTag to ObjectTypeEnum Click Here

Inventor 2020 Help | Inventor Forum | Inventor Customization Forum | Inventor Ideas Forum

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

0 Likes
Message 13 of 16

jbetz42
Contributor
Contributor

I went with your suggestion to initially delete the unused AppearanceAssets and afterwards the MaterialAssets. But had to run the code twice too.

 

But you were right with your suggestion to try vice-versa. The solution is to first delete unused MaterialAssets and afterwards the unused AppearanceAssets.

 

Here is my code:

 

 

 

Private Sub CleanUnsuedStyles3D()
    Dim oAssets As Assets = ThisDoc.Document.Assets

    ' Clean Material Assets first
    For Each oAsset As Asset In oAssets
        Try
            If (oAsset.AssetType = AssetTypeEnum.kAssetTypeMaterial And oAsset.IsReadOnly = False And oAsset.IsUsed = False) Then
                Logger.Info(iLogicVb.RuleName & " | " & ThisDoc.FileName(True) & " | Removed unused Material Asset: " & oAsset.Name)
                oAsset.Delete()
            End If
        Catch
            Logger.Warn(iLogicVb.RuleName & " | " & ThisDoc.FileName(True) & " | Error removing unused Material Asset.")
        End Try
    Next

    ' Clean Appearance Assets second
    For Each oAsset As Asset In oAssets
        Try
            If (oAsset.AssetType = AssetTypeEnum.kAssetTypeAppearance And oAsset.IsReadOnly = False And oAsset.IsUsed = False) Then
                Logger.Info(iLogicVb.RuleName & " | " & ThisDoc.FileName(True) & " | Removed unused Appearance Asset: " & oAsset.Name)
                oAsset.Delete()
            End If
        Catch
            Logger.Warn(iLogicVb.RuleName & " | " & ThisDoc.FileName(True) & " | Error removing unused Appearance Asset.")
        End Try
    Next
End Sub

 

0 Likes
Message 14 of 16

WCrihfield
Mentor
Mentor

Hi @jbetz42.  Glad to see that you were able to derive a solution that works for you from our suggestions.  What I did later on, within my own set of solutions, is created a separate Function routine for both purging unused resources, but also updating the ones being used.  I set this function up to return a Boolean value...True if anything was changed by the function, and False if the function either had no effect, or encountered any sort of error.  Then within that Function, a Boolean variable is created and used to track if any changes are made, then that variable's value is 'returned' at the end.  Then within the 'calling' routine (the routine that calls the function to run) I set it up within a 'Do Loop', so that as long as it returns True, it will continue to run it again, until it returns False, indicating that it is having no further effect.  This takes care of the scenario of sometimes needing multiple runs to clear any sub-styles or styles that were dependent on the ones that were just deleted, which can sometimes go multiple layers deep in rare complex scenarios.

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

Message 15 of 16

ppolcynBNVFN
Enthusiast
Enthusiast

That sounds very promising. Could you make that code available?

0 Likes
Message 16 of 16

WCrihfield
Mentor
Mentor

Hi @ppolcynBNVFN.  I have attached a couple text files for you to try out as external iLogic rules.  I am using two different external iLogic rules, because I usually know what type of document I am working with, and model type files (parts & assemblies) have different types of things that need to be purged &/or updated than drawings, so I just call the one that is appropriate for the document type I am working with.  Then I have other rules for actually creating or setting new standards or styles, and updating pre-existing objects to the new standards.

Wesley Crihfield

EESignature

(Not an Autodesk Employee)