こんにちは!SolidWorks VBAの世界へようこそ。
マクロの記録ボタンを押してコードを眺めてみる……うん、最初は誰もがそこからスタートします。でも、少し複雑なアセンブリを組もうとしたとき、こんな絶望感を味わったことはありませんか?
「何百個もの部品を配置して、合致(Mate)をガチガチに組んでいったはいいものの、途中でエラーが起きて処理がストップ。画面には中途半端に散らばったゴミパーツの山……。Ctrl + Z連打でも元に戻せない!」
プログラミング初学者から一歩抜け出そうとするエンジニアが、必ず直面する「アセンブリ自動化の悪夢」です。
今回は、この悪夢を完全に断ち切り、まるで銀行のATMのような「ロールバック可能なトランザクション構造」をSolidWorks VBAで実装する方法を伝授します。
ここをクリアすれば、あなたのVBAコードは「おもちゃ」から「プロの現場で使える堅牢なシステム」へと生まれ変わります。一緒に本質をマスターしていきましょう!
—
なぜ、アセンブリ自動化は途中で失敗するのか?
SolidWorksのAPIは非常に強力ですが、その裏側にあるC++のネイティブエンジンは、VBAの「うっかりエラー」に少しルーズです。
例えば、以下のような状況でエラーが起きたとします。
1. 新規アセンブリドキュメントを開く
2. 部品Aを置く
3. 部品Bを置く
4. 【ここでエラー!】 ファイルパスが間違っていて部品Cがロードできない、あるいは合致の面指定をミスった。
この瞬間、VBAが止まると、「部品AとBだけが中途半端に配置されたアセンブリファイル」がメモリ(またはディスク)に残ります。これを人間が手動で片付けるのは、地獄のような作業ですよね。
プロの解決策:セーフティネット(トランザクション)を張る
データベースの世界では常識ですが、複数の処理を「すべて成功するか、すべて無かったことにするか(原子性:Atomicity)」の単位で管理することをトランザクションと呼びます。
これをSolidWorks VBAで実現するアプローチは以下の通りです。
1. 処理の最初に「今からアセンブリを触るよ」と宣言し、エラー時の脱出ルート(例外処理)を確保する。
2. 万が一、予期せぬエラー(`On Error Goto`)が発生したら、保存せずにアセンブリドキュメントを強制的に破棄(CloseDoc)する。
3. ユーザーの目に触れる画面描画(`Visible` や `EnableRedraw`)を一度フリーズさせ、バックグラウンドで安全に処理を完結させる。
これだけで、途中で何が起きようとも、SolidWorksの環境は一瞬で「実行前の綺麗な状態」に巻き戻されます。
—
実装コード:ロールバック構造を持つアセンブリ構築エンジン
それでは、実際のコードを見てみましょう。
そのままコピペしてVBAエディタ(Module)に貼り付ければ動くように設計しています。今回は「新規アセンブリを開き、部品を配置して、エラーが起きたら綺麗に消し去る」一連の流れを記述しています。
Option Explicit
‘ =================================================================================
‘ 匠のインフラ:アセンブリ構築トランザクション・テンプレート
‘ =================================================================================
Sub Main_AssemblyTransaction()
Dim swApp As SldWorks.SldWorks
Dim swAssyDoc As SldWorks.AssemblyDoc
Dim swModel As SldWorks.ModelDoc2
Dim newDocPath As String
Dim isSuccess As Boolean
‘ 1. 初期化とアプリケーションの取得
Set swApp = Application.SldWorks
If swApp Is Nothing Then
MsgBox “SolidWorksが起動していません。”, vbCritical
Exit Sub
> End If
‘ 2. 画面描画のロック(爆速化&画面のちらつき防止)
swApp.CommandInProgress = True
‘ エラーハンドラ(トランザクションの脱出ルート)の有効化
On Error GoTo ErrorHandler
isSuccess = False
‘ =============================================================================
‘ 【トランザクション開始】ここからアセンブリの構築がスタート
‘ =============================================================================
Debug.Print “— トランザクション開始 —”
‘ ① 新規アセンブリの作成(テンプレートパスは環境に合わせて変更してください)
Set swModel = swApp.NewDocument(“C:\ProgramData\SolidWorks\SolidWorks 202X\templates\アセンブリ.asmdot”, 0, 0, 0)
If swModel Is Nothing Then
Err.Raise vbObjectError + 1, “AssemblyTx”, “新規アセンブリの作成に失敗しました。”
End If
Set swAssyDoc = swModel
‘ ② 部品を配置するシミュレーション(ここではあえて存在しないパスを指定してエラーを誘発してみましょう)
Dim componentPath As String
componentPath = “C:\Test\NonExistentPart.sldprt” ‘ ← 存在しないファイルパス
Dim swComp As SldWorks.Component2
Dim transform As SldWorks.MathTransform
‘ ※この行でファイルが見つからずエラーが発生します
Set swComp = swAssyDoc.AddComponents3(componentPath, 0, 0, 0)
If swComp Is Nothing Then
Err.Raise vbObjectError + 2, “AssemblyTx”, “部品の配置に失敗しました(ファイルが見つかりません)。”
End If
‘ ③ 合致(Mate)の定義などをここに書いていく…
‘ (今回はここまで到達せずにエラーになります)
‘ =============================================================================
‘ 【トランザクション成功】すべての処理が正常に完了
‘ =============================================================================
isSuccess = True
GoTo Finally
‘ =================================================================================
‘ 【例外処理・ロールバック領域】エラー発生時は必ずここにジャンプする
‘ =================================================================================
ErrorHandler:
isSuccess = False
MsgBox “エラーが発生しました。” & vbCrLf & _
“内容: ” & Err.Description & vbCrLf & _
“–> 変更を破棄して初期状態にロールバックします。”, vbExclamation, “トランザクション中断”
‘ =================================================================================
‘ 【クリーンアップ領域】成功・失敗に関わらず必ず実行される終了処理
‘ =================================================================================
Finally:
‘ 画面描画のロックを解除
swApp.CommandInProgress = False
If Not swModel Is Nothing Then
Dim docTitle As String
docTitle = swModel.GetTitle()
If isSuccess = False Then
‘ 失敗時は「保存確認(はい・いいえ・キャンセル)」を出さずに強制閉鎖!
‘ swCloseDoc_DontSave を指定することで、ゴミデータを一切残しません。
swApp.CloseDoc docTitle
Debug.Print “–> ロールバック完了:ドキュメントを破棄しました。”
Else
Debug.Print “–> コミット完了:アセンブリの構築に成功しました。”
End If
End If
End Sub
—
コードの核心:ここがプロの技術
上記のコードで、特に注目してほしい3つのポイントを解説します。
1. `On Error GoTo` と `Finally` パターンの構築
VBAにはJavaやC#のような `try-catch-finally` 構文がありません。そのため、自前でジャンプ先(ラベル)を用意して、安全な終了ルートを担保する必要があります。
処理が成功しようが失敗しようが、必ず `Finally:` ラベルを通る構造にすることで、「画面のロック解除(`CommandInProgress = False`)」の消し忘れを防いでいます。これを忘れるとSolidWorksが操作不能になるので、非常に重要なライフサイクル管理です。
2. `swCloseDoc_DontSave`(変更を保存せずに閉じる)
エラーが起きたとき、もしそのアセンブリがすでにディスク上に保存されていたり、ユーザーに「保存しますか?」とダイアログを出してしまうと大惨事です。
`swApp.CloseDoc` を使うことで、未保存のドキュメントをメモリから綺麗に消去できます。これにより、「失敗した残骸がPCの裏側に残り続ける」という最悪の事態を防ぐことができます。
3. `swApp.CommandInProgress = True` の魔法
これ、あまり知られていない秘技ですが、マクロ実行中にSolidWorksのバックグラウンドで不要な再計算やグラフィック描画が走るのを完全に停止させます。
アセンブリの構築スピードが何倍にも跳ね上がるだけでなく、処理途中の画面の乱れを防ぐため、「プロっぽい」滑らかな動作を実現できます。
—
よくあるエラーと陥りやすい罠
罠:エラー処理の中で別のエラーが起きて無限ループ
初心者がやりがちなのが、`ErrorHandler` の中身でさらにエラーを起こし、VBAが完全にフリーズするパターンです。
これを防ぐため、エラーハンドラ内では「複雑なオブジェクト操作」をせず、「開いているドキュメントを閉じる」「画面ロックを解除する」という最低限の安全処理だけに絞るのが鉄則です。
罠:参照設定やパスのミス
今回のコードでは、存在しないファイルを指定して強制的にエラーを起こさせています。実際に自分の環境で動かすときは、`componentPath` に実在する部品(`.sldprt`)のパスを指定して、まずは成功ルート(Commit)を確認してみてください。その後、わざとパスを書き換えてロールバックの動作テストを行うと、挙動が手に取るように理解できます。
—
まとめ:ここをクリアすれば、SolidWorks VBAの基本はバッチリ!
お疲れ様でした!今回は少し踏み込んだ「アセンブリ構築におけるトランザクション構造」について解説しました。
- 途中で失敗したら、中途半端に残さずすべて捨てる(ロールバック)
- 画面のロックと解除は、例外時も含めて必ずペアで行う
- `CloseDoc` を駆使して、クリーンなメモリ管理を徹底する
この概念が頭に入っていれば、何千個ものパーツを自動配置するような大規模なマクロを組んでも、あなたのSolidWorks環境が汚染されることは二度とありません。
「ただ動くだけのマクロ」から、「実務で安心して使える堅牢なシステム」へ。
あなたのVBAスキルは、確実に次のステージへ到達しました。明日からの開発に、ぜひこの知見を取り入れてみてくださいね!
