Eng-Tips is the largest engineering community on the Internet

Intelligent Work Forums for Engineering Professionals

  • Congratulations waross on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Error 91 while traversing assembly - Object Not Set

Status
Not open for further replies.

shawn76o

Nuclear
Nov 14, 2006
31
0
0
US
I seem to have a problem grasping the concept of VB objects and their requirements for use. I'm trying to traverse an assembly to check the custom properties of every component for certain values. The problem first occurs when I get to the 2nd level of the assembly, and I call a subroutine that uses a bunch of If Then statements to check if the values were written in upper case, lower case, or a combination of both (because custom prop values are case-sensitive?). When the first line of the CheckCase subroutine tries to execute, I get "Object variable or With block variable not set (Error 91)". Can anyone tell me what I'm doing wrong?

Code:
Option Explicit
Public docType              As Integer
Public swApp                As SldWorks.SldWorks
Public swModel              As SldWorks.ModelDoc2
Dim returnOK                As Boolean
[red]Public Part                 As SldWorks.ModelDoc2[/red]


Private Sub cmdMakeBOM_Click()
Unload FormScanParts
main.MainSub
Exit Sub

End Sub

Sub cmdPreScan_Click()

Dim swRootComp              As SldWorks.Component2
Dim swConf                  As SldWorks.Configuration

Set swApp = GetObject(, "SldWorks.Application")
swApp.Visible = True
Set swModel = swApp.ActiveDoc

If swModel Is Nothing Then
    Call MsgBox("A SolidWorks document needs to be loaded!", vbExclamation, "Custom Properties")  ' Display error message
    returnOK = False
    swApp.Visible = True
    
    End     ' If no model currently loaded, then exit
    Else
    docType = swModel.GetType
    If (docType = swDocAssembly) Then
        Set swConf = swModel.GetActiveConfiguration
        Set swRootComp = swConf.GetRootComponent
        
        TraverseComponent swRootComp    'Traverse assembly
        
        Else
        MsgBox ("File is not assembly")
        End 'Exit if file is not assembly
    End If
End If

End Sub

Sub TraverseComponent(swComp As SldWorks.Component2)
    'this recursively traverses all of the components in an assembly
    Dim vChildComp                  As Variant
    Dim swChildComp                 As SldWorks.Component2
    Dim ModName                     As String
    Dim i                           As Integer
    Dim vChildComp2                 As Variant
    Dim i2                          As Integer
    Dim swChildComp2                As SldWorks.Component2
    Dim vChildComp3                 As Variant
    Dim i3                          As Integer
    Dim swChildComp3                As SldWorks.Component2
    Dim Pass                        As Boolean
    Dim Matl                        As String
    Dim itmX                        As ListItem
    Dim MatCase                     As String
    Dim ThkCase                     As String
    Dim VolCase                     As String
    Dim strTemp                     As String
    Dim ShortName                   As String
    Dim lCount                      As Integer
    Dim AddNew                      As Boolean
    Dim Mat                         As String
    Dim Vol                         As String
    Dim Thk                         As String
       
    'Set up the Parts list box
    With PartsList
        ' Create the column headers.
        .ListItems.Clear
        .ColumnHeaders.Clear
        .ColumnHeaders.Add , , "PART NUMBER"
        .ColumnHeaders.Add , , "MATERIAL"
        .ColumnHeaders.Add , , "VOLUME"
        .ColumnHeaders.Add , , "THICKNESS"
        .View = lvwReport
        .Sorted = False
    End With
    
    vChildComp = swComp.GetChildren 'Get the childrent of this component
    
    For i = 0 To UBound(vChildComp) 'Get children on 1st level
    ProgressBar.Value = (i / UBound(vChildComp) * 100)
    
    'Set the objects
    Set swChildComp = vChildComp(i)
    Set Part = swChildComp.GetModelDoc()
    ModName = swChildComp.Name  'Get the name of the component
   
    
    'Check for components excluded from BOM or suppressed
    Debug.Print ModName & " " & CStr(swChildComp.GetSuppression) & " " & CStr(swChildComp.ExcludeFromBOM)
    If (swChildComp.GetSuppression <> 0) And (swChildComp.ExcludeFromBOM = False) Then
        Pass = False    'reset Pass variable
        
        'Check if Material property exists
        'Because custom props are case sensitive, we need to check case too
        Call CheckCase(MatCase, ThkCase, VolCase)
        
        If True = (MatCase <> "") Then   'If we get a Custom Prop "Material"
            Matl = Part.GetCustomInfoValue("", MatCase) 'Get the material number
            Call CheckMatl(Matl, Pass)  'Check its validity
        End If
        
        If Pass = True Then     'If material is valid
        
            'Check Custom property names & cases
            If False = (Part.GetCustomInfoValue("", VolCase) <> "") Or False = (Part.GetCustomInfoValue("", ThkCase) <> "") Then
                'Trim out the extras, we just want the part name
                ShortName = NewParseString(swChildComp.Name, "/", 1, 1)
                ShortName = NewParseString(ShortName, "-", 1, 0)
                AddNew = True   'Have we already listed this part?
                For lCount = 1 To PartsList.ListItems.Count
                    If ShortName = PartsList.ListItems.Item(lCount) Then AddNew = False
                Next lCount
                If AddNew = True Then   'List if no other occurences
                    Mat = Part.GetCustomInfoValue("", MatCase)
                    Vol = Part.GetCustomInfoValue("", VolCase)
                    Thk = Part.GetCustomInfoValue("", ThkCase)
                    'Replace empty strings with "missing" message
                    Call WhatsMissing(Mat, Thk, Vol)
                    Set itmX = PartsList.ListItems.Add(1, , ShortName)
                    itmX.SubItems(1) = Mat
                    itmX.SubItems(2) = Vol
                    itmX.SubItems(3) = Thk
                End If
            End If
        
        End If  'Listed any Material with missing properties
    End If
    
    
        vChildComp2 = swChildComp.GetChildren   'Get the children of this component
        For i2 = 0 To UBound(vChildComp2)   'Get children on 2nd level
        
        'Set the objects
        Set swChildComp2 = vChildComp2(i2)
        [red]Set Part = swChildComp2.GetModelDoc()[/red]
        ModName = swChildComp2.Name
        
        'Check for components excluded from BOM or suppressed
        Debug.Print ModName & " " & CStr(swChildComp2.GetSuppression) & " " & CStr(swChildComp2.ExcludeFromBOM)
        If (swChildComp2.GetSuppression <> 0) And (swChildComp2.ExcludeFromBOM = False) Then
            Pass = False    'reset Pass variable
            
            'Check case for "Material" custom prop
            'Checking case again, too
            [red]Call CheckCase(MatCase, ThkCase, VolCase)[/red]
            
            If True = (MatCase <> "") Then   'If we get a Custom Prop "Material"
                Matl = Part.GetCustomInfoValue("", MatCase) 'Get the material number
                Call CheckMatl(Matl, Pass)  'Check its validity
            End If
            
            If Pass = True Then     'If material is valid
                
                'Check custom property names & cases
                If False = (Part.GetCustomInfoValue("", VolCase) <> "") Or False = (Part.GetCustomInfoValue("", ThkCase) <> "") Then
                    'Trim out the extras, we just want the part name
                    ShortName = NewParseString(swChildComp2.Name, "/", 1, 1)
                    ShortName = NewParseString(ShortName, "-", 1, 0)
                    AddNew = True   'Have we already listed this part?
                    For lCount = 1 To PartsList.ListItems.Count
                        If ShortName = PartsList.ListItems.Item(lCount) Then AddNew = False
                    Next lCount
                    If AddNew = True Then   'List if no other occurences
                        Mat = Part.GetCustomInfoValue("", MatCase)
                        Vol = Part.GetCustomInfoValue("", VolCase)
                        Thk = Part.GetCustomInfoValue("", ThkCase)
                        'Replace empty strings with "missing" message
                        Call WhatsMissing(Mat, Thk, Vol)
                        Set itmX = PartsList.ListItems.Add(1, , ShortName)
                        itmX.SubItems(1) = Mat
                        itmX.SubItems(2) = Vol
                        itmX.SubItems(3) = Thk
                    End If
                End If
            End If  'Listed any Material with missing properties
        End If
        
            vChildComp3 = swChildComp2.GetChildren  'Set the Child variant
            For i3 = 0 To UBound(vChildComp3)   'Get childrent on 3rd level
            
            'Set objects
            Set swChildComp3 = vChildComp3(i3)
            Set Part = swChildComp3.GetModelDoc()
            ModName = swChildComp3.Name
            
            'Check for components excluded from BOM or suppressed
            Debug.Print ModName & " " & CStr(swChildComp3.GetSuppression) & " " & CStr(swChildComp3.ExcludeFromBOM)
            If (swChildComp3.GetSuppression <> 0) And (swChildComp3.ExcludeFromBOM = False) Then
                Pass = False    'reset Pass variable
                
                'Check case for "Material" custom prop
                'Checking case again, too
                Call CheckCase(MatCase, ThkCase, VolCase)
                
                If True = (MatCase <> "") Then   'If we get a Custom Prop "Material"
                    Matl = Part.GetCustomInfoValue("", MatCase) 'Get the material number
                    Call CheckMatl(Matl, Pass)  'Check its validity
                End If
                
                If Pass = True Then     'If material is valid
                    
                    'Check custom property names & cases
                    If False = (Part.GetCustomInfoValue("", VolCase) <> "") Or False = (Part.GetCustomInfoValue("", ThkCase) <> "") Then
                        'Trim out the extras, we just want the part name
                        ShortName = NewParseString(swChildComp3.Name, "/", 1, 1)
                        ShortName = NewParseString(ShortName, "-", 1, 0)
                        AddNew = True   'Have we already listed this part?
                        For lCount = 1 To PartsList.ListItems.Count
                            If ShortName = PartsList.ListItems.Item(lCount) Then AddNew = False
                        Next lCount
                        If AddNew = True Then   'List if no other occurences
                            Mat = Part.GetCustomInfoValue("", MatCase)
                            Vol = Part.GetCustomInfoValue("", VolCase)
                            Thk = Part.GetCustomInfoValue("", ThkCase)
                            'Replace empty strings with "missing" message
                            Call WhatsMissing(Mat, Thk, Vol)
                            Set itmX = PartsList.ListItems.Add(1, , ShortName)
                            itmX.SubItems(1) = Mat
                            itmX.SubItems(2) = Vol
                            itmX.SubItems(3) = Thk
                        End If
                    End If
                End If  'Listed any Material with missing properties
            End If
            Next i3
        Next i2
    Next i
    
    StatusLabel.Caption = "Finished!"
    If PartsList.ListItems.Count = 0 Then cmdMakeBOM.Enabled = True
    PreScanDone = True
End Sub

Sub CheckMatl(Matl As String, Pass As Boolean)

Select Case Matl

    Case "20102", "20105", "20112", "20114", "30009", "30098", "30099", _
    "31060", "31102", "31103", "31104", "31105", "31113", "31117", "31237", _
    "31266", "31275", "31355", "31357"
    'Material is valid and properties will be evaluated
    Pass = True
    
End Select
    
End Sub

Sub CheckCase(MatCase As String, ThkCase As String, VolCase As String)

'Check case for "Material" custom prop
    [red]If Part.GetCustomInfoValue("", "Material") <> "" Then MatCase = "Material"[/red]
    If Part.GetCustomInfoValue("", "MATERIAL") <> "" Then MatCase = "MATERIAL"
    If Part.GetCustomInfoValue("", "material") <> "" Then MatCase = "material"
    
    'Check case for "Thickness" custom prop
    If Part.GetCustomInfoValue("", "Thickness") <> "" Then ThkCase = "Thickness"
    If Part.GetCustomInfoValue("", "THICKNESS") <> "" Then ThkCase = "THICKNESS"
    If Part.GetCustomInfoValue("", "thickness") <> "" Then ThkCase = "thickness"
    
    'Check case for "Volume" custom prop
    If Part.GetCustomInfoValue("", "Volume") <> "" Then VolCase = "Volume"
    If Part.GetCustomInfoValue("", "VOLUME") <> "" Then VolCase = "VOLUME"
    If Part.GetCustomInfoValue("", "volume") <> "" Then VolCase = "volume"

End Sub
Sub WhatsMissing(Mat As String, Thk As String, Vol As String)

If Mat = "" Then Mat = "(missing)"
If Thk = "" Then Thk = "(missing)"
If Vol = "" Then Vol = "(missing)"

End Sub

Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer)
Unload FormScanParts
If CloseMode = 0 Then End
End Sub
 
Replies continue below

Recommended for you

I noticed that the problem occurs because for some reason, the

[red]swChildComp2.GetModelDoc()[/red]

is returning "Nothing", although

[red]swChildComp2.Name[/red]

is returning part # "P-2-3-35-A1-3/94103A-6"

I don't understand... why "Nothing" ???
 
OK, I figured out what was happening, and that leads me to another question. The GetModelDoc() method was returning Null (Nothing) because the component was set to "Lightweight". I found this documented in Solidworks API Help.

However, I still need the macro to check the custom properties of these components. Even after reading about Lightweight components in SW API, I haven't figured out how to achieve a solution.

I'm sure there must be a way...
 
The simplest solution would be to resolve all the components prior to traversing the assembly with AssemblyDoc::ResolveAllLightWeightComponents.
 
Thanks handleman!
That's exactly what I did - and it fixed the problem nicely! Also, because it takes a minute on larger assemblies, I took it a step further and added a message to tell the user what is happening.

Code:
Public swApp                As SldWorks.SldWorks
---------------------------------------------------
Dim swAssy                  As SldWorks.AssemblyDoc
Set swAssy = swApp.ActiveDoc
[green]'Notify the user program will be busy momentarily while lightweight components are resolved[/green]
StatusLabel.Font.Size = 10
StatusLabel.ForeColor = RGB(255, 0, 0)
StatusLabel.Caption = "Resolving all Lightweight Components - Please standby..."
Me.Repaint
[green]'Resolve all lightweight components[/green]
swAssy.ResolveAllLightWeightComponents (False)
StatusLabel.Caption = ""
Me.Repaint
 
Status
Not open for further replies.
Back
Top