Navigate CATIA V6 Assembly Populating Attributes by CSV

Navigate CATIA V6 Assembly Populating Attributes by CSV

The following script recursively traverses a CATIA V6 product structure after reading a CSV file into a dictionary of custom classes, where the key is the first attribute in the CSV, read row. Based on this key it matches the V6 Part Number as it walks the structure to a key in the dictionary and then uses the stored attributes in the custom class to update the V6 object attributes.

'Class CSVFileObject
Public PartNumber As String
Public Manufacturer As String
Public HasBeenProcessed As Boolean

Private Sub Class_Initialize()
    HasBeenProcessed = False
End Sub

''CSV File Structure
'Partnumber,Attribute1, Attribute2, Attribute3,ect..

Sub Main()

    Dim ioCATIA As Application
    Set ioCATIA = CATIA
    
    WriteToLogFile ioCATIA, "########################################################################################"
    WriteToLogFile ioCATIA, "Starting Attribute Update on Product Structure : " & Format(Now, "hh:mm:ss dddd, mmm d yyyy")
    WriteToLogFile ioCATIA, ""
    
    Dim PartsDictionary As Scripting.Dictionary
    Set PartsDictionary = CreateCSVStructure(ioCATIA)
    
    Dim ProcessedDictionary As Scripting.Dictionary
    Set ProcessedDictionary = New Scripting.Dictionary
    
    Dim ioActiveEditor As Editor
    Set ioActiveEditor = ioCATIA.ActiveEditor
    
    Dim ioActiveObject As VPMRootOccurrence
    Set ioActiveObject = ioActiveEditor.ActiveObject
    
    Dim ioVPMReference As VPMReference
    Set ioVPMReference = ioActiveObject.ReferenceRootOccurrenceOf
    ProcessedDictionary.Add ioVPMReference.GetAttributeValue("PLM_ExternalID"), ioVPMReference
    
    WriteToLogFile ioCATIA, ""
    WriteToLogFile ioCATIA, "Updating Attribute on Root Occurence"
    UpdateAttributes ioVPMReference, PartsDictionary
    
    Dim ioOccurences As VPMOccurrences
    Set ioOccurences = ioActiveObject.Occurrences
    
    Dim Indentation As Integer
    Indentation = 1
    
    NavigateProductStructure ioOccurences, PartsDictionary, ProcessedDictionary, Indentation
    
    WriteToLogFile ioCATIA, ""
    WriteToLogFile ioCATIA, "Finishing Attribute Update on Product Structure : " & Format(Now, "hh:mm:ss dddd, mmm d yyyy")
    WriteToLogFile ioCATIA, "########################################################################################"
    MsgBox ("Completed the Update of the Attributes, View Log File for Errors.")
End Sub

Sub NavigateProductStructure(ioOccurences As VPMOccurrences, PartsDictionary As Scripting.Dictionary, ProcessedDictionary As Scripting.Dictionary, Indentation As Integer)

    Dim ioIndex As Integer
    For ioIndex = 1 To ioOccurences.Count
        
        Dim ioOccurence As VPMOccurrence
        Set ioOccurence = ioOccurences.Item(ioIndex)
        
        Dim ioVPMInstance As VPMInstance
        Set ioVPMInstance = ioOccurence.PLMEntity
        
        Dim ioVPMReference As VPMReference
        Set ioVPMReference = ioVPMInstance.ReferenceInstanceOf
        
        Dim MatchKey As String
        MatchKey = ioVPMReference.GetAttributeValue("PLM_ExternalID")
        
        If (ProcessedDictionary.Exists(MatchKey) = False) Then
            ProcessedDictionary.Add MatchKey, ioVPMReference
            UpdateAttributes ioVPMReference, PartsDictionary, Indentation
        Else
            WriteToLogFile ioVPMReference.Application, ">>>>>Current Part or Product: " & MatchKey & " Has Already Been Processed.", Indentation * 4
        End If
        
        If (ioOccurence.Occurrences.Count > 0) Then
            Indentation = Indentation + 1
        End If
                     
        NavigateProductStructure ioOccurence.Occurrences, PartsDictionary, ProcessedDictionary, Indentation
      
        If (ioIndex = ioOccurences.Count) Then
            Indentation = Indentation - 1
        End If
    Next
    
End Sub

Sub UpdateAttributes(ioVPMReference As VPMReference, PartsDictionary As Scripting.Dictionary, Optional Indentation As Integer = 0)

    Dim MatchKey As String
    MatchKey = ioVPMReference.GetAttributeValue("PLM_ExternalID")
    WriteToLogFile ioVPMReference.Application, "Current Part or Product: " & MatchKey, Indentation * 4
    
    If (PartsDictionary.Exists(MatchKey)) Then
        Dim NewCSVFileObject As CSVFileObject
        Set NewCSVFileObject = PartsDictionary.Item(MatchKey)
        
        If (NewCSVFileObject.HasBeenProcessed = False) Then
        
            'Update Attributes Here
            ioVPMReference.SetAttributeValue "Manufacturer", NewCSVFileObject.Manufacturer
            WriteToLogFile ioVPMReference.Application, "++++>Setting Attribute: Manufacturer with Value: " & NewCSVFileObject.Manufacturer, Indentation * 4
            
            ioVPMReference.SetAttributeValue "V_Name", NewCSVFileObject.PartNumber
            WriteToLogFile ioVPMReference.Application, "++++>Setting Attribute: V_Name with Value: " & NewCSVFileObject.PartNumber, Indentation * 4
            
            'Update Attribbute so we dont keep Processing it
            NewCSVFileObject.HasBeenProcessed = True
        Else
            WriteToLogFile ioVPMReference.Application, ">>>>>Current Part or Product: " & MatchKey & " Has Already Been Processed.", Indentation * 4
        End If
        
    Else
        MsgBox ("Part Number : " & MatchKey & " Was Missing From the CSV File.")
        WriteToLogFile ioVPMReference.Application, "---->Part Number:" & MatchKey & " Was Missing From the CSV File.", Indentation * 4
    End If
    
End Sub

Sub WriteToLogFile(ioCATIA As Application, iMessageString As String, Optional Indentation As Integer = 0)

    Dim ioFolderPath As String
    ioFolderPath = "C:\tmp"

    Dim ioFilePath As String
    ioFilePath = "C:\tmp\UpdateAttributeLog.log"
    
    If (ioCATIA.FileSystem.FolderExists(ioFolderPath) = False) Then
        ioCATIA.FileSystem.CreateFolder (ioFolderPath)
        MsgBox ("Creating Log Folder " & ioFolderPath)
    End If
    
    If (ioCATIA.FileSystem.FileExists(ioFilePath) = False) Then
        ioCATIA.FileSystem.CreateFile ioFilePath, True
        MsgBox ("Creating Log File " & ioFilePath)
    End If
    
    Dim ioFile As File
    Set ioFile = ioCATIA.FileSystem.GetFile(ioFilePath)
    
    Dim ioTxtStream As TextStream
    Set ioTxtStream = ioFile.OpenAsTextStream("ForAppending")
    ioTxtStream.Write (Space(Abs(Indentation)) & iMessageString & vbLf)

End Sub

Sub MessageAttributes(ioVPMReference As VPMReference)

    Dim MessageString As String
    MessageString = "Name : " & ioVPMReference.GetAttributeValue("V_Name") & vbCrLf
    MessageString = MessageString & "Manufacturer : " & ioVPMReference.GetAttributeValue("Manufacturer")

    MsgBox (MessageString)
End Sub

Function FileSelection(ioCATIA As Application) As String

    FileSelection = ioCATIA.FileSelectionBox("Select a CSV File", "*.csv", CatFileSelectionModeOpen)
        If (FileSelection = "") Then
        Do While FileSelection = ""
            Dim MessageResult As String
            MessageResult = MsgBox("No File Selected, Do you Want to Select a File?", vbYesNo)
            If (MessageResult = vbNo) Then
                End
            Else
                FileSelection = FileSelection(ioCATIA)
            End If
        Loop
    End If
    
    WriteToLogFile ioCATIA, "Opening File: " & FileSelection

End Function

Function CreateCSVStructure(ioCATIA As Application) As Scripting.Dictionary

    Dim ReturnDictionary As Scripting.Dictionary
    Set ReturnDictionary = New Scripting.Dictionary
    
    Dim ioFilePath As String
    ioFilePath = FileSelection(ioCATIA)
    
    Dim ioFile As File
    Set ioFile = ioCATIA.FileSystem.GetFile(ioFilePath)
    
    Dim ioTxtStream As TextStream
    Set ioTxtStream = ioFile.OpenAsTextStream("ForReading")
    
    Do Until ioTxtStream.AtEndOfStream
         Dim ioLine As String
         ioLine = ioTxtStream.ReadLine
         If (Len(ioLine) > 0) Then
            
            WriteToLogFile ioCATIA, "Reading CSV Line " & ioLine
            
            Dim StringArr() As String
            StringArr = Split(ioLine, ",")
            
            Dim NewCSVFileObject As New CSVFileObject
            Set NewCSVFileObject = New CSVFileObject
            
            'Add Additional Attributes to the Class then map them here
            
            NewCSVFileObject.PartNumber = StringArr(1)
            NewCSVFileObject.Manufacturer = StringArr(2)
            
            ReturnDictionary.Add StringArr(0), NewCSVFileObject

         End If
         
    Loop
    Set CreateCSVStructure = ReturnDictionary
    
    WriteToLogFile ioCATIA, "Number of CSV Lines Read: " & ReturnDictionary.Count
End Function