C#ATIA

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

外部のマクロを実行する2

こちらの続きです。
外部のマクロを実行する1 - C#ATIA


前回はCATVBAからCATScriptを呼び出す処理でしたが、
今度はCATVBAからCATVBAを呼び出します。

まず、「C:\temp」フォルダにVBAプロジェクトのライブラリ
「Outside_Macro_Test1」を作りモジュール名「AddHBody」
のモジュールを作りました。
f:id:kandennti:20160418112250p:plain
「AddHBody」の中には、前回CATScriptと同様です。

'vba
Sub CATMain()
    Dim partDocument1 As PartDocument
    Set partDocument1 = CATIA.ActiveDocument
    
    Dim part1 As Part
    Set part1 = partDocument1.Part
    
    Dim hybridBodies1 As HybridBodies
    Set hybridBodies1 = part1.HybridBodies
    
    For I = 1 To 5
        Call hybridBodies1.Add
    Next
    part1.Update
End Sub

次に同一プロジェクト内にモジュール名「Call_Inside」の
モジュールを作りました。
f:id:kandennti:20160418112320p:plain
こちらのコードも、前回のVBAのコードと同等なのですが、
上記の「AddHBody」モジュールのCATMainを呼び出すように
しました。

'vba
Sub CATMain()
    Call AddHBody.CATMain '←呼び出し
    
    Dim Doc As PartDocument
    Set Doc = CATIA.ActiveDocument
    
    Dim HBs As HybridBodies
    Set HBs = Doc.Part.HybridBodies
    
    Dim I As Long
    For I = 1 To HBs.Count
        HBs.Item(I).Name = "Hoge" + CStr(I)
    Next
    Doc.Part.Update
End Sub

まぁ、特別な事は無いです。 スコープの問題さえクリアしていれば
呼び出す際は「モジュール名 . 関数名」にすれば良いだけなので。

結果はこちらです。
f:id:kandennti:20160418112330p:plain

正しく処理できました。


問題は、別プロジェクトから任意の関数を呼び出す場合です。
まず別プロジェクトを作ります。「C:\temp」フォルダにVBAプロジェクトの
ライブラリ「Outside_Macro_Test2」を作りモジュール名「Call_Outside」
のモジュールを作りました。
f:id:kandennti:20160418112340p:plain

どの様にして呼び出せばよいのか? よくわからなかったので、
ExcelVBAを参考にしてみます。
Office TANAKA - Excel VBA Tips[他ブックのマクロを実行する]
(OfficeTANAKAさん いつもお世話になっちゃうなぁ)

「Call_Outside」の中身はこんなコードにしてみました。

'vba
Sub CATMain()
    Application.Run "Outside_Macro_Test1!AddHBody.CATMain"
    
    Dim Doc As PartDocument
    Set Doc = CATIA.ActiveDocument
    
    Dim HBs As HybridBodies
    Set HBs = Doc.Part.HybridBodies
    
    Dim I As Long
    For I = 1 To HBs.Count
        HBs.Item(I).Name = "Hoge" + CStr(I)
    Next
    Doc.Part.Update
End Sub

実行すると
f:id:kandennti:20160418112403p:plain

余裕でダメなんですよ。そもそもCATIAのApplicationクラスには
Run関数なんて無いんです。
f:id:kandennti:20160418112549p:plain
"R" で始まるのは "RefreshDisplay" しか無いんです。


そこで登場するのが、前回のExecuteScript関数なんです。
で、「Call_Outside」を直してみました。

'vba
Sub CATMain()
    Dim VBAProjectPath As String 'プロジェクトまでのパス
    VBAProjectPath = "C:\temp\Outside_Macro_Test1.catvba"
    
    Dim LibraryType As CatScriptLibraryType 'ライブラリの種類
    LibraryType = catScriptLibraryTypeVBAProject
    
    Dim ScriptName As String 'モジュール名
    ScriptName = "AddHBody"
    
    Dim FunctionName As String '関数名
    FunctionName = "CATMain"
    
    Dim Params() As Variant '引数 空でも渡す
    
    Dim SS As Variant 'SystemService
    Set SS = CATIA.SystemService
    
    '外部呼出し
    Call SS.ExecuteScript(VBAProjectPath, LibraryType, _
                          ScriptName, FunctionName, Params)
                          

    Dim Doc As PartDocument
    Set Doc = CATIA.ActiveDocument
    
    Dim HBs As HybridBodies
    Set HBs = Doc.Part.HybridBodies
    
    Dim I As Long
    For I = 1 To HBs.Count
        HBs.Item(I).Name = "Hoge" + CStr(I)
    Next
    Doc.Part.Update
End Sub

前回はササッとやってしましましたが、コメント付けました。
Params()に関しては試していないのですが、不要でも空の
Variant型配列は渡す必要があるようです。
実行結果はこちら。
f:id:kandennti:20160418112330p:plain

正しく処理できました。 ん!VBEのProjectTreeを見ると
f:id:kandennti:20160418112432p:plain

呼び出された側のProjectが増えてる・・・。
何これ? 怖いんだけど・・・。

何度も試したのですが、これ以上は増えませんでした。
マクロライブラリ-見ると増えたわけではありませんでした。
f:id:kandennti:20160418112442p:plain
VBEを消しても直らず、CATIAを落とせば元に戻りました。
表示上の問題かなぁ。



よく考えると、ExecuteScript関数は、"プロジェクトまでのパス"
"ライブラリの種類" "モジュール名" "関数名" と何から何まで指定して
います。試しに「Outside_Macro_Test1」プロジェクト自体をライブラリ
から外してしまいます。 こんな感じです。
f:id:kandennti:20160418112448p:plain

この状態で、先程のマクロを実行すると
f:id:kandennti:20160418112330p:plain

正しく実行できました。 ExecuteScript関数はライブラリとして
取り込んでいないプロジェクトのマクロの呼び出しも可能のようです。
但し、実行後はプロジェクトを取り込んだ状態になってしまいます。
先程の同一プロジェクトが2つ表示された状態になるのは、この事が
原因なのかも知れません。