要素にパラメータの値を反映する(式を編集)2|CATIAマクロの作成方法
今回はマクロ案から頂いた以下のご質問に対する回答内容となっています。
以前公開した「要素にパラメータの値を反映する(式を編集)」で少し問題があったようです。
SELECTELEMENT2で選択のフィルターを点にしています。
Filter(0) = “Point”
しかし、交差で作成した点(intersect) は選択できなくなってしまいます。
選択できるように
Filter(0) = “AnyObject”
に変更しました。
すると、’ 式を作成する為の名前を取得でエラーが起きてしまいます。
Dim CorrectName1$: CorrectName1 = part1.Parameters. GetNameToUseInRelation(Ref1)
Dim CorrectName2$: CorrectName2 = part1.Parameters. GetNameToUseInRelation(Ref2)Filter(0) = “AnyObject”でも名前の取得ができる方法を
公開して頂けると助かります。
SelectElement2で「Point」をフィルターにした場合、[点]コマンドで作成した点、もしくは分離(Isolate)された点しか選択できなくなってしまいます。
そのため[交差]コマンドで作成した点や [投影]コマンドで作成された点は選択できない状態となってしまいます。
今回は以前公開したサンプルマクロを修正し、[点]コマンド以外で作成された点にも対応できるようにする方法を解説していきます。
※今回の内容は「要素にパラメータの値を反映する(式を編集)」の続きです。
上記リンクページを理解している前提で進めていくので、まだの方は先に一読ください。
交差(Intersect)で作成した点が選択できない理由
前回紹介したサンプルマクロでは、以下のような「SelectElement2を使って、選択したエレメントをReferenceとして取得する関数」を作成し、これをメインのプロシージャ[Sub CATMain()]で呼び出すことでユーザー選択の「点」を取得していました。
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 |
Private partDocument1 As PartDocument Private Part1 As Part '-------------------------------------------------------------------------------------------------------------------------------' Sub CATMain() '準備 Set partDocument1 = CATIA.ActiveDocument Set Part1 = partDocument1.Part 'ユーザーによる2点の選択 Dim Filter(0) As Variant Filter(0) = "Point" Dim Ref1 As Reference Set Ref1 = SelectItemReference(Filter, "中心点を選択") Filter(0) = "Point" Dim Ref2 As Reference Set Ref2 = SelectItemReference(Filter, "参照点を選択") '***中略*** End Sub '-------------------------------------------------------------------------------------------------------------------------------' '***SelectElement2*** Private Function SelectItemReference(Filter, msg As String) As Reference Dim Status As String Dim selection1 'As Selection Set selection1 = partDocument1.Selection With selection1 .Clear Status = .SelectElement2(Filter, msg, False) If Status = "Cancel" Then Call MsgBox("中止します") End End If Set SelectItemReference = .Item(1).Reference .Clear End With Set SEL = Nothing End Function |
このときユーザー選択の点を取得するため、
SelectElement2のフィルターとしては「”Point”」を指定しました。
では、この「Point」が何を表しているかを見てみましょう。
「CAA V5 Visual Basic Help」ヘルプの「Hybrid Shapes Automation Objects」ページを見ると「Point」は以下のように表されています。
オブジェクト名を見ればわかると思いますが、「Point」以下のオブジェクトは[点]コマンドのそれぞれの定義タイプ(座標、平面上、曲線上など)で作成された点を意味しています。
つまり「Point」の中に[交差]コマンドで作成した点が含まれていないためフィルターとして認識されず、選択ができなかったというわけです。
※ 分離(Isolate)された点も「Point」に含まれます。
解決案① Filterを「AnyObject」に変更
[交差]コマンドで作成した点が作成できない理由がフィルターにあることから、フィルターの内容を変えれば選択可能することができるということがわかります。
ということでフィルターにすべてのオブジェクトを表す「AnyObject」を指定します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
Private partDocument1 As PartDocument Private Part1 As Part '-------------------------------------------------------------------------------------------------------------------------------' Sub CATMain() '準備 Set partDocument1 = CATIA.ActiveDocument Set Part1 = partDocument1.Part 'ユーザーによる2点の選択 Dim Filter(0) As Variant Filter(0) = "AnyObject" 'フィルターオブジェクト変更 Dim Ref1 As Reference Set Ref1 = SelectItemReference(Filter, "中心点を選択") Filter(0) = "AnyObject" 'フィルターオブジェクト変更 Dim Ref2 As Reference Set Ref2 = SelectItemReference(Filter, "参照点を選択") '***中略*** End Sub |
これにより[交差]コマンドで作成した点が選択できるようになります。
ただ選択可能にはなりましたが、冒頭で紹介したとおり以下コードでエラーが発生してしまいます。
Dim CorrectName1$: CorrectName1 = part1.Parameters. GetNameToUseInRelation(Ref1)
Dim CorrectName2$: CorrectName2 = part1.Parameters. GetNameToUseInRelation(Ref2)
これは「AnyObject」がすべてのオブジェクトを選択できてしまうことに原因があります。
CATIAの仕様として形状領域でオブジェクトを選択すると、エッジやフェース、頂点といったサブエレメント(内部要素)が選択されます。
実際に[交差]コマンドで作成した点を例に見てみましょう。
画像下側に表示されるステータスバーの文字に注目してください。
仕様ツリーから選択した場合は「交差.1」を選択していますが、形状領域から選択した場合は「交差.1の頂点」つまりはサブエレメントを選択している状態になっていることがわかります。
この選択の違いを理解したうえで、Filterを「AnyObject」にしたマクロを実行してみましょう。
このとき、選択する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 |
'***SelectElement2*** Private Function SelectItemReference(Filter, msg As String) As Reference Dim Status As String Dim selection1 'As Selection Set selection1 = partDocument1.Selection With selection1 .Clear Status = .SelectElement2(Filter, msg, False) If Status = "Cancel" Then Call MsgBox("中止します") End End If '修正**************************************************************************************************** If TypeName(selection1.Item(1).Value) = "ZeroDimFeatVertexOrWireBoundaryMonoDimFeatVertex" Then Set SelectItemReference = .Item(1).Reference.Parent 'ユーザー選択が頂点の場合は選択オブジェクトの親を取得 .Clear Else Set SelectItemReference = .Item(1).Reference .Clear End If '******************************************************************************************************* End With Set SEL = Nothing End Function |
ユーザー選択の点をReferenceとして取得する部分のコードを条件分岐させます。
選択したオブジェクトが「頂点」だった場合は、その親のオブジェクトをReferenceとして取得するようにすれば以下のような処理が行われ問題は解決です。
「交差.1」が選択された場合 → 頂点ではないのでそのまま「交差.1」を取得
「交差.1の頂点」が選択された場合 → 頂点なのでその親の「交差.1」を取得
Filterを「AnyObject」にしたときの問題点
Filterを「AnyObject」にした場合、サーフェスや曲線、ソリッドなどあらゆるものが選択できる状態となってしまうため、フィルターとしての機能がなくなってしまうという点は理解しておく必要があります。
上記コードはあくまでも「点以外は選択してはいけない」とユーザーが理解している前提のマクロとなっています。マクロを個人で使うのであれば自分が気を付ければいいだけの話ですが、共有して使う場合は点以外のものが選択された場合のエラー処理なども必要になるため少し考えどころです。
解決案② Filterを複数設定
Filterを「AnyObject」としてしまうとフィルターとしての機能は消えてしまいます。
そこでフィルターの機能はある程度残せるよう、フィルターを複数設定するというのも1つの手です。
フィルターを定義するとき、以下のように書くことで複数設定することができます。
Dim Filter As Variant
Filter = Array(Object1,Object2,Object3)
Object部にはフィルターにかけたいオブジェクト名を入力します。
上記では3つ入力していますが、いくつも設定することが出来ます。
上記コードを利用することで「AnyObject」よりはフィルター機能が活かすことができます。
Dim Filter As Variant
Filter = Array(“Point”,”HybridShapeIntersection”)
上記のコードの場合、フィルターとして「Point」と「HybridShapeIntersection」を指定、つまりは[点]コマンドで作成した点と[交差]コマンドで作成した点のみをフィルターにかけることができます。
「AnyObject」とは違いサブエレメントが選択されることがないため、サブエレメント選択の対策をする必要もありません。
Filterを複数設定にしたときの問題点
フィルターとして「Point」と「HybridShapeIntersection」を指定した場合、点以外にも[交差]コマンドで作成された曲線やサーフェスも選択することが出来てしまうためフィルター機能としてはまだ完璧とは言えません。
また[点]コマンド/[交差]コマンド以外で作成した点は選択することができないというのも問題があります。([投影]コマンドで作成した点などは選択不可)
AnyObjectと同様に、これを理解したうえで使うのであればいいですが、複数人(特にマクロを理解していない人)で使う場合は点以外のものが選択された時のエラー処理が必要になってきます。
まとめ
今回は2つの案を紹介しましたが、まとめると以下のようになっています。
解決案① AnyObject
メリット 解決案②よりは選択できる点の種類が多い
デメリット 何でも選択可能な状態のためフィルター機能が無意味
点以外が選択された場合のエラー処理が必要
解決案② Point & HybridShapeIntersection
メリット 解決案①よりはフィルター機能が働く
デメリット フィルターに入っていない点は選択不可
点以外が選択された場合のエラー処理が必要
どちらも完璧なフィルターではないため、点以外が選択された場合のエラー処理が必要になります。
個人で作業効率を上げるためだけに使うマクロであれば、何をすればエラーになるか理解できているため問題ありませんが、共有して複数人で使う場合はこのままではあまり実用的なマクロとは言えません。
一応、今回頂いた質問には回答できていると思うのでこれでまとめとしますが、個人的に勉強して良いフィルターの設定方法が見つかればまたページを作成しようと思います。
CATIAマクロを本気で勉強するなら