iLogic script to replace dimension styles in an Inventor drawing

iLogic script to replace dimension styles in an Inventor drawing

Anonymous
Not applicable
3,799 Views
11 Replies
Message 1 of 12

iLogic script to replace dimension styles in an Inventor drawing

Anonymous
Not applicable

For starters, it may seem like this question has been asked many times, but I've done a lot of searching through this forum with no luck.

 

I have a bunch of drawings where I need to replace old styles with the new styles in our style library. I'll explain what I'd like the iLogic to do by explaining what I currently have to do manually.

 

1. Find the dimension, right-click, then edit dimension style.

2. Once in the styles library, I find the style I want to replace, right-click, replace style, find what I want to take its place, purge replaced style, save and exit.

 

I found a little script that will do this, but only to one (the first) dimension. Here it is:

 

Sub Main()
	'change dimension style

'drawing document
Dim oDrawDoc As DrawingDocument = ThisDoc.Document
'active sheet
Dim oSheet As Sheet = oDrawDoc.ActiveSheet

'reference to the first dimension
Dim oDim As GeneralDimension = oSheet.DrawingDimensions(1)
'the current dimension style object
Dim oStyle As DimensionStyle = oDim.Style

'reference to the style manager
Dim oStylesMgr As DrawingStylesManager = oDrawDoc.StylesManager

'get the reference to another dimension style
Dim oNewStyle As DimensionStyle _
	= oStylesMgr.DimensionStyles.Item("Dimension-180-Arial _XXX")
'change the style
oDim.Style = oNewStyle
End Sub

 I'd like to get this to replace all dimension styles with "Dimension-180-Arial _XXX". One thing to note is that when I do this manually, I don't lose my dimension type (reference parenthesis, number of decimal places shown, etc.). When I use the above script, I DO lose those things (e.g. it will update "(0.750)" to "0.750". Reference parenthesis will be gone. I know the "XXX" implies the tolerance (three digits past the decimal), but when I do it manually, it doesn't affect that. Doing it manually changes the font size and color. Running the script changes everything. I'm not really sure why there's a difference.

 

Lastly, if what I'm trying to do isn't possible, I'd like to be able to take all dimensions on the drawing and set them to font size 180 and Arial.

 

Thanks in advance!

0 Likes
Accepted solutions (1)
3,800 Views
11 Replies
Replies (11)
Message 2 of 12

WCrihfield
Mentor
Mentor

You should only need to actually "Edit" a dimension "Style" once per drawing document.  Then you should be able to set the drawing selection filter to "Select All Inventor Dimensions" (or similar), then window select all dimensions on the sheet then simply change the style they are all using to the newly edited dimension style.  If the drawing document doesn't already contain the dimension style you need, then after you create the dimension style the way you want it, you should be able to save it to the style library.  Then when you open an older drawing document, if it contains the same main drawing standard styles set, all you would have to do is use the [Manage tag > Styles and Standards panel > Update] tool to update the styles in that old document with the new styles.  Then if the dimensions that exist on that old document weren't already using that updated style, you will have to do the filtered window select process mentioned above, to select them all , then while they are all selected, go to the Annotate tab > Format panel > and choose that newly updated style, and all those selected dimensions will be using that new style.

 

To do this by code, we would likely need to capture this target (newly updated) dimension style into a variable.  Then either programmatically select/capture all the dimension type objects within all the sheets of the drawing into a collection, or loop through each sheet, and loop through each possible type of dimension object within each sheet, changing their Style to the target Style.  Does that sound like what you would want?

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

0 Likes
Message 3 of 12

WCrihfield
Mentor
Mentor
Accepted solution

Here is a fairly simple iLogic code that specifies one DimensionStyle at the beginning, then iterates through each sheet of the active drawing, then every instance of each different type of DrawingDimension, changing their styles to the source style.  I used a Try...Catch block to help avoid an error if it doesn't find a dimension style by that name within the current drawing.  Keep in mind that you may need have to copy this style from the style library to the document, before it will find that Style, and before it will let you assign the style to objects within the document.

   I also added a bit of commented out code in there to show you how to replace existing styles with a different style (similar to how you would do it within the Styles & Standards Editor dialog).

 

 

If ThisApplication.ActiveDocumentType <> DocumentTypeEnum.kDrawingDocumentObject Then
	MsgBox("This rule '" & iLogicVb.RuleName & "' only works for Drawing Documents.",vbOKOnly, "WRONG DOCUMENT TYPE")
	Exit Sub
End If
Dim oDDoc As DrawingDocument = ThisDrawing.Document
Dim oDSMgr As DrawingStylesManager = oDDoc.StylesManager
Dim oNewStyle As DimensionStyle
Try
	oNewStyle = oDSMgr.DimensionStyles.Item("Dimension-180-Arial _XXX")
Catch
	MsgBox("That source Dimsnesion Style was not found. Exiting.", vbOKOnly, " ")
	Exit Sub
End Try

'Dim oStylesToReplace As ObjectCollection = ThisApplication.TransientObjects.CreateObjectCollection
'oStylesToReplace.Add("OldStyleName")
'oDSMgr.ReplaceStyles(oStylesToReplace,oNewStyle)

For Each oSheet As Inventor.Sheet In oDDoc.Sheets
	For Each oBDimSet As BaselineDimensionSet In oSheet.DrawingDimensions.BaselineDimensionSets
		oBDimSet.Style = oNewStyle
	Next
	For Each oCDimSet As ChainDimensionSet In oSheet.DrawingDimensions.ChainDimensionSets
		oCDimSet.Style = oNewStyle
	Next
	For Each oGDim As GeneralDimension In oSheet.DrawingDimensions.GeneralDimensions
		oGDim.Style = oNewStyle
	Next
	For Each oODim As OrdinateDimension In oSheet.DrawingDimensions.OrdinateDimensions
		oODim.Style = oNewStyle
	Next
	For Each oODimSet As OrdinateDimensionSet In oSheet.DrawingDimensions.OrdinateDimensionSets
		oODimSet.Style = oNewStyle
	Next
Next

 

 

If this solved your problem, or answered your question, please click ACCEPT SOLUTION.
Or, if this helped you, please click 'LIKE' 👍.

If you have time, please... Vote For My IDEAS 💡and Explore My CONTRIBUTIONS

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

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

Message 4 of 12

Anonymous
Not applicable

Thank you so much! This gives me plenty to work with and works great. This is going to save us a ton of time!

0 Likes
Message 5 of 12

freesbee
Collaborator
Collaborator

Dear Wesley,

the code you have provided is very interesting, in particular those commented lines (15 to 17).

I am trying to realize what you describe (replacing existing styles with a different one), and for the moment I need to accomplish this in VBA. Unfortunately I am struggling with the syntax, and I wonder if you could give me a hint on this.

 

I understand the logic behind, but I am in trouble with the syntax, as I am not a real programmer. To my understanding your line 15 would become in VBA the following 2 lines:

Dim oStylesToReplace As ObjectCollection
Set oStylesToReplace = ThisApplication.TransientObjects.CreateObjectCollection()

Then I try to add one object to this collection

oStylesToReplace.Add (oDSMgr.DimensionStyles.Item(1))

and exactly here my code fails: "Object doesn't support this property or method".

To some reason the VBA editor is always adding one space between .Add and the following parenthesis, and this makes me think that I am doing something wrong, but I cannot figure out what I am doing wrong.

Maybe you could give me a hint?

Thank you in advance

Massimo Frison
CAD R&D // PDM Admin · Hekuma GmbH
0 Likes
Message 6 of 12

freesbee
Collaborator
Collaborator

...sorry for disturbing: I found my error myself from another post.

The proper way to populate the collection appears to be:

 

oStylesToReplace.Add oDSMgr.DimensionStyles.Item(1)

 

So no parenthesis around the passed object (probably that is exactly what the VBA editor was trying to tell me when adding that space after .Add ).

Again, sorry, I am not a programmer 😌

Massimo Frison
CAD R&D // PDM Admin · Hekuma GmbH
Message 7 of 12

WCrihfield
Mentor
Mentor

Hi @freesbee.  VBA can be a bit odd where syntax is concerned.  There are often two ways to use a 'method' (Sub or Function) that has 'input parameters'.  You can either start that line with the keyword 'Call', followed by that line of code to run the method which encloses the inputs within the ( & ) characters ; or you can start the line without that 'Call' keyword, then do not enclose the inputs within the ( & ) characters.  Declaring and 'Set'...ing values to variables is also a bit odd in VBA, because variables for simple data types like String, Double, Integer (and similar) do not need to use the 'Set' keyword when setting the values of those types of variables, but if the variable's Type is reference (Document, Sheet, etc) then you need to use the 'Set' keyword when setting its value.  None of that special stuff is needed in vb.net (iLogic).

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

0 Likes
Message 8 of 12

freesbee
Collaborator
Collaborator

Dear Wesley @WCrihfield ,

I could bring my code ahead so now I have a functionality that works as desired. However, I get in trouble when I try to compose "the general case". I wonder if you could give me a hint into the right direction (it appears to me that you have outstanding programming skills 😅).

I have put together one sub that replaces dimensionstyles in one drawing:

 

Private Sub ReplaceDimStyle()
    
Dim oDrawDoc As DrawingDocument
Set oDrawDoc = ThisApplication.ActiveDocument

Dim oStylesMgr As DrawingStylesManager
Set oStylesMgr = oDrawDoc.StylesManager

Dim oStylesToReplace As ObjectCollection
Set oStylesToReplace = ThisApplication.TransientObjects.CreateObjectCollection()

Dim withStyle As DimensionStyle

For Each dimStyle In oStylesMgr.DimensionStyles
    If dimStyle.name = "myDesiredDimStyle_G2" Then
        Set withStyle = dimStyle
        Exit For
    End If
Next

For Each dimStyle In oStylesMgr.DimensionStyles
    If Left(dimStyle.name, 6) = "oldStyle-" Then
        oStylesToReplace.Add dimStyle
    End If
Next

If Not withStyle Is Nothing Then
    Call oStylesMgr.ReplaceStyles(oStylesToReplace, withStyle, True)
End If
End Sub

 

This one does its job properly, replacing (and purging) all DimensionStyles beginning by "oldStyle-" with the desired "myDesiredDimStyle_G2". Perfect.

Then I've put together another sub that replaces CenterMark styles, which looks in principle identical to the first one:

 

Private Sub ReplaceCenterMarkStyle()
Dim oDrawDoc As DrawingDocument
Set oDrawDoc = ThisApplication.ActiveDocument

Dim oStylesMgr As DrawingStylesManager
Set oStylesMgr = oDrawDoc.StylesManager

Dim oStylesToReplace As ObjectCollection
Set oStylesToReplace = ThisApplication.TransientObjects.CreateObjectCollection()

Dim withStyle As CentermarkStyle

For Each cMarkStyle In oStylesMgr.CentermarkStyles
    If cMarkStyle.name = "myCenterMark" Then
        Set withStyle = cMarkStyle
        Exit For
    End If
Next

For Each cMarkStyle In oStylesMgr.CentermarkStyles
    If Left(cMarkStyle.name, 11) = "oldCenterMark-" Then
        oStylesToReplace.Add cMarkStyle
    End If
Next

If Not withStyle Is Nothing Then
    Call oStylesMgr.ReplaceStyles(oStylesToReplace, withStyle, True)
End If

End Sub

 

This one also gives the expected result, so the skeleton of my functionality is there.

Obviously, I wanted to extend this concept making a sub capable of replacing any style, that should be called from a parent sub which passes the document, the StyleType that should be replaced, and the strings of the old styles to be replaced and the new style to be used instead. Here my understanding is a little bit at the limit, but I think that my second parameter (sType2Replace) should tell my sub in which style type the search and replacement should happen. However, I am not able to figure out how to pass this enumerator properly, as the definition of withStyle should be done within the enumerator that is being passed (in the style type that I want to replace). But I don't get how to do this.

Maybe you can give me a hint how to do this properly?

 

Private Sub doTheJobOfReplacingStyles()
Dim oDrawDoc As DrawingDocument
Set oDrawDoc = ThisApplication.ActiveDocument

Call ReplaceAnyStyle(oDrawDoc, kDimensionStyleType, "oldDimStyle-", "myDesiredDimStyle_G2", True)
Call ReplaceAnyStyle(oDrawDoc, kCentermarkStyles, "oldCenterMark-", "myCenterMark", True)
'obviously the kDimensionStyleType and the kCentermarkStyle here above do not work
End Sub
----------------------
Private Sub ReplaceAnyStyle(ByRef myDrawDoc As DrawingDocument, ByVal sType2Replace As StyleTypeEnum, _
    ByVal searchStyleName As String, ByVal withStyleName As String, ByVal purgeStyles As Boolean)

Set oStylesMgr = myDrawDoc.StylesManager
Dim withStyle As DimensionStyle '<= what shall I do here? it should be sType2Replace

For Each oStyle In oStylesMgr.DimensionStyles '<= the same here
    If oStyle.name = "Standard_G2" Then
        Set withStyle = oStyle
        Exit For
    End If
Next

Dim oStylesToReplace As ObjectCollection
Set oStylesToReplace = ThisApplication.TransientObjects.CreateObjectCollection()

For Each oStyle In oStylesMgr.DimensionStyles '<= the same here
    If Left(oStyle.name, Len(searchStyleName)) = searchStyleName Then
        oStylesToReplace.Add oStyle
    End If
Next

If Not withStyle Is Nothing Then
    Call oStylesMgr.ReplaceStyles(oStylesToReplace, withStyle, purgeStyles)
End If

End Sub

 

 

Massimo Frison
CAD R&D // PDM Admin · Hekuma GmbH
Message 9 of 12

WCrihfield
Mentor
Mentor

Hi @freesbee.  I was out sick yesterday, and am still sick now, so please forgive my lack of responsiveness.  If you want to make the Sub routine universal for any StyleType, and plan on passing in the StyleTypeEnum variation, then you will most likely want to use a 'Select Case' block, or long 'If...Then' block of code which handles each possible variation of that Enum, which there are a lot of.  You can declare the DrawingStylesManager and the ObjectCollection before the Type block, then can also use the ReplaceStyles method after the Type block.

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

0 Likes
Message 10 of 12

freesbee
Collaborator
Collaborator

Dear Wesley @WCrihfield ,

Thank you soooo much for your hint! Thanks to your suggestion, I was able to achieve what I was needing. I have been waiting for this functionality since years, as I have been the one who has requested this API functionality 4 years ago (back in 2019). Luckily, I have asked it in a period when Adsk management had given indications to the development team that every option available in the GUI should be also available in the API, and with this excuse Rocky has been able to deliver it by 2022 without having to go through the tedious idea station.

I will post here the two subs, so that maybe any other forum reader could benefit of it.

 

My first sub does the entire logic of which style shall be replaced with which, error handling (not present here) and so on:

 

Private Sub doTheJobOfReplacingStyles()
'do not forget to build some resilience in the code
Dim oDrawDoc As DrawingDocument
Set oDrawDoc = ThisApplication.ActiveDocument

Call ReplaceAnyStyle(oDrawDoc, kDimensionStyleType, "oldDimStyle-", "myDesiredDimStyle_G2", True)
Call ReplaceAnyStyle(oDrawDoc, kCentermarkStyleType, "oldCenterMark-", "myCenterMark", True)
'any additional styleType option should come here
End Sub

 

 

The second sub is called by the first one, and replaces selectively the styles as specified by the parent:

 

Private Sub ReplaceAnyStyle(ByRef myDrawDoc As DrawingDocument, ByVal sType2Replace As StyleTypeEnum, _
                            ByVal searchStyleName As String, ByVal withStyleName As String, _
                            ByVal purgeStyles As Boolean)

Set oStylesMgr = myDrawDoc.StylesManager

Dim withStyle As Object
Dim myStyleType2Clean As Object

Select Case sType2Replace
Case kDimensionStyleType
    Dim oDimStyle As DimensionStyle
    Set withStyle = oDimStyle
    Set myStyleType2Clean = oStylesMgr.DimensionStyles
Case kCentermarkStyleType
    Dim oCMarkStyle As CentermarkStyle
    Set withStyle = oCMarkStyle
    Set myStyleType2Clean = oStylesMgr.CentermarkStyles
Case Else
    Debug.Print "for demonstration purposes this code only handles two style types"
End Select

For Each oStyle In myStyleType2Clean 'find the style that should replace the other ones
    If oStyle.name = withStyleName Then
        Set withStyle = oStyle
        Exit For
    End If
Next


If Not withStyle Is Nothing Then 'if a candidate was found, now collect all styles to evict in one collection
    Dim oStylesToReplace As ObjectCollection
    Set oStylesToReplace = ThisApplication.TransientObjects.CreateObjectCollection()

    For Each oStyle In myStyleType2Clean
        If Left(oStyle.name, Len(searchStyleName)) = searchStyleName Then
            oStylesToReplace.Add oStyle
        End If
    Next

    If oStylesToReplace.Count > 0 Then
        Call oStylesMgr.ReplaceStyles(oStylesToReplace, withStyle, purgeStyles)
    End If
End If

End Sub

 

 

Thank you so much, sincerely: without your hint I would have never managed.

I wish you a very merry and peaceful Christmas time with you dears. May the new year be really "new" in your ideas, in your commitment and in your success!

Massimo

Massimo Frison
CAD R&D // PDM Admin · Hekuma GmbH
Message 11 of 12

freesbee
Collaborator
Collaborator

Dear All,

I hope that anyone has understood this better than me, because I clearly didn't understand it entirely. After Wesley's hint I was able to extend my syntax shown in post #10 of this thread to process and replace all styles I want to replace. However, I am still struggling with 6 of them:

  1. Datum Target
  2. Hatch
  3. ID
  4. ViewAnnotation
  5. WeldBead
  6. WeldSymbol

Such styles appear to have a style type enumerator, as also the object browser shows:

StyleTypesEnumeratorsStyleTypesEnumerators

but apparently they do not have a style, which is what I really do NOT understand.

This means that while the code

 

Private Sub listDrawingManagerStyles()
Dim oDrawDoc As DrawingDocument
Set oDrawDoc = ThisApplication.ActiveDocument

Set oStylesMgr = oDrawDoc.StylesManager

For Each Item In oStylesMgr.DimensionStyles
    Debug.Print Item.name
Next

End Sub

 

shows me a list of the dimension styles available in my drawing, the code

 

Private Sub listDrawingManagerStyles()
Dim oDrawDoc As DrawingDocument
Set oDrawDoc = ThisApplication.ActiveDocument

Set oStylesMgr = oDrawDoc.StylesManager

For Each Item In oStylesMgr.DatumTargetStyles
    Debug.Print Item.name
Next

End Sub

 

runs into an error, as the style manager does NOT have a .DatumTargetStyles method. The same error happens for the other 5 style types I have listed above.

Does anyone know the reason for this conceptual difference between these 6 style types and the other ones which work fine, or am I missing anything obvious as it often happens to me?

Massimo Frison
CAD R&D // PDM Admin · Hekuma GmbH
Message 12 of 12

freesbee
Collaborator
Collaborator

...so the struggling was huge, but I could identify the problem and correct the syntax accordingly.

The 6 style types I have listed above are classified as "Styles", even if they have a specific StyleTypeEnumerator.

Therefore I have adapted my code to the following, posted here in case anyone else is dealing with this task.

Here my sub handling the overall logic:

 

Private Sub doTheJobOfReplacingStyles()
'do not forget to build some resilience in the code
Dim oDrawDoc As DrawingDocument
Set oDrawDoc = ThisApplication.ActiveDocument

Call ReplaceAnyStyle(oDrawDoc, kDimensionStyleType, "oldDimStyle-", "myDesiredDimStyle_G2", True)
Call ReplaceAnyStyle(oDrawDoc, kCentermarkStyleType, "oldCenterMark-", "myCenterMark", True)
'call generic styles after all specific ones have been already replaced
'otherwise identical names could lead to problems
Call ReplaceAnyStyle(oDrawDoc, kHatchStyleType, "unwantedHatch", "Hatch", True)
End Sub

 

and here is my sub replacing the specific styles:

 

Private Sub ReplaceAnyStyle(ByRef myDrawDoc As DrawingDocument, ByVal sType2Replace As StyleTypeEnum, _
                            ByVal searchStyleName As String, ByVal withStyleName As String, _
                            ByVal purgeStyles As Boolean)

Dim oStylesMgr as DrawingStylesManager
Set oStylesMgr = myDrawDoc.StylesManager

Dim withStyle As Object
Dim myStyleType2Clean As Object

Select Case sType2Replace
Case kDimensionStyleType
    Dim oDimStyle As DimensionStyle
    Set withStyle = oDimStyle
    Set myStyleType2Clean = oStylesMgr.DimensionStyles
Case kCentermarkStyleType
    Dim oCMarkStyle As CentermarkStyle
    Set withStyle = oCMarkStyle
    Set myStyleType2Clean = oStylesMgr.CentermarkStyles
'be aware that even if the StyleTypeEnumerator is specific for the following styletype
'inventor will detect all of the styles listed in my post #11 as if they belong to one type
Case kHatchStyleType
    Dim oHatchStyle As Style
    Set withStyle = oHatchStyle
    Set myStyleType2Clean = oStylesMgr.Styles
Case Else
    Debug.Print "for demonstration purposes this code only handles two specific style types and one generig"
End Select

For Each oStyle In myStyleType2Clean 'find the style that should replace the other ones
    If oStyle.name = withStyleName Then
        Set withStyle = oStyle
        Exit For
    End If
Next


If Not withStyle Is Nothing Then 'if a candidate was found, now collect all styles to evict in one collection
    Dim oStylesToReplace As ObjectCollection
    Set oStylesToReplace = ThisApplication.TransientObjects.CreateObjectCollection()

    For Each oStyle In myStyleType2Clean
        If Left(oStyle.name, Len(searchStyleName)) = searchStyleName Then
            oStylesToReplace.Add oStyle
        End If
    Next

    If oStylesToReplace.Count > 0 Then
        Call oStylesMgr.ReplaceStyles(oStylesToReplace, withStyle, purgeStyles)
    End If
End If

End Sub

 

Be aware to replace those generic styles after all the others have been replaced, otherwise matching style names could lead into problems, as inventor would try to replace one specific style with one generic style (this is something that I still could not address, but now I'm tired and I will stop here for today).

Wow, this was a roller coaster in Inventor API for me!!!

Massimo Frison
CAD R&D // PDM Admin · Hekuma GmbH