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:
- Open the macro editor (Tools → Macros → Edit or New)
- Go to Tools → References
- Browse to
C:\Program Files\SOLIDWORKS PDM\EdmInterface.dll(orEdmLib.dlldepending on your PDM version) - 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+UnlockFileis 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:
- Open the workflow editor for your vault
- Select a transition (e.g., “Approve” → “Released”)
- Add an Action → Run Macro
- Specify the
.swbor.swpmacro 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.