直線のベクトルを取得してリストに表示するマクロ|CATIAマクロの作成方法
今回の記事はマクロ案募集でいただいた内容です。
送って頂いた内容は以下のようなマクロです。
形状セット内の線のベクトルを測定し画面に表示orエクセルを転記するマクロ
「ベクトルを測定して画面に表示」というものがどういうものかイメージできなかった、かつそのベクトルを最終的にどのように使うのかがわからなかったため、かなり私個人の解釈で作っています。
送って頂いたマクロ内容との認識が合っているかわかりませんが、ここでは「形状セット内の直線の単位ベクトルを取得し、その成分(x,y,z)をユーザーフォームを使って画面に表示するマクロ」を紹介していきます。
もし「思ってたマクロと違うよ!」という場合は、再度ご連絡ください。
※「お問い合わせ」からご連絡頂ければメールでのやり取りができるため、認識のズレが起きることなく目的のマクロに近づけられる可能性が高いです。
作成するマクロの内容
今回作成するマクロは先にも述べているとおり「形状セット内の直線の単位ベクトルを取得し、その成分(x,y,z)をユーザーフォームを使って画面に表示するマクロ」です。
マクロの完成イメージとしては以下のような感じです。
形状セットを選択するとユーザーフォームが立ち上がり、各直線の単位ベクトルを表示します。
・取得したすべてのベクトルをユーザーフォームでリスト表示
・リストの項目をクリックすると、それに対応した直線がCATIA上でも選択される
・[コピー]ボタンを押すと左下のテキストボックスの内容をコピーできる
※現在ExcelとCATIAが連携できない環境にいるためExcelに書き出す方法は解説していません。
Excelへの転記方法は「CATIAマクロでExcelを操作する方法」のサンプルマクロを参照ください。
マクロ実行のための事前準備
今回のマクロではユーザーフォーム(UserForm)を使っているので、事前にユーザーフォームを作っておく必要があります。
マクロライブラリー上で左クリックし[Insert]>[UserForm]をクリックします。
するとユーザーフォームが作成されるので、プロパティウィンドウから名前(Name)を「UserForm1」に変更します。(初めて作成する場合はデフォルトで「UserForm1」となっています)
次に今回のマクロで使用する「Label」「ListBox」「TextBox」「CommandButton」というコントロールも事前に作成しておきます。[ToolBox]ウィンドウの各アイコンをクリックし以下のように配置してください。(※大きさや配置はコード上で行うため、適当な位置に配置するだけでOKです)
コントロールが作成できたらユーザーフォームのときと同じように名前を変更します。
(新規作成の場合はどれもデフォルトネームとなっています)
Label → Label1
ListBox → ListBox1
TextBox → TextBox1
CommandButton → CommandButton1
以上で事前準備は完了です。上記で設定した名前のユーザーフォームとコントロールが”存在”さえしていればこのマクロの実行は可能になります。
完成コード
マクロの完成コードは以下のとおりです。
モジュールに入力するコードとユーザーフォームに入力するコードがあります。
モジュール(Module1)コード
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 |
'<モジュールコード> Option Explicit Public SELArray() Public SEL 'UserForm1でも使うため「Public」で宣言 Sub CATMain() On Error Resume Next 'キャンセル時にエラーが出るので無視させる Set SEL = CATIA.ActiveDocument.Selection SEL.Clear Dim FilterArray(0) FilterArray(0) = "HybridBody" '形状セット(HybidBody)以外は選択できないようにする Dim Msg As String Msg = "形状セットを選択してください。" Select Case SEL.SelectElement2(FilterArray, Msg, False) Case "cancel", "undo", "redo" Exit Sub 'キャンセルしたらマクロを終了 End Select Dim SELHB As AnyObject Set SELHB = SEL.Item(1).Value 'SELHBにユーザーが選択した形状セットを入れる SEL.Add SELHB SEL.Search ("type=直線,sel") 'SELHB内の直線を検索&選択(英語環境の場合は[直線]を[Line]に変更) 'SELHB内の直線の数をカウント Dim SELCou As Integer SELCou = SEL.Count '形状セットの中身を確認 If SELCou = 0 Then MsgBox "選択した形状セットには[直線]が入っていません。" Exit Sub End If ReDim SELArray(SELCou) 'はじめに宣言した配列の中身をSELCou個にする Dim GetArray(3) '単位ベクトル(x,y,z)を格納する配列を用意 Dim i As Integer For i = 1 To SELCou Dim SELLine '(As Line) ← Variant型で宣言 Set SELLine = SEL.Item(i).Value '直線の単位ベクトル成分を取得 GetArray(3) = SELLine.GetDirection(GetArray) Dim x1 As Double Dim y1 As Double Dim z1 As Double '小数点第2位までの値に変換して各成分に代入 x1 = Round(GetArray(0), 2) y1 = Round(GetArray(1), 2) z1 = Round(GetArray(2), 2) 'UserForm1にあるListBox1の中に取得した値を代入 With UserForm1.ListBox1 .ColumnCount = 4 .ColumnWidths = "58;43;43;43" .AddItem "" .List(i - 1, 0) = SELLine.Name .List(i - 1, 1) = x1 .List(i - 1, 2) = y1 .List(i - 1, 3) = z1 End With Set SELArray(i) = SELLine 'SETHB内の直線を上から順に配列の中に入れていく(UserFormコード ※1のため) Next i UserForm1.Show vbModeless 'UserFrom1を起動 SEL.Clear End Sub |
ユーザーフォーム(UserForm1)コード
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 |
'<ユーザーフォームコード> Option Explicit Private Sub UserForm_Initialize() 'このUserFormが表示された時に以下を実行 'UserForm1のプロパティ調整 With Me .Caption = "単位ベクトル成分取得" .Width = 220 .Height = 165 End With 'ListBox1のプロパティ調整 With Me.ListBox1 .Left = 10 .Top = 20 .Width = 195 .Height = 90 .SetFocus End With 'Label1のプロパティ調整 With Me.Label1 .Left = 10 .Top = 10 .Width = 194 .Caption = " 名称 | X | Y | Z " .BorderStyle = fmBorderStyleSingle End With 'TextBox1のプロパティ調整 With Me.TextBox1 .Left = 10 .Top = 117 .Width = 100 .TextAlign = fmTextAlignCenter .Height = 18 End With 'CommandButton1のプロパティ調整 With Me.CommandButton1 .Caption = "コピー" .Left = 143 .Top = 117 .Height = 18 .Width = 60 End With End Sub '―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― Private Sub CommandButton1_Click() 'CommandButton1をクリックしたとき以下を実行 'TextBox1の値を選択しコピー With TextBox1 .SelStart = 0 .SelLength = Len(.Value) .Copy End With End Sub '―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― Private Sub ListBox1_Click() 'ListBox1をクリックしたとき以下を実行 SEL.Clear '取得した成分を『(x,y,z)』のかたちでTextBox1に表示 TextBox1.Value = "( " & ListBox1.List(ListBox1.ListIndex, 1) & " , " & _ ListBox1.List(ListBox1.ListIndex, 2) & " , " & _ ListBox1.List(ListBox1.ListIndex, 3) & " )" 'リストで選択したものを仕様ツリー上でも選択状態にする ※1 SEL.Add SELArray(ListBox1.ListIndex + 1) End Sub |
※Project Explorerの左上にある[View Code]アイコンをクリックするとユーザーフォーム内にコードを書くことが出来ます。
上記のコードはココに書き込んでください。
上記のコードの入力ができたらユーザーフォームではなくモジュールの方を実行します。(モジュールでUserForm1を呼び出すため)
コードの解説
今回は非常に長いコードのため、本マクロの核となる重要部分のみを抜粋して解説してきます。
※上記のコードにコメントである程度の説明を入れているためそれらも参照ください。
直線のベクトルを取得
まず大前提として今回のマクロの肝となるのが「直線のベクトルの取得方法」です。
ヘルプで「Vector」と検索したところ「Lineオブジェクト」のメソッドに「GetDirection」というものがありました。このメソッドの説明文は以下のとおりです。
Role: Returns the unit-vector pointing in the direction of the line.
(役割:直線の方向を指す単位ベクトルを返す)
「GetDirectionメソッド」は以下のようにして使うことができます。
1 2 3 4 5 6 7 8 9 10 11 |
Dim Array(3) Array(3) = Object.GetDirection(Array) '※Object ⇒ Lineが入っているオブジェクト Dim x1 As Double Dim y1 As Double Dim z1 As Double x1 = Array(0) '取得したX成分を[x1]に代入 y1 = Array(1) '取得したY成分を[y1]に代入 z1 = Array(2) '取得したZ成分を[z1]に代入 |
このメソッドは事前に用意しておいた配列の[0番目][1番目][2番目]のそれぞれに、取得した単位ベクトルの[X成分][Y成分][Z成分]を代入することができます。
このとき取得した数値はかなり細かく表示されるため、このマクロでは「Round関数」を使って小数点第2位までを取得するようにしています。(57~59行目)
変数 = Round(数値,桁数)
以上で本マクロの一番の重要ポイントである「直線のベクトルを取得」は終了です。
変数「x1」「y1」「z1」にそれぞれの単位ベクトル成分が代入されています。
取得した単位ベクトルをユーザーフォームのリストに表示
上記のメソッドで取得したベクトルを事前準備で作成した「ListBox1」に書き出していきます。
ListBox1に取得した数値を表示させるには、以下のように書きます。
1 2 3 4 5 6 7 8 9 |
With UserForm1.ListBox1 'UserBox1にあるListBox1に以下の内容を行う .ColumnCount = 4 '列の数を指定 .ColumnWidths = "58;43;43;43" '列の幅調整 .AddItem "" 'リストに書き出すために必要 .List(i - 1, 0) = SELLine.Name 'リストの1列目に直線の名前を書き出し .List(i - 1, 1) = x1 'リストの2列目にX成分を書き出し .List(i - 1, 2) = y1 'リストの3列目にY成分を書き出し .List(i - 1, 3) = z1 'リストの4列目にZ成分を書き出し End With |
今回はユーザーフォームに書き出しましたが、表示したい取得したい数値自体は変数「x1」「y1」「z1」の中にそれぞれ入っています。つまりこれら3つの変数を使えばテキストやExcelにも書き出すことが可能ということです。
はじめにも紹介した通り「CATIAマクロでExcelを操作する方法」のサンプルマクロと組み合わせればこれらの数値をExcelに書き出すことができます。
上記のページのサンプルマクロでは「GetCoordinates」という点の座標を取得するメソッドを使っており、今回の「GetDirectionメソッド」とほとんど同じ書き方なのですぐに理解できると思います。
まとめ
今回は「形状セット内の直線の単位ベクトルを取得し、その成分(x,y,z)をユーザーフォームを使って画面に表示するマクロ」についてでした。
特に重要なのは「Lineオブジェクト」の「GetDirectionメソッド」です。
これ以外のコードはほとんど取得した値をどのように表示するかについてのコードなので、マクロの機能的には最悪なくてもいいものが多いです。
つまり今回は表示方法がユーザーフォームであっただけで、MsgBoxでの表示にすればもっと単純なコードにすることができます。(UserForm1関連のコードは全ていらなくなります)
どのように表示するかはそのマクロの使用用途によって変わります。
今回のマクロで一番やりたいことは「直線のベクトルの取得方法」なので、表示方法は自分の使用用途に合わせて書き換えていきましょう。
CATIAマクロを本気で勉強するなら