こちらの続きです。
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" を投げています。 ローカルウィンドウで確認すると
このような感じです。
"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
で良いのかな? と思います。
(でも、上手く行かないものがあったり・・・)