【実務・中級編】【中級者向け】複数コンフィギュレーションを持つアセンブリの全状態をマルチシート図面に自動展開するVBA – SolidWorks VBA解析バイブル

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

【実務直結】複数コンフィギュレーション図面自動展開エンジンの設計思想と実装

「コンフィギュレーションが増えるたびに、手作業で図面シートを増やし、ビューを配置する。そんな非効率な作業に、いつまでエンジニアの貴重な時間を費やすつもりだ?」

もし君が、単に「APIを叩いてビューを出す」だけのコードを書いているとしたら、それは自動化ではなく、単なる「不安定なマクロ」に過ぎない。実務における真の自動化とは、例外処理、メモリ管理、そして設計の拡張性が担保された「プロダクト」を構築することだ。

本記事では、アセンブリ内の全コンフィギュレーションを検知し、それぞれに対応する専用シートを自動生成してビューを配置する、プロフェッショナル仕様の図面生成アルゴリズムを伝授する。

1. 凡庸な設計と、プロフェッショナルな設計の決定的な違い

多くの開発者が陥る罠は、「空のシートを毎回生成し、その都度図面枠(Sheet Format)を流し込む」というアプローチだ。これは極めて非効率である。なぜなら、図面枠の属性(タイトルブロックのプロパティ等)をプログラムから一つずつ制御するのは、計算量もコードの複雑性も跳ね上がるからだ。

私が提唱するアーキテクチャは、「マスターテンプレート・クローニング戦略」である。

設計の要諦

1. Template-Based Approach: 完璧に作り込まれた「雛形シート(Master Sheet)」を1枚用意しておく。
2. Sheet Cloning: 新しいシートを作る際、`NewSheet` ではなく、既存のマスターシートを `CopySheet` する。これにより、図面枠、レイヤー設定、カスタムプロパティの初期設定を瞬時に継承できる。
3. Configuration Injection: クローンしたシートに対して、対象のコンフィギュレーションを指定してビューを注入する。

この設計により、コードは劇的にシンプルになり、実行速度と堅牢性が飛躍的に向上する。

2. 実装コード:マルチシート・コンフィギュレーション展開エンジン

以下に、実務でそのまま利用可能なレベルまで昇華させたVBAコードを示す。単なるコピペではなく、各ブロックが「何を解決しているか」を読み解いてほしい。

Option Explicit

''' <summary>
''' アセンブリの全コンフィギュレーションを走査し、
''' 各コンフィギュレーション専用の図面シートを自動生成する。
''' </summary>
Public Sub GenerateMultiConfigDrawing()
    Dim swApp As SldWorks.SldWorks
    Dim swModel As SldWorks.ModelDoc2
    Dim swDraw As SldWorks.DrawingDoc
    Dim swSheet As SldWorks.Sheet
    Dim vConfigNames As Variant
    Dim configName As Variant
    Dim templateSheetName As String
    Dim i As Integer
    
    ' --- 初期化フェーズ ---
    Set swApp = Application.SldWorks
    Set swModel = swApp.ActiveDoc
    
    ' モデルが図面でない場合はエラー終了(ガード句)
    If swModel Is Nothing Then Exit Sub
    If swModel.GetType <> swDocASSEMBLY Then
        MsgBox "アセンブリファイルを開いた状態で実行してください。", vbCritical
        Exit Sub
    End If
    
    Set swDraw = swModel ' 現在開いている図面を操作対象とする(※注:図面を先に開いておく設計が望ましい)
    ' 本来は、アセンブリから新しい図面を作成するロジックをここに挟む
    
    ' 雛形となるシート名(あらかじめ図面内に作成しておく)
    templateSheetName = "MasterTemplate"
    
    ' コンフィギュレーション名の取得
    vConfigNames = swModel.GetConfigurationNames
    
    ' 画面更新の停止(パフォーマンス最適化)
    swApp.UserControl = False 
    
    On Error GoTo ErrorHandler
    
    ' --- メインループフェーズ ---
    For Each configName In vConfigNames
        ' 1. マスターシートをコピーして新しいシートを作成
        ' CopySheet(Name, TemplateSheetName)
        Dim newSheetName As String
        newSheetName = "Config_" & configName
        
        ' 同名のシートが既に存在する場合は削除するか、名前を変更する処理が必要(実務上の考慮点)
        If Not SheetExists(swDraw, newSheetName) Then
            swDraw.CopySheet newSheetName, templateSheetName
        Else
            ' 既存シートがある場合はスキップ、あるいは再利用のロジック
        End If
        
        ' 2. 作成したシートをアクティブにする
        swDraw.ActivateSheet newSheetName
        Set swSheet = swDraw.GetCurrentSheet
        
        ' 3. ビューの配置
        ' 配置座標(単位はメートル。実務に合わせて調整)
        Dim viewX As Double, viewY As Double
        viewX = 0.15 ' 150mm
        viewY = 0.15 ' 150mm
        
        ' モデルのコンフィギュレーションを指定してビューを作成
        ' CreateDrawingViewFromModelView3(ModelName, ViewName, X, Y, Z)
        Dim swView As SldWorks.View
        Set swView = swDraw.CreateDrawingViewFromModelView3(swModel.GetPathName, "*Isometric", viewX, viewY, 0)
        
        If Not swView Is Nothing Then
            ' ビューにコンフィギュレーションを紐付け
            swView.ReferencedConfiguration = configName
            ' 配置の微調整(必要に応じて)
            swView.ScaleDecimal = 0.5 ' スケール調整
        End If
        
        Debug.Print "Successfully processed: " & configName
    Next configName

    ' --- 終了フェーズ ---
    swModel.ForceRebuild3 True
    MsgBox "全コンフィギュレーションの展開が完了しました。", vbInformation

CleanUp:
    swApp.UserControl = True
    Set swView = Nothing
    Set swSheet = Nothing
    Set swDraw = Nothing
    Set swModel = Nothing
    Set swApp = Nothing
    Exit Sub

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

''' <summary>
''' 指定した名前のシートが図面内に存在するか確認する
''' </summary>
Private Function SheetExists(swDraw As SldWorks.DrawingDoc, sheetName As String) As Boolean
    Dim vSheetNames As Variant
    Dim i As Integer
    vSheetNames = swDraw.GetSheetNames
    
    For i = 0 To UBound(vSheetNames)
        If vSheetNames(i) = sheetName Then
            SheetExists = True
            Exit Function
        End If
    Next i
    SheetExists = False
End Function

3. プロダクション実装における「極限の知見」

コードを書くだけでは不十分だ。現場で「動かない」「壊れた」と言わせないために、以下の3点を叩き込んでおけ。

① メモリ管理とオブジェクトの解放

VBAはガベージコレクションが強力ではない。特にループ内で大量の `View` オブジェクトや `Sheet` オブジェクトを生成する場合、`Set obj = Nothing` による明示的な解放を怠ると、SolidWorks自体のメモリ消費が膨れ上がり、最終的にクラッシュ(強制終了)を招く。大規模アセンブリを扱うなら、これは必須の作法だ。

② `ForceRebuild` の戦略的配置

ループ内で毎回 `Rebuild` を呼び出すのは、パフォーマンスに対する自殺行為だ。図面ビューの計算は非常に重い。

  • Bad: ループ内で毎回 `swModel.ForceRebuild3`
  • Good: 全てのシート作成とビュー配置が完了した後、最後に一度だけ `ForceRebuild3` を実行する。

③ エラーハンドリングの「深度」

`On Error Resume Next` を安易に使うな。それはバグを隠蔽する行為だ。
本コードのように `On Error GoTo ErrorHandler` を使い、エラーが発生した際に「どのコンフィギュレーションで止まったのか」をログに出力、あるいはユーザーに通知する設計にせよ。実務では、特定のコンフィギュレーションに「破損したパーツ」が含まれているだけで、マクロ全体が死ぬことが多々ある。

4. まとめ:自動化エンジニアとしてのマインドセット

自動化とは、単に「楽をするための手段」ではない。「ヒューマンエラーを排除し、設計の品質を一定に保つための品質管理プロセス」だ。

今回紹介した「テンプレート・クローニング戦略」は、保守性が極めて高い。図面枠のデザインが変わっても、マスターシートを修正するだけで、プログラム本体に手を加えることなく全ての自動生成図面に反映される。これこそが、アーキテクトが目指すべき設計思想である。

次に君がコードを書くときは、単なる「動くコード」ではなく、「変更に強く、エラーに負けない、プロフェッショナルな資産」を構築することを意識してほしい。

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