【入門編】【上級プロ向け】大規模マルチシート図面生成時の「COMオブジェクトのメモリリーク完全防止とガーベッジコレクション最適化」 – SolidWorks VBA解析バイブル

スポンサーリンク
スポンサーリンク

数百枚の図面を一括生成しても落ちないために。SolidWorks VBAにおける「COMオブジェクト解放」の極意

こんにちは。設計自動化の世界へようこそ。

「マクロの記録」を使って、なんとか図面の寸法を書き換えるところまではできた。でも、いざ「100枚、200枚の図面をループで一気に生成して保存する」という実戦的なツールを作ろうとすると、途中でSolidWorksがフリーズしたり、「メモリ不足です」と冷たく告げられたりして、途方に暮れてしまったことはありませんか?

実は、そこには「マクロの記録」では絶対に教えてくれない、プロフェッショナルへの登竜門が隠されています。

今日は、大規模な自動化処理を完遂させるために避けては通れない、COMオブジェクトのメモリリーク防止と、劇的な安定化を実現するための設計思想について、じっくりとお話ししていきましょう。ここをクリアすれば、あなたの書くコードは「動くツール」から「現場で信頼されるシステム」へと進化します。

1. なぜ、あなたのマクロは「途中で力尽きる」のか?

まず、敵の正体を知ることから始めましょう。

SolidWorks VBAが操作しているのは、VBAそのものではなく、背後で動いているSolidWorks本体(COMオブジェクト)です。

VBAで `Set swApp = Application.SldWorks` と書いた瞬間、VBAとSolidWorksの間には「接続(参照)」が生まれます。この接続は、あなたが「もう使い終わったよ」と明示的に伝えない限り、SolidWorks側は「まだこのデータを使っているんだな」と判断して、メモリの中に大切に抱え込み続けます。

これを繰り返すとどうなるでしょうか?

1. 1枚目の図面を開く $\rightarrow$ メモリに確保
2. 2枚目の図面を開く $\rightarrow$ メモリに確保(1枚目はそのまま)
3. …
4. 100枚目の図面を開く $\rightarrow$ メモリがパンパンになり、SolidWorksが窒息してクラッシュ!

これが、大規模処理におけるメモリリーク(メモリ漏れ)の正体です。

2. 概念図:オブジェクトの「参照カウント」を理解する

VBAの世界では、オブジェクトがメモリに留まる仕組みを「参照カウント」と呼びます。

想像してみてください。図面という「本」があります。

  • あなたがその本を手に取ると、カウントは 1 になります。
  • 別の変数(別の指)でもその本を指すと、カウントは 2 になります。
  • カウントが 0 になったとき(誰もその本を指さなくなったとき)、初めて本は本棚(メモリ)から片付けられます。

プロのエンジニアは、このカウントを「意図的にゼロにする」技術に長けています。

3. 【実践】メモリリークを封じ込める「黄金の解放パターン」

では、具体的にどう書けばいいのか。数百枚の図面を生成・配置する際の、最も堅牢なコード構造を見てみましょう。

ポイントは、「使い終わったら、逆順で、徹底的に、Nothingを代入する」ことです。

Option Explicit

' ==============================================================================
' テーマ: 大規模図面生成におけるメモリ管理の最適化
' 概要: ループ内でオブジェクトを適切に解放し、メモリリークを防止する
' ==============================================================================
Sub GenerateMassiveDrawings()
    Dim swApp As SldWorks.SldWorks
    Dim swModel As SldWorks.ModelDoc2
    Dim swDraw As SldWorks.DrawingDoc
    Dim swSheet As SldWorks.Sheet
    Dim swView As SldWorks.View
    Dim i As Integer
    Dim filePath As String
    
    ' 1. SolidWorksアプリケーションへの接続
    Set swApp = Application.SldWorks
    
    If swApp Is Nothing Then
        MsgBox "SolidWorksを起動してください。"
        Exit Sub
    End If

    On Error GoTo ErrorHandler

    ' --- 大規模ループ開始 ---
    For i = 1 To 100 ' 例として100枚の処理
        
        ' [重要] 処理のたびに、新しいファイルパスを生成
        filePath = "C:\Temp\Drawing_Part_" & i & ".SLDDRW"
        
        ' 2. 図面の新規作成(またはテンプレートから作成)
        ' ここでは例として新規作成
        Set swModel = swApp.NewDocument("C:\Temp\Template.drwdot", 0, 0, 0)
        
        If Not swModel Is Nothing Then
            Set swDraw = swModel
            
            ' --- 図面操作のメインロジック ---
            ' シートの制御
            Set swSheet = swDraw.GetCurrentSheet
            swSheet.SetName "Sheet_" & i
            
            ' ビューの配置(例)
            Set swView = swDraw.CreateDrawViewFromModelView3("C:\Temp\Part_" & i & ".SLDPRT", "*Front", 0.1, 0.1, 0)
            
            ' --- 図面の保存 ---
            swModel.SaveAs3 filePath, 0, 2
            
            ' 3. 【超重要】ドキュメントを閉じる
            ' 変数を Nothing にする前に、まず物理的にドキュメントを閉じる
            swApp.CloseDoc swModel.GetTitle
            
            ' -------------------------------------------------------
            ' 4. 【黄金の解放パターン】オブジェクトのライフサイクルを終了させる
            ' 参照の深いもの(子)から、浅いもの(親)へと順に Nothing を代入します
            ' -------------------------------------------------------
            Set swView = Nothing    ' ビューを解放
            Set swSheet = Nothing   ' シートを解放
            Set swDraw = Nothing    ' 図面ドキュメントを解放
            Set swModel = Nothing   ' モデルドキュメントを解放
            
            ' 5. OSに制御を戻し、メモリの整理を促す
            ' これを入れることで、ループ中のフリーズを防ぎ、安定性が劇的に向上します
            DoEvents 
        End If
        
        Debug.Print i & "枚目の処理が完了しました。"
    Next i
    ' --- ループ終了 ---

    MsgBox "すべての図面生成が正常に完了しました!", vbInformation
    
CleanUp:
    ' 最後にメインのオブジェクトを解放
    Set swApp = Nothing
    Exit Sub

ErrorHandler:
    MsgBox "エラーが発生しました: " & Err.Description, vbCritical
    Resume CleanUp
End Sub

4. プロが実践する「安定化のための3つのテクニック」

コードを書く際、以下の3点を意識するだけで、あなたのマクロの信頼性は別次元になります。

① `DoEvents` の魔法

ループの中に `DoEvents` という命令を忍ばせておきましょう。これは「一旦、Windowsの他の処理(画面更新やマウス操作など)に時間を譲ってあげてね」という命令です。これがないと、マクロがCPUを占有しすぎて、SolidWorksが「応答なし」状態になりやすくなります。

② 「逆順解放」の原則

オブジェクトには階層構造があります。
`Application` $\rightarrow$ `Document` $\rightarrow$ `Sheet` $\rightarrow$ `View`
解放するときは、この逆、つまり `View` $\rightarrow$ `Sheet` $\rightarrow$ `Document` の順で行うのが、メモリ管理における最も美しい作法です。親を先に消そうとすると、子が迷子(浮いたオブジェクト)になり、リークの原因になります。

③ `CloseDoc` と `Set … = Nothing` は別物

ここが一番の間違いやすいポイントです。

  • `swApp.CloseDoc`:SolidWorksの画面からファイルを取り除く(物理的な動作)
  • `Set swModel = Nothing`:VBAがそのファイルを指し示すのをやめる(参照の解除)

両方セットで行うこと。 これが大規模処理を完遂させる鉄則です。

最後に:一歩上のエンジニアへ

ここまで読んでくれたあなたは、もう単なる「マクロ記録の利用者」ではありません。オブジェクトのライフサイクルを意識し、システムの挙動をコントロールしようとする「エンジニア」への階段を登り始めています。

最初は「`Set … = Nothing` を書くのが面倒だな」と感じるかもしれません。しかし、深夜に自動化ツールがクラッシュして、数時間の作業が水の泡になる絶望感を味わった後では、この数行がいかに尊いものか、痛いほどわかるはずです。

一歩ずつ、確実に。
堅牢なコードを積み上げて、素晴らしい自動化の世界を楽しんでくださいね。応援しています!

タイトルとURLをコピーしました