C#ATIA

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

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

VBAから外部のプログラムを起動して、処理したいことが偶にあります。
Excelであればこんな感じです。
他アプリを起動する:Excel VBA|即効テクニック|Excel VBAを学ぶならmoug


過去にブログに記載したものでも、実際にWscript.Shellを使いました。
(GetLinkReportSupport.clsのGetLinkReport関数内です)
ファイル間リンクの取得6 - C#ATIA


外部のプログラムを利用する場合、ちょっとした問題があります。
例として、あまり現実味がないのですがCATVBAからCATScriptを
呼び出す処理をしてみます。

まず、呼び出されるCATScriptです。
これを 「C:\temp」フォルダに「AddHBody.CATScript」として
作成しておきます。

'CATScript
'AddHBody.CATScript
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

内容はアクティブなPartファイルに、形状セットを5個作るだけです。


続いて、呼び出し側のVBAのコードです。

'vba
Sub Call_By_Shell()
    Dim CATScriptPath As String
    CATScriptPath = "C:\temp\AddHBody.CATScript"
    
    '外部呼出し
    Call CreateObject("Wscript.Shell").Run(CATScriptPath, 5)
    
    '形状セット名リネーム
    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

内容は先程のCATScriptを実行して、出来上がった形状セット名を
全て変更します。 もちろん2つに分ける意味は全く無いのですが。

Partファイルを新規に作成し、VBAを実行した結果がこちら。
f:id:kandennti:20160414173832p:plain

形状セットは作成されているのですが、リネームされていません。
再度実行した結果がこちら。
f:id:kandennti:20160414173850p:plain

最初に実行した分はリネームできているのですが、2回目に作成
された分はやはりリネームされていません。
CATScriptを呼び出すのですが、処理終了とは無関係でVBA
突っ走って処理しているんです。

最初のリンクにも記載されていますが、公式なものを見ると
Run メソッド

Wscript.Shellのrun関数の第三引数を "True" にすると
"呼び出された処理が終わるまで、呼び出し側の処理が止まる"
と記載されているみたいです。

なので、VBA側のコードをこのように修正しました。

'vba
Sub Call_By_Shell()
    ・・・
    
    '外部呼出し
    Call CreateObject("Wscript.Shell").Run(CATScriptPath, 5, True)
    
    ・・・

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

エラーがVBA側で出ちゃうんです。 形状セットは出来上がるので
CATScriptは呼び出されるのですが、処理終了を拾えないんです。
恐らくCATScript側が処理終了のサインを発しないんだろうと思います。
Wscript.Shellを利用した方法だと、ちょっとした工夫必要なんです。


CATIAのマクロには外部のプログラムを実行させる関数が、実装されています。
存在は前から知っていたのですが、どうしてもエラーになり利用できなかった
のですが、最近になってようやくわかりました。
以前紹介したTech-Eckeのサイトの
「CATScript/VBS」-「Externe Scripts und Anwendungen」
にサンプルがあります。
Tech-Ecke


参考にしてコードを直しました。

'vba
Sub Call_By_ExecuteScript()
    Dim CATScriptPath As String
    CATScriptPath = "C:\temp"
    
    Dim LibraryType As CatScriptLibraryType
    LibraryType = catScriptLibraryTypeDirectory
    
    Dim ScriptName As String
    ScriptName = "AddHBody.CATScript"
    
    Dim FunctionName As String
    FunctionName = "CATMain"
    
    Dim Params() As Variant
    
    '外部呼出し
     Call CATIA.SystemService.ExecuteScript(CATScriptPath, _
                                           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

実行してみると
f:id:kandennti:20160414173916p:plain
エラーなんです。 どうしてもダメなんです。
それで、ExecuteScript関数は見つけなかった事にしていたんですw

それが最近になってこんな感じに修正してみました。

    ・・・

    Dim SS As Variant 'SystemService
    Set SS = CATIA.SystemService
    
    '外部呼出し
    Call SS.ExecuteScript(CATScriptPath, LibraryType, _
                          ScriptName, FunctionName, Params)

    ・・・

やっぱりいつものヤツだなと思い、Variant型に一度入れてみました。
 結果はこちら。
f:id:kandennti:20160414173935p:plain

エラーなく、リネームの正しく処理してくれました。

CATScript側を修正し形状セット500個にしても、リネーム処理は正しく
行えているので、呼び出し側は処理を待っていてくれています。
f:id:kandennti:20160414173947p:plain