A question that surfaces repeatedly on r/MechanicalEngineering and r/SolidWorks: how much C# vs VBA do you actually need for a SolidWorks CAD automation role? The answers in those threads range from “VBA is enough” to “you need modern .NET”—and both are correct, depending on what the role actually involves.

The real answer is architectural: VBA macros and C# COM add-ins solve different problems. Understanding the boundary between them—and being able to explain it—is what separates candidates who have run a few macros from those who can design production automation systems.

What VBA Macros Actually Are

A SolidWorks VBA macro (.swp file) is a VBA script that SolidWorks loads into its own VBA host runtime when the user clicks Tools → Macro → Run. It executes top-to-bottom and exits. When it exits, it is gone—no persistent state, no background threads, no way to receive a SolidWorks event.

VBA macros run inside the SolidWorks process. The API calls cross a COM apartment boundary, but they stay in-process. For operations that traverse small amounts of geometry, this overhead is imperceptible.

The SolidWorks VBA runtime can access the full SolidWorks.Interop.sldworks.dll and SolidWorks.Interop.swconst.dll API surface—identical to what C# uses—through the SolidWorks type library. There is no capability gap at the level of individual API calls.

The gap is architectural.

The Performance Cliff

When a C# program is launched outside SolidWorks (a standalone console app, a Windows Form, a script), it connects to the running SolidWorks instance via Marshal.GetActiveObject("SldWorks.Application"). Every call then crosses two boundaries: a process boundary and a COM apartment boundary. This is classic out-of-process COM marshalling.

The performance difference is not marginal. From measured figures documented in production SolidWorks automation work:

OperationIn-process (VBA macro or C# add-in)Out-of-process (standalone C# app)
GetBodies2 on a part2 ms~200 ms
Traverse 500-component assembly~2 seconds3–5 minutes
Per-call overhead~0.01 ms~0.5–2 ms

A macro that needs to iterate 500 components and check custom properties on each one—fine in VBA. The same logic in a standalone C# process: unusably slow.

A C# COM add-in (loaded in-process, same as VBA) has identical performance to VBA for individual calls. The add-in architecture eliminates the out-of-process penalty entirely.

This is why “use C# instead of VBA” is incomplete advice. The right advice is: if you need persistence or events, use a C# add-in. If you need performance at scale, use a C# add-in. If your task is a one-shot batch operation that can complete before the user gets bored, a VBA macro is fine and faster to build.

The Hard Architectural Wall: What Only Add-ins Can Do

The limitations of VBA macros are not API coverage gaps—they are consequences of the macro lifecycle. A macro exits. Everything that requires a live COM object beyond the end of a macro run is impossible in VBA.

Event handling

SolidWorks events are implemented via COM IConnectionPoint interfaces. To receive a DocumentAdded event, you implement a sink interface and register it via IConnectionPoint.Advise. This requires a live object. When the macro exits, the object is destroyed and the subscription is cancelled.

VBA has no mechanism to stay alive between user actions. Any approach using DoEvents loops to simulate an event-driven pattern blocks the SolidWorks UI and misses events during heavy rebuilds.

Add-ins receive ConnectToSW(object ThisSW, int Cookie) on load and stay alive for the entire SolidWorks session. Every event subscription made in ConnectToSW persists until DisconnectFromSW(). This is the only way to:

  • React to FileOpenNotify2 when a document opens
  • Watch for FeatureManagerDestroyNotify2 on feature suppression
  • Trigger a rebuild check whenever the user changes a configuration
  • Run a background export queue via OnIdle

Property Manager Pages

The sidebar panel that SolidWorks uses for Hole Wizard, Smart Fasteners, and Part Reviewer is a IPropertyManagerPage2 object. It contains dropdowns, listboxes, sliders, checkboxes, selection boxes, and preview buttons—controls integrated with the SolidWorks view context.

VBA has no path to create one. The only alternative in VBA is a chain of InputBox calls, which are modal Windows dialogs with no integration with the 3D viewport.

Add-ins create Property Manager Pages in ConnectToSW and respond to user actions through IPropertyManagerPage2Handler7.

Toolbars and command groups

ICommandManager.AddCommandGroup2 registers a toolbar programmatically that survives SolidWorks version upgrades and applies to all users on a network install. In macros, adding a toolbar button requires each user to manually configure it via Tools → Customize, and the configuration resets when SolidWorks upgrades.

Persistent state

Any task that needs to remember what it did between runs—an export history, a batch queue, a per-session configuration, a progress checkpoint for a multi-hour batch—requires storage outside a macro’s transient execution. Add-ins can maintain in-memory state across the session and write to a state file; macros cannot.

The ISwAddin Interface

A C# COM add-in is a DLL that implements ISwAddin from SolidWorks.Interop.swpublished.dll:

[ComVisible(true)]
[Guid("YOUR-GUID-HERE")]
public class MyAddin : ISwAddin
{
    private ISldWorks _swApp;
    private int _addinCookie;

    public bool ConnectToSW(object ThisSW, int Cookie)
    {
        _swApp = (ISldWorks)ThisSW;
        _addinCookie = Cookie;
        
        // Register event handlers, create command groups, set up PropertyManagerPage
        _swApp.ActiveDocChangeNotify += OnActiveDocChange;
        
        return true;
    }

    public bool DisconnectFromSW()
    {
        _swApp.ActiveDocChangeNotify -= OnActiveDocChange;
        return true;
    }
    
    private int OnActiveDocChange()
    {
        // Runs every time the active document changes — impossible in a VBA macro
        return 0;
    }
}

The add-in is registered in three locations:

  1. HKLM\SOFTWARE\Classes\CLSID\{GUID}\InprocServer32 — standard COM registration. For .NET Framework, the value is mscoree.dll with Assembly, Class, and RuntimeVersion = v4.0.30319 sub-values. For .NET 8+, it points to a comhost.dll generated by the EnableComHosting publish option.

  2. HKLM\SOFTWARE\SolidWorks\AddIns\{GUID} — SolidWorks discovery: Title, Description, icon.

  3. HKCU\Software\SolidWorks\AddInsStartup\{GUID} — per-user startup preference (0 or 1).

The most common failure mode is swLoadAddinError_e.swRegistrationError (error code 6): CoCreateInstance can’t find the DLL because regasm /codebase wasn’t run, or the DLL is in a path SolidWorks can’t load from. The SolidWorks WPF COM add-in assembly resolution fix covers the specific failure mode where satellite assemblies aren’t found.

The .NET Framework Constraint

SolidWorks’s COM shim loads add-ins through mscoree.dll with CLR version v4.0.30319. This means .NET Framework 4.x only—by default. Modern features like Span, nullable reference types, and the new System.Text.Json API are available in .NET Framework 4.8, but async/await patterns and library ecosystem packages that target .NET 8+ are not.

.NET 8 add-ins are possible using EnableComHosting in the .csproj and registering the generated comhost.dll with regsvr32 instead of regasm. This is non-trivial and not the path to start with. The SolidWorks COM add-in vs Inventor modern .NET post explains why Inventor moved to this model and what it takes to replicate it for SolidWorks.

For most production use cases, .NET Framework 4.8 is adequate.

When VBA Is the Right Call

VBA is appropriate when:

  • The task is a one-shot batch operation (export N files to DXF, update N custom properties, check N parts for a condition)
  • The result is needed immediately and the engineer running it will be present
  • Distribution is to a small team who can manage a .swp file

VBA becomes the wrong call when:

  • The batch size is large enough that out-of-process performance would matter (threshold: ~50+ component traversals)
  • The operation needs to trigger automatically on a user action (document open, configuration change)
  • You need a custom UI integrated with the SolidWorks viewport
  • Multiple users need to install and maintain it consistently

The when to upgrade from a SolidWorks macro to a full add-in post works through the decision with specific thresholds.

Portfolio Projects That Demonstrate the Right Skills

Batch DXF export macro. IPartDoc.ExportToDWG2 with sheet metal mode, multi-config support, error handling for parts with no flat pattern. Start here: it teaches you the API surface without the COM registration overhead. The VBA macro DXF export edge cases post documents the six failure modes your portfolio version should handle gracefully.

Assembly traversal with custom property update. IAssemblyDoc.GetComponents(False), iterate, read IModelDocExtension.CustomPropertyManager, write updated values. Demonstrates you understand the difference between component references and the underlying document—a common source of bugs in first-time automation work.

C# COM add-in with a Property Manager Page. IPropertyManagerPage2 with a selection box and a run button. Even a simple one—“select faces, click Export, get DXF”—demonstrates you understand the add-in lifecycle: ConnectToSW, event subscription, IPropertyManagerPage2Handler7.OnButtonPress. This is what separates “has written VBA” from “can ship an add-in.”

Event-driven rebuild watcher. Subscribe to ModelDocExtension.RebuildCompleteNotify. On each rebuild, check a condition and write to a log. No UI needed—the value is demonstrating you understand why this requires an add-in and how the event subscription lifetime works.

BOM to structured output. IBOMTable iteration, configuration-aware BOM reading, JSON or CSV output for ERP handoff. The live BOM from SolidWorks to Excel: native table vs macro vs PDM post covers the three approaches—your portfolio version should handle the case where IBOMTable.GetColumnTitle returns an empty string for custom property columns.

The Transition Path

Most engineers who use SolidWorks API professionally start with VBA macros—they’re faster to write, have zero setup, and work immediately. The natural progression:

  1. VBA macros for one-shot tasks and initial API exploration
  2. C# standalone (out-of-process) for learning C# syntax with familiar SolidWorks API calls—accept the performance penalty during learning
  3. C# COM add-in once you need events, PropertyManagerPage, or production-quality distribution

The SolidWorks API in-process vs standalone comparison explains the performance difference quantitatively if you want the numbers behind step 2 vs 3.

The VBA API knowledge transfers directly. Every interface, method, and enum in SolidWorks.Interop.sldworks.dll is accessible from both VBA and C#. What changes is the plumbing around it—how the object is obtained, how long it lives, and what infrastructure it can subscribe to. Engineers who interview well for CAD automation roles can explain exactly which problems require which architecture and why—not just that they’ve run macros.