空のボディーを一括で削除するマクロ|CATIAマクロの作成方法
今回は「ドキュメント内にある空のボディーを一括で削除するマクロ」の作り方を解説していきます。
『空の形状セットを一括で削除するマクロ』と考え方は同じなので、今回の説明では説明不足と感じる方はそちらのページもあわせて読んでみて下さい。
今回のマクロは主に『Selectionオブジェクト』を使っての操作となっています。
そのため「Selectionオブジェクトとは何ぞや」という人は、先に『Selectionオブジェクト』ページを読むことをオススメします。
完成マクロのイメージ
今回作成するマクロは『空のボディーを一括で削除するマクロ』です。
上のGIF画像を見れば大体わかりますが、このマクロの機能をまとめると以下のとおりです。
・削除したボディーの数をメッセージで表示
・空のボディーが無い場合、その旨をメッセージで表示
・「パーツ ボディー」は空であっても削除しない(削除できないため)
Selectionオブジェクトさえ理解できていればすぐに理解できる内容です!
マクロコード
完成コードは以下のとおりです。
日本語環境のCATIAであれば以下のコードをコピペすれば使用可能です。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
Sub CATMain() Dim SEL As Selection Set SEL = CATIA.ActiveDocument.Selection SEL.Search ("タイプ=ボディー,all") Dim SELCount As Integer SELCount = SEL.Count Dim BodyCount As Integer BodyCount = 0 Dim i As Integer For i = SELCount To 1 Step -1 Dim SELBody As Body Set SELBody = SEL.Item(i).Value If SELBody.Name <> "パーツ ボディー" Then If SELBody.Shapes.Count = 0 And SELBody.Sketches.Count = 0 Then SEL.Clear SEL.Add SELBody SEL.Delete BodyCount = BodyCount + 1 SEL.Search ("タイプ=ボディー,all") End If End If Next i SEL.Clear If BodyCount = 0 Then MsgBox "空のボディーがありません。" Else MsgBox BodyCount & "個のボディーを削除しました。" End If End Sub |
各行でどのような操作を行っているかは下記で解説しているので、VBAを理解したい方はそちらを参照ください。
コード解説
察しのいい方はお気づきかもしれませんが、上から順に処理を行っていくと形状セットが空なのに削除されない場合が出てきます。以下の構成で確認してみましょう。
上から順に処理をしていくと以下のような流れになります。
①「形状セット.1」を確認 →「形状セット.2」が入っているため無視
②「形状セット.2」が確認 → 中身が無いので削除
③「形状セット.3」を確認 →「形状セット.4」が入っているため無視
④「形状セット.4」を確認 →「点.1」「直線.1」が入っているため無視
結果として上から処理をしていくと以下のように空の形状セットが残ってしまいました。
これは一番初めに「形状セット.1」を確認した時に「形状セット.2」が入っていたために起こってしまった現象です。人間の目からすれば「形状セット.2」の中身も空なのでまとめて消してくれよと思いますがプログラムはそう都合よく動いてはくれません。
この問題を解決するにはどうすればいいかを考えると「形状セット.1」を確認させる前にその中に入っている「形状セット.2」の中身を確認させる必要があるということに気づきます。
さらに「形状セット.2」の中に形状セットが入っている場合や、さらにその中に形状セットが入っている場合も考えていくと、一番下にある形状セットから順に中身を確認していく必要があるということがわかります。
処理の結果が変わってきちゃうんですね
ここでは各行で行っている操作を上から順に説明していきます。
『空の形状セットを一括で削除するマクロ』もほとんど同じコードで作成しているので、そちらのページの内容も参考になると思います。
Selectionの定義とボディーの選択
Dim SEL As Selection
Set SEL = CATIA.ActiveDocument.Selection
SEL.Search (“タイプ=ボディー,all”)
Dim SELCount As Integer
SELCount = SEL.Count
はじめに『Selectionオブジェクト』のSearchメソッドを使ってボディーを全範囲(all)で検索し、結果をすべて選択しています。要は「アクティブドキュメント内にあるボディーをすべて選択状態にする」という操作を行っています。
そして選択状態の数(つまりは現在アクティブドキュメントに存在するボディーの数)をカウントし整数型の変数であるSELCountに代入します。
上記のコードを実行するとイメージ的には以下のような操作が行われます。
カウント用の変数の準備
Dim BodyCount As Integer
BodyCount = 0
つぎにカウント用の変数を準備しておきます。
マクロの終了時に、この変数を使って「何個削除したか」を表示します。
この変数は最後の方にでてくるので、ここでカウント用の変数を作ったということだけ頭に入れておけば大丈夫です。
マクロのメイン処理部
Dim i As Integer
For i = SELCount To 1 Step -1
Dim SELBody As Body
Set SELBody = SEL.Item(i).Value
If SELBody.Name <> “パーツ ボディー” Then
If SELBody.Shapes.Count = 0 And SELBody.Sketches.Count = 0 Then
SEL.Clear
SEL.Add SELBody
SEL.Delete
BodyCount = BodyCount + 1
SEL.Search (“タイプ=ボディー,all”)
End If
End If
Next i
つぎにループ文と条件分岐文を使って空のボディーがあった場合に削除するという、このマクロのメインの処理を行っていきます。
内容が複雑なのでループと条件分岐の外枠から順に何をしているのか見ていきましょう。
ループの枠組み
Dim i As Integer
For i = SELCount To 1 Step -1
’ループさせたい処理のコード
Next i
まずは「For~Nxt文」を使ってループ文を作成します。
「Step -1」を付けることでカウント用の変数 i をループ毎に1ずつ減らしていくことが出来ます。
つまり上記のコードの場合、変数 i がSELCount(現在アクティブドキュメントに存在するボディーの数)から1になるまでの間ループし続けます。
ループ毎にボディーの取得
Dim i As Integer
For i = SELCount To 1 Step -1
Dim SELBody As Body
Set SELBody = SEL.Item(i).Value
Next i
次にループカウント用の変数 i を使い、ループ毎にボディーを変数SELBodyに代入します。
「SEL.Item(i)」と『Selectionオブジェクト』のItemメソッドを使うことで、選択状態のオブジェクト(今回の場合はボディー)の中から1つだけを取り出すことができます。
イメージとしては選択状態のオブジェクトは下の画像のようにそれぞれ表すことができます。
選択状態の1番下のものに関しては「SEL.Item(SELCount)」と表すこともできます。
上記のコードではループ文を利用し、ループ毎に変数SELBodyにボディーを代入しています。
たとえば上の画像でいうと2回目のループ時には、下から2番目にある「ボディー.6」がSELBodyに代入されるということです。
これによりすべてのボディーに対して何かしらの操作を行うことができるようになりました。
条件分岐①
Dim i As Integer
For i = SELCount To 1 Step -1
Dim SELBody As Body
Set SELBody = SEL.Item(i).Value
If SELBody.Name <> “パーツ ボディー” Then
‘処理コード
End If
Next i
次に条件分岐をして操作を行うボディーを絞っていきます。
ここの分岐条件は「SELBodyに入っているボディーの名前が”パーツ ボディー”であるか、ないか」です。
もし「パーツ ボディー」でなければ処理を行いますが、「パーツ ボディー」の場合は何も処理を行わないという条件分岐になっています。
これは今回のマクロで行う操作がボディーの削除であるため必要な分岐となっています。
デフォルトで存在している「パーツ ボディー」は削除できないため、この条件分岐をしていないと「パーツ ボディー」の中身が空だった場合にも削除を行おうとしてエラーが発生してしまいます。
そのためボディーの中でも「パーツ ボディー」のみは操作の対象から除外するという意味でこの条件分岐が設けられています。
※逆にいえば「パーツ ボディー」の名称を変更してしまうとこのマクロはうまく作動しないということなので、この部分は各自の使用用途に合わせて条件を書き換えましょう。(たとえば初めにやったすべてのボディー選択時に「パーツ ボディー」のみ選択を解除したり、名称でなくSEL.Item(1)を利用するなど)
条件分岐②
Dim i As Integer
For i = SELCount To 1 Step -1
Dim SELBody As Body
Set SELBody = SEL.Item(i).Value
If SELBody.Name <> “パーツ ボディー” Then
If SELBody.Shapes.Count = 0 And SELBody.Sketches.Count = 0 Then
‘処理コード
End If
End If
Next i
次にさらに条件分岐を追加し操作の対象となるボディーを絞っていきます。
ここの分岐条件は「SELBody内に形状、もしくはスケッチが入っているか、いないか」です。
もし形状、スケッチのどちらも入っていない場合はそのまま処理を行いますが、どちらかが入っている場合は何も処理を行わないという条件分岐になっています。
「Shapes」はパートデザインワークベンチで作成する形状(パッド、ポケット、エッジフィレットなど)の総称です。つまり「SELBody.Shapes.Count」とはSELBodyの中にある形状の数を意味します。「Sketches」はスケッチのことを意味するので、「SELBody.Sketches.Count」とはSELBodyの中にあるスケッチの数を意味します。
つまり上記のコードではSELBodyの中にある形状とスケッチの個数が0個のときに処理を行うという条件分岐をおこなっています。
ボディーに対しての操作
Dim i As Integer
For i = SELCount To 1 Step -1
Dim SELBody As Body
Set SELBody = SEL.Item(i).Value
If SELBody.Name <> “パーツ ボディー” Then
If SELBody.Shapes.Count = 0 And SELBody.Sketches.Count = 0 Then
SEL.Clear
SEL.Add SELBody
SEL.Delete
BodyCount = BodyCount + 1
SEL.Search (“タイプ=ボディー,all”)
End If
End If
Next i
これまでいくつかの条件で絞ってきたボディーに対して「削除」という操作を行います。
ボディーの削除の流れは以下のように行います。
SEL.Clear ① 選択状態をすべて解除
SEL.Add SELBody ② SELBodyのみを選択状態にする
SEL.Delete ③ 選択状態のものを削除
これにより名前が”パーツ ボディー”以外の形状もしくはスケッチの入っていないボディーを、ツリーの下にあるものから順に削除していくことができます。
ただボディー削除の流れで選択状態をすべて解除してしまったので、このままだとループに影響が出てしまいます。これを避けるため「SEL.Search (“タイプ=ボディー,all”)」を使い、もう1度ボディーをすべて選択状態にする必要があります。
これでマクロのメインの処理部の内容は終了です。
後処理
SEL.Clear
If BodyCount = 0 Then
MsgBox “空のボディーがありません。”
Else
MsgBox BodyCount & “個のボディーを削除しました。”
End If
最後にマクロ終了時の処理を行います。
まずはループ用にボディーをすべて選択状態にしていたので、ここで「SEL.Clear」を使ってすべて解除しておきます。(マクロ終了時に選択状態のままでもいいという場合はこのコードは必要ありません)
最後にマクロ完了を兼ねて、削除したボディーの数をメッセージボックスで表示します。またそれと同時に削除したボディーが0個、つまりは空のボディーが無かった場合もその旨をメッセージボックスで表示します。
削除したボディーの数ははじめに宣言していたBodyCountに代入されています。これはマクロのメイン処理部のループ内の「BodyCount = BodyCount + 1 」のコードにより削除毎にカウントしていたためです。
つまりまとめるとBodyCountが0の場合は何も削除しておらず、BodyCountが0でない場合はBodyCount個のボディーが削除されたということです。これをIf文で条件分岐させることでそれぞれの状況に合わせたメッセージを表示することができます。
お疲れさまでした!!
まとめ
今回は「空のボディーを一括で削除するマクロ」のコード解説でした。
コード自体はあまり長くないのですが、解説するとどうしても長くなってしまうため少し理解するのが難しいかもしれません。ただ徐々に理解できるようになっていくため部分ごとに分けて少しずつ理解できるよう勉強を続けることが大事です。
はじめのうちは、こういった既にできているマクロのコードを見るのもいいですが、よりVBAを理解したい場合は実際に自分で考えながらマクロを作るのが一番です。VBAコードを見るのに慣れてきたら自分の考えたオリジナルマクロを作成していきましょう。
CATIAマクロを本気で勉強するなら