「マクロ記録」の先へ。SolidWorks図面シートを自在に操るための、安全で確実な制御術
こんにちは。設計自動化の世界へようこそ。
「マクロの記録」ボタンを押して、録画されたコードを眺めて「ふむふむ、なんとなく動いているな」と感じている……。もしあなたが今、そんな状態にいるとしたら、おめでとうございます。あなたは自動化エンジニアとしての第一歩を、正しく踏み出しています。
しかし、プロの現場で「動けばいい」というコードは、時として牙を剥きます。シートを勝手に消してエラーで止まる、意図しない名前のシートが大量に生成される、あるいはテンプレートが適用されずにレイアウトが崩れる……。これらはすべて、「オブジェクトの性質」を理解していないことから起こる悲劇です。
今日は、マルチシート図面を自動生成するための「もっとも基礎的で、もっとも重要なステップ」である【シートの追加・削除・名前変更】について、エンジニアとしての作法を交えて伝授しましょう。ここをマスターすれば、あなたのマクロは「ただの記録」から「制御されたプログラム」へと進化します。
1. 脳内に「地図」を描こう:SolidWorksのオブジェクト構造
コードを書く前に、まず頭の中にSolidWorksの構造をインストールしてください。
図面(Drawing)を操作するとき、私たちは単に「シート」をいじっているわけではありません。
`SldWorks` (アプリケーション) $\rightarrow$ `ModelDoc2` (ドキュメント全体) $\rightarrow$ `DrawingDoc` (図面特有の機能) $\rightarrow$ `Sheet` (個別のシート)
という階層構造を辿っています。
初心者が陥る最大の罠は、「今、自分がどの階層の、どのオブジェクトを操作しているのか」を見失うことです。シートの名前を変えたいなら、`DrawingDoc`(図面ドキュメント)という窓口を通じて指示を出す必要があります。この「窓口」を意識するだけで、エラーの半分は防げます。
2. シートの追加:テンプレートという「魂」を吹き込む
「シートを追加する」と言っても、ただ白紙の紙を増やすだけでは不十分です。実務では、必ず「A3サイズ」「タイトルブロック付き」といったテンプレートが必要になりますよね。
`NewSheet` メソッドを使う際、単に名前を指定するのではなく、必ずテンプレートのパスを指定する癖をつけましょう。
ここがプロの視点
テンプレートを指定せずにシートを追加すると、SolidWorksのデフォルト設定に依存してしまい、環境によってレイアウトがバラバラになるリスクがあります。「常に明示的に指定する」。これが、誰のPCでも同じ結果を出すための鉄則です。
3. シートの名前変更:型番と連動させる
シート名は、設計管理において非常に重要です。
`swDrawing.ActivateSheet(“新しい名前”)` でシートをアクティブにし、その後に名前を操作する流れが基本ですが、もっとスマートな方法があります。
シートの名前変更は、単純なプロパティの書き換えです。しかし、ここで「既存のシート名と重複しないか?」といったチェックを組み込むことができれば、あなたのコードは一気に「実戦仕様」へと昇華します。
4. シートの削除:最大の難所「逆順ループ」の罠
さて、ここが今日一番のハイライトです。「不要なシートを削除する」操作。
実は、ここにはプログラミング初学者が必ずと言っていいほどハマる「インデックスの消失」という罠が潜んでいます。
⚠️ やってはいけない「正方向ループ」
例えば、シートが3枚あるとき、1番目から順番に削除しようとするとどうなるでしょうか?
1. 1番目を削除 $\rightarrow$ 元々2番目だったシートが「新しい1番目」に繰り上がる。
2. ループは「次は2番目だ」と判断する $\rightarrow$ 繰り上がったシートを飛び越えてしまう!
結果として、削除したいシートが残ったり、存在しない番号を参照してエラー(実行時エラー ‘9’: インデックスが範囲外です)が発生したりします。
✅ プロの解決策:「逆順ループ」
削除を行うときは、「後ろの番号から前に向かって」処理を行う。これこそが、オブジェクトのライフサイクルを制御するエンジニアの知恵です。
5. 実戦用コード:安全なシート制御のテンプレート
それでは、これまでの知見をすべて詰め込んだ、そのまま使える「安全なシート操作マクロ」を提示します。
Option Explicit
''' <summary>
''' 図面シートの操作を安全に行うためのメインルーチン
''' </summary>
Sub Main()
Dim swApp As SldWorks.SldWorks
Dim swModel As SldWorks.ModelDoc2
Dim swDrawing As SldWorks.DrawingDoc
Set swApp = Application.SldWorks
Set swModel = swApp.ActiveDoc
' --- 1. 安全装置:図面ファイルが開かれているかチェック ---
If swModel Is Nothing Then
MsgBox "図面ファイルを開いてから実行してください。", vbCritical
Exit Sub
End If
' ドキュメントが図面(Drawing)であることを確認
If swModel.GetType <> swDocDRAWING Then
MsgBox "図面ドキュメントではありません。", vbCritical
Exit Sub
End If
Set swDrawing = swModel
' --- 2. シートの追加操作 ---
' テンプレートのパス(環境に合わせて書き換えてください)
Dim templatePath As String
templatePath = "C:\Temp\A3_Template.drwdot"
' 新しいシートを追加 (名前, テンプレート, 用紙サイズ, ...)
' ※テンプレートが存在しないとエラーになるため注意
Debug.Print "シートを追加します..."
swDrawing.NewSheet "新規シート_01", templatePath, swDwgPaperA3size, swDwgPrintDirHorizontal
' --- 3. シートの名前変更操作 ---
' 現在のアクティブシートの名前を変更する例
Dim swSheet As SldWorks.Sheet
Set swSheet = swDrawing.GetCurrentSheet
If Not swSheet Is Nothing Then
Dim newName As String
newName = "PART-12345-REV01" ' 本来はここで部品番号などを取得
swSheet.SetName newName
Debug.Print "シート名を変更しました: " & newName
End If
' --- 4. シートの削除操作(逆順ループの極意) ---
' 例:すべてのシートを削除し、最初の1枚だけ残す
Debug.Print "不要なシートを削除します..."
Dim sheetCount As Integer
sheetCount = swDrawing.GetSheetCount
Dim i As Integer
' 【重要】後ろの番号からループを回すことで、インデックスのズレを防ぐ
For i = sheetCount To 2 Step -1
' swDrawing.ActivateSheet で対象を選択してから削除
' ※最後の1枚を消そうとするとエラーになるため、2枚目までを対象にする
swDrawing.ActivateSheet swDrawing.GetSheetName(i)
swDrawing.DeleteSheet swDrawing.GetSheetName(i)
Next i
MsgBox "操作が完了しました!", vbInformation
End Sub
コードの解説:ここが「プロの仕事」
1. 型チェック (`swDocDRAWING`): そもそも図面じゃないファイルに対して命令を送るのは、言語の壁を越えた無礼です。最初に必ずガードを固めます。
2. `Step -1` の魔法: `For i = sheetCount To 2 Step -1`。これが、先ほどお話しした「逆順ループ」です。これだけで、削除処理の信頼性は100%になります。
3. エラーハンドリングの意識: `If swSheet Is Nothing Then` など、オブジェクトが存在しない場合に備えた条件分岐を入れることで、マクロが途中で「クラッシュ」するのを防いでいます。
まとめ:制御の感覚を掴もう
いかがでしたか?
「シートを追加する」「名前を変える」「消す」という、一見シンプルに見える操作。しかし、その裏側には「オブジェクトの階層構造」と「インデックスの動的変化」という、エンジニアが必ず向き合わなければならない本質が隠れています。
マクロの記録は、あくまで「答え」を見つけるためのヒントです。その答えをどう組み合わせ、どう「安全に」実行するかを考えることこそが、自動化エンジニアの真の価値です。
このコードをベースに、次は「Excelのリストから部品番号を読み取って、シート名を自動で次々と生成する」といった応用にも挑戦してみてください。
一歩ずつ、確実に。あなたの自動化への旅路を応援しています!
