Pack and Go through the UI is fine for a one-off operation. When you’re doing it repeatedly — versioning a drawing before a revision cycle, archiving a job package, moving a drawing to a different project folder with all its references intact — you want a macro that runs Pack and Go, tells you where the new file landed, closes the original, and opens the copy. The SOLIDWORKS API supports all of this via the IPackAndGo interface, but the documentation examples stop at SavePackAndGo and leave the “then open the copy” part as an exercise for the reader.
This post shows a complete working VBA macro. It covers the IPackAndGo interface in enough depth to adapt it to your specific use case, and flags the three edge cases that break most implementations people try.
The IPackAndGo Interface
You get a PackAndGo object from IModelDocExtension.GetPackAndGo — the extension of whatever document is currently active. This works on assemblies, parts, and drawings. For drawings, the returned object includes the drawing file itself plus all referenced models; you have to set IncludeDrawings = True explicitly or the .slddrw is excluded from the packaged file list.
Key properties and methods:
| Member | What it does |
|---|---|
IncludeDrawings | Includes .slddrw files for assemblies/parts (for drawings, keeps the drawing in the file list) |
IncludeSuppressed | Includes suppressed components |
FlattenToSingleFolder | Dumps everything into one flat directory instead of preserving folder structure |
AddPrefix / AddSuffix | Prepends/appends a string to all destination filenames |
GetDocumentNamesCount | Returns the total number of referenced documents |
GetDocumentNames(out names) | Returns original source paths for all documents |
GetDocumentSaveToNames(out paths, out statuses) | Returns destination paths — what the files will be named after Pack and Go runs |
SetSaveToName(True, folder) | Sets the target folder (first argument True means it’s a folder path, not a zip path) |
SetDocumentSaveToNames(names) | Override individual destination paths |
SavePackAndGo(IPackAndGo) | Executes the operation — returns a status array |
The critical relationship: GetDocumentNames and GetDocumentSaveToNames return arrays in the same order. Index 0 in the source array corresponds to index 0 in the destination array. This is the mechanism you use to find the new .slddrw path — match by source extension, then read the corresponding destination path.
Why GetDocumentSaveToNames Is the Right Way to Get the New Filename
The naive approach is to construct the destination path yourself: take the original filename, append your prefix, point it at the destination folder. This breaks as soon as the folder structure gets involved.
When FlattenToSingleFolder = False (the default), Pack and Go mirrors the source directory tree under the destination root. A file at C:\Projects\Rev2\Parts\bracket.sldprt ends up at C:\Destination\Parts\bracket.sldprt. If you also added a prefix, it becomes C:\Destination\Parts\COPY_bracket.sldprt. Constructing that path manually requires replicating SOLIDWORKS’s own path-transformation logic.
GetDocumentSaveToNames does that calculation for you. Call it after setting your prefix, suffix, and destination folder but before calling SavePackAndGo. The returned array reflects exactly where each file will land. Read the .slddrw entry from that array and you have the authoritative new path.
Common Failure: IncludeDrawings Is False When Running From a Drawing
When the active document is an assembly, GetDocumentNames returns the assembly’s parts and sub-assemblies. If you called IncludeDrawings = True, it also returns any .slddrw that references the assembly.
When the active document is a drawing, the drawing file is still excluded from GetDocumentNames unless you set IncludeDrawings = True. This trips up most first implementations: Pack and Go runs, the drawing is copied, but GetDocumentSaveToNames returns no .slddrw entry because the interface was configured as if you were packing the referenced models only.
Always set IncludeDrawings = True when automating Pack and Go from a drawing.
Complete VBA Macro
The macro below:
- Validates that the active document is a drawing
- Configures Pack and Go options
- Calls
GetDocumentSaveToNamesto identify the new.slddrwpath before executing - Runs
SavePackAndGo - Closes the original drawing
- Opens the new drawing
Option Explicit
Sub Main()
Dim swApp As SldWorks.SldWorks
Dim swDoc As SldWorks.ModelDoc2
Dim swExt As SldWorks.ModelDocExtension
Dim swPnG As SldWorks.PackAndGo
Dim origPath As String
Dim destFolder As String
Dim status As Boolean
Dim statuses As Variant
Dim errors As Long
Dim warnings As Long
Dim srcNames As Variant
Dim dstNames As Variant
Dim docStatus As Variant
Dim newDrwPath As String
Dim nCount As Long
Dim i As Long
Set swApp = Application.SldWorks
Set swDoc = swApp.ActiveDoc
If swDoc Is Nothing Then
MsgBox "No document is open."
Exit Sub
End If
If swDoc.GetType <> swDocDRAWING Then
MsgBox "Active document must be a drawing."
Exit Sub
End If
' Save before packing — Pack and Go on an unsaved file produces
' unpredictable results with relative reference paths
swDoc.Save3 swSaveAsOptions_Silent, errors, warnings
origPath = swDoc.GetPathName
destFolder = "C:\PackedDrawings\" ' << change to your target folder
' Get Pack and Go object from the active document's extension
Set swExt = swDoc.Extension
Set swPnG = swExt.GetPackAndGo
' Include the .slddrw itself in the package
swPnG.IncludeDrawings = True
swPnG.IncludeSuppressed = False
swPnG.IncludeToolboxComponents = False
swPnG.FlattenToSingleFolder = True
' Set destination folder (True = folder path, not zip path)
status = swPnG.SetSaveToName(True, destFolder)
' Optionally add a prefix so the copy doesn't overwrite the source
' if source and dest happen to share the same folder
' swPnG.AddPrefix = "COPY_"
' Get count and pre-dimension arrays to match
nCount = swPnG.GetDocumentNamesCount
ReDim dstNames(nCount - 1)
ReDim docStatus(nCount - 1)
' GetDocumentSaveToNames returns paths AFTER applying prefix/suffix
' and folder transformation — this is the authoritative list
status = swPnG.GetDocumentSaveToNames(dstNames, docStatus)
' Find the new drawing path in the destination list
newDrwPath = ""
For i = 0 To nCount - 1
If LCase(Right(CStr(dstNames(i)), 7)) = ".slddrw" Then
newDrwPath = CStr(dstNames(i))
Exit For
End If
Next i
If newDrwPath = "" Then
MsgBox "Drawing not found in Pack and Go file list." & vbCrLf & _
"Check that IncludeDrawings = True."
Exit Sub
End If
' Execute Pack and Go
statuses = swExt.SavePackAndGo(swPnG)
' Verify the new file exists before closing original
If Dir(newDrwPath) = "" Then
MsgBox "Pack and Go finished but new drawing not found at:" & vbCrLf & newDrwPath
Exit Sub
End If
' Close the original
swApp.CloseDoc origPath
' Open the new drawing
Dim newDoc As SldWorks.ModelDoc2
Set newDoc = swApp.OpenDoc6(newDrwPath, swDocDRAWING, _
swOpenDocOptions_Silent, "", errors, warnings)
If newDoc Is Nothing Then
MsgBox "Pack and Go complete, but could not open:" & vbCrLf & newDrwPath & _
vbCrLf & "Errors: " & errors
Else
swApp.ActivateDoc3 newDrwPath, True, swRebuildOnActivation_Always, errors
MsgBox "Done. Opened: " & newDrwPath
End If
End Sub
Edge Cases to Know
The file count after adding a drawing. If you start from an assembly and set IncludeDrawings = True, the drawing count increases. Always call GetDocumentNamesCount after setting IncludeDrawings, not before. The count changes when you toggle that property.
FlattenToSingleFolder and filename collisions. If the assembly references two parts named bracket.sldprt in different subdirectories, flattening produces two files with the same target name. SOLIDWORKS will overwrite one silently. If your drawing references a complex assembly with many vendors contributing identically named parts, keep FlattenToSingleFolder = False and construct the new drawing path by matching against the source origPath in GetDocumentNames.
SavePackAndGo return value. SavePackAndGo returns a Variant array, not a Boolean. A non-empty array means something went wrong. Check it before closing the original document:
statuses = swExt.SavePackAndGo(swPnG)
Dim failCount As Long
failCount = 0
If Not IsEmpty(statuses) Then
Dim j As Long
For j = 0 To UBound(statuses)
If statuses(j) <> swFileSaveError_None Then failCount = failCount + 1
Next j
End If
If failCount > 0 Then
MsgBox failCount & " file(s) failed to pack. Original not closed."
Exit Sub
End If
The drawing must be saved before packing. Pack and Go reads file paths from disk. An unsaved drawing with a temp internal name will produce broken references in the packed copy. The macro above calls Save3 before running — don’t remove that call.
Adapting for Renaming Instead of Prefixing
If you need the packed copy to have a completely different name (not just a prefix), use SetDocumentSaveToNames instead of AddPrefix. This takes an array of destination paths in the same order as GetDocumentNames:
Dim srcNames As Variant
status = swPnG.GetDocumentNames(srcNames)
' Build a parallel array of destination paths
Dim newNames() As String
ReDim newNames(nCount - 1)
Dim srcPath As String
Dim baseFolder As String
baseFolder = "C:\PackedDrawings\"
For i = 0 To nCount - 1
srcPath = CStr(srcNames(i))
Dim fname As String
fname = Mid(srcPath, InStrRev(srcPath, "\") + 1)
' Apply your custom naming logic here
newNames(i) = baseFolder & fname
Next i
' Pass array to SetDocumentSaveToNames
status = swPnG.SetDocumentSaveToNames(newNames)
When SetDocumentSaveToNames is used, AddPrefix and AddSuffix are ignored.
Where This Fits in a Drawing Release Workflow
Pack and Go is the right tool when you need a self-contained copy of a drawing with all its references — not just the .slddrw in isolation. If your drawing references an assembly with 40 parts and 3 sub-assemblies, the packed folder has everything needed to open the drawing on a machine that has never seen those files.
For release workflows where PDM handles the archiving, automate the vault export with PDM Task Scheduler or the Task API instead. Pack and Go is for the non-PDM case: job shops, freelancers, or engineering teams handing off a deliverable to a supplier who doesn’t have access to your vault.
If your use case involves batch exports across multiple drawings — not a single Pack and Go but a sweep across a project folder — the pattern from the batch STEP and DXF export post applies: build a file list, loop, and call the operation in silent mode. The same OpenDoc6 with swOpenDocOptions_Silent works for drawings.
For a broader map of what’s automatable via API versus what needs the Task Scheduler or a full add-in, the SolidWorks workflow automation guide has the decision tree.