【入門編】【上級プロ向け】図面自動生成プロセスにおける「イベント駆動型(Event-Driven)非同期バックアップと例外安全なリトライ機構」 – SolidWorks VBA解析バイブル

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

「マクロが止まったら終わり」を卒業する。図面自動生成をプロのシステムへと昇華させる「堅牢なリトライ機構」の実装術

こんにちは。現場の自動化設計を支えるエンジニアの皆さん。
今日は、少し踏み込んだ、でも「現場で生き残るために絶対に避けては通れない」極めて重要なテーマについてお話ししましょう。

皆さんは、こんな経験はありませんか?
「30分かけて走らせた大規模な図面自動生成マクロが、終了間際でネットワークの瞬断が起き、エラーを吐いて真っ白な状態で止まってしまった……」
「マクロの記録で作ったコードを、なんとなく `On Error Resume Next` でエラーを無視するように書き換えたけれど、どこで何が起きたか分からず、結局データが壊れてしまった……」

もし心当たりがあるなら、おめでとうございます。あなたは今、「スクリプト作成者」から「自動化エンジニア」へ脱皮する境界線に立っています。

今日は、単なるコードの書き方ではなく、「失敗することを前提とした、プロフェッショナルな設計思想」を伝授します。

1. なぜ「マクロの記録」では、プロの現場で通用しないのか?

SolidWorksの「マクロの記録」は、素晴らしい学習ツールです。しかし、記録されたコードには決定的な欠落があります。それは「例外(エラー)への対処」と「状態の管理」です。

「On Error Resume Next」という名の劇薬

初学者が最初に手にする魔法の言葉が `On Error Resume Next` です。これは「エラーが出ても無視して次の行へ進め」という命令です。
しかし、図面生成のような重いプロセスにおいて、これは非常に危険です。

  • ネットワーク切断: 図面を開く瞬間にサーバーとの通信が切れた場合、オブジェクト(`DrawingDoc`)は `Nothing` になります。
  • COM例外: SolidWorksの内部処理が追いつかず、APIが一時的に応答不能になることがあります。

ここでエラーを無視して進むと、存在しないオブジェクトに対して「ビューを配置せよ」という命令が飛び、プログラムは制御不能なクラッシュを引き起こします。「エラーを隠す」のではなく、「エラーを検知し、正しく対処する」。これがプロの設計です。

2. 究極の設計思想:イベント駆動型リトライと例外安全

今回私たちが実装するのは、以下の3つの柱を持つ「セーフティネット機構」です。

1. State Machine(状態管理): 今、図面のどの工程(ファイル作成中、ビュー配置中、保存中)にいるのかを常に記録します。
2. Exponential Backoff Retry(指数バックオフ・リトライ): エラーが起きた際、即座に再試行するのではなく、少し間隔を空けて(例:1秒、2秒、4秒…)再試行します。これにより、ネットワークの復帰を待ちます。
3. Exception Safety(例外安全): もしリトライしてもダメだった場合、中途半端なファイルを残さず、安全にクリーンアップ(終了処理)を行います。

3. 実装コード:堅牢な図面生成エンジンのテンプレート

ここでは、クラスモジュールを活用した高度な構造を紹介します。VBAでクラスを使うのは、プロフェッショナルへの第一歩です。

手順1:クラスモジュール `clsDrawingAutomator` の作成

このクラスが、図面生成の「司令塔」となり、エラーを監視します。

' --- Class Module: clsDrawingAutomator ---
Option Explicit

' 状態を定義するための列挙型
Public Enum GenerationState
    State_Idle
    State_CreatingFile
    State_AddingViews
    State_Saving
    State_Completed
    State_Failed
End Enum

Private swApp As SldWorks.SldWorks
Private currentState As GenerationState
Private maxRetries As Integer

' 初期化
Private Sub Class_Initialize()
    currentState = State_Idle
    maxRetries = 3 ' 最大3回までリトライ
End Sub

' メインの実行メソッド
Public Sub ExecuteDrawingProcess(templatePath As String, savePath As String)
    Dim retryCount As Integer
    Dim success As Boolean
    
    Set swApp = Application.SldWorks
    success = False
    retryCount = 0
    
    ' --- メインループ(リトライ機構) ---
    Do While retryCount <= maxRetries And Not success
        On Error GoTo ErrorHandler
        
        ' 状態に応じて処理を分岐(ステートマシン)
        Select Case currentState
            Case State_Idle, State_CreatingFile
                currentState = State_CreatingFile
                Call CreateDrawingStep(templatePath)
                
            Case State_AddingViews
                Call AddViewsStep()
                
            Case State_Saving
                Call SaveStep(savePath)
                currentState = State_Completed
                success = True
        End Select
        
        ' 成功したらループを抜ける
        If success Then Exit Do
        
ErrorHandler:
        retryCount = retryCount + 1
        Debug.Print "Error encountered at State: " & currentState & ". Attempt: " & retryCount
        
        ' エラーの種類に応じた高度な判定(ここでは簡易的に全てリトライ対象とする)
        If retryCount <= maxRetries Then
            ' 指数バックオフ:リトライ間隔を徐々に伸ばす (1s, 2s, 4s...)
            Dim waitTime As Double
            waitTime = (2 ^ (retryCount - 1))
            Debug.Print "Waiting " & waitTime & " seconds before retry..."
            
            ' VBAで待機するための簡易的なSleep(実際にはAPIを使用)
            Dim startTime As Double
            startTime = Timer
            Do While Timer < startTime + waitTime
                DoEvents ' SolidWorksの操作をブロックしないために重要!
            Loop
            
            ' 状態を「最初からやり直し」にするか「中断した所から」にするかは設計次第
            ' 今回は安全のため、ファイル作成からやり直す設計にします
            currentState = State_Idle 
        Else
            ' リトライ上限に達した場合
            currentState = State_Failed
            MsgBox "致命的なエラーが発生しました。リトライ上限に達しました。", vbCritical
            Call Cleanup
            Exit Sub
        End If
    Loop
    
    If success Then
        MsgBox "図面生成が正常に完了しました!", vbInformation
    End If
End Sub

' --- 各ステップの個別メソッド(ここに具体的なAPI操作を記述) ---

Private Sub CreateDrawingStep(path As String)
    Dim swDoc As SldWorks.DrawingDoc
    Set swDoc = swApp.NewDocument(path, 0, 0, 0)
    If swDoc Is Nothing Then Err.Raise vbObjectError + 513, "CreateDrawing", "Template not found or COM error"
    Debug.Print "Step: File Created"
    ' 次のステートへ
    currentState = State_AddingViews
End Sub

Private Sub AddViewsStep()
    ' ここにビュー配置の複雑なAPI処理を記述
    ' 例: swDoc.CreateDrawViewFromModelView3(...)
    Debug.Print "Step: Views Added"
    currentState = State_Saving
End Sub

Private Sub SaveStep(path As String)
    Dim swModel As SldWorks.ModelDoc2
    Set swModel = swApp.ActiveDoc
    Dim errors As Long, warnings As Long
    
    ' 保存実行
    Dim status As Boolean
    status = swModel.SaveAs3(path, 0, 2) ' 2 = swSaveAsOptions_Silent
    
    If Not status Then Err.Raise vbObjectError + 514, "SaveStep", "Save failed (Network issue?)"
    Debug.Print "Step: Saved"
End Sub

' 異常終了時のクリーンアップ
Private Sub Cleanup()
    Debug.Print "Cleaning up resources..."
    ' 未保存のドキュメントを閉じるなどの処理
    On Error Resume Next
    swApp.CloseDoc swApp.ActiveDoc.GetTitle
End Sub

手順2:標準モジュールからの呼び出し

' --- Standard Module ---
Sub RunProfessionalAutomation()
    Dim automator As New clsDrawingAutomator
    
    Dim template As String
    Dim destination As String
    
    template = "C:\Templates\A3_Standard.drwdot"
    destination = "C:\Output\Part_Drawing_001.SLDDRW"
    
    ' 実行!
    automator.ExecuteDrawingProcess template, destination
End Sub

4. ここが「プロ」の分かれ道:技術的ポイントの解説

このコードには、初心者が陥りがちな罠を回避するための「知恵」が詰まっています。

① `DoEvents` の重要性

リトライ待機中に `Wait` を使う際、ただのループではなく `DoEvents` を入れています。これがないと、待機中にSolidWorksが「応答なし」状態になり、ユーザーが強制終了せざるを得なくなります。「ユーザーの操作権を奪わない」のも、優れたエンジニアの配慮です。

② ステートマシンによる「再開ポイント」の管理

`currentState` 変数によって、「今どこまで進んだか」を管理しています。これにより、エラーが起きた際に「最初からやり直すべきか」「中断した箇所からリトライすべきか」をロジカルに判断できます。

③ 指数バックオフ(Exponential Backoff)

`waitTime = (2 ^ (retryCount – 1))` の部分です。
ネットワークが一時的に不安定な場合、即座に再試行しても失敗する確率が高いです。少しずつ待ち時間を増やすことで、システムが自然に復旧するのを待つ、非常にスマートな回避策です。

5. まとめ:次は、あなた自身のシステムを構築しよう

いかがでしたでしょうか?
「マクロの記録」で得た知識は、いわば「単語」です。しかし、今回紹介したようなリトライ機構や状態管理は、それらを組み合わせて物語を作る「文法」にあたります。

「エラーは起きるもの。だからこそ、どう起きても大丈夫な仕組みを作る」

このマインドセットを持てたとき、あなたの書くコードは「ただの自動化」から「信頼されるシステム」へと進化します。

最初は難しく感じるかもしれません。でも、一つずつクラスモジュールを使い、エラーハンドリングを丁寧に書いていくことで、必ず習得できます。もしエラーにぶつかったら、それは成長のチャンスです。

応援しています。さあ、次の自動化プロジェクトへ踏み出しましょう!

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