A forum thread from 2026-08-06 captures the problem precisely: a user has a manual workflow — roll back to a feature state, show the body, align the view normal to the target face, then do File > Save As DXF. It works. They then try to replicate it in VBA using IPartDoc.ExportToDWG2, pass the same file path, and get either a failed export (False return, no error) or a DXF that contains nothing. No accepted answer exists because the root cause isn’t obvious from the API documentation.
The short answer: manual DXF export from File > Save As is a viewport projection. ExportToDWG2 with Action=0 is face-selection-based geometry extraction. They are fundamentally different export paths that produce similar results when everything is set up correctly — but they require different prerequisites, and the manual workflow’s steps do not map one-to-one to API calls.
What manual Save As DXF actually does
When a user opens a non-sheet-metal part, rolls back the feature tree, aligns the view to look perpendicular to a flat face, and chooses File > Save As > DXF, SOLIDWORKS:
- Takes the current viewport camera direction as the projection normal
- Projects all visible edges from the active document into a 2D plane perpendicular to that camera direction
- Writes those projected curves to a DXF file
This is a dumb projection: SOLIDWORKS takes whatever is visible on screen and flattens it in the current look direction. The “view align” step is how the user tells SOLIDWORKS which face to flatten — by pointing the camera directly at it. The rollback state determines which features are present (and therefore which edges are visible). The body visibility setting determines whether the target body’s edges appear in the projection at all.
This is identical to how IModelDoc2.Extension.SaveAs3() with the DXF filter works in the API — it honours the current view direction.
What ExportToDWG2(Action=0) does
IPartDoc.ExportToDWG2 with Action=0 (swExportToDWG_ExportSelectedFacesOrLoops) is a face-based extraction. It:
- Reads the faces currently selected in the selection manager
- Projects each selected face’s boundary curves and interior edges onto the plane defined by the alignment array
- Writes the resulting 2D curves to the DXF file
No viewport is involved. The camera can be pointing anywhere. The output orientation is controlled entirely by the 12-element AlignmentData array (elements 0–2 = origin, 3–5 = X-axis, 6–8 = Y-axis, 9–11 = face normal).
This is the opposite of sheet metal flat pattern export (Action=1), where the alignment array is silently ignored and the orientation is determined by the fixed face. For Action=0, the alignment array is respected and required.
If no faces are selected when ExportToDWG2 is called with Action=0, the method returns False with no diagnostic. This is the most common cause of silent failure.
The API equivalent of each manual step
Rollback → Feature suppression
The manual rollback bar moves the feature tree to an intermediate state, temporarily removing later features from the part. In the API, there is no direct “move the rollback bar” call for parts (unlike for assemblies where you can edit component suppression). The closest equivalent is suppressing later features:
Dim swFeat As SldWorks.Feature
Set swFeat = swModel.FeatureByName("Cut-Extrude1") ' the feature that covers the target face
swFeat.SetSuppression2 swSuppressFeatureState, swThisConfiguration, Nothing
swModel.EditRebuild3
After calling ExportToDWG2, unsuppress:
swFeat.SetSuppression2 swUnSuppressFeatureState, swThisConfiguration, Nothing
swModel.EditRebuild3
Gotcha: If the feature you’re trying to suppress has children (other features that reference it), suppressing it will also suppress those children. Check the FeatureManager structure before automating this — or use a dedicated export configuration where later features are already suppressed.
An alternative that avoids modifying the active configuration: use IModelDoc2.ShowConfiguration2() to switch to a configuration where the part is in the pre-rollback state, export, then switch back.
Body show → IBody2.Visible
In a multi-body part, bodies can be hidden in the FeatureManager. A hidden body’s faces cannot be selected and won’t appear in a face-based export.
Dim vBodies As Variant
vBodies = swPart.GetBodies2(swSolidBody, False)
If IsNull(vBodies) Or IsEmpty(vBodies) Then
MsgBox "No solid bodies found"
Exit Sub
End If
Dim swBody As SldWorks.Body2
Set swBody = vBodies(0)
swBody.Visible = True
GetBodies2 with the second parameter False returns all bodies including hidden ones. This is important — if you passed True, hidden bodies would be excluded, and you’d get null with nothing to work with.
View align → Face selection + alignment array
This is where the critical difference lies. The manual “align view to face normal” step is replaced by two things in the API:
- Explicitly selecting the target face
- Building the alignment array from the face geometry
You do not need to change the viewport at all.
' Find the largest planar face as the export candidate
Dim swBestFace As SldWorks.Face2
Dim maxArea As Double
maxArea = 0
Dim vFaces As Variant
vFaces = swBody.GetFaces()
Dim i As Long
For i = 0 To UBound(vFaces)
Dim swF As SldWorks.Face2
Set swF = vFaces(i)
Dim swSurf As SldWorks.Surface
Set swSurf = swF.GetSurface()
If swSurf.IsPlane() Then
Dim fArea As Double
fArea = swF.GetArea()
If fArea > maxArea Then
maxArea = fArea
Set swBestFace = swF
End If
End If
Next i
' Select it
swModel.ClearSelection2 True
Dim bSel As Boolean
bSel = swBestFace.Select4(True, Nothing)
If Not bSel Then
MsgBox "Face selection failed. Is the body visible and the document fully resolved?"
Exit Sub
End If
Then build the alignment array from the face normal:
Dim normalArr As Variant
normalArr = swBestFace.Normal ' returns outward normal as Double(2) in metres-space
' Compute an arbitrary X-axis perpendicular to the normal
' Using cross product with world Y (or world Z if normal is near-parallel to Y)
Dim xArr(2) As Double
If Abs(normalArr(1)) < 0.9 Then
' Cross(N, worldY) = (-N_z, 0, N_x)
xArr(0) = -normalArr(2)
xArr(1) = 0
xArr(2) = normalArr(0)
Else
' Cross(N, worldZ) = (N_y, -N_x, 0)
xArr(0) = normalArr(1)
xArr(1) = -normalArr(0)
xArr(2) = 0
End If
' Normalize
Dim xLen As Double
xLen = Sqr(xArr(0) * xArr(0) + xArr(1) * xArr(1) + xArr(2) * xArr(2))
xArr(0) = xArr(0) / xLen
xArr(1) = xArr(1) / xLen
xArr(2) = xArr(2) / xLen
' Y-axis = Cross(N, X)
Dim yArr(2) As Double
yArr(0) = normalArr(1) * xArr(2) - normalArr(2) * xArr(1)
yArr(1) = normalArr(2) * xArr(0) - normalArr(0) * xArr(2)
yArr(2) = normalArr(0) * xArr(1) - normalArr(1) * xArr(0)
Dim alignData(11) As Double
alignData(0) = 0 : alignData(1) = 0 : alignData(2) = 0 ' origin
alignData(3) = xArr(0) : alignData(4) = xArr(1) : alignData(5) = xArr(2) ' X-axis
alignData(6) = yArr(0) : alignData(7) = yArr(1) : alignData(8) = yArr(2) ' Y-axis
alignData(9) = normalArr(0) : alignData(10) = normalArr(1) : alignData(11) = normalArr(2) ' normal
Complete working VBA macro
The following macro combines all of these steps. It finds the largest planar face in the first solid body, selects it, builds the alignment array from the face normal, and exports DXF to the same directory as the part file.
Option Explicit
Private Const SW_SOLID_BODY As Integer = 1
Private Const swSuppressFeatureState As Integer = 1
Private Const swUnSuppressFeatureState As Integer = 0
Private Const swThisConfiguration As Integer = 1
Sub ExportLargestFaceToDXF()
Dim swApp As SldWorks.SldWorks
Set swApp = Application.SldWorks
Dim swModel As SldWorks.ModelDoc2
Set swModel = swApp.ActiveDoc
If swModel Is Nothing Then
MsgBox "No active document open."
Exit Sub
End If
If swModel.GetType() <> swDocPART Then
MsgBox "Open a part document (not an assembly or drawing)."
Exit Sub
End If
Dim swPart As SldWorks.PartDoc
Set swPart = swModel
' --- Get bodies (False = include hidden bodies) ---
Dim vBodies As Variant
vBodies = swPart.GetBodies2(SW_SOLID_BODY, False)
If IsNull(vBodies) Or IsEmpty(vBodies) Then
MsgBox "No solid bodies found. Check feature suppression state."
Exit Sub
End If
Dim swBody As SldWorks.Body2
Set swBody = vBodies(0)
swBody.Visible = True ' ensure visible — hidden bodies cannot be selected
' --- Find the largest planar face ---
Dim vFaces As Variant
vFaces = swBody.GetFaces()
If IsNull(vFaces) Or IsEmpty(vFaces) Then
MsgBox "No faces found on body."
Exit Sub
End If
Dim swBestFace As SldWorks.Face2
Dim maxArea As Double
maxArea = 0
Dim i As Long
For i = 0 To UBound(vFaces)
Dim swF As SldWorks.Face2
Set swF = vFaces(i)
Dim swSurf As SldWorks.Surface
Set swSurf = swF.GetSurface()
If swSurf.IsPlane() Then
Dim fArea As Double
fArea = swF.GetArea()
If fArea > maxArea Then
maxArea = fArea
Set swBestFace = swF
End If
End If
Next i
If swBestFace Is Nothing Then
MsgBox "No planar face found. ExportToDWG2 requires a planar face for Action=0."
Exit Sub
End If
' --- Select the face ---
swModel.ClearSelection2 True
Dim bSel As Boolean
bSel = swBestFace.Select4(True, Nothing)
If Not bSel Then
MsgBox "Face selection failed." & Chr(10) & _
"Is the body visible? Is the document fully resolved?"
Exit Sub
End If
' --- Build alignment array from face normal ---
' For Action=0, the alignment array IS used (unlike sheet metal Action=1 where it is ignored)
Dim normalArr As Variant
normalArr = swBestFace.Normal ' outward normal, 3 doubles
Dim xArr(2) As Double
If Abs(normalArr(1)) < 0.9 Then
xArr(0) = -normalArr(2) : xArr(1) = 0 : xArr(2) = normalArr(0)
Else
xArr(0) = normalArr(1) : xArr(1) = -normalArr(0) : xArr(2) = 0
End If
Dim xLen As Double
xLen = Sqr(xArr(0) * xArr(0) + xArr(1) * xArr(1) + xArr(2) * xArr(2))
xArr(0) = xArr(0) / xLen : xArr(1) = xArr(1) / xLen : xArr(2) = xArr(2) / xLen
Dim yArr(2) As Double
yArr(0) = normalArr(1) * xArr(2) - normalArr(2) * xArr(1)
yArr(1) = normalArr(2) * xArr(0) - normalArr(0) * xArr(2)
yArr(2) = normalArr(0) * xArr(1) - normalArr(1) * xArr(0)
Dim alignData(11) As Double
alignData(0) = 0 : alignData(1) = 0 : alignData(2) = 0
alignData(3) = xArr(0) : alignData(4) = xArr(1) : alignData(5) = xArr(2)
alignData(6) = yArr(0) : alignData(7) = yArr(1) : alignData(8) = yArr(2)
alignData(9) = normalArr(0) : alignData(10) = normalArr(1) : alignData(11) = normalArr(2)
' --- Build output path ---
Dim sModelPath As String
sModelPath = swModel.GetPathName()
If Len(sModelPath) = 0 Then
MsgBox "Save the part first — GetPathName() returned empty."
Exit Sub
End If
Dim sOutPath As String
sOutPath = Left(sModelPath, InStrRev(sModelPath, ".") - 1) & ".dxf"
' --- Export ---
' Action 0 = swExportToDWG_ExportSelectedFacesOrLoops
' ExportAppearances = True (include face appearance colours in DXF)
' SetupSheet = False (no sheet setup)
' SheetScale = 0 (use model units)
Dim bRet As Boolean
bRet = swPart.ExportToDWG2(sOutPath, "", 0, True, alignData, False, 0, Nothing, Nothing)
swModel.ClearSelection2 True
If bRet Then
MsgBox "DXF exported: " & sOutPath
Else
MsgBox "Export failed. Checklist:" & Chr(10) & _
"1. Planar face found and selected? (check above)" & Chr(10) & _
"2. Body visible (swBody.Visible = True)?" & Chr(10) & _
"3. Output directory exists and is writable?" & Chr(10) & _
"4. Part document active (not assembly or drawing)?"
End If
End Sub
The three failure modes you will hit
1. Nothing selected → silent False return
The most common failure. ExportToDWG2 with Action=0 requires at least one face in the selection manager before the call. If ClearSelection2 was called after building the selection, or if Select4 returned False and you didn’t check the return value, the selection manager is empty and the export fails silently.
Fix: Always check bSel = swBestFace.Select4(True, Nothing) and abort if bSel is False.
2. Body hidden → face selection fails
A body that is set to hidden in the FeatureManager cannot be selected programmatically. Select4 returns False without any diagnostic, which leads back to failure mode 1. This reproduces the manual “body show” step — without it, the face doesn’t exist as a selectable object.
Fix: Set swBody.Visible = True before attempting face selection. If the body is in a suppressed feature folder (e.g., inside a suppressed Combine operation), you need to unsuppress the feature first.
3. Alignment array respected for Action=0 but NOT for Action=1
This is the counterintuitive one. The SOLIDWORKS API documentation buries it: for sheet metal flat pattern export (Action=1), the alignment array is silently ignored — the output orientation is determined by the fixed face. For face-based export (Action=0), the alignment array IS used.
If you’re porting code from a sheet metal exporter that passes Nothing or a zeroed-out array for alignment, that code will not work for face-based export. Passing an identity transform without correct X/Y axes produces unpredictable output orientation.
The sheet metal flat pattern DXF export post covers the Action=1 path in detail — including why the alignment array is ignored there and what does control orientation. The two paths are documented separately because they behave differently in enough ways to matter.
When to use Action=0 vs Action=1 vs SaveAs3
| Scenario | Use | Notes |
|---|---|---|
| Sheet metal flat pattern | ExportToDWG2(Action=1) | Alignment array is ignored; orientation = fixed face |
| Non-sheet-metal solid body face | ExportToDWG2(Action=0) | Alignment array controls orientation; face must be selected |
| Multi-body part, one specific face | ExportToDWG2(Action=0) | Ensure target body visible; select exact face |
| Replicate exact manual Save As experience | SaveAs3() with DXF filter | Uses current view direction; matches manual export precisely |
| Drawing view DXF | IDrawingDoc.SaveAs | Different workflow; applies to drawing documents |
If you need the API output to match the manual export exactly — same DXF coordinate system, same origin, same orientation — use SaveAs3() and control the view orientation before calling it. The SaveAs3 path uses the viewport, so you can set the view with swModel.ShowNamedView2("*Top", swStandardViews_e.swTopView) or swModel.ShowNamedView2("*Front", swStandardViews_e.swFrontView) before exporting.
If precision and reliability matter more than matching the manual experience, ExportToDWG2(Action=0) is the better choice — you’re selecting the exact face geometry rather than relying on a viewport projection that can include unintended edges.
Applying this to batch export
For batch DXF export from an assembly, the pattern is:
- Open each part (or activate it from the assembly using
IComponent2.GetModelDoc2) - Check whether the part needs a feature suppressed or a body shown
- Select the target face (by largest area, by a custom property tag, or by geometric criteria)
- Build the alignment array from the face normal
- Call
ExportToDWG2(Action=0)with the path and alignment data - Restore any suppressed features
- Close the document or move to the next component
The SolidWorks workflow automation guide covers the scaffolding for processing multiple files in sequence, including the OpenDoc6 / CloseDoc cycle and silent-open options that prevent the SOLIDWORKS UI from refreshing for each file.
For teams exporting flat patterns from sheet metal assemblies, CadShift handles this loop automatically — including the body visibility checks, fixed-face orientation logic, and post-export DXF normalisation that the raw API does not provide.