Update or Create Custom iProperty in Sheet Metal Parts from an Assembly

Update or Create Custom iProperty in Sheet Metal Parts from an Assembly

JBerns
Advisor Advisor
863 Views
5 Replies
Message 1 of 6

Update or Create Custom iProperty in Sheet Metal Parts from an Assembly

JBerns
Advisor
Advisor

Community,

 

My goal is to update three custom iProperties in all the sheet metal parts of an assembly.
If a custom iProperty is missing, it needs to be added and then its value set.

 

I have evaluated using iLogic at the part level, but prefer to use VBA from the assembly level.
I am using VBA because of its better debugging (learning) interface. Therefore, no Try-Catch clauses, only On Error statements.

 

The three custom iProperties are:
- Customer: the customer name for the job
- Material: a classification code based on the sheet metal material
- Grade : a classification code also based on the sheet metal material

 

I am using Brian Ekins' ( @ekinsb ) code to get the references in the assembly.
https://modthemachine.typepad.com/my_weblog/2009/03/accessing-assembly-components.html

 

This gets all the file references in the assembly, including those in subassemblies.

 

I am using more code from Brian to update the custom iProperty.
https://modthemachine.typepad.com/my_weblog/2010/02/custom-iproperties.html

 

The UpdateCustomiProperty code works well when tested in a part document, but fails for me when called from the assembly level. No errors occur, but the iProperty is not added/updated.

 

Can anyone offer suggestions as to how to modify the UpdateCustomiProperty  code to get the sheet metal part custom iProperties updated/added from the assembly level?

 

Here is what I have so far:

Option Explicit

Public Sub ProcessReferences()
    'Initialize strings
    Dim strCustomerName As String
    strCustomerName = "NONE SELECTED"  'Simplified here, but normally set through a UserForm

    'Get the active assembly
    Dim oAsmDoc As AssemblyDocument
    Set oAsmDoc = ThisApplication.ActiveDocument
 
'yes, I will test here to ensure active doc is an assembly
'Get all of the referenced documents Dim oRefDocs As DocumentsEnumerator Set oRefDocs = oAsmDoc.AllReferencedDocuments 'Iterate through the list of documents Dim oRefDoc As Document For Each oRefDoc In oRefDocs 'Test if reference is a sheet metal part If oRefDoc.SubType = "{9C464203-9BAE-11D3-8BAD-0060B0CE6BB4}" Then Call UpdateCustomiProperty(oRefDoc, "CUSTOMER", strCustomerName) End If 'Update document oRefDoc.Update Next End Sub Public Sub UpdateCustomiProperty(ByRef Doc As Document, ByRef PropertyName As String, ByRef PropertyValue As Variant) 'String 'Get the custom property set Dim customPropSet As PropertySet Set customPropSet = Doc.PropertySets.Item("Inventor User Defined Properties") 'Get the existing property, if it exists. Dim prop As Property On Error Resume Next Set prop = customPropSet.Item(PropertyName) 'Check to see if the above call failed. If it failed 'then the property doesn't exist. If Err.Number <> 0 Then 'Failed to get the existing property so create a new one. Call customPropSet.Add(PropertyValue, PropertyName) Else 'Change the value of the existing property. prop.Value = PropertyValue End If 'Update document Doc.Update End Sub

To test, just add some sheet metal parts to an assembly, add the code to VBA editor in the assembly, and then run macro named ProcessReferences.


Thank you for your time and attention. I look forward to the replies.

 

 

Kind regards,

Jerry

-----------------------------------------------------------------------------------------
CAD Administrator
Using AutoCAD & Inventor 2025
Autodesk Certified Instructor
Autodesk Inventor 2020 Certified Professional
Autodesk AutoCAD 2017 Certified Professional
0 Likes
Accepted solutions (1)
864 Views
5 Replies
Replies (5)
Message 2 of 6

JBerns
Advisor
Advisor

Community,

 

More debugging this morning led to a solution.

 

The UpdateCustomiProperty subroutine receives three parameters: a document, a string, and a variant.

 

In the ProcessReferences subroutine I had declared (DIM) the custom iProperty value as a string.

Dim strCustomerName As String

Although the string's value passed successfully to the UpdateCustomiProperty subroutine, the string value was not accepted during the PropertySet Add method.

Call customPropSet.Add(PropertyValue, PropertyName)   ' FAILS HERE

I changed the custom iProperty value declaration to a variant,

Dim strCustomerName As Variant

and then passed the variant to the UpdateCustomiProperty subroutine, it worked as expected.

 

I was certain you could pass any variable type to a variant, but this seems to cause a problem for the PropertySet Add method.

 

I would welcome any feedback on this issue.

 


Kind regards,
Jerry

-----------------------------------------------------------------------------------------
CAD Administrator
Using AutoCAD & Inventor 2025
Autodesk Certified Instructor
Autodesk Inventor 2020 Certified Professional
Autodesk AutoCAD 2017 Certified Professional
0 Likes
Message 3 of 6

Anonymous
Not applicable

Hey Jerry,

 

How's it going? I looked at your code and I believe I found the issue. I changed the PropertyValue back to a String datatype and changed the failed line to Set prop = customPropSet.Add(PropertyValue, PropertyName). Try that and hopefully it solves it on your end. I included the iLogic version as well if you needed it.

 

DanV

 

VBA version

Option Explicit

Public Sub ProcessReferences()
    'Initialize strings
    Dim strCustomerName As String
    strCustomerName = "NONE SELECTED"  'Simplified here, but normally set through a UserForm

    'Get the active assembly
    Dim oAsmDoc As AssemblyDocument
    Set oAsmDoc = ThisApplication.ActiveDocument
 
    'yes, I will test here to ensure active doc is an assembly
    
    'Get all of the referenced documents
    Dim oRefDocs As DocumentsEnumerator
    Set oRefDocs = oAsmDoc.AllReferencedDocuments

    'Iterate through the list of documents
    Dim oRefDoc As Document
    For Each oRefDoc In oRefDocs
    
        'Test if reference is a sheet metal part
        If oRefDoc.SubType = "{9C464203-9BAE-11D3-8BAD-0060B0CE6BB4}" Then
            Call UpdateCustomiProperty(oRefDoc, "CUSTOMER", strCustomerName)
        End If
            
        'Update document
        oRefDoc.Update
            
    Next
    
End Sub

Public Sub UpdateCustomiProperty(ByRef Doc As Document, ByRef PropertyName As String, ByRef PropertyValue As String) 'String
    'Get the custom property set
    Dim customPropSet As PropertySet
    Set customPropSet = Doc.PropertySets.Item("Inventor User Defined Properties")

    'Get the existing property, if it exists.
    Dim prop As Property
    On Error Resume Next
    Set prop = customPropSet.Item(PropertyName)

    'Check to see if the above call failed.  If it failed
    'then the property doesn't exist.
    If Err.Number <> 0 Then
        'Failed to get the existing property so create a new one.
            Set prop = customPropSet.Add(PropertyValue, PropertyName)
    Else
        'Change the value of the existing property.
            prop.Value = PropertyValue
    End If
        
    'Update document
    Doc.Update

End Sub

iLogic Version

Sub Main() 
    'Initialize strings
    Dim strCustomerName As String
    strCustomerName = "NONE SELECTED"  'Simplified here, but normally set through a UserForm

    'Get the active assembly
    Dim oAsmDoc As AssemblyDocument
    oAsmDoc = ThisApplication.ActiveDocument
 
    'yes, I will test here to ensure active doc is an assembly
    
    'Get all of the referenced documents
    Dim oRefDocs As DocumentsEnumerator
    oRefDocs = oAsmDoc.AllReferencedDocuments

    'Iterate through the list of documents
    Dim oRefDoc As Document
    For Each oRefDoc In oRefDocs
    
        'Test if reference is a sheet metal part
        If oRefDoc.SubType = "{9C464203-9BAE-11D3-8BAD-0060B0CE6BB4}" Then
            Call UpdateCustomiProperty(oRefDoc, "CUSTOMER", strCustomerName)
        End If
            
        'Update document
        oRefDoc.Update
            
    Next
    
End Sub

Public Sub UpdateCustomiProperty(ByRef Doc As Document, ByRef PropertyName As String, ByRef PropertyValue As String) 'String
    'Get the custom property set
    Dim customPropSet As PropertySet 
	customPropSet = Doc.PropertySets.Item("Inventor User Defined Properties")

    'Get the existing property, if it exists.
    Dim prop As Inventor.Property
    Try
		prop = customPropSet.Item(PropertyName)
	Catch
		prop = customPropSet.Add(PropertyValue, PropertyName)
	Finally
		prop.Value = PropertyValue
	End Try
	   
    Doc.Update

End Sub

 

0 Likes
Message 4 of 6

JBerns
Advisor
Advisor

@Anonymous,

 

Thanks for looking at this. As I mentioned, a got this code from Brian Ekins.

 

Brian's UpdateCustomiProperty subroutine accepts the custom iProperty value as a variant so that you can send a string, date, number, or date.

 

Although your change will work since I am only passing strings, why can't the variable declared as a variant receive a value declared as a string, and then use it correctly in a Call statement or a Set statement?

 

Also thanks for the iLogic code. If the iLogic Editor had a better editor/debugger I would certainly be using it. MsgBox(es) get very tedious.

 

 

Regards,

Jerry

-----------------------------------------------------------------------------------------
CAD Administrator
Using AutoCAD & Inventor 2025
Autodesk Certified Instructor
Autodesk Inventor 2020 Certified Professional
Autodesk AutoCAD 2017 Certified Professional
0 Likes
Message 5 of 6

Anonymous
Not applicable
Accepted solution

Jerry,

 

Ok if you want to use a Variant instead of a specific datatype then you want to use ByVal instead of ByRef in your sub. With ByRef you are referencing the original argument and it's datatype. So that means that the datatype in the sub must match. With ByVal you are passing a copy of the variable. In doing so with a copy it will try convert to match the datatype in the sub. If there's no reason for it to be referencing the original variable then use ByVal. But if you do need to have it reference the original variable then make the Dim strCustomerName As Variant and keep ByRef in your sub. Hope that makes sense.

 

For iLogic, use Object instead of Variant.

 

DanV

 

Option Explicit

Public Sub ProcessReferences()
    'Initialize strings
    Dim strCustomerName As String
    strCustomerName = "NONE SELECTED"  'Simplified here, but normally set through a UserForm

    'Get the active assembly
    Dim oAsmDoc As AssemblyDocument
    Set oAsmDoc = ThisApplication.ActiveDocument
 
    'yes, I will test here to ensure active doc is an assembly
    
    'Get all of the referenced documents
    Dim oRefDocs As DocumentsEnumerator
    Set oRefDocs = oAsmDoc.AllReferencedDocuments

    'Iterate through the list of documents
    Dim oRefDoc As Document
    For Each oRefDoc In oRefDocs
    
        'Test if reference is a sheet metal part
        If oRefDoc.SubType = "{9C464203-9BAE-11D3-8BAD-0060B0CE6BB4}" Then
            Call UpdateCustomiProperty(oRefDoc, "CUSTOMER", strCustomerName)
        End If
            
        'Update document
        oRefDoc.Update
            
    Next
    
End Sub

Public Sub UpdateCustomiProperty(ByVal Doc As Document, ByVal PropertyName As String, ByVal PropertyValue As Variant) 'String
    'Get the custom property set
    Dim customPropSet As PropertySet
    Set customPropSet = Doc.PropertySets.Item("Inventor User Defined Properties")

    'Get the existing property, if it exists.
    Dim prop As Property
    On Error Resume Next
    Set prop = customPropSet.Item(PropertyName)

    'Check to see if the above call failed.  If it failed
    'then the property doesn't exist.
    If Err.Number <> 0 Then
        'Failed to get the existing property so create a new one.
            Set prop = customPropSet.Add(PropertyValue, PropertyName)
    Else
        'Change the value of the existing property.
            prop.Value = PropertyValue
    End If
        
    'Update document
    Doc.Update

End Sub
Message 6 of 6

JBerns
Advisor
Advisor

@Anonymous,

 

Thanks for the quick reply and explanation on ByRef versus ByVal. That does make sense.

On to the next phase of development. Have a great day.

 

Regards,

Jerry

-----------------------------------------------------------------------------------------
CAD Administrator
Using AutoCAD & Inventor 2025
Autodesk Certified Instructor
Autodesk Inventor 2020 Certified Professional
Autodesk AutoCAD 2017 Certified Professional
0 Likes