Just my two cents...
Variants and safearrrays are not things which you typically have to deal while using vlisp calls. Particularly if you use these vlisp functions, vlax-get, vlax-put and vlax-invoke.
For instance:
Command: (vlax-get-property <pline objet> 'coordinates)
Select vla object: #<variant 8197 ...>
Whereas (vlax-get <pline objet> 'coordinates)
Retuns a flat list of coordinates.
IOW there's quite bit of confusing documention floating around.
In my reading of Variants and Safearrays I got to thinking about the problem I was having
here. Not that I could use a Safearray to solve the issue in a better way but... I guess it got me thinking about Lists in general, and how I typically build/parse them.
My reasons for wanting to improve my abilites with Visual LISP is because I'm trying to make my work cleaner, easier to understand, and easier for me to process after-the-fact. I've got little utility routines that I'd written years ago for replacing characters in a string, for example. I'm a poor programmer on my best days and one of my major faults is that I either over-comment the things that I write or I put no comments at all. Some of these routines, in which I hadn't commented a bit of it, I find myself working through the routine step by step, trying to
visualize the process in my head, and invariably getting confused along the way and having to start over. I guess it's just me getting old.
Safearray's are a PITA.
Have you read this http://www.afralisp.net/vl/array.htm
You may have to "Select ALL" to see the text, bad color choice.
Here is one example that I liked to explain how the list are arranged. [that was confusing to me]
;; The inner list is the LAST array dim '(0 . 3) = 4 ""
;; while '(0 . 2) = 3 lists
(vlax-safearray->list (vlax-make-safearray vlax-vbString '(0 . 2) '(0 . 3)))
(("" "" "" "") ("" "" "" "") ("" "" "" ""))
(vlax-safearray->list (vlax-make-safearray vlax-vbString '(0 . 3) '(0 . 2)))
(("" "" "") ("" "" "") ("" "" "") ("" "" ""))
IMO dealing with list are much more straight forward.
I read that article that Kenny wrote and I have a better understanding of Safearrays now, than before I read it, but there are still bits and pieces that I find terribly confusing. For example:
The remaining arguments to "vlax-make-safearray" specify the upper and lower bounds of each dimension of the array. The lower bound for an index can be zero or any positive or negative number. Have another look at the function we called earlier :
_$ (setq sheet_type (vlax-make-safearray vlax-vbString '(0 . 2)))
This function created a single-dimension array consisting of three strings with a starting index of 0 (element 0, element 1 and element 2).
Consider this :
_$ (setq pt1 (vlax-make-safearray vlax-vbDouble '(1 . 3)))
The lower bound specified in this example is one and the upper bound specified is three, so the array will hold three doubles (element 1, element 2 and element 3).
And later...
Let's create a Array with two dimensions, each dimension with three elements:
_$ (setq two_dim (vlax-make-safearray vlax-vbString '(0 . 1) '(1 . 3)))
#<safearray...>
_$ (vlax-safearray-fill two_dim '(("Sheet1" "Sheet2" "Sheet3") ("a" "b" "c")))
#<safearray...>
_$ (vlax-safearray->list two_dim)
(("Sheet1" "Sheet2" "Sheet3") ("a" "b" "c"))
This is just a list of lists.
The first list, '(0 . 1) is the number of dimensions.
The second list, '(1 . 3) is the number of elements
And now a three dimensional Array with two elements in each dimension:
_$ (setq three_dim (vlax-make-safearray vlax-vbString '(0 . 2) '(1 . 2)))
#<safearray...>
_$ (vlax-safearray-fill three_dim '(("Sheet1" "Sheet2") ("a" "b") ("d" "e")))
#<safearray...>
_$ (vlax-safearray->list three_dim)
(("Sheet1" "Sheet2") ("a" "b") ("d" "e"))
Here we have a list of three lists.
This time, the first list '(0 . 2) defines three dimensions and the second '(1 . 2) defines 2 elements in each dimension.
Let's see if I'm on the right track here...
(setq two_dim (vlax-make-safearray vlax-vbString '(0 . 1) '(1 . 3)))
(setq three_dim (vlax-make-safearray vlax-vbString '(0 . 2) '(1 . 2)))
The remaining arguments to "vlax-make-safearray" specify the upper and lower bounds of each dimension of the array. The lower bound for an index can be zero or any positive or negative number.
So the arguments to vlax-make-safearray are, first, the Data Type (in these examples vlax-vbString) and, next, the number of dimensions (or lists, counting from 0) and the number of elements in each list (counting from 1)?
So, in the following:
Have a look at the following :
_$ (setq pt1 (vlax-make-safearray vlax-vbDouble '(1 . 3)))
#<safearray...>
_$ (vlax-safearray-put-element pt1 1 100)
100
_$ (vlax-safearray-put-element pt1 2 100)
100
_$ (vlax-safearray-put-element pt1 3 75)
75
_$ (vlax-safearray->list pt1)
(100.0 100.0 75.0)
_$ (vlax-safearray-put-element pt1 1 50)
50
_$ (vlax-safearray->list pt1)
(50.0 100.0 75.0)
There's only one dimension that we're dealing with here so we specify that the dimension has 3 elements in it. Yeah?
Now let's populate a two-dimension array of strings :
_$ (setq two_dim (vlax-make-safearray vlax-vbString '(0 . 1) '(1 . 3)))
#<safearray...>
_$ (vlax-safearray-put-element two_dim 0 1 "a")
"a"
_$ (vlax-safearray->list two_dim)
(("a" "" "") ("" "" ""))
_$ (vlax-safearray-put-element two_dim 0 2 "b")
"b"
_$ (vlax-safearray-put-element two_dim 0 3 "c")
"c"
_$ (vlax-safearray-put-element two_dim 1 1 "d")
"d"
_$ (vlax-safearray-put-element two_dim 1 2 "e")
"e"
_$ (vlax-safearray-put-element two_dim 1 3 "f")
"f"
_$ (vlax-safearray->list two_dim)
(("a" "b" "c") ("d" "e" "f"))
'(0 . 1) = 2 lists (0, & 1)
'(1 . 3) = 3 elements per list (1, 2, & 3)
That about right?
Could that have been written this way as well?
(setq two_dim (vlax-make-safearray vlax-vbString '(1 . 2) '(1 . 3)))
'(1 . 2) = 2 lists (1, & 2)
'(1 . 3) = 3 elements per list (1, 2, & 3)
Or like this?
(setq two_dim (vlax-make-safearray vlax-vbString '(1 . 2) '(0 . 2)))
'(1 . 2) = 2 lists (1, & 2)
'(0 . 2) = 3 elements per list (0, 1, & 2)