Set unique attributes values to variables

Set unique attributes values to variables

djurk_haas
Advocate Advocate
2,296 Views
22 Replies
Message 1 of 23

Set unique attributes values to variables

djurk_haas
Advocate
Advocate

Hello,

 

The code belows works fine and prompts a list eg:

1 6504
1 6504
1 6512
1 5628
1 5219
1 6512
1 6512
1 6504

 

Can anyone help me to modify the code so that only the unique attributes values are stored into variables?

From the list above the adjusted code must store only the unique attributesvalues into serveral variables:

 

(setq kostenplaats01 "6504")

(setq kostenplaats02 "6512")

(setq kostenplaats03 "5628")

(setq kostenplaats04 "5219")

 

(defun C:FSDA (/ blkss ent foundit att comment); = block FSD's Attributes
  (vl-load-com)
  (if (setq blkss (setq ss  (ssget "_X" '((0 . "insert")(66 . 1)(2 . "`*U*,FM_RM3")))))
    (progn ; then
      (prompt "\nComments:")
      (repeat (sslength blkss)
        (setq
          ent (ssname blkss 0)
          n 0
        ); setq
        (while
          (and
            (not foundit)
            (setq ent (entnext ent))
            (= (cdr (assoc 0 (entget ent))) "ATTRIB")
          ); end and
          (setq att (vlax-ename->vla-object ent))
          (if (= (vla-get-TagString att) "KOSTENPLAATS")
            (progn
              (setq
                foundit T
                comment (vla-get-TextString att); value [= "" if none specified]
              )
              (prompt
                (strcat
                  "\n" ; new line
                  (itoa (setq n (1+ n))); step integer upward and convert to text
                  " " ; space separator
                  (if (= comment "") "NO COMMENT SPECIFIED" comment)
                ); strcat
              );prompt
            ); progn
          ); if
        ); while
        (setq foundit nil)
        (ssdel (ssname blkss 0) blkss)
      ); repeat
    ); progn
  ); if
  (princ)
); defun

 

Thanks

0 Likes
Accepted solutions (2)
2,297 Views
22 Replies
  • Lisp
Replies (22)
Message 2 of 23

dlanorh
Advisor
Advisor

Try this. The kostenplaats## variables will be global.

 

 

(defun C:FSDA (/ ss cnt obj vlst); = block FSD's Attributes
  (vl-load-com)
  (setq ss (ssget "_X" '((0 . "INSERT") (66 . 1) (2 . "`*U*,FM_RM3"))))
  (cond (ss
          (repeat (setq cnt (sslength ss))
            (setq obj (vlax-ename->vla-object (ssname ss (setq cnt (1- cnt))))
                  val (vl-some '(lambda (x) (if (= (vlax-get x 'tagstring) "KOSTENPLAATS") (vlax-get x 'textstring))) (vlax-invoke obj 'getattributes))
            );end_setq
            (if (not (vl-position val vlst)) (setq vlst (cons val vlst)))
          );end_repeat
          (setq cnt 1)
          (foreach v vlst 
            (cond ( (< cnt 10) (set (read (strcat "kostenplaats" "0" (itoa cnt))) v))
                  (t (set (read (strcat "kostenplaats" (itoa cnt))) v))
            );end_cond
            (setq cnt (1+ cnt))
          );end_foreach
        )
        (t (alert "NOTHING Found"))
  );end_cond
  (princ)
);end_defun

 

 

 

 

I am not one of the robots you're looking for

0 Likes
Message 3 of 23

djurk_haas
Advocate
Advocate

Thanks for the quick reply. The code works fine but:

(princ kostenplaats01)     gives the result  ""

 

 

 

0 Likes
Message 4 of 23

dlanorh
Advisor
Advisor

@djurk_haas wrote:

Thanks for the quick reply. The code works fine but:

(princ kostenplaats01)     gives the result  ""

 

 

 


Sorry, I missed the "NO COMMENT SPECIFIED" condition.

 

Attempt 2

 

(defun C:FSDA (/ ss cnt obj vlst); = block FSD's Attributes
  (vl-load-com)
  (setq ss (ssget "_X" '((0 . "INSERT") (66 . 1) (2 . "`*U*,FM_RM3"))))
  (cond (ss
          (repeat (setq cnt (sslength ss))
            (setq obj (vlax-ename->vla-object (ssname ss (setq cnt (1- cnt))))
                  val (vl-some '(lambda (x) (if (= (vlax-get x 'tagstring) "KOSTENPLAATS") (vlax-get x 'textstring))) (vlax-invoke obj 'getattributes))
            );end_setq
            (if (= val "")(setq val "NO COMMENT SPECIFIED"))
            (if (not (vl-position val vlst)) (setq vlst (cons val vlst)))
          );end_repeat
          (setq cnt 1)
          (foreach v vlst 
            (cond ( (< cnt 10) (set (read (strcat "kostenplaats" "0" (itoa cnt))) v))
                  (t (set (read (strcat "kostenplaats" (itoa cnt))) v))
            );end_cond
            (setq cnt (1+ cnt))
          );end_foreach
        )
        (t (alert "NOTHING Found"))
  );end_cond
  (princ)
);end_defun

 

I am not one of the robots you're looking for

0 Likes
Message 5 of 23

dlanorh
Advisor
Advisor
Accepted solution

Disregard above

 

(defun C:FSDA (/ ss cnt obj vlst); = block FSD's Attributes
  (vl-load-com)
  (setq ss (ssget "_X" '((0 . "INSERT") (66 . 1) (2 . "`*U*,FM_RM3"))))
  (cond (ss
          (repeat (setq cnt (sslength ss))
            (setq obj (vlax-ename->vla-object (ssname ss (setq cnt (1- cnt))))
                  val (vl-string-trim " " (vl-some '(lambda (x) (if (= (vlax-get x 'tagstring) "KOSTENPLAATS") (vlax-get x 'textstring))) (vlax-invoke obj 'getattributes)))
            );end_setq
            (if (and (> (strlen val) 0) (not (vl-position val vlst))) (setq vlst (cons val vlst)))
          );end_repeat
          (setq cnt 1)
          (foreach v vlst
            (cond ( (< cnt 10) (set (read (strcat "kostenplaats" "0" (itoa cnt))) v))
                  (t (set (read (strcat "kostenplaats" (itoa cnt))) v))
            );end_cond
            (setq cnt (1+ cnt))
          );end_foreach
        )
        (t (alert "NOTHING Found"))
  );end_cond
  (princ)
);end_defun

 

I am not one of the robots you're looking for

0 Likes
Message 6 of 23

djurk_haas
Advocate
Advocate

Thanks a lot it works great.


Next question.


Do you know how to set these variable (eg kostenplaats01) into an attributevalue in a specific block?


The blocknames are "renvooi01", "renvooi02", "renvooi03" and so on, all these blocks have the same tag "kostenplaats".

0 Likes
Message 7 of 23

dlanorh
Advisor
Advisor

That could be incorporated into the lisp, it would save creating the global variables. ie, extract values to list then put list items to block attributes.

 

Points to note : 

 

The list of extracted attribute values is unsorted, the values correspond to selection set order which in turn depends on how the blocks were selected for the selection set. In this case "_X" I think it would be the order in which they were created. So, does the list need sorting and if so, how? How would that order relate to the block order?

 

The target attributed blocks must be in the drawing does this need checking?

 

 

 

 

I am not one of the robots you're looking for

0 Likes
Message 8 of 23

djurk_haas
Advocate
Advocate

The order does not matter in principle but it would be more like fantastic if it were in ascending order (variables are always 4 digits).
The blocks should be present in the drawing. A check might be useful for handling errors.

0 Likes
Message 9 of 23

dlanorh
Advisor
Advisor

OK. Not much I can do today, but should be able to start tomorrow.

 

I had one other thought, what happen if there are more entries than blocks, or won't that happen?

I am not one of the robots you're looking for

0 Likes
Message 10 of 23

djurk_haas
Advocate
Advocate

That won't happen

0 Likes
Message 11 of 23

dlanorh
Advisor
Advisor
Any chance of a sample drawing to test? It needs to be saved as 2012 or earlier.

I am not one of the robots you're looking for

0 Likes
Message 12 of 23

djurk_haas
Advocate
Advocate

When I run FSDA also the "kostenplaats" 9999 in block Renvooi01 is set to a variable (kostenplaats01).

That's not right, only the tag kosten plaats in the blocks FM_RM3 should be set to a variable.

Doesn't this piece of code work?

 

(2 . "`*U*,FM_RM3")
0 Likes
Message 13 of 23

dlanorh
Advisor
Advisor

Thanks for the drawing. A big help.

 

The code snippet works as intended. The error may have been because I did not localize all the variables.

 

I'm still testing the code as I've several insertion methods to try. So far they all work.

 

Once that is complete I have to add the block check routine and a local error.

 

I'm a bit behind schedule as I was diverted to a site this morning and lost half a day.

I am not one of the robots you're looking for

0 Likes
Message 14 of 23

dlanorh
Advisor
Advisor
Accepted solution

Attached is working lisp with block checking. This expects 10 blocks references to be present in the drawing (renvooi01->renvooi10). If one or more are missing it will alert, tell you which one(s) is/are missing and exit.

 

If you wish to remove this I have indicated which lines you can comment out or delete. If you want to keep it but change the number of blocks the first setq has a variable "ll" which is set to 10. Change this to the number of blocks as you require and it will automatically generate the consecutive check list numbers (01 -> n) required.

 

In the test drawing your "renvooi01" block contained the number 9999. This is overwritten. Any changes, let me know.

 

I am not one of the robots you're looking for

Message 15 of 23

djurk_haas
Advocate
Advocate

Thank you very much for the sent code it works perfectly.

 

Is it also possible to place the variables in the blocks FM_RM3 with matching attributesvalues ​​Renvooi 01 upto Renvooi 10 (tag GEBRUIK)?
This instead of placing them in the blocks Renvooi01 to Renvooi02.

The check should therefore be performed whether there are indeed the blocks FM_RM3 present with the value for the  tag GEBRUIK-> Renvooi 01 up to Renvooi 10.

 

Thanks in advance

0 Likes
Message 16 of 23

dlanorh
Advisor
Advisor

I'll try to sort something out in the next few days, but having the same effective name (FM_RM3) as the data block complicates thing so some of the functions will need to be re-written.

 

I am not one of the robots you're looking for

0 Likes
Message 17 of 23

dlanorh
Advisor
Advisor

Attached is updated lisp to handle the new scenario. It didn't take as long as I thought it would. I have given the file a different name to distinguish it from the former. The command to run is the same. As before this checks that there are 10 blocks (controlled by the "ll" variable) where the "GEBRUIK" tag has a value of "Renvooi 01" -> "Renvooi 10" If this isn't the case it will report an error and exit. This will also happen if you have two values the same or a value outside the range. (Briefly tested only)

 

 

I am not one of the robots you're looking for

0 Likes
Message 18 of 23

djurk_haas
Advocate
Advocate

Hi Dlanor,


It works almost perfectly.

However, if a drawing now changes and there are less "KOSTENPLAATS" then the current data will not be deleted and a duplication will occur.
I think it can be "easily" solved by making sure that at the beginning of the code all existing tag values ​​(KOSTENPLAATS) are deleted (start from scratch).

 

To make it completely awesome it would be great if the tags "BEDRIJFSORGAAN, RUIMTEFUNCTIE and RUIMTESOORT were filled with values ​​as set in the lisp in the attachment.

 

Greetings

0 Likes
Message 19 of 23

dlanorh
Advisor
Advisor

@djurk_haas wrote:

Hi Dlanor,


It works almost perfectly.

However, if a drawing now changes and there are less "KOSTENPLAATS" then the current data will not be deleted and a duplication will occur.
I think it can be "easily" solved by making sure that at the beginning of the code all existing tag values ​​(KOSTENPLAATS) are deleted (start from scratch).

 

To make it completely awesome it would be great if the tags "BEDRIJFSORGAAN, RUIMTEFUNCTIE and RUIMTESOORT were filled with values ​​as set in the lisp in the attachment.

 

Greetings


I don't fully understand the red highlighted text. Are both these and the extra requirements related to the 10 target "FM_RM3" blocks?

I am not one of the robots you're looking for

0 Likes
Message 20 of 23

djurk_haas
Advocate
Advocate

Yes that's right.

When the drawing is modified and there are fewer "KOSTENPLAATS" (not target FM_RM3) for example 3 instead of 4, the code fills the first 3 target FM_RM3 but the fourth still remains from the previous execution of the code.

 

 

 

0 Likes