こんにちは!SolidWorks自動化の現場で泥臭くも美しいコードを書き続けている、君の専属の先輩エンジニアです。
「マクロの記録」ボタンを押して図面を作り、いざ図面を開いてみたら……ビューの大きさがバラバラ、表題欄のスケール(尺度)は「1:1」のままで大慌て。そんな絶望を味わったことはないかい?
今回は、中級者へのステップアップとして、「図面ビューごとの縮尺を自動判定し、一括補正した上で、表題欄のテキストまで完璧に同期させる」という、実務で即戦力になるマクロを授けよう。
ここをクリアすれば、SolidWorks VBAの本質である「オブジェクトの辿り方」と「APIの呼吸」が手に取るようにわかるようになる。しっかりついてきな!
—
1. なぜ「図面ビューのスケール制御」でみんな躓くのか?
SolidWorksの図面(Drawing)は、3Dモデル(Part/Assembly)の投影図である「ビュー」の集合体だ。
ここで初心者がやりがちな間違いが、「シート全体のプロパティだけでスケールを判断しようとする」こと。
実際の図面では、全体アセンブリのビューは「1:10」、詳細部の拡大ビューは「2:1」のように、ビューごとにスケールが混在するのが当たり前。だからこそ、APIを使って「各ビューが持つ本当の縮尺」を一つずつ剥ぎ取って確認し、ルールに従って補正してあげる必要があるんだ。
そしてもう一つの罠が「表題欄(シートフォーマット)の更新」。
表題欄の文字は、通常の図面ビューとは別のレイヤー(正確にはシートフォーマット領域)に存在するため、普通にアクセスしようとしても跳ね返されてしまう。ここをAPIでどう攻略するか、が見所だよ。
—
2. 全体設計:マクロの動きを俯瞰する
今回のスクリプトが裏側で何をやっているのか、実行の流れを整理しておこう。
1. アクティブな図面ドキュメントを掴む
2. シート上のすべての図面ビュー(DrawingView)を巡回する
3. 各ビューのスケール(分子と分母)を取得する
4. 規定外のスケール(例: 1:1以外、あるいは小さすぎる/大きすぎるもの)を検知し、適切な値に書き換える
5. メインビューのスケールを抽出し、表題欄の「SCALE」などの文字を自動書き換えする
これらをスマートに、かつ堅牢(ロバスト)に実装していく。
—
3. 実装コード:図面ビュー自動補正マクロ
さあ、お待ちかねの実用コードだ。
開発環境(VBE)の標準モジュールにそのまま貼り付けて、すぐに現場でテストできるようにコメントをみっちり入れておいた。コピペして使ってくれて構わないよ。
Option Explicit
‘ ==============================================================================
‘ 【マクロ名】DrawingScaleOptimizer
‘ 【概要】図面内の全ビューの縮尺を自動判定し、指定範囲外のものを補正しつつ
‘ 表題欄の尺度テキストを連動して書き換える実用マクロ
‘ ==============================================================================
Sub DrawingScaleOptimizer()
Dim swApp As SldWorks.SldWorks
Dim swModel As SldWorks.ModelDoc2
Dim swDraw As SldWorks.DrawingDoc
Dim swSheet As SldWorks.Sheet
Dim vViews As Variant
Dim swView As SldWorks.View
Dim i As Long
‘ スケール判定用の変数 (Scale = 1V:DH の分子と分母)
Dim scaleNumerator As Double
Dim scaleDenominator As Double
Dim currentScaleText As String
‘ アプリケーションとアクティブドキュメントの取得
Set swApp = Application.SldWorks
Set swModel = swApp.ActiveDoc
‘ ドキュメントが開かれていない、または図面(Drawing)ではない場合は終了
If swModel Is Nothing Then
MsgBox “ドキュメントが開かれていません。”, vbCritical, “エラー”
Exit Sub
End If
If swModel.GetType() <> swDocDRAWING Then
MsgBox “このマクロは図面ドキュメントでのみ実行可能です。”, vbCritical, “エラー”
Exit Sub
End If
Set swDraw = swModel
Set swSheet = swDraw.GetCurrentSheet
‘ — 【ステップ1】シート上の全図面ビューを取得 —
vViews = swSheet.GetViews()
If IsEmpty(vViews) Then
MsgBox “図面ビューが見つかりませんでした。”, vbExclamation, “警告”
Exit Sub
End If
‘ — 【ステップ2】ビューごとのスケールチェックと補正 —
‘ ※今回は例として「すべての詳細図以外のビューを 1:2 (0.5) に統一する」ロジックにします
Dim targetNumerator As Double
Dim targetDenominator As Double
targetNumerator = 1#
targetDenominator = 2# ‘ 1:2スケールを基準とする
Dim processedCount As Long
processedCount = 0
For i = LBound(vViews) To UBound(vViews)
Set swView = vViews(i)
‘ シートそのものを表すルートビュー(名前がシート名と同じもの)はスキップ
If swView.GetName2() <> swSheet.GetName() Then
‘ 現在のビューのスケールを取得 (Scale = 1V : D)
‘ ※GetScale2 ではなく GetScale だと正確な比率が取れない場合があるため注意
scaleNumerator = swView.ScaleDecimal
‘ デバッグ出力(イミディエイトウィンドウで確認可能)
Debug.Print “ビュー名: ” & swView.GetName2() & ” / 現在のスケール: ” & scaleNumerator
‘ 例:もしスケールが 1:1 (1.0) 以外だったら、強制的に 1:2 に補正する
If scaleNumerator <> (targetNumerator / targetDenominator) Then
‘ 第1引数: 分子, 第2引数: 分母
swView.Scale2 targetNumerator, targetDenominator, True
processedCount = processedCount + 1
End If
‘ メインとなる最初のビューのスケールを表題欄用に保持しておく(ここでは最初のモデルビューを採用)
If currentScaleText = “” Then
currentScaleText = swView.GetScaleName()
End If
End If
Next i
‘ — 【ステップ3】表題欄(シートフォーマット)のテキスト書き換え —
‘ 実際の現場では表題欄のノート(Note)を走査して「SCALE」という文字を探して書き換えます
Call UpdateTitleBlockScale(swModel, currentScaleText)
‘ 画面を最新の状態に再描画
swModel.GraphicsRedraw2
MsgBox “処理が完了しました。” & vbCrLf & _
“スケールを補正したビュー数: ” & processedCount & vbCrLf & _
“適用スケール: ” & currentScaleText, vbInformation, “完了”
End Sub
‘ ==============================================================================
‘ 【サブプロシージャ】表題欄のスケール文字を動的に書き換えるヘルパー関数
‘ ==============================================================================
Private Sub UpdateTitleBlockScale(swModel As SldWorks.ModelDoc2, newScaleStr As String)
Dim swDraw As SldWorks.DrawingDoc
Set swDraw = swModel
‘ シートフォーマットの編集モードに切り替え
swDraw.EditTemplate
Dim swView As SldWorks.View
Set swView = swDraw.GetTemplateView
Dim swAnnotation As SldWorks.Annotation
Dim swTextAnnotation As SldWorks.TextTemplate ‘ あるいは Noteオブジェクト
Dim swNote As SldWorks.Note
‘ テンプレートビュー内のアノテーション(文字など)を走査
Set swNote = swView.GetFirstNote()
Do While Not swNote Is Nothing
‘ ノートのテキスト内容に “SCALE” が含まれていたら書き換える
If InStr(1, swNote.GetText(), “SCALE”, vbTextCompare) > 0 Or _
InStr(1, swNote.GetText(), “尺度”, vbTextCompare) > 0 Then
‘ 表題欄のスケール表記を更新 (例: “SCALE: 1:2” のように整形)
swNote.SetText “SCALE: ” & newScaleStr
Exit Do
End If
Set swNote = swNote.GetNext()
Loop
‘ 通常の図面シート編集モードに戻る
swDraw.EditSheet
End Sub
—
4. エンジニアが知るべき「陥りやすい罠」と回避の極意
このコードを書いていく中で、君が必ず直面するであろう「SolidWorks特有のハマりどころ」を先回りして伝えておくね。
罠1: `GetViews` が返す「ルートビュー」の存在
`swSheet.GetViews()` を実行すると、取得できる配列の最初の要素には、図面ビューそのものではなく「シート(用紙)」を管理するルートビューが含まれることが多い。
これをうっかり通常のビューとして扱って `Scale2` メソッドなどを叩くと、容赦なくエラー(あるいは無視)が起きる。
だからコード内でも `If swView.GetName2() <> swSheet.GetName()` というガード節を設けて、シート自体を誤ってイジらないようにしているんだ。ここ、テストに出るくらい大事だよ。
罠2: シートフォーマット(表題欄)の壁
通常の図面要素は `swModel.Extension` やドキュメント直下から触れるのに、なぜわざわざ `EditTemplate` なんてめんどくさいモード切替を挟んだのか?
それは、SolidWorksの図面が「図面ビューレイヤー」と「シートフォーマット(表題欄)レイヤー」という2つの世界に分かれているからだ。
表題欄の文字を書き換えるには、一時的に「テンプレート編集モード」にトリップし、その中にあるノートオブジェクトを捕まえてテキストを書き換えてから、元の世界(シート編集モード)に生還してこなければならない。このライフサイクルの管理ができてこそ、中級者エンジニアの証だ。
—
5. まとめ:ここをクリアすれば、君はもう初心者じゃない
お疲れ様!今回のスクリプトを通じて、以下のスキルが君の血肉になったはずだ。
- 図面ドキュメント特有の階層構造(シート ➔ ビュー配列)のハック
- ビューごとのスケール値(分子・分母)の取得と動的コントロール
- モード切替(`EditTemplate` / `EditSheet`)を伴う高度なオブジェクト操作
「マクロの記録」では絶対に作れない、現場の痒い所に手が届く実用的な自動化ツールが、これで自分の手で組めるようになったね。
ここをクリアした君なら、次は「パーツのプロパティから自動で材料名を取得して表題欄に流し込む」なんて応用も簡単にできるはずだ。
分からないことがあれば、いつでもこの先輩エンジニアのところに聞きに来るといい。一緒にSolidWorksの限界を超えていこう!
