Jump to content

Recommended Posts

Posted

Hi everyone,

 

Hopefully someone can help me out here.

What I am looking to do is create a LISP that can compare values from any 2 selected attribute values.

For example, I want the user to select 1 value from one block and select another value from another and return information from those select. Maybe something like the distance between them or the difference between them like -0.35 or 1.23 etc etc.

 

I currently use this bit of code below for the selection. What this allows me to do is to pick a point to associate with the Text or Mtext version of the text.

The main issue I am having with the code below is that the y1 "INSERT" portion only allows me to select the first attribute in a block. What I want to be able to do is to get the value of the selected  attribute in a block. If I change the "INSERT" To "ATTRIB" and use nentsel it works fine but then I cant get the insertion point of the block to check distances.

 

Can anyone help me out?

Thanks,

  (if (and (setq ent1 (car (_entsel "\nPick first elevation value: ")))
	   (setq y1 (cdr (assoc 0 (entget ent1))))
	   )
    (cond ((= y1 "INSERT")
	   (setq pt1 (trans (reverse (cdr (reverse (cdr (assoc 10 (entget ent1)))))) 0 1)
	         hgt1 (atof (cdr (assoc 1 (entget (entnext ent1)))))))
	         	  
	  ((= y1 "TEXT")
   	   (setvar "OSMODE" 32)
	   (if (setq pt1 (getpoint "\nFirst grade point: "))
	     (setq pt1 (reverse (Cdr (reverse pt1)))
		   hgt1 (atof (cdr (assoc 1 (entget ent1)))))))
	  
	  ((= y1 "MTEXT")
	   (setvar "OSMODE" 32)
	   (if (setq pt1 (getpoint "\nFirst grade point: "))
	     (setq pt1 (reverse (cdr (reverse pt1)))
		   hgt1 (atof (getpropertyvalue ent1 "Text")))))
	  )
	
     );end if

DO OTHER STUFF HERE

(defun _entsel (msg / p r)
  (setvar "ErrNo" 0)
  (while (not (cond ((and (null (setq p (entsel (strcat "\n" msg)))) (/= 52 (getvar 'errno)))
		     (prompt "\nMissed grade value, try again...")
		    )
		    ((null p) t)
		    ((setq r p))
	      )
	 )
  )
  r
)

 

Posted

If you use nentsel and pick a attribute you will get what you want.

 

(setq val (cdr (assoc 1 (entget (car (nentsel "\nPick an Attribute or *Text "))))))

 

Use assoc (0 . "ATTRIB") rather than a insert.

Posted

Unfortunately, nentsel only returns the attribute object itself, without any reference to the original block itself... I find it a bit frustrating that this is the case.

 

If your attribute tag is fixed throughout your blocks, then you can hard-code it into your code. Otherwise, you may need to prompt the user for the tag (which can be somewhat annoying). However, do take a look at some of these functions that you can use to obtain attributes, in which you can then call it this way: Attribute Functions

 

(LM:vl-getattributevalue (vlax-ename->vla-object (car (entsel "\nPick your block: "))) "<your_tag>")

 

This way, you have the attribute, while also having the original block object itself too.

Posted

Hey @Jonathan Handojo

 

Long time no see. 

You helped me out initially with an interpolate lisp way back when. 

Thank you very much for that. I learned a lot and have greatly improved on it and my office loves it. 

 

I do look at Lee Mac's stuff all the time and learn a lot from his stuff as well. 

 

What I am trying to do is to setup a lisp that people in the office can use to quickly check other people work. I have 1 block where I need to get the insertion point as well as the single attribute value in it. I also have another block where there is 4 attributes and I just need to get the value the user selected. There may also be a 3rd and 4th block where I just need the value of the attribute. 

 

From what you said about nentsel, I may have to use conditional statements to get the information I want depending on what's selected. Looks like I may have to work on this over the weekend. I am stuck using ACAD 2024lt at the office and that hasn't got Vlide and any debugging capabilities. 

 

 

Posted (edited)
34 minutes ago, Strydaris said:

Long time no see. 

You helped me out initially with an interpolate lisp way back when. 

Thank you very much for that. I learned a lot and have greatly improved on it and my office loves it.

 

Hi @Strydaris, really good to hear that you've improved a lot.

 

In this case, I think you can do something like this:

 

(defun AttributeAndBlock (msg / att blk det)
    (while
        (progn
            (setvar "errno" 0)
            (initget "Exit")
            (setq det (entsel msg))
            (cond
                (   (= (getvar "errno") 7) (princ "\nNothing selected."))
                (   (member det '("Exit" nil)) (setq det nil))
                (   (not (wcmatch (cdr (assoc 0 (entget (setq blk (car det))))) "INSERT"))
                    (princ "\nObject is not a block")
                )
                (   (not
                        (and
                            (setq att (nentselp (cadr det)))
                            (wcmatch (cdr (assoc 0 (entget (setq att (car att))))) "ATTRIB")
                        )
                    )
                    (princ "\nAttribute not detected.")
                )
                (   t
                    (setq det (list blk att))
                    nil
                )
            )
        )
    )
    det
)

 

(AttributeAndBlock "\nSelect Attribute [Exit] <exit>: ")

 

Edited by Jonathan Handojo
Posted

You can obtain the parent block reference from a selected attribute reference by querying the entity stored in DXF group 330 (which stores a soft pointer to the owner) - here is an example:

(defun c:test ( / att atx )
    (while
        (progn
            (setvar 'errno 0)
            (setq att (car (nentsel)))
            (cond
                (   (= 7 (getvar 'errno))
                    (princ "\nMissed, try again.")
                )
                (   (null att)
                    nil
                )
                (   (/= "ATTRIB" (cdr (assoc 0 (setq atx (entget att)))))
                    (princ "\nSelected object is not an attribute.")
                )
                (   (prompt
                        (strcat
                            "\nUser selected attribute \""
                            (cdr (assoc 2 atx))
                             "\" with value \""
                            (cdr (assoc 1 atx))
                             "\" belonging to block \""
                            (cdr (assoc 2 (entget (cdr (assoc 330 atx)))))
                            "\"."
                        )
                    )
                )
            )
        )
    )
    (princ)
)

 

  • Like 1
Posted

Beaten to it by better minds I think but I'd have used nentselp, adding in the checking as above... though I didn't realise about the DXF 330 Lee Mac refers to

 

(setq MyBlockSel (entsel "Select Attribute"))
(setq MyBlock (car MyBlockSel))
(setq MyPt (cadr MyBlockSel))
(setq MyText (car (nentselp MyPt)))

 

Posted

Thanks lee about the 330 I have use ssget pt, where the pt is that cadr of the nentsel.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...