CATProduct内で選択したPartをまとめて新規Productに出力するマクロ|CATIAマクロの作成方法
今回の記事は「マクロ案」よりいただいた内容です。
送って頂いた内容は以下のようなマクロです。
ワークベンチ:
Productマクロ案:
Product内から選択した任意の数のpartファイルのみで、
かつ位置関係を保ったままの新規productを作成
今回のマクロではユーザー選択として「SelectElement3メソッド」を使います。
SelectElement3の使い方がわからない方は上記リンクよりご確認ください。
マクロの機能
今回作成したマクロは
『ユーザーが選択したPartをまとめて1つの新規Productに出力するマクロ』です。
具体的な機能は以下のとおりです。
・選択されたCATPartを新規プロダクトに書き出す
・新規プロダクトの名称は「New Product」
・CATPartの配置情報は元のProductと同じにする
選択するのはCATPartで1番上に表示される「Part」の部分です。
デザインモードでは表示されないので、設計モードに切り替える必要があるので注意して下さい。
サンプルコード
マクロのサンプルコードは以下のとおりです。
本マクロでは「SelectElement3メソッド」を使っているので、SelectElement3のツールバーの使い方がわからない方は先にリンクページを参照下さい。
Option Explicit
Sub CATMain()
If TypeName(CATIA.ActiveDocument) <> "ProductDocument" Then
MsgBox "CATProductのみ対応のマクロです。"
Exit Sub
End If
Dim Doc As ProductDocument
Set Doc = CATIA.ActiveDocument
Dim SEL
Set SEL = CATIA.ActiveDocument.Selection
Dim Filter
Filter = Array("Part")
Dim msg As String
msg = "出力するPartを選択してください。"
Dim Status As String
Status = SEL.SelectElement3(Filter, msg, False, CATMultiSelTriggWhenUserValidatesSelection, False)
If Status <> "Normal" Then
MsgBox "キャンセルしました。"
Exit Sub
End If
Dim i As Integer
Dim Parts As Collection
Set Parts = New Collection
CATIA.RefreshDisplay = False
For i = 1 To SEL.Count
Parts.Add SEL.Item(i).Value
Next i
SEL.Clear
Dim ProductParts As Collection
Set ProductParts = New Collection
For i = 1 To Parts.Count
Dim PartName As String
PartName = Parts.Item(i).Name
Call SEL.Search("(ツリー内の名前=" & PartName & "' ''('* & プロダクト・ストラクチャー.パーツ),all")
ProductParts.Add SEL.Item(1).Value
Next i
For i = 1 To ProductParts.Count
SEL.Add ProductParts.Item(i)
Next i
SEL.Copy
SEL.Clear
Dim NewPro As ProductDocument
Set NewPro = CATIA.Documents.Add("Product")
Dim RootPro As Product
Set RootPro = NewPro.Product
RootPro.PartNumber = "New Product"
Set SEL = NewPro.Selection
SEL.Add RootPro
SEL.Paste
CATIA.RefreshDisplay = True
MsgBox "完了しました。"
End Sub
簡単な実行確認はしていますが、エラーの発生や意図しない動きをする可能性があります。
コード解説
ここでは上記マクロコードのいくつかの部分を抜粋して解説していきます。
今回のマクロは選択したCATPartをコピーして、新規CATProductに貼り付けるだけのシンプルな処理の流れになっています。(コピペすれば配置情報も追従します)
ドキュメントの定義
If TypeName(CATIA.ActiveDocument) <> "ProductDocument" Then
MsgBox "CATProductのみ対応のマクロです。"
Exit Sub
End If
Dim Doc As ProductDocument
Set Doc = CATIA.ActiveDocument
まず、はじめにアクティブドキュメントの定義をします。
今回のマクロはCATProductでのみ有効なものなので、アクティブドキュメントがCATProduct以外の場合はTypeName関数を使った条件分岐でマクロを終了するようにしています。
条件分岐の先、つまりはアクティブドキュメントがCATProductの場合は変数「Doc」にアクティブドキュメントを代入します。
ユーザー選択(CATPart)
Dim SEL
Set SEL = CATIA.ActiveDocument.Selection
Dim Filter
Filter = Array("Part")
Dim msg As String
msg = "出力するPartを選択してください。"
Dim Status As String
Status = SEL.SelectElement3(Filter, msg, False, CATMultiSelTriggWhenUserValidatesSelection, False)
If Status <> "Normal" Then
MsgBox "キャンセルしました。"
Exit Sub
End If
Dim i As Integer
Dim Parts As Collection
Set Parts = New Collection
CATIA.RefreshDisplay = False
For i = 1 To SEL.Count
Parts.Add SEL.Item(i).Value
Next i
SEL.Clear
つぎに「SelectElement3メソッド」を使って、ユーザーに「CATPart」を選択させます。
今回は「CATPart」のみを選択させたいので、設計モードで選択可能になる「Part」をフィルターとしてユーザー選択をさせます。(デザインモードでのCATPartは「Product」となり、CATPartのみのフィルターとならないため)
選択された「Part」は「Parts」というコレクション内に格納しておきます。これにより選択状態が解除されても、ユーザーが選択した「Part」をいつでも使うことが可能になります。
選択されたPartの親となるCATPartをコレクションに格納
Dim ProductParts As Collection
Set ProductParts = New Collection
For i = 1 To Parts.Count
Dim PartName As String
PartName = Parts.Item(i).Name
Call SEL.Search("(ツリー内の名前=" & PartName & "' ''('* & プロダクト・ストラクチャー.パーツ),all")
ProductParts.Add SEL.Item(1).Value
Next i
以降でユーザー選択された「Part」を新規Productにコピペしていく処理を行いますが、現在選択されている「Part」ではプロダクト間のコピペができないので「親のPart」(下の画像でいう上側のPart)を取得していきます。
いろいろ探したのですが直接「親のPart」を取得できる方法が見つからなかったのでここでは、「検索機能」を使って親のPartを取得しています。
Dim PartName As String
PartName = Parts.Item(i).Name
Call SEL.Search(“(ツリー内の名前=" & PartName & “' "('* & プロダクト・ストラクチャー.パーツ),all")
まずはユーザーが選択した「Part」の名前を取得し、ドキュメント内で検索をかけます。
例えば「Part1」という名前の場合は「Part1 (*」という文字列で検索します。
(「Part」と「親のPart」は名前が紐づいているためこの検索方法で親のPartが選択できます)
ここで注意なのですが、必ずしも親のPartだけが検索に引っかかるとは限りません。
ほとんどの場合は親のPartしか選択されないはずですが、もしこの検索部分で別のPartが選択されてしまった場合、違うPartがコピペされる可能性があるので少し注意して下さい。
マクロ動作がうまくいっているかは要確認ですよ!
あとはループ文で親のPartを「ProductParts」というコレクションに格納していくだけです。
これにより「Parts」同様、いつでも「親のPart」を呼び出すことが可能になります。
ProductPartsを新規Productにコピペ
For i = 1 To ProductParts.Count
SEL.Add ProductParts.Item(i)
Next i
SEL.Copy
SEL.Clear
Dim NewPro As ProductDocument
Set NewPro = CATIA.Documents.Add("Product")
Dim RootPro As Product
Set RootPro = NewPro.Product
RootPro.PartNumber = "New Product"
Set SEL = NewPro.Selection
SEL.Add RootPro
SEL.Paste
CATIA.RefreshDisplay = True
最後に先ほど格納した「ProductParts」内の全てのPartをコピペします。
まずは、「ProductParts」内の全てのPartを全て選択状態にしてコピーします。
あとは新規Productを作成し、一番上のProduct(RootProductともいう)に貼り付ければ完了です。
(Productの新規作成の方法は「Documentsコレクション」を参照下さい)
ちなみに「CATIA.RefreshDisplay」はExcelマクロでいう「Application.ScreenUpdating」のようなもので、マクロ実行中のアニメーションを省略し処理時間を少し短縮することができます。(ScreenUpdatingほど有能なものではありません)
まとめ
今回は「CATProduct内で選択したPartをまとめて新規Productに出力するマクロ」についての内容でした。
処理の流れとしては、ユーザーが選択したCATPartを取得し、新規CATProductにコピペするだけの簡単なものです。ユーザー選択の際のフィルターの関係で少しややこしくなっていますが最終的にやりたかったのは「CATPartを取得する」というだけのことです。
CATProductでのマクロは「Product」と「Part」の関係性を理解するのが難しいですが、非常に重要な内容なのでいろいろなマクロに触れて理解していってください。
CATIAマクロを本気で勉強するなら








