リストから独自のセーフ配列バリアント型へ
AutoLISP 備え付けのサポート関数で対応できないものは、プログラムを作成して適切に変換する必要があります。例えば、2次元図形のライトウェイトポリライン作成関数の vla-AddLightWeightPolyline は頂点の配列を引数に取りますが、vlax-vbDouble 型で、データの並びが3次元の座標を含まない[x0,y0,x1,y1,x2, y2,…]と並んだ直列の一次元のセーフ配列バリアント型とする必要があります。
このような変換を行ううえで必要となってくる関数をまず取り上げます。
AutoLISP関数 |
---|
(vlax-safearray-fill sarray 'element-values) |
sarray:セーフ配列 element-values:リスト |
リストの内容でセーフ配列を初期化します。 |
戻り値: セーフ配列 |
vlax-safearray-fill 関数は、リストの内容でセーフ配列を初期化します。
sarray 引数には、セーフ配列を指定します。
element-values 引数は、初期化する値を収めたリストを指定します。セーフ配列が多次元の場合はリストの構造はそれに対応する入れ子構造としなければなりません。配列要素に対してリストの要素が不足していた場合は、元の値がそのまま残ります。リストの要素の方が多かった場合は、エラーが発生します。
戻り値は、初期化されたセーフ配列が返ります。

vlax-safearray->list 関数の使用例は以下のとおりです。
_$ (setq sarray (vlax-make-safearray vlax-vbDouble '(0 . 1) '(0 . 2))) ⏎
#<safearray...>
_$ (vlax-safearray-fill sarray '((100.0 110.0 120.0) (200.0 210.0 220.0))) ⏎
#<safearray...>
_$ (vlax-safearray->list sarray) ⏎
((100.0 110.0 120.0) (200.0 210.0 220.0))
この vlax-safearray->list 関数を使用して、実数を格納したリストを倍精度浮動小数点数型で適切なサイズのセーフ配列のバリアント型に変換するサポート関数を用意します。

(defun list->v-sarray:vbDouble (alist) (if alist (vlax-make-variant (vlax-safearray-fill (vlax-make-safearray vlax-vbDouble (cons 0 (1- (length alist)))) alist ) ) ) )
_$ (setq varray (list->v-sarray:vbDouble '(10 20 30)))⏎
#<variant 8197 ...>
_$ (vlax-safearray->list (vlax-variant-value varray))⏎
(10.0 20.0 30.0)
これを使って、以下に変換関数のバリエーションを示します。
3次元の座標から、Z値を切り捨ててXとYの値を含むセーフ配列バリアント型を作成します。

(defun point->xyPoint (point) (list->v-sarray:vbDouble (list (nth 0 point) (nth 1 point))) )
_$ (setq varray (point->xyPoint '(10 20 30)))⏎
#<variant 8197 ...>
_$ (vlax-safearray->list (vlax-variant-value varray))⏎
(10.0 20.0)
3 次元の複数の座標を含んだリストを、各 Z 値を切り捨てて、X と Y の値を含む 1 次元のセーフ配列バリアント型に変換します。

(defun pointList->xyPointArray (plist) (list->v-sarray:vbDouble (apply 'append (mapcar (function (lambda (pnt /) (list (nth 0 pnt) (nth 1 pnt)))) plist) ) ) )
_$ (setq varray (pointList->xyPointArray '((10 11 12) (20 21 22) (30 31 32))))⏎
#<variant 8197 ...>
_$ (vlax-safearray->list (vlax-variant-value varray))⏎
(10.0 11.0 20.0 21.0 30.0 31.0)
三次元の複数の座標を含んだリストを、1次元のセーフ配列バリアント型に変換します。

(defun pointList->xyzPointArray (plist) (list->V-sarray:vbDouble (apply 'append plist)) )
_$ (setq varray (pointList->xyzPointArray '((10 11 12) (20 21 22) (30 31 32))))⏎
#<variant 8197 ...>
_$ (vlax-safearray->list (vlax-variant-value varray))⏎
(10.0 11.0 12.0 20.0 21.0 22.0 30.0 31.0 32.0)
このように、変換関数は単純なものです。もしこの他の新しいタイプの変換が必要な場合は、変換先の型を確認して作成してください。
セーフ配列バリアント型からリストへ
逆にセーフ配列バリアント型をLISPのリストに変換する必要も出てきますが、次の ActiveX 対応関数を利用することできます。ここの引数はセーフ配列であり、セーフ配列バリアント型ではありません。
AutoLISP関数 |
---|
(vlax-safearray->list sarray) |
sarray:セーフ配列 |
セーフ配列をLISPのリストに変換します。 |
戻り値:リスト |
vlax-safearray->list 関数は、セーフ配列をリストの形式で返します。
sarray 引数には、セーフ配列を指定します。
戻り値はセーフ配列の内容を表すリストで、配列が多次元の場合はリストの入れ子構造に変換されます。

実際の変換の場面の多くは、まずセーフ配列バリアント型が得られるので、バリアント型から vlax-variant-value 関数でセーフ配列を取り出した後に vlax-safearray->list 関数で LISP のリストに変換します。この二つを兼ねたサポート関数を定義しておくと便利です。
(defun VariantSafeArray->List (varOfArray /) (vlax-safearray->list (vlax-variant-value varOfArray)) )
また、リストからセーフ配列バリアント型への変換で見たように、実際の ActiveX 対応関数から得られるセーフ配列は、複数頂点の XYZ といった座標の情報を表していても一次元の配列となっており、多次元の構造をもって得られることはありません。そのため、一次元のリストに構造をつけるサポート関数を用意しておくと便利です。
(defun organizeGroup (alist capacity / stock) (if (and alist (<= capacity (length alist))) (progn (repeat capacity (setq stock (append stock (list (car alist))) alist (cdr alist) ) ) (append (list stock) (organizeGroup alist capacity)) ) ) )
関数単体の使い方は以下のとおりです。
_$ (organizeGroup '(0 1 2 3 4 5 6) 2) ⏎
((0 1) (2 3) (4 5))
_$ (organizeGroup '(0 1 2 3 4 5 6) 3) ⏎
((0 1 2) (3 4 5))
_$ (organizeGroup '(0 1 2 3 4 5 6) 4) ⏎
((0 1 2 3))
Boolean 型
ActiveX には、真偽を表す Boolean 型が存在します。AutoLISP においては特別な型ではなく、記述する場合はシンボル名を用います。なお、オブジェクトをダンプ表示させたプロパティの値では、整数で表されます。
AutoLISPのシンボル名 | オブジェクトダンプでの表示 | |
---|---|---|
真 | :vlax-true | -1 |
偽 | :vlax-false | 0 |