Warm tip: This article is reproduced from stackoverflow.com, please click
vba solidworks

Saving all parts in an assembly as STEP with custom properties. How to solve run-time error 91?

发布于 2020-03-27 15:42:52

I'm trying to write a macro with VBA in Solidworks that will go through all the sub assemblies and save every part as STEP-file where the name is determined by a custom property. I don't have a lot of programming experience as I'm an mechanical engineer but I try to automate some processes from time to time. Most of this code I got from others and I tried to tweak it to my situation. I do understand most of what is happening though.

The problem I'm having is that I keep getting a

91 runtime error

When I go to debugging Solidworks tells me the problem is in the line name = swPart.GetTitle. At first it said "name = nothing". I tried looking for the problem and when i added Set swApp = Application.SldWorks to the sub I still got the error but now name is always something.

Dim swApp As SldWorks.SldWorks
Dim swAssy As SldWorks.AssemblyDoc
Dim swConf As SldWorks.Configuration
Dim swRootComp As SldWorks.Component2
Dim retVal As Boolean
Dim errors As Long, warnings As Long
Dim revision As String
Dim vaultPath As String
Dim name As String
Dim longstatus As Long, longwarnings As Long

Sub main()

Set swApp = Application.SldWorks
Set swAssy = swApp.ActiveDoc
Set swConf = swAssy.GetActiveConfiguration
Set swRootComp = swConf.GetRootComponent3(True)

vaultPath = "C:\Users\Engineering\Desktop\test\" 'set folder for vault (change this later)

TraverseComponent swRootComp, 1, vaultPath

End Sub

Sub TraverseComponent(swComp As SldWorks.Component2, nLevel As Long, vaultPath As String)
    Dim vChilds As Variant, vChild As Variant
    Dim swChildComp As SldWorks.Component2
    Dim MyString As String
    Dim swCustPropMgr As SldWorks.CustomPropertyManager
    Set swApp = Application.SldWorks
    vChilds = swComp.GetChildren
    For Each vChild In vChilds
        Set swChildComp = vChild
        Dim FileName As String
        FileName = swChildComp.GetPathName
        FileName = Left(FileName, InStr(FileName, ".") - 1)
        FileName = Right(FileName, Len(FileName) - InStrRev(FileName, "\"))
        Debug.Print "Part Name    : " & FileName
        MyString = FileName
        Dim ActiveConfig As String
        ActiveConfig = swChildComp.ReferencedConfiguration
        Debug.Print "Configuration: " & ActiveConfig
        FileName = swChildComp.GetPathName
        If UCase(Right(FileName, 6)) = "SLDPRT" Then
            'MsgBox ("part found")
            Dim swPart As SldWorks.ModelDoc2
            Set swPart = swApp.OpenDoc6(swChildComp.GetPathName, 1, 0, "", longstatus, longwarnings)
            'Dim name As String 'I tried adding this but it made no difference
            name = swPart.GetTitle 'get the title of the active document
            'chop the extension off if present
            If Right(name, 7) = ".SLDPRT" Or Right(name, 7) = ".SLDasm" Then
                name = Left(name, Len(name) - 7)
            End If
            Set swCustPropMgr = swPart.Extension.CustomPropertyManager("") 'get properties
            revision = swCustPropMgr.Get("Revision") 'get revision
            retVal = swApp.SetUserPreferenceIntegerValue(swUserPreferenceIntegerValue_e.swStepAP, 214) 'change the step file options
            'save with revision if present
            If revision = "" Or revision = Null Then
            retVal = swPart.Extension.SaveAs(vaultPath & name & ".step", swSaveAsVersion_e.swSaveAsCurrentVersion, swSaveAsOptions_e.swSaveAsOptions_Silent, Nothing, errors, warnings)
            Else
            retVal = swPart.Extension.SaveAs(vaultPath & name & " - Rev " & revision & ".step", swSaveAsVersion_e.swSaveAsCurrentVersion, swSaveAsOptions_e.swSaveAsOptions_Silent, Nothing, errors, warnings)
            End If
            swApp.CloseDoc swPart.GetTitle
        End If
        Debug.Print
        TraverseComponent swChildComp, nLevel + 1, vaultPath
    Next

End Sub
Questioner
Jesper K.
Viewed
17
Sinue 2020-01-31 18:55

A suppressed component is not the only reason why you could get a "nothing" after calling OpenDoc. This happens e.g. if the component is loaded lightweight or is otherwise not fully loaded. Then you are also not able to get the ModelDoc (PartDoc) data of a component object.

To prevent this completely you could execute the next lines only if the swPart variable is not nothing.

If (Not swPart Is Nothing) Then 
    name = swPart.GetTitle 'get the title of the active document
    ...
End If

Additionally I can say you don't necessarily need to use OpenDoc/CloseDoc because the component is already loaded into memory when the assembly is loaded. Therefore it is enough to call GetModelDoc2 of the child component. But in the end it has the same behaviour and will return nothing if the component is not fully loaded.

set swPart = swChildcomp.GetModelDoc2()