C#ATIA

↑タイトル詐欺 主にFusion360API 偶にCATIA V5 VBA(絶賛ネタ切れ中)

指定した型のParentを取得する

以前から "ちょっと欲しいなぁ" と思っていた関数が何となく
出来上がりました。 個人的にはC#のジェネリックがイメージです。

コードはこちら

'vba
'T型のParent取得
Function GetParent_Of_T(ByVal AnyOj As AnyObject, ByVal T$) As AnyObject
    If TypeName(AnyOj) = TypeName(AnyOj.Parent) Then
        Set GetParent_Of_T = Nothing
        Exit Function
    End If
    If TypeName(AnyOj) = T Then
        Set GetParent_Of_T = AnyOj
    Else
        Set GetParent_Of_T = GetParent_Of_T(AnyOj.Parent, T)
    End If
End Function

第一引数には、駆け上がるParentを持つオブジェクトで、
第二引数は、Parentの型の名称です。

    MsgBox TypeName(AnyOj)

で、取得できるような名称です。

使い道としては、こんな感じで
f:id:kandennti:20160401190254p:plain
マクロを実行しこんな処理を行うと

    Set Doc = CATIA.ActiveDocument

CATProductのドキュメントを取得しますが、実際の処理では
Part1のドキュメントが欲しい場合が多々あります。

SelectionのSelectElement2を利用して、選択したボディから
ボディの存在しているPartやPartDocumentを取得したい場合は
こんな感じで可能になります。

'vba
Sub GetParent_Of_T__Test()
    Dim Sel As Selection: Set Sel = CATIA.ActiveDocument.Selection
    Dim SelVri As Variant: Set SelVri = Sel 'SelectElement2を利用する為の対策
    Dim Filter As Variant: Filter = Array("Body") '選択制限
    
    '選択
    Sel.Clear
    Select Case SelVri.SelectElement2(Filter, "選択して下さい", False)
        Case "Cancel", "Undo", "Redo"
            Exit Sub
    End Select
    Dim SelectItem As AnyObject: Set SelectItem = Sel.Item(1).Value
    Sel.Clear
    
    '選択要素からPartの取得
    Dim ParentType$: ParentType = "Part"
    Dim SelectPart As Part
    Set SelectPart = GetParent_Of_T(SelectItem, ParentType)
    If SelectPart Is Nothing Then Exit Sub '取得失敗対策
    
    '選択要素からPartDocumentの取得
    Dim SelectPDoc As PartDocument
    Set SelectPDoc = GetParent_Of_T(SelectItem, "PartDocument")
    If SelectPDoc Is Nothing Then Exit Sub '取得失敗対策
    
    Dim Msg$
    Msg = "選択した" + CStr(Filter(0)) + "は" + _
          "「 " + SelectPart.Name + " 」です。" + vbNewLine + _
          "「 " + SelectPDoc.FullName + " 」" + vbNewLine + _
          "が、該当するファイルです。"
    MsgBox Msg
End Sub

試しに実行すると、この様になります。
f:id:kandennti:20160401190304p:plain
本音を書けば、ドキュメントさえ取得してしまえば大体事が足りますが・・・。

今まで、

    Set Piyo = Hoge.Parent.Parent.Parent

のような書き方をしていたものが、少し清楚に書けるわけです。(と思っています)

注意点としては、取得できない場合、GetParent_Of_T関数の戻り値が
Nothingの場合があるので、Is Nothingのチェックはされたほうが良いかと思います。

但し、万能ではなくこちらのGetLeafBody関数の様に、上手く行かない場合
もあります。
ボディ - ボディ の最短距離の測定3 - C#ATIA