What Is a SolidWorks Macro? Record One, Then Harden It
What a SolidWorks macro is and how to write one: why recorded code breaks in production, how to harden it, what .swp really means, and 5 rules that hold up.
In This Article
A SolidWorks macro is a small program that runs inside SolidWorks and collapses a series of manual steps into a single command. It is usually written in VBA, stored with a .swp extension, and once run it does its job and ends. Writing a macro means using the SolidWorks API — the two are not rivals; one stands on top of the other.
The real subject of this article is not the definition but the practice. Because almost everyone who starts with macros gets stuck in the same place: they record an operation with the Macro Recorder, run the generated code, and the code either does nothing or does the wrong thing. The reason is not that the recorder is broken — it is that recorded code is, by design, dependent on the screen state at the moment of recording. Below I cover first how to record, then how to strip that dependency out.
Where a macro pays off is clear: work that is rule-bound and repeated. Placing standard views on a drawing, filling in title block fields, exporting STEP files from every part in a folder, bulk-filling custom properties, generating a file name according to a revision rule.
The repetition count is what decides it here. Turning a job you do once a month into a macro usually costs more than doing it by hand; even a rough automation of a job you do ten times a day pays for itself. Rather than guessing which job crosses that threshold, you should measure it — I described the method step by step in how to start an automation project.
If you are curious about where a macro sits technically, and how it relates to the API and add-in architecture, I covered the difference between macros, the API and add-ins in a separate article. The focus here is entirely practical: how to record, how to fix, how to run.
The recorder is the fastest way to learn the API. You perform an operation by hand and SolidWorks writes out the API calls that correspond to it. Instead of searching the documentation for which method on which interface to call, you see it directly.
The flow works like this:
- Start recording. The record, pause and stop commands live under the
Tools > Macromenu; they can also be opened as a separate Macro toolbar. Menu placement changes between versions, so if you cannot find it, typing "macro" into the command search box is the quickest route. - Perform the operation at your normal speed. The recorder captures the commands SolidWorks executes, not your mouse movement. Going slowly or being "tidy" gains you nothing.
- Stop the recording. When you stop, SolidWorks asks you to save the macro. Give it a meaningful name and remember where you put it.
- Open the code.
Tools > Macro > Editopens the macro in the VBA editor.
A small habit: take the recording on a clean document and for a single operation, not in the middle of your real work. Record five operations together and you will spend your time working out which line of the generated code belongs to which operation.
What gets recorded, and what does not
The recorder does not capture everything. What it captures are the commands SolidWorks performs on the document. Among the things it cannot capture:
- View operations (rotating, zooming) — these mostly do not enter the recording, and where they do they have no functional equivalent
- Some settings you make in dialog boxes — the results appear in the code, the intermediate steps do not
- Certain version-specific commands — not every command has a recorder equivalent
So recorded code is not a complete copy of the job you did, but its skeleton. You should read it as a list of hints, not as a recipe.
This is the topic most often skipped, and where people starting with macros lose the most time. Recorded code usually runs but cannot be trusted. For three separate dependencies:
1. Dependence on selection
The recorder generally turns "select this face" into a line resembling: a single selection command saying "select the feature with this name in the document." That name — something like Boss-Extrude1 — belongs to the model you recorded on.
That line looks for the feature carrying that name in that model. If another model has no such name the selection fails — and SelectByID2 does not throw an error, it just returns False. The code carries on, the next line tries to operate on "whatever is selected," and it either blows up or processes the wrong object.
In some cases the recorder generates selection based on coordinates rather than names. Those coordinates are a point in the model you recorded on. When the model changes, something else is at that point.
2. Dependence on the active document
One of the first lines of recorded code is always the same: "get the active document." Whatever file happens to be in the foreground is what gets worked on.
ActiveDoc gives you the document currently in the foreground. If no document is open it returns Nothing. If the macro does not check for this, it stops at first use with an "Object variable not set" error. Worse: if a document of the wrong type is open, it may not error at all. A macro written for a part, run while a drawing is open, silently does nothing — and the user believes the macro worked.
3. Dependence on screen and session state
Recorded code assumes the context at the moment you recorded it: which configuration was active, which sheet was open, which objects were already selected, which unit system the document used. None of this is written in the code — the code simply takes it as given.
Hardening comes down to four moves: getting the active document under control, checking its type, removing the dependence on selection, and checking the result.
Get the active document and verify its type
Every macro should start with this check. This short block cuts off most of the errors you will meet in the field before they happen.
The first job of every macro should be asking two questions: is there a document and is it the right type? So first you get the active document, and if that comes back empty you tell the user "open a part document first" and exit. Then you check the document's type; if you expect a part and an assembly is open, you say "this macro only works on part files" and exit again.
This tiny block cuts off most of the errors you will meet in the field before they surface. And most importantly, it turns silent failure into a loud error: the user now knows why the macro did nothing.
Remove the dependence on selection
Replace the recorded SelectByID2 line with a call that takes the object straight from the model. Selection is a user interface concept; the code has no need of it.
The robust version works like this: you remove the selection command entirely and ask the model for the object directly — "give me the feature with this name." If what comes back is empty, meaning the feature does not exist in this model, the macro stops and tells the user: "the expected feature is not in this model."
The difference is subtle but important: in the first version the macro carried on working on the wrong object; in the second it stops and reports.
There are cases where you genuinely need the selection — for instance when the macro is meant to work on whatever the user has just selected. Then the rule becomes: do not assume the selection, read it and validate it. How many objects are selected, are they the right type, and if not, tell the user.
Check the result
Most API methods return a value, and that value is usually ignored. Even the recorder assigns it to a boolstatus variable and then never checks it.
A concrete example: the call that writes a custom property returns a result code. The recorder assigns that code to a variable but never looks at it. You should look — if the returned value is not what you expected, tell the user "the property could not be written." Since the exact meaning of the returned code can vary by version, it is worth confirming against the documentation for the version you are using.
A warning: the SolidWorks API handles lengths in system units — even if your document displays millimetres, the number you write in code is interpreted as metres. That is why you see values like 0.05 in recorded code. Forgetting this conversion when typing numbers by hand is the most common and most insidious macro bug.
VBA macros are stored with a .swp extension. This file has an important property: it is both the executable program and the source code itself. There is no separate build step; whoever you hand the file to can both run the macro and open, read and change the code inside it.
The practical consequences:
- Sharing is easy. You copy a single file, the other side runs it. No installation.
- The code is open. Sharing the macro means sharing your code. If there is logic you want to restrict, a macro is the wrong container.
- Version tracking is hard. Because it is a binary file, you cannot see line-level differences in tools like Git. There is no answer to "who changed what."
- You do not know who is using which copy. By the third revision of a macro distributed to ten people, you cannot track who is on which version.
The last two items show where a macro's limit begins. When you reach that threshold, the discussion stops being "macro or something else" and becomes an architectural decision — I went into it in moving from a VBA macro to an add-in architecture.
SolidWorks also supports .NET-based macros. That is an intermediate step between a macro and an add-in, and a separate subject.
The VBA editor offers a full debugging environment, and not using it is the biggest waste of time available to you while writing macros.
Breakpoints. Clicking to the left of a line stops the macro on that line. Once stopped, hovering over variables shows you their values.
Stepping. You advance the macro line by line. You see directly which If block it enters and how many times the loop runs. This is the most productive method for understanding recorded code.
The Immediate window. During execution you can ask for the value of an expression, or write to this window from code with Debug.Print. This is how you observe the flow without stopping it with MsgBox — especially inside a loop.
The errors you will meet most often and their causes:
| Symptom | Likely cause |
|---|---|
| "Object variable or With block variable not set" | ActiveDoc returned Nothing, or an object call returned an empty result |
| The macro never errors but never does anything either | The wrong document type is open, or the selection failed and the code silently carried on |
| Right on the first run, wrong on the second | The previous selection was not cleared; the macro is now operating on a different object |
| Dimensions are off by a factor of a thousand | Unit confusion — the API expects metres, millimetres were written in the code |
| It does not work on another computer | A hard-coded file path, or a reference that machine does not have |
The second row of that table is the most expensive one. Output is believed to have been produced and is not; the error is discovered in production.
1. Discipline your naming from the start. Macro1, Macro1_final, Macro1_final_v2 are useless three weeks later. Let the file name say what it does: Drawing_Export_PDF. The same goes for variables inside the code; changing the recorder's Part and boolstatus should be your first job.
2. Check for errors at every step. Is there a document, is the type right, was the object found, did the method return success. The rule is simple: do not pass silently. The cost of skipping a check is ten times the cost of writing it.
3. Think about undo behaviour. If the macro makes many changes to the model, the user may not be able to undo them with a single Ctrl+Z. The SolidWorks API allows several operations to be gathered into one undo step; which methods do this can vary by version, so confirm from the documentation. If you cannot do it, at least tell the user up front.
4. Give the user feedback. When the macro finishes, let it say what it did: how many files were processed, how many were skipped, where the output was written. A macro with no feedback gets checked by hand every time it runs — which takes back the time it saved. This corresponds to the verification item in the four-step measurement framework that explains where automation gains evaporate.
5. Do not assume file paths. A hard-coded path starting with C:\Users\... works on your machine. Derive the path from the document (the folder the model sits in), ask the user, or at the very least check whether the folder exists before writing to it.
Do I need to know programming to write a SolidWorks macro? Not to start; the recorder produces working code. But making that code reliable requires basic VBA — variables, conditions, loops, error checking. The fastest way to learn is to read recorded code by stepping through it line by line.
Why doesn't my recorded macro work on another model? Almost always because of the dependence on selection. The recorder generates code that selects objects by name or by coordinate; that name or coordinate is different in another model. The fix is replacing the selection lines with calls that take the object straight from the model.
What extension does a macro file have? VBA macros use the .swp extension. This file is both executable and the source code itself; there is no separate build step.
How do I add a macro to a toolbar? From the macro tab in the Customize screen you select the macro file and define a button and an icon; a keyboard shortcut can be assigned from the same place. The exact location of the screen can vary with your version.
Are macros and the API different things? No, they are not rivals. When you write a macro you are already calling the API; the API is the access layer and a macro is one of the forms that uses it. I explained the distinction in detail in the macro, API and add-in guide.
The macro runs but the result is wrong. Where should I start? Put a breakpoint on the first line you suspect in the VBA editor and step forward. Confirm from the Immediate window whether the variables really carry the values you expect. Most wrong results come out of a selection that failed without erroring, or a unit conversion.
The order for learning macros is this: record, read, harden.
The recorder shows you which API method to call — far faster than searching the documentation. But the code it produces depends on the selection at that moment, on the open document, and on screen state. A usable macro emerges by stripping those dependencies out one at a time: get the active document under control, verify the type, do not assume the selection, check every return value, tell the user what you did.
Set these five habits up from the start and your third macro gets written far faster than your first — because by then you are starting from the same skeleton every time. You can see the concrete result of an automation that starts at macro level and grows with the process in the SolidWorks CAD automation case study.