AutoCAD VBAで曲線の長さを取得する方法|AutoCAD VBAマクロの作成方法

AutoCAD VBAで曲線の長さを取得する際、線分やポリラインであれば、Lengthプロパティから簡単に取得することができます。しかし、円や円弧、楕円、スプラインなど、Lengthプロパティが用意されていない曲線オブジェクトも存在しているため、「曲線」とひとまとめにいっても、Lengthプロパティにアクセスするだけの単純な処理では長さを取得できない場合があります。

こんな時に役立つのが、AutoCADの自動化ツールとしてVBAと並んで使用されるAutoLISPです。AutoLISPには、線分、ポリライン、円弧、楕円、スプラインなどの曲線(AcDbCurve)の長さを取得するための「vlax-curve-getDistAtParam関数」が用意されています。この関数を利用することで、VBAからAutoLISPを経由して曲線の長さを簡単に取得することが可能になります。

 

曲線の長さを測定する関数

下記はAutoCADの要素(AcadEntity)を入力として、曲線が入力されたらその長さを返し、曲線以外の要素が入力された場合は「-1」を返す関数です。曲線の長さの測定はVBAではなくLISPのvlax-curve-getDistAtParam関数を使っているため、VBA処理の中で一度LISPに処理を渡しています。

AutoCADはコマンドラインに直接LISPコードを入力して実行することができるため、LISPファイル(.lsp)などの外部ファイルは作成せずに、VBAからコマンドラインに直接”文字列として”LISPコードを送信して実行させています。LISPを使ってはいますがファイルとしてはdvbのみで実行可能です。
 

 LISP処理抜粋

LISPの処理だけ抜粋すると下記のようなコードとなっており、VBAでは下記のコードを文字列として動的に作成し、コマンドラインに送信することでVBAの処理の一部としてLISPを利用しています。

このLISPコードでは長さを測定する対象の曲線のオブジェクトID(obj-id)を入力として、測定結果をシステム変数のUSERR1に格納するというような処理を行っています。最終的にVBAはシステム変数に格納された値を参照することでLISPで測定した値を取得することができるという流れになっています。
  

コード解説

VBA処理

VBAの処理としては非常に単純で、曲線の長さを取得するためのLISPコードを文字列として作成してコマンドラインに送信しているだけです。送信したLISPコードでは測定結果をシステム変数「USERR1」に格納させているため、LISPの処理後にVBAでその値を取得して関数の戻り値としています。

VBAでコマンドラインに指定のコマンド文字列を送信するにはAcadDocumentオブジェクトのSendCommandメソッドを使います。SendCommandメソッドはその名の通り、指定の図面(ドキュメント)のコマンドラインに任意のコマンド文字列を送信(実行)するためのメソッドです。

 icon-code  SendCommandメソッド 

Call ThisDocument.SendCommand(sCmd)

引数のsCmdにはコマンドラインに送信する文字列(String)を入力します。
たとえばVBAからAutoLISPのメッセージボックスを表示する「alert関数」を使用したい場合、SendCommandメソッドを使って下記のように記載することで利用することができます。

コマンドラインに送信するデータはString型であるため対象の文字列の前後をダブルクォーテーションで囲う必要がありますが、送信するLISPのコードにもダブルクォーテーションが含まれる場合は、上記コードのようにダブルクォーテーションのエスケープが必要になります。

また、SendCommandメソッドで送信する文字列の最後には改行コード(vbCr)を付与しておく必要があります。この改行コードは手作業でいう[Enter]の押下と同じ意味であり、改行コードが存在しない場合は[Enter]が押されていない状態、つまりはコマンド実行がされていない状態となってしまうため注意が必要です。(※実行されないだけで文字列がコマンドラインに入力された状態となる)

VBAで指定のシステム変数の値を取得するには同じくAcadDocumentオブジェクトのGetVariableメソッドを使います。引数としてシステム変数名を入力することでその値の取得が可能です。今回作成した関数では”実数”を格納するためのユーザー向けシステム変数であるUSERR1でデータのやり取りを行っているためGetVariableメソッドの引数には”USERR1″を入力しています。
 

LISP処理

曲線の長さをLISPで取得するためには、その対象の曲線をオブジェクトとして取得する必要があります。VBAでは引数として「oEntity」というAcadEntity型の変数で入力されていますが、この変数に格納されているオブジェクトをLISPに渡す必要があるということです。

VBAのオブジェクトをLISPに渡す方法はありますが、ここではオブジェクトIDを使っています。オブジェクトIDはAutoCAD上に作成されるすべてのオブジェクトに自動付与される、オブジェクトを識別するためのIDで、重複するものは一切ありません。そのため、オブジェクトIDがわかれば、そのIDがどのオブジェクトを表しているのかも特定することができます。AutoCAD VBA/AutoLISPではオブジェクトIDからオブジェクトを取得するためにObjectIDtoObjectメソッドが用意されています。

下記はAutoLISPでオブジェクトIDからオブジェクトを取得して変数に格納するためのコードです。「obj-id」にオブジェクトIDを入力することで、「curve-obj」にオブジェクトが格納されます。

VBAではObjectIDプロパティを使うことでオブジェクトIDを取得することが可能のため、上記コードの「obj-id」部分に「oEntity.ObjectID」で取得した値を入力すればLISPでも同じオブジェクトに対して処理を行うことができるようになります。(VBAのReplace関数を使うと簡単に置き換え可能)
 

測定対象の曲線オブジェクトの取得ができたら「vlax-curve-getDistAtParam関数」を使って曲線の長さを取得します。このvlax-curve-getDistAtParam関数の構文は下記の通りです。

 icon-code  vlax-curve-getDistAtParam関数 

(vlax-curve-getDistAtParam curve-obj param)

curve-objには測定対象の曲線オブジェクトを、paramには曲線のパラメータをそれぞれ入力します。戻り値はcurve-objの始点からparamで指定したパラメータまでの距離となり、関数が失敗した場合はnilが返されます。vlax-curve-getDistAtParam関数は曲線の始点から”指定の区間まで”の距離を測定する関数ですが、距離を測定する区間を”終点まで”とすることで曲線の長さを取得することができます

距離を測定する区間を”終点まで”とするにはparamに曲線の終了パラメータを入力する必要があります。指定の曲線の終了パラメータを取得するには「vlax-curve-getEndParam関数」を利用します。

 icon-code  vlax-curve-getEndParam関数 

(vlax-curve-getEndParam curve-obj)

curve-objには終了パラメータを取得する対象の曲線オブジェクトを入力します。戻り値はcurve-objの終了パラメータの数値となり、関数が失敗した場合はnilが返されます。ここで入力するcurve-objには上記のvlax-curve-getDistAtParam関数に入力した曲線オブジェクトと同じものを入力します。

これらの関数を組み合わせることで下記のようなコードにまとめることができます。これにより「curve-obj」に入力された曲線の長さを測定し、その測定値がシステム変数USERR1に格納させることができます。

 

まとめ

AutoCAD VBAにはできることに限界がありますが、AutoLISPと組み合わせることでできる処理の幅が広がります。今回のようにコマンドラインを経由することで、外部ファイル(.lsp)を用意することなく簡単にAutoLISPと連携させることができるため非常に使い勝手が良い手法です。

AutoCADの自動化においてはAutoLISPでしか実現できない処理も様々存在しているため、AutoCAD VBAだけでなくAutoLISPの知識もある程度つけておくことをおすすめします。下記リンク先ではVBAだけでなくAutoLISPも絡めたコードを紹介しているので、ぜひあわせてご参照ください。
 

メインページへ戻る
 

 関連書籍

2024年9月6日AutoCAD, VBA

Posted by Lic