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:

  1. Takes the current viewport camera direction as the projection normal
  2. Projects all visible edges from the active document into a 2D plane perpendicular to that camera direction
  3. 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:

  1. Reads the faces currently selected in the selection manager
  2. Projects each selected face’s boundary curves and interior edges onto the plane defined by the alignment array
  3. 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:

  1. Explicitly selecting the target face
  2. 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

ScenarioUseNotes
Sheet metal flat patternExportToDWG2(Action=1)Alignment array is ignored; orientation = fixed face
Non-sheet-metal solid body faceExportToDWG2(Action=0)Alignment array controls orientation; face must be selected
Multi-body part, one specific faceExportToDWG2(Action=0)Ensure target body visible; select exact face
Replicate exact manual Save As experienceSaveAs3() with DXF filterUses current view direction; matches manual export precisely
Drawing view DXFIDrawingDoc.SaveAsDifferent 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:

  1. Open each part (or activate it from the assembly using IComponent2.GetModelDoc2)
  2. Check whether the part needs a feature suppressed or a body shown
  3. Select the target face (by largest area, by a custom property tag, or by geometric criteria)
  4. Build the alignment array from the face normal
  5. Call ExportToDWG2(Action=0) with the path and alignment data
  6. Restore any suppressed features
  7. 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.