C#ATIA

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

Excelフォームボタンからマクロの起動 (未確認)

Excelのフォームのボタンを押したら、指定した座標系を元に
 XYZの値を入力した位置に、点を作成したい」
と言う内容の御質問を頂きました。

生憎、古いExcelしかインストールされていないため(マクロ動かない)
完全には再現できませんが、近い事はしてみたいと思います。


絶対座標系を元に点1を作成し、点1を元に座標系2を作成しました。
f:id:kandennti:20171017184349p:plain
この座標系2を元に座標を指定した点を作成したい と解釈しましたので
その通りにマクロの記録をとってみると、この様になりました。

'vba
Sub CATMain()

Dim partDocument1 As PartDocument
Set partDocument1 = CATIA.ActiveDocument

Dim part1 As Part
Set part1 = partDocument1.Part

Dim hybridShapeFactory1 As HybridShapeFactory
Set hybridShapeFactory1 = part1.HybridShapeFactory

Dim hybridShapePointCoord1 As HybridShapePointCoord
Set hybridShapePointCoord1 = hybridShapeFactory1.AddNewPointCoord(10#, 20#, 30#)

Dim axisSystems1 As AxisSystems
Set axisSystems1 = part1.AxisSystems

Dim axisSystem1 As AxisSystem
Set axisSystem1 = axisSystems1.Item("座標系.2")

Dim reference1 As Reference
Set reference1 = part1.CreateReferenceFromObject(axisSystem1)

hybridShapePointCoord1.RefAxisSystem = reference1

Dim hybridBodies1 As HybridBodies
Set hybridBodies1 = part1.HybridBodies

Dim hybridBody1 As HybridBody
Set hybridBody1 = hybridBodies1.Item("形状セット.1")

hybridBody1.AppendHybridShape hybridShapePointCoord1

part1.InWorkObject = hybridShapePointCoord1

part1.Update

End Sub

こちらにも記載しましたが、僕の場合は記録を取った
マクロを実行し再現されるかどうかを確認しています。
VBAでマクロを作成する際の我流な手順1 - C#ATIA
今回は、再現できたので記録は取れているようです。

コードを見ると "座標系.2" が見つかるので、その続きを見てみると

・・・

Dim axisSystem1 As AxisSystem
Set axisSystem1 = axisSystems1.Item("座標系.2")

Dim reference1 As Reference
Set reference1 = part1.CreateReferenceFromObject(axisSystem1)

hybridShapePointCoord1.RefAxisSystem = reference1

・・・

リファレンスを取得し、作成した点の「RefAxisSystem」プロパティに
座標系2のリファレンスを割り当てています。
どうやらこれが キモ のようです。

念の為、「リファレンスとは何者か?」 と聞かれてもお答えする
自信がありません。
(CATIAのマクロに取り組み始めた際、最初にぶつかる壁が
 リファレンスのような気がしてます)
プログラム的に言えば、パラメータ(引数)として受け取る型が
複数種類ある場合、オーバーロードを利用する事になると思うのですが
多数あるため大量になりすぎ、手間です。
それだったら必要な情報だけを持った抽象的なクラスを作成し、
受け取った側で情報が足りなかったら、エラー出したほうが
面倒じゃないな って感じで存在しているのかとは
思っているのですが、真実はわかりませんし
ここは読み飛ばしてください・・・。


やることがわかったので、後は座標系の指定と座標値の入力を
追加してやれば良いですね。

Sub CATMain()

    Dim partDocument1 As PartDocument
    Set partDocument1 = CATIA.ActiveDocument
    
    'セレクション
    Dim Sel As Variant 'Selectionだとエラーになります
    Set Sel = partDocument1.Selection
    
    '選択の為のフィルター
    Dim Filter As Variant
    Filter = Array("AxisSystem")
    
    '座標系選択
    Dim Msg As String
    Msg = "座標系を選択してください / ESC-中止"
    
    Sel.Clear
    Select Case Sel.SelectElement2(Filter, Msg, False)
        Case "Cancel", "Undo", "Redo"
            Exit Sub '中止
    End Select
    
    '選択した座標系を代入
    Dim axisSystem1 As AxisSystem
    Set axisSystem1 = Sel.Item(1).Value
    
    '座標値入力
    Msg = "座標値を入力して下さい。 例)10,20,30"
    
    Dim PosStr As String
    PosStr = InputBox(Msg, , "10,20,30")
    
    If PosStr = vbNullString Then Exit Sub '空欄/キャンセル中止
    
    '入力値判断
    Dim PosStrAry As Variant
    PosStrAry = Split(PosStr, ",")
    
    If UBound(PosStrAry) < 2 Then Exit Sub 'XYZ分無いので中止
    
    '文字を数値化
    Dim Pos(2) As Variant
    Dim i As Long
    For i = 0 To 2
        If Not IsNumeric(PosStrAry(i)) Then
            Exit Sub '数字じゃないので中止
        End If
        Pos(i) = CDbl(PosStrAry(i))
    Next
    
    Dim part1 As Part
    Set part1 = partDocument1.Part
    
    Dim hybridShapeFactory1 As HybridShapeFactory
    Set hybridShapeFactory1 = part1.HybridShapeFactory
    
    Dim hybridShapePointCoord1 As HybridShapePointCoord
'    Set hybridShapePointCoord1 = hybridShapeFactory1.AddNewPointCoord(10#, 20#, 30#)
    Set hybridShapePointCoord1 = hybridShapeFactory1 _
                        .AddNewPointCoord(Pos(0), Pos(1), Pos(2))
    
'    Dim axisSystems1 As AxisSystems
'    Set axisSystems1 = part1.AxisSystems
'
'    Dim axisSystem1 As AxisSystem
'    Set axisSystem1 = axisSystems1.Item("座標系.2")
    
    Dim reference1 As Reference
    Set reference1 = part1.CreateReferenceFromObject(axisSystem1)
                                    '選択した座標系です↑
    
    hybridShapePointCoord1.RefAxisSystem = reference1
    
    Dim hybridBodies1 As HybridBodies
    Set hybridBodies1 = part1.HybridBodies
    
    Dim hybridBody1 As HybridBody
    Set hybridBody1 = hybridBodies1.Item("形状セット.1")
    
    hybridBody1.AppendHybridShape hybridShapePointCoord1
    
    part1.InWorkObject = hybridShapePointCoord1
    
    part1.Update

End Sub

追記した部分にはコメントを入れ、不要部分はコメント化して残りました。
(個人的には嫌いなのですが、この方がわかりやすいと思ったので)

"形状セット.1" が必要になりますが、これで動作すると思います。
これで、目的の半分は達成しました。



続いて、"Excelから" ですが、これを "外部から" と置き換え進めます。
探したところ過去にこれを書いていました。

仕方なく、OOoBasicをやってみました3 - C#ATIA

外部の場合は、記録を取ったマクロの冒頭の

Sub CATMain()

    Dim partDocument1 As PartDocument
    Set partDocument1 = CATIA.ActiveDocument

  ・・・

の "CATIA" が見当たらないので、リンク先のような記述で
"CATIA" を教えてあげれば良いだけです。
(但し、CATIAが起動している状態で実行が条件です)

つまり、Excelのボタンのクリックイベントに

Sub CATMain()
    
    Dim Cat As Application
    Set Cat = CreateObject("CATIA.Application")
    
    Dim partDocument1 As PartDocument
'    Set partDocument1 = CATIA.ActiveDocument
    Set partDocument1 = Cat.ActiveDocument

  ・・・

の様に記載すれば、同じような動作が出来ます。
(やったことは無いのですが、PythonRuby等の他言語同様です)

恐らく
"点は、多数作成したい"
"毎回、座標系を指定するのは面倒"
"セルの値を元に、点を作成したい"
等もあるかと思いますので、わからない事があれば
コメント下さい。(メールはあまりチェックしていないもので・・・)


追記です。
参照設定について記載し忘れました。

「参照設定が不要」 なのではなく 「参照設定なしでも動きます」
です。 OOoBasicのところにも記載しましたが、参照設定無しで
行う場合は全て置換機能で「As 」 → 「'As 」に置き換えコメント化
させてしまいます。

Excel側で参照設定を行う場合は、CATIAのVBエディタで参照設定
されているものを同様に設定する必要があります。
が、面倒なのが本音です。
こちらは以前のC#時の画像がありますが、
DotNetでCATIA V5のマクロを作成する際の準備 - C#ATIA
それっぽい名称になっているため、控えていなくても
何となくチェックを入れるべきものはわかるかと思います。