読者です 読者をやめる 読者になる 読者になる

C#ATIA

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

Ariawaseを利用してみたい3

こちらの続きです。
Ariawaseを利用してみたい2 - C#ATIA


先日は動く状態にまではしたのですが、同等な処理とはなっておらず
実行速度が著しく落ちます。 そこで同等処理を目指し再挑戦です。

2度のループと同等にする為、データムポイントを作成と形状セットへの代入
を分けるため、こんな感じの関数を用意します。

'vba
'データムポイント作成
Private Function CreateDetumPoint(ByVal pnt As Variant) As HybridShapePointExplicit
    Call oHybShpPt.SetCoordinates(pnt)
    Call oPart.UpdateObject(oHybShpPt)
    Set CreateDetumPoint = oHybShpFact.AddNewPointDatum(oHybShpPt)
End Function

'形状セットへ代入
Private Sub AppendDetumPoint(ByVal pnt As Object)
    Call oHybBdy.AppendHybridShape(pnt)
End Sub

問題は呼び出し側です。 苦しみました。
最初このような感じで書きました。

'VBA - using_ariawase
'これは動かないです
    Poss = ArrMap(Init(New Func, vbVariant, AddressOf Create3dPos, vbLong), ArrRange(1&, 500&))
    DetumPnts = ArrMap(Init(New Func, HybridShapePointExplicit, AddressOf CreateDetumPoint, vbVariant), Poss)

2行目のInit関数の2番目の引数は "戻り値の型" の指定となっていた為
素直にCATIAのオブジェクトの型(HybridShapePointExplicit)を
指定したのですが、ダメなんです。


気持ちを切り替え、サンプルのFizzBuzzのInin関数部分にブレークポイントを入れ実行します。

'vba
''' EntryPoint
Sub Main()
    Debug.Print Join(ArrMap(Init(New Func, vbString, AddressOf FizzBuzz), ArrRange(1&, 100&)))
End Sub

FizzBuzzの場合は "vbString" を投げています。 ローカルウィンドウで確認すると
このような感じです。

f:id:kandennti:20151118124641p:plain

"param(0)"部分が2番目の引数に該当するのですが、Long型を
受け取っています。 "vbString" を投げてLong型を受け取るのは、定数かEnum
だろうと予測できたのですが、"HybridShapePointExplicit" は何なのだろう?
と再び行き詰まりました。
(この時、素直にVBAのHelpを見ればよかった・・・)


結局、"vbString" がVBAの定数だとわかり、"vbObject" にすればよい事が
わかりました。
Office TANAKA - Excel VBA関数[VarType関数]

昨日のコードを直すとこんな感じです。

'VBA - using_ariawase
 ・
 ・
'------------ Create DetumPoints ------------------------------
    Call ArrMap(Init(New Func, vbEmpty, AddressOf AppendDetumPoint, vbObject), _
         ArrMap(Init(New Func, vbObject, AddressOf CreateDetumPoint, vbVariant), _
         ArrMap(Init(New Func, vbVariant, AddressOf Create3dPos, vbLong), ArrRange(1&, 500&))))
 ・
 ・

かなり無理矢理な1行ですが、元のコード同様の2回ループさせた状態が再現でき、実行速度も
同じ程度にまでになりました。

CATIAでariawaseを利用する際は、関数側の戻り値の型が
"Sub(戻り値なし)" → vbEmpty
"配列(座標値等のCATSafeArrayVariant等)" → vbVariant
"CATIAのオブジェクト" → vbObject
で良いのかな? と思います。
(でも、上手く行かないものがあったり・・・)