Most SolidWorks engineers reach for VBA when they need to automate something. It’s right there in the Tools menu, no build toolchain required, and the macro recorder gives you a starting point for anything the GUI can do. Batch exporting drawings from the PDM vault is exactly this kind of task — repetitive, time-consuming, and automatable. What’s less obvious is where VBA’s limits are, and how to get PDM state awareness without switching to a C# application.

This post covers the VBA path: from the basic folder-loop approach to a PDM-aware export that checks workflow states before touching a file.

The Core Problem: SolidWorks Is Already Open

VBA macros run inside the active SolidWorks session. That sounds convenient, but it creates a subtle issue when you’re batch-processing drawings: you need to open files one at a time, export them, and close them — all while the macro itself is running inside the same SolidWorks instance.

This is the in-process vs standalone distinction. In-process (VBA) shares the COM apartment with SolidWorks, so you’re calling Application.SldWorks to get the already-running instance. Standalone (C# or VB.NET console app) creates a new SolidWorks instance via Activator.CreateInstance. Both work for batch export; they behave differently under error conditions.

The short version: VBA works fine for batch export of drawings that load cleanly. Where it breaks down is when SolidWorks shows a modal dialog (missing reference, broken drawing view, license error) that requires a click — your macro blocks on the dialog and the batch run stops. The SolidWorks API in-process vs standalone guide covers this in depth. For most teams, VBA handles 90% of cases cleanly if you use the right open options.

Approach 1: Local Working Folder Loop (No PDM Dependency)

If your team already syncs files to a local working folder before release — either manually or via Task Scheduler — this is the fastest macro to write and maintain. No PDM references needed.

Option Explicit

Sub BatchExportToPDF()

    Dim swApp As SldWorks.SldWorks
    Dim swModel As ModelDoc2
    Dim sFolder As String
    Dim sFile As String
    Dim sPDFPath As String
    Dim lErrors As Long
    Dim lWarnings As Long
    Dim bRet As Boolean
    
    Set swApp = Application.SldWorks
    
    ' Set your local working folder path here
    sFolder = "C:\PDMWorkingFolder\Products\Drawings\"
    
    ' Ensure trailing backslash
    If Right(sFolder, 1) <> "\" Then sFolder = sFolder & "\"
    
    sFile = Dir(sFolder & "*.slddrw")
    
    Do While sFile <> ""
    
        Dim sFullPath As String
        sFullPath = sFolder & sFile
        
        ' Open silently — suppress missing reference dialogs
        Set swModel = swApp.OpenDoc6( _
            sFullPath, _
            swDocDRAWING, _
            swOpenDocOptions_Silent, _
            "", _
            lErrors, _
            lWarnings)
        
        If Not swModel Is Nothing And lErrors = 0 Then
        
            ' Build output path: same folder, .PDF extension
            sPDFPath = Left(sFullPath, Len(sFullPath) - 6) & "PDF"
            
            bRet = swModel.Extension.SaveAs( _
                sPDFPath, _
                swSaveAsCurrentVersion, _
                swSaveAsOptions_Silent, _
                Nothing, _
                lErrors, _
                lWarnings)
            
            If Not bRet Then
                Debug.Print "Failed: " & sFile & " (error " & lErrors & ")"
            End If
            
            swApp.CloseDoc swModel.GetTitle
            
        Else
            Debug.Print "Could not open: " & sFile & " (error " & lErrors & ")"
        End If
        
        Set swModel = Nothing
        sFile = Dir
        
    Loop
    
    MsgBox "Batch export complete."

End Sub

Critical flag: swOpenDocOptions_Silent. Without it, SolidWorks will show a dialog for every drawing whose referenced .sldprt or .sldasm isn’t in the same folder or on the configured search path. With it, SolidWorks opens the drawing anyway — broken views render as gray cross-hatches — and the export proceeds. The PDF output for a broken drawing won’t have view geometry, which is sometimes acceptable (title block and notes still export) and sometimes not.

To suppress broken-view exports entirely, check the warnings after opening:

' swFileMissing = 2 (warning code for missing references)
' swDocumentWarning_UnresolvedDocuments = 128
If (lWarnings And 128) <> 0 Then
    Debug.Print "Skipped (unresolved refs): " & sFile
    swApp.CloseDoc swModel.GetTitle
    GoTo NextFile
End If

The warning bitmask values are in swOpenWarning_e — check the SolidWorks API help for the full enum.

Approach 2: PDM-Aware Export via EdmLib in VBA

If you need to filter drawings by vault state (exported only “Released” drawings, for example), you can reference EdmLib directly from VBA.

Adding the reference:

  1. Open the macro editor (Tools → Macros → Edit or New)
  2. Go to Tools → References
  3. Browse to C:\Program Files\SOLIDWORKS PDM\EdmInterface.dll (or EdmLib.dll depending on your PDM version)
  4. Check the entry and click OK

Once referenced, you can enumerate the vault from within the macro:

Option Explicit

Sub PDMFilteredExport()

    Dim swApp As SldWorks.SldWorks
    Dim vault As New EdmVault5
    Dim folder As IEdmFolder5
    Dim file As IEdmFile5
    Dim pos As IEdmPos5
    
    Set swApp = Application.SldWorks
    
    ' Connect to vault using cached credentials (PDM client must be logged in)
    vault.LoginAuto "YourVaultName", 0
    
    ' Start from a specific folder in the vault
    Set folder = vault.GetFolderFromPath("\\YourVaultName\Products\Drawings")
    
    Set pos = folder.GetFirstFilePosition()
    
    Do While Not pos.IsNull
    
        Set file = folder.GetNextFile(pos)
        
        ' Filter: only .slddrw in "Released" state
        If LCase(Right(file.Name, 6)) <> "slddrw" Then GoTo NextFile
        
        Dim state As IEdmState5
        Set state = file.CurrentState
        If state.Name <> "Released" Then GoTo NextFile
        
        ' Get local working copy path
        Dim sLocalPath As String
        sLocalPath = file.GetLocalPath(0)
        
        ' Check that the local file exists (vault might not be synced)
        If Dir(sLocalPath) = "" Then
            Debug.Print "Not synced locally: " & file.Name
            GoTo NextFile
        End If
        
        ' Read custom properties for output naming
        Dim sPartNumber As String
        Dim sRevision As String
        Dim fileAttrib As IEdmEnumeratorAttribute
        
        ' PDM custom property access via file attribute
        Dim attrib As IEdmFileAttribute
        Set attrib = file.GetAttributeHandler(EdmAttrib_ByName, "PartNumber")
        If Not attrib Is Nothing Then sPartNumber = attrib.StringValue
        
        Set attrib = file.GetAttributeHandler(EdmAttrib_ByName, "Revision")
        If Not attrib Is Nothing Then sRevision = attrib.StringValue
        
        ' Build output path from PDM properties
        Dim sOutput As String
        Dim sOutFolder As String
        sOutFolder = "C:\ReleasePacket\"
        
        If sPartNumber <> "" Then
            sOutput = sOutFolder & sPartNumber & "_Rev" & sRevision & ".pdf"
        Else
            ' Fall back to filename-based path
            sOutput = sOutFolder & Left(file.Name, Len(file.Name) - 6) & "pdf"
        End If
        
        ' Export using SolidWorks
        Call ExportDrawingToPDF(swApp, sLocalPath, sOutput)
        
NextFile:
    Loop
    
    MsgBox "PDM export complete."
    
End Sub

Sub ExportDrawingToPDF(swApp As SldWorks.SldWorks, sSource As String, sDest As String)

    Dim swModel As ModelDoc2
    Dim lErrors As Long, lWarnings As Long
    
    Set swModel = swApp.OpenDoc6( _
        sSource, swDocDRAWING, _
        swOpenDocOptions_Silent, "", _
        lErrors, lWarnings)
    
    If swModel Is Nothing Or lErrors <> 0 Then
        Debug.Print "Open failed: " & sSource
        Exit Sub
    End If
    
    Dim bRet As Boolean
    bRet = swModel.Extension.SaveAs( _
        sDest, swSaveAsCurrentVersion, _
        swSaveAsOptions_Silent, Nothing, _
        lErrors, lWarnings)
    
    If Not bRet Then
        Debug.Print "Export failed: " & sSource & " err=" & lErrors
    End If
    
    swApp.CloseDoc swModel.GetTitle

End Sub

What GetLocalPath(0) returns: the path where the file would live in the local working folder, whether or not it’s been downloaded. Always check Dir(sLocalPath) before opening — the file might not be synced.

PDM attribute access: The EdmAttrib_ByName approach above reads the file-level custom properties stored in the PDM database, not the SolidWorks model properties. These are the same values set via PDM card edit, which may or may not match what’s in the SolidWorks custom property tab depending on your vault configuration. If you need the SolidWorks model-level properties (the ones from the title block), open the model in SolidWorks and read via CustomPropertyManager — more accurate but slower.

Recursing Into Subfolders

The examples above operate on a single folder. For recursive vault traversal, use GetFirstSubFolderPosition:

Sub TraverseFolder(vault As EdmVault5, folder As IEdmFolder5, swApp As SldWorks.SldWorks)

    ' Process files in current folder
    Dim filePos As IEdmPos5
    Set filePos = folder.GetFirstFilePosition()
    
    Do While Not filePos.IsNull
        Dim file As IEdmFile5
        Set file = folder.GetNextFile(filePos)
        ' ... filter and export as above
    Loop
    
    ' Recurse into subfolders
    Dim subPos As IEdmPos5
    Set subPos = folder.GetFirstSubFolderPosition()
    
    Do While Not subPos.IsNull
        Dim subFolder As IEdmFolder5
        Set subFolder = folder.GetNextSubFolder(subPos)
        TraverseFolder vault, subFolder, swApp
    Loop

End Sub

Call it as TraverseFolder vault, vault.GetFolderFromPath("\\VaultName\Products"), swApp.

Exporting to DXF (Sheet Metal Flat Patterns)

The same macro structure works for DXF export from drawings. Replace the SaveAs extension with .DXF and the format stays default:

' DXF export — works for drawing files (.slddrw)
Dim sDXFPath As String
sDXFPath = Left(sLocalPath, Len(sLocalPath) - 6) & "DXF"

bRet = swModel.Extension.SaveAs( _
    sDXFPath, swSaveAsCurrentVersion, _
    swSaveAsOptions_Silent, Nothing, _
    lErrors, lWarnings)

This exports the drawing sheet as DXF — useful when you have a dedicated flat pattern drawing. If you want to export the flat pattern directly from the part file (not via the drawing), you need IPartDoc.ExportFlatPatternView or ExportToDWG2 — covered in the batch DXF export from SolidWorks guide.

The drawing-based DXF approach has one key advantage: you control exactly what appears on the flat pattern sheet, including annotation layers, bend lines, and any etch sketches. The part-level export is cleaner but strips sheet-level content.

For teams doing this at volume — hundreds of sheet metal parts per release packet — the manual layer mapping and bend line trimming in every export is the bottleneck. CadShift’s batch DXF export handles layer assignment, bend line trimming, and BOM quantity embedding in a single pass, which is where the manual macro approach hits its ceiling.

When VBA Isn’t Enough

VBA is the right tool when:

  • The batch runs occasionally (not nightly scheduled)
  • The engineer running it can be present to dismiss any dialogs that slip through
  • The output format is straightforward PDF or DXF without custom naming logic

Switch to a C# standalone application when:

  • The export needs to run scheduled and unattended
  • You need reliable vault checkin of the exported PDFs (PDM checkin via IEdmFile5.LockFile + UnlockFile is prone to deadlocks in VBA due to STA/MTA apartment issues)
  • Error handling needs to be bulletproof (the standalone app can restart a SolidWorks instance if it hangs, something VBA can’t do from inside the same process)

The SolidWorks PDM Batch Plot guide covers the C# API approach and the Task Scheduler path for scheduled unattended runs.

Running the Macro From PDM

One underused feature: SolidWorks PDM can trigger a macro as part of a workflow transition. In PDM Administration:

  1. Open the workflow editor for your vault
  2. Select a transition (e.g., “Approve” → “Released”)
  3. Add an Action → Run Macro
  4. Specify the .swb or .swp macro file path and optionally a specific subroutine

This lets the export happen automatically when a drawing moves to Released state — no engineer needs to remember to run the batch export. The macro runs in the SolidWorks session that processed the workflow transition, so the user’s SolidWorks must be open. For fully headless execution, the C# Task Host approach is more reliable.

For teams starting out, the folder-loop VBA macro above handles most real-world batch plot needs without infrastructure overhead. Add the EdmLib reference when you need state filtering — the jump from folder loop to PDM-aware export is a reference and about 20 lines of additional code.