C#ATIA

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

CATIAのマクロをDotNetで作る事をオススメしない理由

MVVMお勉強中ですが、イヤになってきたので久々にC#でCATIAの
マクロをちょっと作ろうかなぁ と思ったのですが、諦めました。

何時かは書こうかと思っていたので、折角の機会なので。

1.マクロの記録が取れない

結構重要です。 個人的には各コマンド類(~Factory.AddNew~メソッド類)
や検索キーワード(Selection.Search "~")等は、イチイチ覚えていません。
必要な時に記録を取って、必要な部分だけ(大半が2行)コピーし後は
捨てています。こちらのマクロを作ったのは、その為です。
GrabCAD - CAD library


2.参照設定がシンドイ

こちらでは参照設定の方法を記載しましたが
DotNetでCATIA V5のマクロを作成する際の準備 - C#ATIA

こちらのコメント部に、imihitoさんアドバイスを頂きました。
Excelフォームボタンからマクロの起動 (未確認) - C#ATIA

CATIAっぽい全てのものを設定する必要は無いのですが、
結果的に何の参照が不足しているのかわからず、VBエディターを
開き、オブジェクトブラウザで該当するファイルを調べまくっている
と言うのが本音です。

3.デバッグが辛い

IDEを利用する利用の1つが、デバッグの行いやすさじゃないかと
思います。(インテリセンスもあるかもしれませんが)
個人的にはローカルウィンドウが重要で、変数の中身の状態が確認出来る
だけではなく、プロパティ類の中身をさかのぼって確認出来る点は
非常にありがたく、未知のオブジェクトを調べる際はかなり重宝します。
ところが、C#(DotNet)ではダメなんです。

こちらはVBAで"形状セット1"を選択した状態です。
f:id:kandennti:20171103175501p:plain
スケッチやジオメトリ(点・線・面)等も確認可能ですし、Parentをさかのぼって
行けばPartやPartDocumentも取得可能です。
(Documentが取得できれば、大半 事が足ります)

一方、C#の場合はこちら。
f:id:kandennti:20171103175513p:plain
"形状セット1"の名前すら確認出来ない状態です。 種類の部分は
”MECMOD.HybridBod{System.__ComObject}”と表示されていますが
これは形状セットとわかっている為、キャストした状態だからです。
キャストしないとこんな感じです。
f:id:kandennti:20171103175523p:plain
"INFITF.CATBaseDispatch" じゃ何だかわからないです。

GetTypeメソッドを利用しても

{Name = "__ComObject" FullName = "System.__ComObject"}

と返って来るだけ。 COMオブジェクトだってことは、GetTypeする前から
知ってます・・・。

COM相互運用が原因だとはわかっているのですが、
「動くようにしましたよ」ってだけで同等ではないです。

4.CATSafeArrayVariantが機能していない(と思った)

今日わかったのがこれです。これが書きたかったんです。

"CATSafeArrayVariant" は、点の座標値等受け取る際のもので
Variant配列です。 単純に面を選択し重心を所得する
VBAのコードです。

'vba using-'KCL0.0.12'
Sub CATMain()
    If Not CanExecute("PartDocument") Then Exit Sub
    
    Dim msg$: msg = "面を選択"
    Dim elm As SelectedElement
    Set elm = KCL.SelectElement(meg, "Face")
    If elm Is Nothing Then Exit Sub
    
    Dim doc As PartDocument
    Set doc = elm.Document
    
    Dim ref As Reference
    Set ref = elm.Reference
    
    Dim spa_wb As Object
    Set spa_wb = doc.GetWorkbench("SPAWorkbench")
    
    Dim mes As Variant 'Measurable
    Set mes = spa_wb.GetMeasurable(ref)
    
    Dim cog(2) As Variant 'これが CATSafeArrayVariant
    Call mes.GetCOG(cog)
    
    Debug.Print "重心 : "; Join(cog, ",")
End Sub

最後の方の "cog(2)" が、"CATSafeArrayVariant"です。
取得する際のGetCOGメソッドは、Measurableオブジェクトですが、
正しく型指定するとエラーになります。
(この手の、処理結果を引数のVariant配列に返す、悪魔仕様の
 ものは大半が型指定するとエラーになります)

同様の処理をC#でさせます。
(コードが長くなりすぎる為、例外処理はほぼしてません)

//cs ↓これらの参照設定必要です
using System.Runtime.InteropServices;
using INFITF;
using MECMOD;
using SPATypeLib;

    class Program
    {
        static void Main()
        {
            //モロモロ
            var cat = (INFITF.Application)Marshal.GetActiveObject("CATIA.Application");
            var doc = cat.ActiveDocument as MECMOD.PartDocument;

            //選択
            var msg = "面を選択";
            var sel = doc.Selection;
            var cancel_code = new string[] { "Cancel", "Undo", "Redo" };
            var filter = new object[] { "Face" };

            sel.Clear();
            string res = sel.SelectElement2(filter, msg, false);
            if (cancel_code.Any(x => x.ToString() == res)) { return; }

            var face_ref = sel.Item2(1).Reference;

            //SPAWorkbench
            var SpaWB = doc.GetWorkbench("SPAWorkbench") as SPAWorkbench;
            if (SpaWB == null) { return; }

            //Measurable
            var mes = SpaWB.GetMeasurable(face_ref);

            //重心
            var cog = new object[3];
            mes.GetCOG(cog);

            Console.WriteLine(string.Format(
                "重心 : {0},{1},{2}", cog[0], cog[1], cog[2]));
            Console.ReadKey();
        }
    {

VBAのVariant配列は、C#の場合object配列です。 これ

            mes.GetCOG(cog);

ここでエラーになる予定だったのですが、正しく処理してます・・・。
不安定ですね・・・。本当は

            var mes_oj = mes as object;
            mes_oj.GetCenter(cog);

だと、型付けが邪魔で出来ないから

            dynamic mes_oj = mes as object;
            mes_oj.GetCenter(cog);

にしたけど、やっぱりエラーになるよ って書きたかったのですけどね。

こちらでも機能してないって書いてあるんですけど。
http://www.coe.org/p/fo/st/per=10&sort=0&thread=24278&p=1




他にも 
C#だと "遅い" → どうでも良いです。
DLL化すれば同レベルで処理します。(要レジストリに登録ですが)

C#だと配布しやすい → catvbsやvbsでも同様です。

・catvbsやvbsだとソースコード見られちゃう
  → CATVBAでパスワード付けるか。
 vbsを暗号化
VBScriptの暗号化 | VBScript さんま屋


・他言語熟知者にとってのVBAの学習コスト 
  →VBA異質だから、結構納得。

検索すると結構 "PythonでCATIAのマクロ" がHitするのですが、
動的型付け言語の方がC#より向いている気がします。

現状、DotNetで作る価値が見つかりませんね。

※追記です
GetCOGのパラメータです。
f:id:kandennti:20171106092508p:plain
配列としか出ていませんでした。

Drawのテーブルに最後の列を追加2

こちらの続きです。
Drawのテーブルに最後の列を追加 - C#ATIA

前回のマクロ、ちょっとダメなんです。
セルの文字だけのコピーだったので、フォントのボールド等が正しくなかったのです。
f:id:kandennti:20171027123422p:plain

寸法テーブルのサイズ変更する方法をmineさんに教えて
頂いたのですが、実際に使う際、一定しない列数を追加し
テーブルの見出し? も入れたいのです。
f:id:kandennti:20171027123434p:plain
結構めんどくさいんです。

そこで修正してみました。

'vba DrawTable_Add_LastColumn ver0.0.2  using-'KCL0.0.12'  by Kantoku

Option Explicit

Private Const Def = "hoge,piyo,huga" 'デフォルト文字

Sub CATMain()

    'ドキュメントのチェック
    If Not CanExecute("DrawingDocument") Then Exit Sub

    'テーブル選択
    Dim Msg As String
    Msg = "列を追加するテーブルを選択 // [Esc]=Cancel"
    
    Dim Tbl As DrawingTable
    Set Tbl = KCL.SelectItem(Msg, "DrawingTable")
    If Tbl Is Nothing Then Exit Sub
    
    'ユーザー
    Msg = "追加するタイトルを入力 例)hoge,piyo""
    Dim Inp As String
    Inp = InputBox(Msg, "", Def)
    If Inp = vbNullString Then Exit Sub
    
    '追加数列
    Dim Txts As Variant: Txts = Split(Inp, ",")
    Dim AddCnt As Long: AddCnt = UBound(Txts) + 1
    
    '元列数
    Dim CntCol As Long: CntCol = Tbl.NumberOfColumns
    Dim AllColCnt As Long: AllColCnt = CntCol + AddCnt
    
    '列追加
    Tbl.ComputeMode = CatTableComputeOFF
    
    Dim i As Long
    For i = 1 To AddCnt
        Call Tbl.AddColumn(CntCol)
    Next
    
    '最後を追加の最初にコピー
    Call Copy_Column(AllColCnt, CntCol, Tbl)
    
    '空欄設置
    Call Reset_Column(CntCol + 1, AllColCnt, Tbl)
    
    'タイトル設置
    Call Set_Title(Txts, 25#, Tbl)
    
    Tbl.ComputeMode = CatTableComputeON
End Sub

Private Sub Set_Title(ByVal Ary As Variant, _
                      ByVal Width As Double, _
                      ByVal Tbl As DrawingTable)
    Dim Ed As Long: Ed = Tbl.NumberOfColumns
    Dim St As Long: St = Ed - UBound(Ary)
    
    Dim i As Long, Cell As DrawingText
    Dim Cnt As Long: Cnt = 0
    
    For i = St To Ed
        Call Tbl.SetColumnSize(i, Width)
        Set Cell = Tbl.GetCellObject(1, i)
        Cell.Text = Ary(Cnt)
        Cnt = Cnt + 1
        Cell.TextProperties.Justification = catCenter
    Next
End Sub

Private Sub Reset_Column(ByVal A As Long, _
                         ByVal B As Long, _
                         ByVal Tbl As DrawingTable)

    Dim Vw As DrawingView: Set Vw = Tbl.Parent.Parent
    Dim Dmy As DrawingText: Set Dmy = Vw.Texts.Add("", 0#, 0#)
    Dmy.TextProperties.Justification = catCenter
    
    Dim CntRow As Long: CntRow = Tbl.NumberOfRows
    Dim Cell As DrawingText
    Dim i As Long
    
    For i = 1 To CntRow
        Set Cell = Tbl.GetCellObject(i, B)
        Call Copy_DrwTxtProperties(Cell.TextProperties, _
                                   Dmy.TextProperties)
        Cell.Text = ""
    Next
    
    For i = B To A + 1 Step -1
        Call Copy_Column(i, i - 1, Tbl)
    Next
    
    Dim Sel As Selection
    Set Sel = KCL.GetParent_Of_T(Vw, "DrawingDocument").Selection
    With Sel
        .Clear
        .Add Dmy
        .Delete
    End With
End Sub

Private Sub Copy_Column(ByVal A As Long, _
                        ByVal B As Long, _
                        ByVal Tbl As DrawingTable)
    Dim CntRow As Long: CntRow = Tbl.NumberOfRows
    Dim Cell(1) As DrawingText
    Dim TxtPpt(1) As DrawingTextProperties
    Dim i As Long
    
    For i = 1 To CntRow
        Set Cell(0) = Tbl.GetCellObject(i, A)
        Set Cell(1) = Tbl.GetCellObject(i, B)
        Call Copy_DrwTxtProperties(Cell(0).TextProperties, _
                                   Cell(1).TextProperties)
        Cell(1).Text = Cell(0).Text
    Next
End Sub

Private Sub Copy_DrwTxtProperties(ByVal Tpp1 As DrawingTextProperties, _
                                  ByVal Tpp2 As DrawingTextProperties)
    With Tpp2
        .AnchorPoint = Tpp1.AnchorPoint
        .Blanking = Tpp1.Blanking
        .Bold = Tpp1.Bold
        .Color = Tpp1.Color
        .FONTNAME = Tpp1.FONTNAME
        .FONTSIZE = Tpp1.FONTSIZE
        .FrameName = Tpp1.FrameName
        .FrameType = Tpp1.FrameType
        .Italic = Tpp1.Italic
        .Justification = Tpp1.Justification
        .Kerning = Tpp1.Kerning
        .Mirror = Tpp1.Mirror
        .Overline = Tpp1.Overline
        .StrikeThru = Tpp1.StrikeThru
        .Subscript = Tpp1.Subscript
        .Underline = Tpp1.Underline
    End With
End Sub

見事な肥大化っぷり・・・。
最初の時点ではかなり遅かったのですが、DrawingTable.ComputeModeを
利用するとストレスを感じるほどでは無くなりました。

マクロ実行後、ダイアログが出現しカンマ区切りで文字を入力すると
区切った分の列を追加し、見出しとして入力されます。

作ったけど、使うかなぁ・・・。

Drawのテーブルに最後の列を追加

Drawの穴寸法/座標寸法テーブルで、最後の列を増やしたい事が
結構あるのですが、恐らく手動では出来ないような気がしてます。
手動で出来ます(コメント部で、mineさんに教えて頂きました)
f:id:kandennti:20171023192119p:plain
(方法知っている方いらっしゃいましたら、教えて頂けると助かります)

仕方ないので、マクロを作成しました。

'vba DrawTable_Add_LastColumn ver0.0.1  using-'KCL0.0.12'  by Kantoku

Option Explicit

Sub CATMain()

    'ドキュメントのチェック
    If Not CanExecute("DrawingDocument") Then Exit Sub

    'テーブル選択
    Dim Msg As String
    Msg = "最後に列を追加するテーブルを選択 // [Esc]=Cancel"
    
    Dim Tbl As DrawingTable
    Set Tbl = KCL.SelectItem(Msg, "DrawingTable")
    If Tbl Is Nothing Then Exit Sub
    
    '一列追加
    Dim CntCol As Long: CntCol = Tbl.NumberOfColumns
    Call Tbl.AddColumn(CntCol)
    
    'コピー
    Dim CntRow As Long: CntRow = Tbl.NumberOfRows
    Dim Txt As String, i As Long
    
    For i = 1 To CntRow
        Txt = Tbl.GetCellString(i, CntCol + 1)
        Call Tbl.SetCellString(i, CntCol, Txt)
        Call Tbl.SetCellString(i, CntCol + 1, "")
    Next
End Sub

最後から2番目の位置に列を追加し、最後の列をコピーしつつ
最後の列を空欄にしています。(vbNullStringではNG)

コード的にはくだらないのですが、これを手動でやると本当に
手間がかかるんですよね。Excelの様に複数のセルをまとめて
コピー出来ないですし。

・・・最後に追加出来ない! ってMS製品でも多いですよね?

参考寸法

手抜きメニューに登録しながらマクロを修正していたら
地味なヤツを見つけました。

こんな感じの、丸括弧付きの寸法って何と呼ぶのが正式なんでしょうか?
(きっとJISとかで決まっていると思うのですが)

f:id:kandennti:20171020102205p:plain

僕は参考寸法と呼んでいます。 こちらでもそんな記載になってます。
寸法の記入の基本ルール
「2重寸法の禁止」の所に記載されています。
(個人的に重複した寸法は、かなり重罪です)

こちらでは括弧寸法と記載されていました。
括弧寸法の使い方をここまで細かく語るエンジニアはいない | メカ設計のツボ|マザーマシンの元エンジニアが語る


これ、図面を描いているAdvanceCADには、寸法をクリックしただけで
行ってくれる機能があるのですが、CATIAには無いですよね?

これを行うだけのマクロです。

'vba Sample_Draw_Ref_Dimension ver0.0.2  using-'KCL0.0.12'

Option Explicit

Private Enum Dimension_Value
    Main_Value = 1
    Dual_Value = 2
End Enum

Sub CATMain()

    'ドキュメントのチェック
    If Not CanExecute("DrawingDocument") Then Exit Sub
    
    Dim Msg$: Msg = "参考/非参考化する寸法を選択 // [Esc]=Cancel"
    Dim DrwDim As DrawingDimension
    Dim DimVal As Variant 'DrawingDimValue
    Dim Bfr$, Afr$, Upr$, Lwr$
    
    Do
        Set DrwDim = KCL.SelectItem(Msg, "DrawingDimension")
        If DrwDim Is Nothing Then Exit Sub
        
        Set DimVal = DrwDim.GetValue
        Call DimVal.GetBaultText(Dimension_Value.Main_Value, _
                                 Bfr, Afr, Upr, Lwr)
        If IsRefDimension(Bfr, Afr) Then
            '既に参考寸法
            Call DimVal.SetBaultText(Dimension_Value.Main_Value, _
                                    Mid(Bfr, 2), _
                                    Left(Afr, Len(Afr) - 1), _
                                    Upr, Lwr)
        Else
            'ただの寸法
            Call DimVal.SetBaultText(Dimension_Value.Main_Value, _
                                    "(" & Bfr, _
                                    Afr & ")", _
                                    Upr, Lwr)
        End If
    Loop
End Sub

Private Function IsRefDimension(ByVal Bfr As String, _
                                ByVal Afr As String) As Boolean
    IsRefDimension = False
    
    If Bfr = vbNullString Or Afr = vbNullString Then Exit Function
    
    Dim Tp$, Ed$
    Tp = Left(Bfr, 1)
    Ed = Right(Afr, 1)
    
    If Tp = "(" And Ed = ")" Then IsRefDimension = True
End Function

寸法のプロパティの [寸法テキスト]タブ [関連テキスト] の
・前側の最初の文字が「(」
・後側の最後の文字が「)」
の二つの条件がそろった時に、丸括弧を外し
そうでないときは丸括弧を追加します。
f:id:kandennti:20171020102233p:plain

こんな感じです。

・・・地味

手抜きマクロ起動用メニュー3

こちらの続きです。
手抜きマクロ起動用メニュー2 - C#ATIA

「Cat_Macro_Menu_Model.bas」の宣言セクション部に幾つか定数を
設けています。お好みで変更してください。

'Cat_Macro_Menu_Model.bas
'using-'KCL0.0.12'
'タグを追記したモジュールをプロジェクトに追加するだけで
'自動的にボタンを追加します

Const FormTitle = "Macro"

'----- メニューの仕様 お好みで ---------------------------------------

'メニューの表示方法
'True-モーダレス表示  False-モーダル表示
Private Const MENU_SHOW_TYPE = True

'メニューを閉じるタイミング
'True-フォームのXボタンを押して閉じます False-ボタンクリック後閉じます
Private Const MENU_HIDE_TYPE = True

'メニューのマルチページの設定
'変更する際は
'{ タグのグループ番号 : ページのタイトル文字 }
'の状態にして下さい
Private Const GROUP_NUMBER_CAPTION = _
            "{ 1 : Part }" & _
            "{11 : Assy }" & _
            "{21 : Draw }" & _
            "{51 : Other }"
'-----------------------------------------------------------------
・・・

・「MENU_SHOW_TYPE」
  メニューの表示で、モーダレスかモーダルかをBoolean型で切り替えられます。

・「MENU_HIDE_TYPE」
  メニュー終了タイミングですが、Upしたデータのコメント間違えていました・・。
  正しくは上記の状態で、Boolean型で切り替えられます。
  ボタンクリック後に終了させるか、表示しっぱなしかです。

  実質、「モーダレス + 表示しっぱなし」 か 「モーダル + クリック後終了」
  に、なるのだろうと思います。

・「GROUP_NUMBER_CAPTION」
  マルチページの分類と表示させる文字になります。
  挿入する標準モジュールの {Gp}タグは、こちらの番号にない場合は
  ボタンが表示されません。


続いて、フォームコードの「Cat_Macro_Menu_View.frm」の宣言セクション部です。
フォームのレイアウト等はこちらの定数で、若干調整が可能です。
(環境によってはボタンの文字が途切れる等あるかもしれないため・・・))

'Cat_Macro_Menu_View.frm
'メニューのUIです。

'フォーム
Private FrmMargin As Variant '上,下,左,右のボタン配置のマージン
Private Const ADJUST_F_W = 13 'フォームの左右の調整幅
Private Const ADJUST_F_H = 30 'フォームの上下の調整幅

'マルチページ
Private Const ADJUST_M_W = 5 'マルチページの左右の調整幅
Private Const ADJUST_M_H = 18 'マルチページの上下の調整幅

'ボタン
Private Const BTN_W = 70 'ボタンの幅-フォームの最低幅以下にすると余白が増える
Private Const BTN_H = 20 'ボタン1個の高さ

・・・

各マルチページに該当するボタンがない場合は、ページ自体が作成されません。
又、各ページに配置されるボタンの順番は、モジュール名でソートして表示させています。
好みの順番で表示させたい場合は・・・・モジュール名を工夫してください。
(良いアイデアが思いつきませんでした)

あと何か有ったかなぁ? マクロ用のメニューなんて今更だし。


念の為、このままではOffice製品では機能しないです。

プロジェクト名・パスの取得方法は、imihitoさんが
こちらのコメント欄に記載して頂いてます。
実行中のプロジェクト名とパス取得する - C#ATIA

ボタン押した際の各マクロの実行方法は、こちらの
「Application.Run」の方法で可能だろうと思います。
外部のマクロを実行する2 - C#ATIA


正規表現もまともに使ったの初めてでしたし、まさか自分が
CallByNameを使うコードを書く日が来るとは思っていませんでしたよ。

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
それっぽい名称になっているため、控えていなくても
何となくチェックを入れるべきものはわかるかと思います。

手抜きマクロ起動用メニュー2

こちらの続きです。
手抜きマクロ起動用メニュー1 - C#ATIA

CATVBAプロジェクトにマクロのモジュールを追加するだけで、
メニューボタンを自動的に追加します。

但し、追加するモジュールにボタンとなる情報を追記する
必要が有り、以下 [タグ] と表記して説明します。


〇ファイルの構成
同一のプロジェクト内に以下のファイルをD&Dで追加してください。

・Cat_Macro_Menu_Model.bas
・Cat_Macro_Menu_View.frm
・Cat_Macro_Menu_View.frx
・Button_Evt.cls
・KCL.bas

f:id:kandennti:20171017152458p:plain
ツールバーに登録する、通常のマクロのメニューから起動する際は
「Cat_Macro_Menu_Model.bas」の「CATMain」を指定してください。

〇タグ記載位置
タグは各モジュールの宣言セクション(先頭部分)に記載する必要が有ります。
f:id:kandennti:20171017152335p:plain
こちらで説明されている宣言セクションになります。
Office TANAKA - VBAの変数[変数の適用範囲]

特に注意が必要なのは、上記の赤矢印のラインより上に記載する
と言うことです。
このような状態(ラインがない状態)ではタグを認識する事が
出来ない為メニューにボタンが表示されません。
f:id:kandennti:20171017152345p:plain

こちらの様に出来るだけ [Option Explicit] を宣言し、
その上にタグを記載する事をオススメします。
f:id:kandennti:20171017152427p:plain


〇タグフォーマット
タグのフォーマットは
{ キーワード : 値 }
の状態になっている必要が有ります。("{" ":" "}" は半角です)
Upしたサンプルでは1行に1タグになっていますが。

'{GP:1}{BackColor:12648447}
Option Explicit

Sub CATMain()
    MsgBox "hoge"
End Sub

の様に一行に複数のタグを記載しても大丈夫です。
※タグのキーワードは半角文字で大・小文字は問いません


〇タグ内容
タグは自動生成するボタンの情報を記載する必要が有ります。
{Gp} : グループの略称でボタン作成する際は必須です。
   値はLong型で指定してください。

   メニュー内のどのタブにボタンを作成するかを示しています。
   Upしたファイルの「Cat_Macro_Menu_Model.bas」の宣言セクション部
   の「GROUP_NUMBER_CAPTION」定数部分の数値と一致させる
   必要が有ります。

'vba CATIA V5用 マクロ起動(テヌキ)メニュー Ver0.0.1  by Kantoku
'Cat_Macro_Menu_Model.bas
'using-'KCL0.0.12'

・・・

'メニューのマルチページの設定
'変更する際は
'{ タグのグループ番号 : ページのタイトル文字 }
'の状態にして下さい
Private Const GROUP_NUMBER_CAPTION = _
            "{ 1 : Part }" & _
            "{11 : Assy }" & _
            "{21 : Draw }" & _
            "{51 : Other }"
・・・

   現状では、1-Part 11-Assy 21-Draw 51-Other
   の設定になっているので、任意の数値を記載してください。
   
   逆にライブラリのようなモジュールファイルの場合、ボタンを作成したくない
   はずです。{Gp}タグを記載しない事でメニューに表示させない事に
   なります。

{Ep} : エントリーポイントの略称で任意の設定で、値は文字列型です。
   各モジュールのエントリーポイント(実行されるプロシージャ名)を指定
   しますが、省力時は「CATMain」になります。

   Upしている「sample_IsExists_LeftAxis.bas」では
   「CATMain」が無く、以下の状態になっています。

'vba sample_IsExists_LeftAxis_ver0.0.1  using-'KCL0.0.12'  by Kantoku
'Part内の左手座標系の有無チェック

'{Gp:1}
'{Ep:LeftHand}
'{Caption:LeftHandAxis}
'{ControlTipText:Part内の左手座標系の有無チェック}
'{BackColor:33023}
Option Explicit

Sub LeftHand()
    'ドキュメントのチェック
    If Not CanExecute("PartDocument") Then Exit Sub
・・・

   {Ep:LeftHand}となっており、ボタンを押した際
   「LeftHand()」が実行されるようになっています。

   {Ep}タグで指定されたプロシージャが見つからない場合は
   自動的に「CATMain」を探しますが、両方見つからない場合は
   ボタンが作成されません。

   制限としてチェックがちょっと甘く「Private Sub」や「Function」
   となっているプロシージャは指定しないで下さい。

   又、引数付きのプロシージャも指定しないで下さい。

他は全てでは有りませんが、CommandButtonオブジェクトのプロパティを
指定する事が可能です。制限はこちらです。
・レイアウトを維持する為これらのキーワードを指定しても
 無視されます。
「Top」「Left」「Height」「Width」

・プロパティの値がオブジェクトとなっているものは指定されても
 無視されます。
「Font」「MouseIcon」「Picture」

・プロパティの値が定数となっている場合、定数ではなく
 数値で指定する必要があります。(後に説明します)

{Caption} : ボタンに表示される文字で、値は文字列型です。
   何のマクロのボタンかわからなくなるため設定を推奨します。

{ControlTipText:} : ボタン上にマウスカーソルを持っていく
   ことでに表示される文字で、値は文字列型です。
   何のマクロのボタンかわからなくなるため設定を推奨します。

{BackColor}:ボタンの色で、値はLong型です。
   通常プロパティでは、[&H000000FF&]のような状態で
   表示されていますが、値部分にそのまま入力しても
   色は反映されません。
f:id:kandennti:20171017152557p:plain
   イミディエイトウインドウで「?」(又はprint)で表示させると
   Long型の値が返って来ますので、この値を設定してください。

?&H000000FF&
 255 

   又、定数を指定いるプロパティに関しても同様の方法で
   Long型で設定してください。
   ・・・正直に書くと、試していませんが。



タグについてグダグダ記載しましたが、見た目。機能を
度外視すれば

'{Gp:1}

さえ追記すれば、メニューにボタンが表示されるようになります。

フォーム側の説明は次回に