I'm new to AutoLISP. I've gone through many tutorials most of which just show you math and how to loop. There are only a handful of tutorials that deal with acutal block manipulation which is where I struggle.
I've seen some of the great LISP functions that Lee Mac and Nate Holt (and others) have created and shared, but I have yet to find a routine that does the following:
(1) Find the block where BLOCK NAME = "VIFCD_001" AND ATTRIBUTE [TAG1] = "-M161"
(2) Inside that same block change the ATTRIBUTE [DESC] = "NEW PART NUMBER"
I would prefer that "BLOCK NAME" "TAG NAME" and "DESC NAME" be arguments in a function.
I've been trying to work from this routine (below), that will change attributes of a block. The only LISP routine I know prompts the user to select the block, however, I cannot prompt the user for anything - I need the block name to be passed as an argument
How do I use LISP to select the block where BLOCK NAME = "VIFCD_001" and its attribute TAG1="-M161"
THE CALL
(setq ent (car (entsel))) ;Prompts the user to select a block (changeVars "DESC" "NEW PART NUMBER" ent)
THE FUNCTION
(defun changeVars (tag newvalue ent / alist) (if (and (= (type ent) (read "VLA-OBJECT")) newvalue) (progn (setq alist ( vlax-invoke ent 'GetAttributes)) (foreach a alist) (if (= (vla-get-tagstring a) tag) (vlax-put-property a 'TextString newvalue) );endif );end foreach );end progn (if (= 'ename (type ent)) (reptag tag newvalue (vlax-ename->vla-object ent)) );endif );endif (princ) );end defun
Solved! Go to Solution.
Solved by Ranjit_Singh1. Go to Solution.
Here is one example.
;;Ranjit Singh
;;8/3/17
(defun somefunc (tagname value blockname / etdata) (mapcar '(lambda (x) (while (/= "SEQEND" (cdr (assoc 0 (setq etdata (entget (setq x (entnext x))))))) (and (= (cdr (assoc 0 etdata)) "ATTRIB") (mapcar '(lambda (x y) (and (= x (cdr (assoc 2 etdata))) (entmod (subst (cons 1 y) (assoc 1 etdata) etdata)))) (list tagname) (list value))))) (mapcar 'cadr (ssnamex (ssget "_x" (list '(0 . "insert") (cons 2 blockname) '(66 . 1)))))))
EDIT: If you want to pass ent then change this
(mapcar 'cadr (ssnamex (ssget "_x" (list '(0 . "insert") (cons 2 blockname) '(66 . 1)))))
to
(mapcar 'cadr (ssnamex (ssget "_x" (list '(0 . "insert") (assoc 2 (entget blockname)) '(66 . 1)))))
and call the function like
(somefunc "DESC" "NEW PART NUMBER" ent)
Thank you Ranjit.
This is helpful, however, I was hoping to have the user not select the object.
This function will need to be purely automated without any prompts for the user to select objects or type inputs.
I need to select the block where BLOCK NAME = VIFCD_001 and its attribute TAG1 = "-M161"
*this command below is wrong, but my question to you is how do I use LISP to identify a block where BLOCKNAME="VIFCD_001" AND TAG1="-M161"*
(setq ent (entsel <block name> <tag name>)) (setq ent (entsel "VIFCD_001", "-M161"))
I think I'm getting close, but can someone help? This produces a NIL value, but I believe these are the properties I need to access.
(setq ss (ssget "_X" '((0 . "INSERT") (2 . "VIFCD_001") (5 . "1C7F"))))
Below are the properties for two blocks (both named VIFCD_001)
Properties for Block #1
(
(-1 . <Entity name: 3aceb1f0>)
(0 . "INSERT")
(330 . <Entity name: 35557820>)
(5 . "1C7F")
(100 . "AcDbEntity")
(67 . 0)
(410 . "Model")
(8 . "Syms")
(100 . "AcDbBlockReference")
(66 . 1)
(2 . "VIFCD_001")
(10 0.0867055 5.14515e-06 0.0)
(41 . 1.0)
(42 . 1.0)
(43 . 1.0)
(50 . 0.0)
(70 . 0)
(71 . 0)
(44 . 0.0)
(45 . 0.0)
(210 0.0 0.0 1.0)
)
Properties for Block #2
(
(-1 . <Entity name: 3acea5b0>)
(0 . "INSERT")
(330 . <Entity name: 35557820>)
(5 . "1C43")
(100 . "AcDbEntity")
(67 . 0)
(410 . "Model")
(8 . "Syms")
(100 . "AcDbBlockReference")
(66 . 1)
(2 . "VIFCD_001")
(10 145.197 0.100673 0.0)
(41 . 1.0)
(42 . 1.0)
(43 . 1.0)
(50 . 0.0)
(70 . 0)
(71 . 0)
(44 . 0.0)
(45 . 0.0)
(210 0.0 0.0 1.0)
)
@david.faunce wrote:
Thank you Ranjit.
This is helpful, however, I was hoping to have the user not select the object.
This function will need to be purely automated without any prompts for the user to select objects or type inputs.
I need to select the block where BLOCK NAME = VIFCD_001 and its attribute TAG1 = "-M161"
*this command below is wrong, but my question to you is how do I use LISP to identify a block where BLOCKNAME="VIFCD_001" AND TAG1="-M161"*
(setq ent (entsel <block name> <tag name>)) (setq ent (entsel "VIFCD_001", "-M161"))
There has to be some way to identify the block. Block name is one. Other could be block insertion point if you are after a particular block. If you want to update a tag in any instance of the block then you just create a selection set of all the blocks and then iterate through them. My example is good for plugging in your overall function? I thought that was the goal since you needed a function with arguments. Something like this
(defun c:somefunc (/ ctr ss1) (setq ctr 0 ss1 (ssget "_x" '((0 . "insert") (2 . "VIFCD_001")))) (repeat (sslength ss1) (somefunc "DESC" "NEW PART NUMBER" (ssname ss1 ctr)) (setq ctr (1+ ctr)))) (defun somefunc (tagname value blockname / etdata) (mapcar '(lambda (x) (while (/= "SEQEND" (cdr (assoc 0 (setq etdata (entget (setq x (entnext x))))))) (and (= (cdr (assoc 0 etdata)) "ATTRIB") (mapcar '(lambda (x y) (and (= x (cdr (assoc 2 etdata))) (entmod (subst (cons 1 y) (assoc 1 etdata) etdata)))) (list tagname) (list value))))) (mapcar 'cadr (ssnamex (ssget "_x" (list '(0 . "insert") (assoc 2 (entget blockname)) '(66 . 1)))))))
Is there something I am missing?
@david.faunce wrote:
I think I'm getting close, but can someone help? This produces a NIL value, but I believe these are the properties I need to access.
(setq ss (ssget "_X" '((0 . "INSERT") (2 . "VIFCD_001") (5 . "1C7F")))) ;
.................
You cannot use dxf code 5 in ssget. Read here The ssget function recognizes all group codes except entity names (group code -1), handles (group code 5), and .... If you have the entity handle from some previous data processing and want to select an object with a particular handle, for instance, "1C7F" then call hadnet
(handent "1C7F")
Can't find what you're looking for? Ask the community or share your knowledge.