Change attribute in a selected block

Change attribute in a selected block

Anonymous
Not applicable
1,081 Views
7 Replies
Message 1 of 8

Change attribute in a selected block

Anonymous
Not applicable

Hello, 

I am having a problem with a part of my code. In this part, (i made it so that you can run independently) it asks you the block to change and the attribute value to change. Unfortunately, it says that there's too few arguments when I give the input.

Here's the code:

(defun c:abc (/ b l blk layertable layname)
(setq blk (entsel "\nSelect block to modify: "))
(initget (+ 1 2 4))
(setq b (getreal "\nNew att value? (>0;1<)"))

;open layer (setq LayerTable (vla-get-layers (vla-get-activedocument (vlax-get-acad-object)))) (if (and (tblsearch "LAYER" "MC_BLOCK") (setq layname (vla-item layertable "MC_BLOCK")) (= (vlax-get-property layname 'lock) :vlax-true) ) (vla-put-lock layname :vlax-false)) ;change attribute (setq l (cons (cons "CAMPO_6" (itoa (fix b))))) ;close layer (setq LayerTable (vla-get-layers (vla-get-activedocument (vlax-get-acad-object)))) (if (and (tblsearch "LAYER" "MC_BLOCK") (setq layname (vla-item layertable "MC_BLOCK")) (= (vlax-get-property layname 'lock) :vlax-false) ) (vla-put-lock layname :vlax-true)) (princ) )

Thanks in advance

0 Likes
Accepted solutions (1)
1,082 Views
7 Replies
Replies (7)
Message 2 of 8

cadffm
Consultant
Consultant

CONS need TWO arguments..

(setq l (cons (cons "CAMPO_6" (itoa (fix b)))))

 

The blue cons get just one argument..

 

 

http://help.autodesk.com/view/OARX/2020/DEU/?guid=GUID-5424079C-26CD-4E7D-819A-DE7B7B340077

Sebastian

0 Likes
Message 3 of 8

Ajilal.Vijayan
Advisor
Advisor

The error happens because of this line

(setq l (cons (cons "CAMPO_6" (itoa (fix b)))))

remove the first cons from this line.

Edit:

Is the code you posted is complete ?

Because the posted code does not modify the attribute value and the below mentioned variable is not used anywhere.

(setq l)
0 Likes
Message 4 of 8

Anonymous
Not applicable

Thanks, that helped 🙂
But it's still not operational.

This is the full code i put together for this task:

(defun c:abc (/ b l blk i layertable layname)
(setq blk (entsel "\nSelect blocks to modify: "))
(initget (+ 1 2 4))
(setq b (getreal "\nNew att value? (>0;1<)"))
;open layer
	(setq LayerTable (vla-get-layers (vla-get-activedocument (vlax-get-acad-object))))
(if (and (tblsearch "LAYER" "MC_BLOCK")
         (setq layname (vla-item layertable "MC_BLOCK"))
         (= (vlax-get-property layname 'lock) :vlax-true)
         )
  (vla-put-lock layname :vlax-false))
	
	;modify attribute
	(progn 
	(setq l (cons "CAMPO_6" (itoa (fix b))))
	(LM:SetAttributeValues (ssname blk  l))
    )                

	;close layer
	(setq LayerTable (vla-get-layers (vla-get-activedocument (vlax-get-acad-object))))
(if (and (tblsearch "LAYER" "MC_BLOCK")
         (setq layname (vla-item layertable "MC_BLOCK"))
         (= (vlax-get-property layname 'lock) :vlax-false)
         )
  (vla-put-lock layname :vlax-true))
  (princ)
  )
(defun LM:SetAttributeValues ( blk lst / enx itm )
    (if (= "ATTRIB" (cdr (assoc 0 (setq enx (entget (setq blk (entnext blk)))))))
        (if (setq itm (assoc (strcase (cdr (assoc 2 enx))) lst))
            (progn
                (if (entmod (subst (cons 1 (cdr itm)) (assoc 1 enx) enx))
                    (entupd blk)
                )
                (LM:SetAttributeValues blk lst)
            )
            (LM:SetAttributeValues blk lst)
        )
    )
)

 

 

0 Likes
Message 5 of 8

SeeMSixty7
Advisor
Advisor

Ok it look like you are getting close to what you want, but you have a few issues with proper arguments you are passing to functions.

 

You don't need to enclose the attribute section in a progn code block.

the LM:SetAttributeValues function takes an entity  and a list of attribute tag and value pairs

should look like this (LM:SetAttributeValues (car blk) (list l))

You had specified an ssname function with blk as the argument. your blk is a listed selection point and entity name. (car blk) pulls out the entity name from the list.

your l variable (BTW use something that doesn't look like a 1 for a variable name)

is constructed properly but the function is looking for a list of dotted pairs.

 

Here is some updated code, hopefully this helps.

(defun c:abc (/ b l blk i layertable layname)
(setq blk (entsel "\nSelect blocks to modify: "))
(initget (+ 1 2 4))
(setq b (getreal "\nNew att value? (>0;1<)"))
;open layer
	(setq LayerTable (vla-get-layers (vla-get-activedocument (vlax-get-acad-object))))
(if (and (tblsearch "LAYER" "MC_BLOCK")
         (setq layname (vla-item layertable "MC_BLOCK"))
         (= (vlax-get-property layname 'lock) :vlax-true)
         )
  (vla-put-lock layname :vlax-false))
	
	;modify attribute

	(setq l (cons "CAMPO_6" (itoa (fix b))))
	(LM:SetAttributeValues (car blk) (list l))
           

	;close layer
	(setq LayerTable (vla-get-layers (vla-get-activedocument (vlax-get-acad-object))))
(if (and (tblsearch "LAYER" "MC_BLOCK")
         (setq layname (vla-item layertable "MC_BLOCK"))
         (= (vlax-get-property layname 'lock) :vlax-false)
         )
  (vla-put-lock layname :vlax-true))
  (princ)
  )
(defun LM:SetAttributeValues ( blk lst / enx itm )
    (if (= "ATTRIB" (cdr (assoc 0 (setq enx (entget (setq blk (entnext blk)))))))
        (if (setq itm (assoc (strcase (cdr (assoc 2 enx))) lst))
            (progn
                (if (entmod (subst (cons 1 (cdr itm)) (assoc 1 enx) enx))
                    (entupd blk)
                )
                (LM:SetAttributeValues blk lst)
            )
            (LM:SetAttributeValues blk lst)
        )
    )
)
0 Likes
Message 6 of 8

Anonymous
Not applicable

Thanks a lot, its working... well almost. It is updating the attribute, but only in integer values. I type 0.75, it updates to 0. If I put 2.5, it updates to 2. Since I want to input values between 0 and 1 this is indeed problematic.

If I update the block manually it has no problems in accepting real numbers.

0 Likes
Message 7 of 8

cadffm
Consultant
Consultant

You should stop it and starts to learn each (for you) new lispfunction from scratch.

 

-

(itoa (fix b))

Read more about FIX (AutoLISP)

then read more about itoa and RTOS and DIMZIN

 

 

Sebastian

0 Likes
Message 8 of 8

SeeMSixty7
Advisor
Advisor
Accepted solution

you are using FIX function. That is what that does.

 

(fix number)
number

Type: Integer or Real

A numeric value.

Return Values

Type: Integer

 

If you want to use a real value use RTOS function

Example

(setq l (cons "CAMPO_6" (rtos b 2 2)))