C#ATIA

↑タイトル詐欺 主にCATIA V5 の VBA

CATPart内エラー時のUpdateObject

こちらでコメント頂いた
「GetMeasurableはUpdate出来ないと長さも取得できそうにありません」
について、解決されたようですが、試しているうちに知らなかった事に
出くわした為、記載しておきます。
選択した円弧の長さを表示1 - C#ATIA


テストしたデータはこんな感じです。
f:id:kandennti:20170621131323p:plain
データをUp出来れば良いのですが・・・
全てXY平面上にあり、線は各点を端点としています。
この状態から、点P4の座標値を(5,20,0)→(5,5,0)にマクロで変更させ
L3(P4-P5)の長さを取得します。
途中で交差(ITS)が履歴内に入っていますが、L3とは無関係です。
但し、P4の座標値を変更する事で交差がエラーとなってしまう状態です。
(要は、取得したい線とは無関係な部分でエラーが起きている状態にします)

Sub CATMain()
    '準備
    Dim Doc As PartDocument: Set Doc = CATIA.ActiveDocument
    Dim Pt As Part: Set Pt = Doc.Part
    Dim Hss As HybridShapes: Set Hss = Pt.HybridBodies.Item(1).HybridShapes
    Call Pt.Update
    
    Debug.Print "*** エラー時の線の長さ取得テスト スタート ***"
    
    '長さを取得したい線
    Dim L3 As HybridShape: Set L3 = Hss.Item("L3")
    Dim L3Ref As Reference: Set L3Ref = Pt.CreateReferenceFromGeometry(L3)
    
    '変更する点-本当はHybridShapePointCoord
    Dim P4Vri As Variant: Set P4Vri = Hss.Item("P4")
    
    '長さ測定
    Dim L3Lng As Double
    L3Lng = Doc.GetWorkbench("SPAWorkbench").GetMeasurable(L3Ref).length
    Debug.Print "変更前(エラー無し) : " & CStr(L3Lng) & "mm"
    
    '端点位置変更 - 未更新
    Call P4Vri.SetCoordinates(Array(5, 5, 0))
    
    '更新-エラー発生
    On Error Resume Next
        '本当はエラーで止まる
        Call Pt.Update
    On Error GoTo 0
    L3Lng = Doc.GetWorkbench("SPAWorkbench").GetMeasurable(L3Ref).length
    Debug.Print "変更後(エラー)-Update : " & CStr(L3Lng) & "mm"
    
    '目的の要素のみローカル更新
    Call Pt.UpdateObject(L3)
    L3Lng = Doc.GetWorkbench("SPAWorkbench").GetMeasurable(L3Ref).length
    Debug.Print "変更後-UpdateObject_線のみ : " & CStr(L3Lng) & "mm"
    
    '目的の要素の履歴分ローカル更新
    Call Pt.UpdateObject(P4Vri)
    Call Pt.UpdateObject(L3)
    L3Lng = Doc.GetWorkbench("SPAWorkbench").GetMeasurable(L3Ref).length
    Debug.Print "変更後-UpdateObject_点・線 : " & CStr(L3Lng) & "mm"
End Sub

PartのUpdateでは、エラーが出る為 "On Error Resume Next" を利用してます。

実際に試した結果はこち

*** エラー時の線の長さ取得テスト スタート ***
変更前(エラー無し) : 10mm
変更後(エラー)-Update : 10mm
変更後-UpdateObject_線のみ : 25mm
変更後-UpdateObject_点・線 : 25mm

Update(エラーが発生した状態)では、未更新な状態な為変更される前の
長さを取得してしまいます。
[目的の要素のみローカル更新] と [目的の要素の履歴分ローカル更新](こっちは無意味)
では、単にL3のみの更新とP4・L3の更新の違いです。
実は、 [目的の要素のみローカル更新] では "上手く行かないかも" と思っていたの
ですが、依存する要素(今回はP4)も更新されました。
過去に履歴を時系列順に更新してやらないと上手く出来なかった事が
あったので、僕の場合はこのように更新するように心掛けています。


ここからが試すまで知らなかった事です。
上記のコードを最初このようにしていました。

	・・・
    '目的の要素のみローカル更新
    Call Pt.UpdateObject(L3Ref) 'オブジェクトではなくリファレンスを更新
    L3Lng = Doc.GetWorkbench("SPAWorkbench").GetMeasurable(L3Ref).length
    Debug.Print "変更後-UpdateObject_線のみ : " & CStr(L3Lng) & "mm"

実はこれで問題無いと思っていたからです。
実際に実行してみると、UpdateObject時にエラーとなってしまいました。

AutomationManualを見るとUpdateObjectメソッドの引数は
"AnyObject" で Referenceオブジェクト は "AnyObject" を継承しており
実際によく利用しています。

f:id:kandennti:20170621131307p:plain

上記の事を考えると、CATPart内でエラーが発生している場合は、リファレンスでの
UpdateObjectでは、正しく処理されないようです。
各要素のオブジェクトとリファレンスは、ほぼ同等のものと思っていたのですが・・・。

こちらも非常に勉強になりました。