以前から "ちょっと欲しいなぁ" と思っていた関数が何となく
出来上がりました。 個人的には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)
で、取得できるような名称です。
使い道としては、こんな感じで
マクロを実行しこんな処理を行うと
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
試しに実行すると、この様になります。
本音を書けば、ドキュメントさえ取得してしまえば大体事が足りますが・・・。
今まで、
Set Piyo = Hoge.Parent.Parent.Parent
のような書き方をしていたものが、少し清楚に書けるわけです。(と思っています)
注意点としては、取得できない場合、GetParent_Of_T関数の戻り値が
Nothingの場合があるので、Is Nothingのチェックはされたほうが良いかと思います。
但し、万能ではなくこちらのGetLeafBody関数の様に、上手く行かない場合
もあります。
ボディ - ボディ の最短距離の測定3 - C#ATIA