Applying Dimension to define arrays in AutoLISP?

Applying Dimension to define arrays in AutoLISP?

Prof_Stancescu
Enthusiast Enthusiast
2,352 Views
6 Replies
Message 1 of 7

Applying Dimension to define arrays in AutoLISP?

Prof_Stancescu
Enthusiast
Enthusiast

Hi all,

I have the next problem.
A lot of my blocks in a drawing have a great number of attributes, with many serial tags namely NAME01, NAME02, .. NAME32.
Other are KIND01, KIND02, .. KIND32 etc.
I try to run a personal AutoLISP program having a function (CngAttr) to change each attribute tag value.
Every attribute has a corresponding cell in a DCL file, so their values are changing frequently, but this is the purpose of my AutoLISP program.
My function has three arguments and its call is like (CngAttr "NAME01" (nth (atoi (get_tile "NAME01")) LNAME01) *Blk_name*) where:

NAME01 is the key of the cell in the DCL file associated with the attribute
LNAME01 is the name of the AutoLISP variable which acts as a recipient of the tile value to be processed by the CngAttr function
*Blk_name* is the name of the block with a tag attribute named NAME01
My solution is actually to use the next (32) repeated code:
(CngAttr "NAME01" (nth (atoi (get_tile "NAME01")) LNAME01) *Blk_name*)
(CngAttr "NAME02" (nth (atoi (get_tile "NAME01")) LNAME02) *Blk_name*)
.
.
(CngAttr "NAME32" (nth (atoi (get_tile "NAME01")) LNAME32) *Blk_name*)
As you can see, I have to manually change LNAME01 with LNAME02 .. LNAME32, and I have to make this also for the strings "NAME01" etc..
When I have strings only, I change "NAME01" with (strcat "NAME" CC), where CC is the subject for a while or repeat cycle from 1 to 32, of course.
To be more specific, I also use other functions instead CngAttr, which have more then one line of code, where I have to manually change 01 with 02 etc. to 32 for many boring times. Sometimes a whole function must be repeated, so I reached now 98 forms to load for a not so difficult program to run.
Given the necessity of refining the program, which imply many changes to the code, when I make a change to a code zone with "01", I have to make the same change to "02", "03" a.s.o.. This is why I made a brand new AutoLISP program called CodeMultiply.lsp to change the text of my AutoLISP program file by inserting some (commented) marks in the code. Using that program I am happy - I change the code zone with "01"in the original program, then I run CodeMultiply, and all the changes are correctly incremented - so you see how cheap can be the happiness for an individual...

I have to do this because I have no idea of how to create a simulation of an array (like say, BASIC arrays, where the variable LNAME01 can be defined as LNAME(01) by using the Dim NAME(32) As Byte statement, for instance). You note that my big obstacle is the changing of the bloody name of a LISP variable, not the changing of a string value.

Since LISP is the language for Artificial Inteligence, I suppose that there must be a magic procedure in AutoLISP by using list functions like eval, cons or read and so on to create such structures, isn't it?
If you have a solution for my problem I would be delighted, believe me...
When I shall present a new short and compact program of say, 50 forms instead of 100, to my boss I am sure that this would have a big impact...

Yours,
Constantin from Romania
PS: Sorry for my long story and for my poor English, BTW!

0 Likes
Accepted solutions (2)
2,353 Views
6 Replies
Replies (6)
Message 2 of 7

ВeekeeCZ
Consultant
Consultant

Try 

 

(repeat (setq i 32)
  (CngAttr (strcat "NAME" (if (< i 10) "0" "") (itoa i))
	   (nth (atoi (get_tile "NAME01")) (read (strcat "LNAME" (if (< i 10) "0" "") (itoa i)))) *Blk_name*)
  (setq i (1- i)))

It goes from up to down, but you got the idea in case you mind...

0 Likes
Message 3 of 7

Prof_Stancescu
Enthusiast
Enthusiast

I am astonished how soon you answered to my question - Thank you BeekeeCZ!

 

The first problem is that the next routine (with i=3 instead of 32) does not work well:

 

(defun C:BBB ()
(repeat (setq i 3)
(setq Foo (strcat "NAME" (if (< i 10) "0" "") (itoa i)))
(princ (strcat "\n" Foo))
)
(princ)
)

 

It only produces 3 x "NAME03".

The next one is that the construction (get_tile "NAME01") needs for me to introduce again the (strcat "NAME" CC) where CC="01" instead of "NAME01", isn't it?

0 Likes
Message 4 of 7

ВeekeeCZ
Consultant
Consultant

You need to increment the index i, see the last line of my code.

About (get_title "NAME01") ...you have it the same all the time - if that is waht you need... it could remain as it is. Or do you need that incementing as well?

0 Likes
Message 5 of 7

ВeekeeCZ
Consultant
Consultant
Accepted solution

To answer your question about arrays. As far as I know, there is no array function.

 

You can use the repeat loop as i did, for example....

 

The construction of string is easy... (strcat "NAME" (itoa 3))

 

The construction of the variable name:

- build the string first as well (strcat "LNAME" (itoa 1))

- make a symbol (read (strcat "LNAME" (itoa 1)))

- get the value (eval (read (strcat "LNAME" (itoa 1))))  ; the eval function I've missed in my previous code

- set the value (set (read (strcat "LNAME" (itoa 1))) "value")

 

btw this part (if (< i 10) "0" "") is just about adding the leading zero

 

Message 6 of 7

Prof_Stancescu
Enthusiast
Enthusiast
Accepted solution

Your last answer was REALLY GREAT - Thank you BeekeeCZ...

Mainly, the conclusion is "YESSSS, ONE CAN CREATE AND CAN USE ARRAYS IN AutoLISP JUST LIKE USING THE STATEMENT DIMENSION IN BASIC LANGUAGE". Moreover, the LISP arrays are flexible - their dimensions can be modified freely at run-time.

 

The essence of your answer is here:

 

  1. Make a symbol (read (strcat "LNAME" (itoa 1)))
  2. Get the value (eval (read (strcat "LNAME" (itoa 1))))
  3. Set the value (set (read (strcat "LNAME" (itoa 1))) "value")

I used your advice to build a small application to be used by anyone interested in using vectors and arrays of data via AutoLISP.

From here "you" is not BeekeeCZ, but you, the gentle reader of my conclusions!
I am definitely not an expert like BeekeeCZ, so I can see the things from the novice programmer point of view.

 

(defun C:AAA () ;Main program
  (setq vect (Vector 12 (setq LNAME (list))))
  (princ vect)
  (princ)
)

 

(defun Vector (n aList) ;n=vector length, aList=vector result
  (setq i 1)
  (repeat n
    (set (read (strcat "aList" (if (< i 10) "0" "") (itoa i)))(strcat (if (< i 10) "0" "") (itoa i)))
    (setq aList (append aList (list (eval (read (strcat "LNAME" (if (< i 10) "0" "") (itoa i)))))))
    (setq i (1+ i))
  )
  aList
)

 

If the name of file is BeekeeCZ.lsp and you load the program in AutoCAD, the dialog should be:

 

Command: (load "BeekeeCZ")
VECTOR
Command: AAA
(01 02 03 04 05 06 07 08 09 10 11 12)

 

As you can see, the result is a list (of strings) which looks like a vector of data.

Meantime, no less than 12 lists (of one atom each) with the names LNAME01, LNAME02, ... LNAME12 were created.

By extending the code you can obtain a list of lists, which can be considered a 2D array.

From here to nD arrays is a small step...

 

--------------THE IMPORTANCE OF THE ARRAYS----------------

 

You may say that the task of constructing list of lists is not a big deal, of course.

However, if you re-read my initial problem you will remark the greatness of what this means.

Be careful here:

 

If you create a block in AutoCAD with many attributes named as NAME01, NAME02, ... NAME32 and you want to handle all that attributes you will be bored very soon. You will find that the above application is a gold mine for handling great amounts of attributes.

 

------------------------------

 

Once again, God bless you BeekeeCZ...

I just accepted your last message as the solution for my problem!

 

Constantin from Romania

PS I made a mistake in my title message - see below the right text:

 

(CngAttr "NAME01" (nth (atoi (get_tile "NAME01")) LNAME01) *Blk_name*)
(CngAttr "NAME02" (nth (atoi (get_tile "NAME02")) LNAME02) *Blk_name*)
.
.
(CngAttr "NAME32" (nth (atoi (get_tile "NAME32")) LNAME32) *Blk_name*)

Message 7 of 7

ВeekeeCZ
Consultant
Consultant

You're welcome, Constantin from Romania, glad to help. 🙂

 

Don't hesitate mark your conclusion as the solution as well.