直線のベクトルを取得してリストに表示するマクロ|CATIAマクロの作成方法

今回の記事はマクロ案募集でいただいた内容です。

送って頂いた内容は以下のようなマクロです。

形状セット内の線のベクトルを測定し画面に表示orエクセルを転記するマクロ

「ベクトルを測定して画面に表示」というものがどういうものかイメージできなかった、かつそのベクトルを最終的にどのように使うのかがわからなかったため、かなり私個人の解釈で作っています。

送って頂いたマクロ内容との認識が合っているかわかりませんが、ここでは「形状セット内の直線の単位ベクトルを取得し、その成分(x,y,z)をユーザーフォームを使って画面に表示するマクロ」を紹介していきます。

もし「思ってたマクロと違うよ!」という場合は、再度ご連絡ください。
※「お問い合わせ」からご連絡頂ければメールでのやり取りができるため、認識のズレが起きることなく目的のマクロに近づけられる可能性が高いです。

認識が間違ってたらごめんなさい!

 

作成するマクロの内容

今回作成するマクロは先にも述べているとおり「形状セット内の直線の単位ベクトルを取得し、その成分(x,y,z)をユーザーフォームを使って画面に表示するマクロ」です。

マクロの完成イメージとしては以下のような感じです。
形状セットを選択するとユーザーフォームが立ち上がり、各直線の単位ベクトルを表示します。

 icon-wrench マクロの機能まとめ ・選択した形状セット内の直線を単位ベクトルで取得する
・取得したすべてのベクトルをユーザーフォームでリスト表示
・リストの項目をクリックすると、それに対応した直線が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)コード

'<モジュールコード>

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)コード

'<ユーザーフォームコード>

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メソッド」は以下のようにして使うことができます。

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行目)

 icon-code Round関数の構文

変数 = Round(数値,桁数)

以上で本マクロの一番の重要ポイントである「直線のベクトルを取得」は終了です。
変数「x1」「y1」「z1」にそれぞれの単位ベクトル成分が代入されています。
 

取得した単位ベクトルをユーザーフォームのリストに表示

上記のメソッドで取得したベクトルを事前準備で作成した「ListBox1」に書き出していきます。
ListBox1に取得した数値を表示させるには、以下のように書きます。

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関連のコードは全ていらなくなります)

どのように表示するかはそのマクロの使用用途によって変わります。
今回のマクロで一番やりたいことは「直線のベクトルの取得方法」なので、表示方法は自分の使用用途に合わせて書き換えていきましょう。

 
目次へ戻る
 

icon-book CATIAマクロを本気で勉強するなら

 

2024年8月26日CATIA,CATIAマクロ