Announcements
Attention for Customers without Multi-Factor Authentication or Single Sign-On - OTP Verification rolls out April 2025. Read all about it here.

Is it possible to append an attribute to a browser folder?

HogueOne
Enthusiast

Is it possible to append an attribute to a browser folder?

HogueOne
Enthusiast
Enthusiast

I'm trying to append string data to a browser folder. the purpose of this is so that I can make another code that prompts the user to make the occurrences placed in the browser folder inherit the string values as custom iproperties. this is what I have so far, but it's saying that the object I'm trying to use isn't supported. could someone help me fix this code? I've included another code that allows the user to read attributes from the folder selected, but I don't think either are working properly.

 

 

Sub Main()
    Call MainLogic()
End Sub

Sub MainLogic()
    Dim oDoc As Document = ThisDoc.Document
    Dim oBrowserPanes As BrowserPanes = oDoc.BrowserPanes
    Dim oModelBrowserPane As BrowserPane = oBrowserPanes.Item("Model")
    Dim oBrowserFolders As BrowserFoldersEnumerator = oModelBrowserPane.TopNode.BrowserFolders
    Dim folderNames As New List(Of String)

    ' Populate the list of folder names
    For i As Integer = 1 To oBrowserFolders.Count
        folderNames.Add(oBrowserFolders.Item(i).Name)
    Next

    ' Prompt the user to choose a folder
    If folderNames.Count > 0 Then
        Dim selectedFolderName As String = InputListBox("Please select a browser folder:", folderNames, folderNames(0), "Browser Folder Selection")

        If Not String.IsNullOrEmpty(selectedFolderName) Then
            ' Find the selected folder
            Dim selectedFolder As BrowserFolder = Nothing
            For i As Integer = 1 To oBrowserFolders.Count
                Dim oFolder As BrowserFolder = oBrowserFolders.Item(i)
                If oFolder.Name = selectedFolderName Then
                    selectedFolder = oFolder
                    Exit For
                End If
            Next

            If Not selectedFolder Is Nothing Then
                ' Get the object represented by the browser folder
                Dim obj As Object = selectedFolder.BrowserNode.NativeObject

                ' Prompt the user to enter a string
                Dim userString As String = InputBox("Enter a string to append as an attribute:", "String Input")

                If Not String.IsNullOrEmpty(userString) Then
                    Try
                        ' Attempt to add the attribute
                        AddAttributeToObject(obj, "CustomAttributes", "UserInput", userString)
                        MessageBox.Show("Attribute added successfully to object in folder: " & selectedFolderName, "Success")
                    Catch ex As Exception
                        MessageBox.Show("Error adding attribute: " & ex.Message, "Error")
                    End Try
                Else
                    MessageBox.Show("No string entered.", "Cancelled")
                End If
            Else
                MessageBox.Show("Selected folder not found.", "Error")
            End If
        Else
            MessageBox.Show("No folder selected.", "Cancelled")
        End If
    Else
        MessageBox.Show("No folders found in the browser.", "Error")
    End If
End Sub

Sub AddAttributeToObject(obj As Object, attributeSetName As String, attributeName As String, attributeValue As String)
    If obj Is Nothing Then
        Throw New ArgumentNullException("obj")
    End If

    Dim oAttribSets As AttributeSets
    Try
        oAttribSets = obj.AttributeSets
    Catch ex As Exception
        Throw New Exception("Object does not support attributes.")
    End Try

    Dim oAttribSet As AttributeSet
    If Not oAttribSets.NameIsUsed(attributeSetName) Then
        oAttribSet = oAttribSets.Add(attributeSetName)
    Else
        oAttribSet = oAttribSets.Item(attributeSetName)
    End If

    If Not oAttribSet.NameIsUsed(attributeName) Then
        oAttribSet.Add(attributeName, ValueTypeEnum.kStringType, attributeValue)
    Else
        oAttribSet.Item(attributeName).Value = attributeValue
    End If
End Sub

 

 

Sub Main()
    Call MainLogic()
End Sub

Sub MainLogic()
    Dim oDoc As Document = ThisDoc.Document
    Dim oBrowserPanes As BrowserPanes = oDoc.BrowserPanes
    Dim oModelBrowserPane As BrowserPane = oBrowserPanes.Item("Model")
    Dim oBrowserFolders As BrowserFoldersEnumerator = oModelBrowserPane.TopNode.BrowserFolders
    Dim folderNames As New List(Of String)

    ' Populate the list of folder names
    For i As Integer = 1 To oBrowserFolders.Count
        folderNames.Add(oBrowserFolders.Item(i).Name)
    Next

    ' Prompt the user to choose a folder
    If folderNames.Count > 0 Then
        Dim selectedFolderName As String = InputListBox("Please select a browser folder:", folderNames, folderNames(0), "Browser Folder Selection")

        If Not String.IsNullOrEmpty(selectedFolderName) Then
            ' Find the selected folder
            Dim selectedFolder As BrowserFolder = Nothing
            For i As Integer = 1 To oBrowserFolders.Count
                Dim oFolder As BrowserFolder = oBrowserFolders.Item(i)
                If oFolder.Name = selectedFolderName Then
                    selectedFolder = oFolder
                    Exit For
                End If
            Next

            If Not selectedFolder Is Nothing Then
                ' Get the object represented by the browser folder
                Dim obj As Object = selectedFolder.BrowserNode.NativeObject

                ' Get attributes for the object
                Dim attributeInfo As String = GetAttributeInfo(obj)

                ' Display the attribute information
                If Not String.IsNullOrEmpty(attributeInfo) Then
                    MessageBox.Show(attributeInfo, "Folder Attributes")
                Else
                    MessageBox.Show("No attributes found for this folder.", "Folder Attributes")
                End If
            Else
                MessageBox.Show("Selected folder not found.", "Error")
            End If
        Else
            MessageBox.Show("No folder selected.", "Cancelled")
        End If
    Else
        MessageBox.Show("No folders found in the browser.", "Error")
    End If
End Sub

Function GetAttributeInfo(obj As Object) As String
    If obj Is Nothing Then Return Nothing
    Dim attributeInfo As String = ""
    Dim oSets As Inventor.AttributeSets = Nothing
    Try
        oSets = obj.AttributeSets
    Catch
        Return Nothing
    End Try
    If oSets Is Nothing OrElse oSets.Count = 0 Then Return Nothing

    For Each oSet As Inventor.AttributeSet In oSets
        attributeInfo &= "Attribute Set: " & oSet.Name & vbNewLine
        If oSet.Count = 0 Then Continue For
        For Each oAtt As Inventor.Attribute In oSet
            attributeInfo &= "  - " & oAtt.Name & ": " & oAtt.Value.ToString & vbNewLine
        Next
        attributeInfo &= vbNewLine
    Next

    Return attributeInfo
End Function
0 Likes
Reply
Accepted solutions (1)
376 Views
4 Replies
Replies (4)

WCrihfield
Mentor
Mentor

The BrowserFolder and the BrowserNode Inventor API objects do not have the 'AttributeSets' property, so neither will support attributes at this time.  Also, you may need to use a Try...Catch...End Try statement around where you are accessing BrowserNode.NativeObject property, because some objects will throw an error when accessing it.

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

HogueOne
Enthusiast
Enthusiast

I think I may have found a solution that seems to be working for browser folders. Can you study and/or test this to see how it compares with what you said?

Imports System.Windows.Forms
Sub Main()
    Call MainLogic()
End Sub

Sub MainLogic()
    Dim oDoc As Document = ThisDoc.Document
    Dim oBrowserPanes As BrowserPanes = oDoc.BrowserPanes
    Dim oModelBrowserPane As BrowserPane = oBrowserPanes.Item("Model")
    Dim oBrowserFolders As BrowserFoldersEnumerator = oModelBrowserPane.TopNode.BrowserFolders
    Dim folderNames As New List(Of String)

    ' Populate the list of folder names
    For i As Integer = 1 To oBrowserFolders.Count
        folderNames.Add(oBrowserFolders.Item(i).Name)
    Next

    ' Prompt the user to choose a folder
    If folderNames.Count > 0 Then
        Dim selectedFolderName As String = InputListBox("Please select a browser folder:", folderNames, folderNames(0), "Browser Folder Selection")

        If Not String.IsNullOrEmpty(selectedFolderName) Then
            ManageAttributesForFolder(oDoc, selectedFolderName)
        Else
            Dim result As DialogResult = MessageBox.Show("Are you sure you want to abort the operation?", "Confirm Abort", MessageBoxButtons.YesNo)
            If result = DialogResult.No Then
                MainLogic() ' Restart the process
            End If
        End If
    Else
        MessageBox.Show("No folders found in the browser.", "Error")
    End If
End Sub

Sub ManageAttributesForFolder(doc As Document, folderName As String)
    While True
        Dim options As New List(Of String)
        options.Add("Manage existing attributes")
        options.Add("Append new attribute")
        options.Add("Change folder") ' Added option to change folder
        
        Dim choice As String = InputListBox("What do you want to do?", options, options(0), "Attribute Management")

        If String.IsNullOrEmpty(choice) Then
            Dim result As DialogResult = MessageBox.Show("Done?", "Confirm Exit", MessageBoxButtons.YesNo)
            If result = DialogResult.Yes Then
                Exit Sub
            End If
        ElseIf choice = "Append new attribute" Then
            ' Append new attribute
            Dim attrName As String = InputBox("Enter the name of the attribute:", "Attribute Name")
            If Not String.IsNullOrEmpty(attrName) Then
                Dim attrValue As String = InputBox("Enter the value of the attribute:", "Attribute Value")
                If Not String.IsNullOrEmpty(attrValue) Then
                    Dim attributeSetName As String = "CustomAttributes"
                    AddAttributeToDocument(doc, attributeSetName, attrName, attrValue, folderName)
                    MessageBox.Show("Attribute added successfully." & vbNewLine & 
                                    "Attribute Name: " & attrName & vbNewLine & 
                                    "Attribute Value: " & attrValue, "Success")
                End If
            End If
        ElseIf choice = "Manage existing attributes" Then
            ' Manage existing attributes
            Dim attributeList As List(Of AttributeInfo) = GetDocumentAttributeInfo(doc, folderName)
            ManageExistingAttributes(doc, attributeList, folderName)
        ElseIf choice = "Change folder" Then
            ' Change folder
            Call MainLogic() ' Restart the process to select a different folder
            Exit Sub
        End If
    End While
End Sub

Function GetDocumentAttributeInfo(doc As Document, folderName As String) As List(Of AttributeInfo)
    Dim attributeList As New List(Of AttributeInfo)
    Dim oAttribSets As AttributeSets = doc.AttributeSets

    For Each oSet As AttributeSet In oAttribSets
        For Each oAtt As Attribute In oSet
            If oAtt.Name.StartsWith("Folder_" & folderName & "_") Then
                Dim cleanName As String = oAtt.Name.Substring(("Folder_" & folderName & "_").Length)
                attributeList.Add(New AttributeInfo(oSet.Name, cleanName, oAtt.Value.ToString()))
            End If
        Next
    Next

    Return attributeList
End Function

Sub AddAttributeToDocument(doc As Document, attributeSetName As String, attributeName As String, attributeValue As String, folderName As String)
    If doc Is Nothing Then
        Throw New ArgumentNullException("doc")
    End If

    Dim oAttribSets As AttributeSets = doc.AttributeSets

    Dim oAttribSet As AttributeSet
    If Not oAttribSets.NameIsUsed(attributeSetName) Then
        oAttribSet = oAttribSets.Add(attributeSetName)
    Else
        oAttribSet = oAttribSets.Item(attributeSetName)
    End If

    Dim fullAttributeName As String = "Folder_" & folderName & "_" & attributeName
    oAttribSet.Add(fullAttributeName, ValueTypeEnum.kStringType, attributeValue)
End Sub

Sub ManageExistingAttributes(doc As Document, attributeList As List(Of AttributeInfo), folderName As String)
    If attributeList.Count = 0 Then
        MessageBox.Show("No attributes found for this folder.", "Attribute Management")
        Return
    End If

    While True
        Dim attributeDisplayList As New List(Of String)
        For Each attr In attributeList
            attributeDisplayList.Add(attr.Name & " : " & attr.Value)
        Next

        Dim selectedAttribute As String = InputListBox("Select an attribute:", attributeDisplayList, attributeDisplayList(0), "Attribute Management")

        If String.IsNullOrEmpty(selectedAttribute) Then
            Exit Sub
        End If

        Dim selectedAttributeName = selectedAttribute.Split(":"c)(0).Trim()
        Dim attrToManage = attributeList.Find(Function(a) a.Name = selectedAttributeName)

        Dim actionOptions As New List(Of String)
        actionOptions.Add("Copy attribute")
        actionOptions.Add("Delete attribute")
        Dim action As String = InputListBox("What do you want to do with this attribute?", actionOptions, actionOptions(0), "Attribute Action")

        If action = "Copy attribute" Then
            ' Copy attribute to clipboard
            Dim attributeString As String = attrToManage.Name & ": " & attrToManage.Value
            Clipboard.SetText(attributeString)
            MessageBox.Show("The attribute name and value have been copied to the clipboard.", "Attribute Copied")
        ElseIf action = "Delete attribute" Then
            ' Delete attribute
            Dim result As DialogResult = MessageBox.Show("Are you sure you want to delete the attribute?", "Confirm Deletion", MessageBoxButtons.YesNo)
            If result = DialogResult.Yes Then
                DeleteAttribute(doc, attrToManage, folderName)
                attributeList.Remove(attrToManage)
            End If
        End If

        If attributeList.Count = 0 Then
            MessageBox.Show("No more attributes to manage.", "Attribute Management")
            Exit Sub
        End If
    End While
End Sub

Sub DeleteAttribute(doc As Document, attrInfo As AttributeInfo, folderName As String)
    Dim oAttribSets As AttributeSets = doc.AttributeSets
    Dim oSet As AttributeSet = oAttribSets.Item(attrInfo.SetName)
    Dim fullAttributeName As String = "Folder_" & folderName & "_" & attrInfo.Name
    If oSet.NameIsUsed(fullAttributeName) Then
        oSet.Item(fullAttributeName).Delete()
    End If
End Sub

Class AttributeInfo
    Public SetName As String
    Public Name As String
    Public Value As String

    Public Sub New(setName As String, name As String, value As String)
        Me.SetName = setName
        Me.Name = name
        Me.Value = value
    End Sub
End Class
0 Likes

WCrihfield
Mentor
Mentor
Accepted solution

Hi @HogueOne.  First of all, that is some pretty impressive code.  After reading through all that, it seems like you are storing String type data within document level attributes that you can then retrieve later.  And I assume that you are planning on using that system to help you accomplish the goals mentioned in your original post here (pushing custom iProperties down into the components that you store in the browser folder).  That may work just fine.  It will likely be interesting attempting to create another code that works with that system to make that happen...especially if it is supposed to happen automatically, by simply placing components into the folder.  Some event handlers may need to get involved.  There is the BrowserPanesEvents, but none of the events there sound right.

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

_dscholtes_
Advocate
Advocate

Side-note: I'd advise to restructure the code such that lines 27 and 68 are not necessary. Calling a sub/function in order to repeat it (27) or jumping between different subs/functions because a piece of identical code is to be executed (68) makes the execution order unclear and modification of the program flow more difficult.

If you need to repeat something until a certain condition is met, use a loop construction.

If identical code is needed at different places, create a separate sub/function for it.