空の形状セットを一括で削除するマクロ|CATIAマクロの作成方法
ここでは簡単なマクロを例にマクロ作成の流れを解説していきます。
今回作成するマクロは「ドキュメント内にある空の形状セットを一括で削除するマクロ」です。
VBAの書き方の説明を読んでいるより、実際にマクロを作成した方がより深くVBAを理解できます。
今回のマクロは主に『Selectionオブジェクト』を使っての操作となっています。
そのため「Selectionオブジェクトとは何ぞや」という人は、先に『Selectionオブジェクト』ページを読むことをオススメします。
![](https://i0.wp.com/liclog.net/wp-content/uploads/2019/08/8b7189979aefafdf63a9254eee23b8d4.jpg?resize=96%2C96&ssl=1)
完成マクロのイメージ
今回作成するマクロは『空の形状セットを一括で削除するマクロ』です。
上のGIF画像を見れば大体わかりますが、このマクロの機能をまとめると以下のとおりです。
・削除した形状セットの数をメッセージで表示
・空の形状セットが無い場合、その旨をメッセージで表示
機能自体も少なく単純なマクロですが、実用性は結構高めなのでぜひ作成してみて下さい。
![](https://i0.wp.com/liclog.net/wp-content/uploads/2019/08/8b7189979aefafdf63a9254eee23b8d4.jpg?resize=96%2C96&ssl=1)
Selectionオブジェクトさえ理解できていればすぐに理解できる内容です!
※※Selectionオブジェクトの詳細は下記ページを確認ください※※
マクロの処理のフロー(流れ)を考える
まず作成する前にマクロの処理の流れを考えます。
今回は簡単なフローチャートを用意しておいたので、以下のフローチャートを見ながらマクロの処理の流れを見ていきましょう。
いろいろ書いてありますが以下のポイントさえ押さえておけば大丈夫です。
・仕様ツリーの”下から順”に形状セットの中身を確認していく
└ 形状もしくは形状セットが入っている場合、その形状セットは無視
└ 形状もしくは形状セットが入っていない場合、その形状セットを削除
・すべての形状セットを確認し終えたら終了
ここで重要なのは仕様ツリーの下にある形状セットから順に処理をしていくという点です。
マクロの流れがつかめたら、つぎは実際にコードを書いていきましょう。
察しのいい方はお気づきかもしれませんが、上から順に処理を行っていくと形状セットが空なのに削除されない場合が出てきます。以下の構成で確認してみましょう。
上から順に処理をしていくと以下のような流れになります。
①「形状セット.1」の中身を確認 →「形状セット.2」が入っているため無視
②「形状セット.2」の中身を確認 → 中身が無いので削除
③「形状セット.3」の中身を確認 →「形状セット.4」が入っているため無視
④「形状セット.4」の中身を確認 →「点.1」「直線.1」が入っているため無視
結果として上から処理をしていくと以下のように空の形状セットが残ってしまいました。
これは一番初めに「形状セット.1」を確認した時に「形状セット.2」が入っていたために起こってしまった現象です。人間の目からすれば「形状セット.2」の中身も空なのでまとめて消してくれよと思いますがプログラムはそう都合よく動いてはくれません。
この問題を解決するにはどうすればいいかを考えると「形状セット.1」を確認させる前にその中に入っている「形状セット.2」の中身を確認させる必要があるということに気づきます。
さらに「形状セット.2」の中に形状セットが入っている場合や、さらにその中に形状セットが入っている場合も考えていくと、一番下にある形状セットから順に中身を確認していく必要があるということがわかります。
![](https://i0.wp.com/liclog.net/wp-content/uploads/2019/08/8b7189979aefafdf63a9254eee23b8d4.jpg?resize=96%2C96&ssl=1)
処理の結果が変わってきちゃうんですね
実際にコードを書いてみよう
ではフローチャートに従って実際にマクロのコードを書いていきましょう。
① ドキュメント内にある「形状セット」をすべて検索&選択
形状セットの検索&選択は『Selectionオブジェクト』のSearchメソッドで実行可能です。
まずはSelectionオブジェクトを宣言/定義します。
Dim SEL As Selection
Set SEL = CATIA.ActiveDocument.Selection
Selectionオブジェクトの定義ができたら、SelectionオブジェクトのSearchメソッドを使って「形状セット」の検索&選択の操作を行います。
SEL.Search (“ジェネレーティブ・シェイプ・デザイン.形状セット,all”)
このコードにより仕様ツリーの上にある形状セットから順にすべての形状セットが選択されます。
![](https://i0.wp.com/liclog.net/wp-content/uploads/2019/08/8b7189979aefafdf63a9254eee23b8d4.jpg?resize=96%2C96&ssl=1)
ツリーの上から順に選択されるというところが”ミソ”ですね
これでフローチャートの①のコードは完了です。
いままでのコードをまとめると以下のとおりです。
1 2 3 4 5 6 7 8 |
Sub CATMain() Dim SEL As Selection Set SEL = CATIA.ActiveDocument.Selection SEL.Search ("ジェネレーティブ・シェイプ・デザイン.形状セット,all") End Sub |
このコードを実行するとアクティブドキュメント内の形状セットをすべて選択することができます。
実際に以下のような構成をテキトーに用意して実行して結果を確認してみましょう。
日本語以外の操作環境で上記のコードは使用できないので注意して下さい。
使用できない場合は以下の方法で自身の環境にあったコードを取得する必要があります。
・
![](https://i0.wp.com/liclog.net/wp-content/uploads/2019/10/cc3a6b5c8850849e0be5272c4413df70.png?resize=22%2C22&ssl=1)
・『マクロの記録』を使って
![](https://i0.wp.com/liclog.net/wp-content/uploads/2019/10/cc3a6b5c8850849e0be5272c4413df70.png?resize=22%2C22&ssl=1)
② 検索結果の個数を取得
②では「C = 検索結果の個数」という処理、つまりは検索結果の個数を変数におく処理をしています。
検索結果の個数は現在選択している形状セットの数とイコールです。
現在選択しているオブジェクトの数は『Selectionオブジェクト』のCountプロパティで表すことができます。つまり整数型の変数を宣言し、その中にSelectionオブジェクトのCountプロパティを代入すれば検索結果の個数を取得したことと同義になります。
Dim SELCount As Integer
SELCount = SEL.Count
(※フローチャートでは長いと見づらくなるため「Count」の頭文字「C」を使って表していましたが、マクロのコードは後から見てもわかるような「SELCount」という名前にしておきます)
選択状態のオブジェクトの数が取得できているか確認したい場合は、以下のコードを最後に付け加えて実行してみて下さい。メッセージボックスで取得している個数を表示してくれます。
MsgBox “現在選択しているオブジェクトは” & SELCount & “個です。”
※確認ができたらこの文は邪魔になるので消しておきましょう。
③(④⑦) ループ文の枠組みを作成
③のかたまりは④と⑦の処理からCが0になるまでループ処理を行うことがわかります。
数字が1つずつ減っていき0になったらループを抜けるという処理はFor~Next文とStepを使えば再現することができます。
個人的にFor~Next文を動かすときの変数は「i」「j」をよく使うので、ここでも変数 i を使ってループ文を作成していきます。まずはループの中身は気にせずに枠組みだけ用意しておきます。
Dim i As Integer
For i = SELCount To 1 Step -1
’ループ処理内容
Next i
この枠組みにより変数 i がSELCount(選択状態のオブジェクトの数)から1になるまでループさせることができます。ループは変数 i が0になる前に終了させたいので1までの範囲にします。
次にこの枠組みの中にループさせる処理を書き込んでいきます。
フローチャートでいう⑤⑥⑧⑨の処理は全てこのループ内に組み込まれます。
⑤ 選択状態の形状セットの中でC番目にある形状セットの確認
現在選択している形状セットはすべて、『Selectionオブジェクト』の「Itemメソッド」を使って表すことができます。
たとえば「SEL.Item(1)」と書けば、選択状態の中で1番上にある形状セットのことを表します。
「SEL.Item(2)」と書けば2番目、「SEL.Item(3)」と書けば3番目、「SEL.Item(SELCount)」と書けば一番下にある形状セットを表すことができます。
![](https://i0.wp.com/liclog.net/wp-content/uploads/2019/08/8b7189979aefafdf63a9254eee23b8d4.jpg?resize=96%2C96&ssl=1)
Itemメソッドで表しやすいですね!
ここで先ほど宣言した変数 i はどういう変化をする変数だったかを思い出してみましょう。
先ほどのループにより変数 i はSELCount(選択状態のオブジェクトの数)から1に変化します。
つまりループ処理の中で形状セットのことを「SEL.Item(i)」と表せば、1番下にある形状セットから順にすべての形状セットを処理することができます。
毎回「SEL.Item(i)」と書くのは面倒なので以下のよう書いて変数としておきます。
Dim SELHB As HybridBody ‘形状セット(HybridBody)として宣言
Set SELHB = SEL.Item(i).Value ‘オブジェクトとして代入する場合は.「Value」が必要
以降ではループ内の形状セット(フローチャートでいう「C番目にある形状セット」)はこのSELHB を使って表していきます。
いままでのコードをまとめると以下のとおりです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
Sub CATMain() Dim SEL As Selection Set SEL = CATIA.ActiveDocument.Selection SEL.Search ("ジェネレーティブ・シェイプ・デザイン.形状セット,all") Dim SELCount As Integer SELCount = SEL.Count Dim i As Integer For i = SELCount To 1 Step -1 Dim SELHB As HybridBody Set SELHB = SEL.Item(i).Value Next i End Sub |
⑥ 形状セットの中身によって処理を分岐させる
フローチャートに書かれているとおり、ここでは形状セット(SELHB)の中に「形状」もしくは「形状セット」が入っているかの確認を行います。
確認した結果によって処理の内容を以下のように変えます。
「形状」もしくは「形状セット」が入っているか?
YES ⇒ 何も処理は行わない
NO ⇒ 形状セット(SELHB)を削除
条件分岐をするにはIf文を使います。
If文の分岐条件は先にもいっているとおり形状セット(SELHB)の中に「形状」もしくは「形状セット」が入っているかです。
SELHBの中の形状については『HybridBodyオブジェクト』のHybridShapesプロパティを、SELHBの中の形状セットについては『HybridBodyオブジェクト』のHybridBodiesプロパティを使って以下のように書きます。
If SELHB.HybridBodies.Count = 0 And SELHB.HybridShapes.Count = 0 Then
それぞれSELHB.HybridBodies.CountはSELHB内の形状セットの数を、SELHB.HybridShapes.CountはSELHB内の形状の数をそれぞれ表しています。
つまり上記のコードは[形状セット(SELHB)の中に「形状」と「形状セット」がない場合]という条件を意味しています。
この条件の場合は「形状セット(SELHB)を削除」という処理を行う必要があります。
⑧ 形状セット(SELHB)を削除
形状セットの削除は『Selectionオブジェクト』の「Deleteメソッド」を使いますが、そのまま使ってしまうとうまく実行することができません。
たとえばここで「SEL.Delete」と書くとどうなるでしょうか。
現在は全ての形状セットが選択されている状態です。
この状態でDeleteメソッドを使うと全ての形状セットを削除してしまいます。
そのため一旦『Selectionオブジェクト』の「Clearメソッド」を使い全ての選択状態を解除します。
解除したら『Selectionオブジェクト』の「Addメソッド」を使いSELHBのみを選択状態とします。
この状態にしてからDeleteメソッドを使えばSELHBのみを削除することができます。
上記の流れをコードで書くと以下のようになります。
SEL.Clear
SEL.Add SELHB
SEL.Delete
これで形状セットの削除は完了です。
ただこの処理を行うことで今まで形状セットを選択していた状態が解除されてしまいました。
このままではループの最中に「SEL.Item(i).Value」の部分で数が合わなくなりエラーが発生してしまいます。
という訳でここでもう1度検索&選択の操作を入れ、全ての形状セットを選択状態にします。
こうすることで再びすべての形状セットが選択され問題なくループが成立します。
SEL.Search (“ジェネレーティブ・シェイプ・デザイン.形状セット,all”)
以上で分岐後の処理は終了です。
条件分岐文の部分のコードをまとめると以下のようになります。
If SELHB.HybridBodies.Count = 0 And SELHB.HybridShapes.Count = 0 Then
SEL.Clear
SEL.Add SELHB
SEL.Delete
SEL.Search (“ジェネレーティブ・シェイプ・デザイン.形状セット,all”)
End If
形状セット削除でない方の分岐では何も処理は行わないため「Else」を使う必要もありません。
ベースコードの完成
これですべての処理をコードで書くことができました。
今までのコードをすべてまとめると以下のようになります。
※ループ終了後も形状セットが選択状態だったため、最後から2行目で選択状態の解除をしています。
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 |
Sub CATMain() Dim SEL As Selection Set SEL = CATIA.ActiveDocument.Selection SEL.Search ("ジェネレーティブ・シェイプ・デザイン.形状セット,all") Dim SELCount As Integer SELCount = SEL.Count Dim i As Integer For i = SELCount To 1 Step -1 Dim SELHB As HybridBody Set SELHB = SEL.Item(i).Value If SELHB.HybridBodies.Count = 0 And SELHB.HybridShapes.Count = 0 Then SEL.Clear SEL.Add SELHB SEL.Delete SEL.Search ("ジェネレーティブ・シェイプ・デザイン.形状セット,all") End If Next i SEL.Clear End Sub |
実行すると正常に動くことがわかります。
これでマクロの根本的な機能は作成することができました。
ただはじめに紹介したメッセージ関連の機能はまだ何もついていない状態です。
ということでこのベースコードにいろいろ書き加えて機能を少し増やしていきます。
追加する内容は難しいものではないので説明は割愛します。
以下の完成コードとベースコードを見比べ何が増えたかを見ればすぐ理解できるとおもいます。
完成コード
完成したマクロのコードは以下のとおりです。
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 39 40 |
Sub CATMain() Dim SEL As Selection Set SEL = CATIA.ActiveDocument.Selection SEL.Search ("ジェネレーティブ・シェイプ・デザイン.形状セット,all") Dim SELCount As Integer SELCount = SEL.Count If SELCount = 0 Then MsgBox ("ドキュメント内に形状セットがありません。") End End If Dim HBCount As Integer HBCount = 0 Dim i As Integer For i = SELCount To 1 Step -1 Dim SELHB As HybridBody Set SELHB = SEL.Item(i).Value If SELHB.HybridBodies.Count = 0 And SELHB.HybridShapes.Count = 0 Then SEL.Clear SEL.Add SELHB SEL.Delete HBCount = HBCount + 1 SEL.Search ("ジェネレーティブ・シェイプ・デザイン.形状セット,all") End If Next i SEL.Clear If HBCount = 0 Then MsgBox "空の形状セットがありません。" Else MsgBox HBCount & "個の形状セットを削除しました。" End If End Sub |
上記のコードをコピペすれば日本語環境のCATIAであれば実行することができます。
![](https://i0.wp.com/liclog.net/wp-content/uploads/2019/08/8b7189979aefafdf63a9254eee23b8d4.jpg?resize=96%2C96&ssl=1)
お疲れさまでした!
まとめ
今回は「空の形状セットを一括で削除するマクロ」を例にマクロ作成の流れを見てきました。
初心者のうちは何が何だかわからないと思いますが、いろいろなマクロを見たり作ったりすることで徐々に理解できるようになっていきます。
今の時代、本やインターネットで様々な情報を得ることができます。
それらをうまく活用し、自分の力だけでマクロを作れるように勉強も頑張っていきましょう。
CATIAマクロを本気で勉強するなら