Jump to content

Recommended Posts

Posted (edited)

I have modified a LISP program from the thread of, Area of a polyline.

 

What I am trying to do is:

 

- Obtain the square foot of a single polyline area.

- Obtain the acad handle of the polyline.

 

Within an attribute block containing many different attribute tags:

- Put the value of the square foot into the tag of "NET_SQ_FEET"

- Put the acad handle value into the tag of "ACAD_HANDLE"

 

Currently, from the code below, I am getting an error "VLA-OBJECT ". The code is only attempting to place the value of the square footage. I don't even know where to begin to get the value for the polyline acad handle.

 

(defun c:test ( / area en nm pt )
   (while
       (progn (setvar 'ERRNO 0) (setq en (car (entsel)))
           (cond
               (   (= 7 (getvar 'ERRNO))
                   (princ "\nMissed, try again.")
               )
               (   (eq 'ENAME (type en))
                   (if (vl-catch-all-error-p
                           (setq area (vl-catch-all-apply 'vlax-curve-getarea (list en)))
                       )
                       (princ "\nInvalid Object.")
                   )
               )
               (   (setq area nil)   )
           )
       )
   )

 (setq area (rtos (/ area 144.0) 2 2))

 (if (setq block (ssget "_:S"))
(progn
 (setq block (ssname block 0))
 (LM:vl-SetAttributeValue (vlax-ename->vla-object block) "NET_SQ_FEET" area)
) 
)
 
   (princ)
)
(vl-load-com) (princ)



;;----------------=={ Set Attribute Value }==-----------------;;
;;                                                            ;;
;;  Populates the first attribute matching the tag specified  ;;
;;  found within the block supplied with the value specified, ;;
;;  if present.                                               ;;
;;------------------------------------------------------------;;
;;  Author: Lee Mac, Copyright © 2010 - www.lee-mac.com       ;;
;;------------------------------------------------------------;;
;;  Arguments:                                                ;;
;;  block - VLA Block Reference Object                        ;;
;;  tag   - Attribute TagString                               ;;
;;  value - Value to which the Attribute will be set          ;;
;;------------------------------------------------------------;;
;;  Returns:  Value the attribute was set to, else nil        ;;
;;------------------------------------------------------------;;

(defun LM:vl-SetAttributeValue ( block tag value )
   (setq tag (strcase tag))
   (vl-some
       (function
           (lambda ( attrib )
               (if (eq tag (strcase (vla-get-TagString attrib)))
                   (progn
                       (vla-put-TextString attrib value)
                       value
                   )
               )
           )
       )
       (vlax-invoke block 'GetAttributes)
   )
)

Edited by Ohnoto
Posted

The SSGET function will return a selection set, not an entity; the code below will validate if user selected something and extract the first (and only) item from selection set. Also, seems that Lee's code is expecting a VLA object.

[color=red](if [/color](setq block (ssget "_:S"))
[color=red] (progn
 (setq block (ssname block 0))[/color]
 (LM:vl-SetAttributeValue [color=red](vlax-ename->vla-object[/color] block[color=red])[/color] "NET_SQ_FEET" area)
[color=red] ) 
)[/color]

To list an entity, check the ENTGET function:

(entget block)

The handle is stored on DXF code 5.

Posted

Thanks. I updated the original code. I'll look into where the handle is stored.

Posted (edited)

May be better to use filters to selections.

1. Instead of ENTSEL, this will prevent the user to select nothing but a closed polyline:

(if (setq en (ssget "_:S" '((0 . "LWPOLYLINE") (70 . 1)))[color=red])[/color]
(setq en (ssname en 0))
)

2. For block:

(setq block (ssget "_:S" '((0 . "INSERT"))))

Edited by MSasu
Fixed code example
Posted

I'm getting too few arguments errors when putting in the first code you provided. Could you demonstrate how exactly that should be placed?

Posted

You are right, I missed a paranthesis - please check the fixed code. Sorry for inconvenience.

Posted

Placing this where the ENTSEL is located gives me a "bad argument type: consp " error when selecting the polyline.

Posted

Can you post please how you modified that part?

Posted
(defun c:test ( / area en nm pt )
   (while
       (progn (setvar 'ERRNO 0) (setq en (car
                       (if (setq en (ssget "_:S" '((0 . "LWPOLYLINE") (70 . 1))))
                         (setq en (ssname en 0))
                         )))
           (cond
               (   (= 7 (getvar 'ERRNO))
                   (princ "\nMissed, try again.")
               )
               (   (eq 'ENAME (type en))
                   (if (vl-catch-all-error-p
                           (setq area (vl-catch-all-apply 'vlax-curve-getarea (list en)))
                       )
                       (princ "\nInvalid Object.")
                   )
               )
               (   (setq area nil)   )
           )
       )
   )

Posted

This is how you should have changed that part:

[color=red][s](setq en (car[/s][/color]
         [color=black](if [/color](setq en (ssget "_:S" '((0 . "LWPOLYLINE") (70 . 1))))
          (setq en (ssname en 0))
          [color=red][color=black])[/color][s]))[/s][/color]

You may write it much simple:

(defun c:test ( / area en nm pt)
(if (setq en (ssget "_:S" '((0 . "LWPOLYLINE") (70 . 1))))
 (if (vl-catch-all-error-p
      (setq area (vl-catch-all-apply 'vlax-curve-getarea (list (ssname en 0))))
     )
  (princ "\nInvalid Object.")
 )
 )
(setq area (rtos (/ area 144.0) 2 2))
[color=magenta]...[/color]

Posted

Simpler is better :)

 

Moving on to the acad handle. What I have found is to get the information using a line code like:

 

(setq handle (cdr (assoc 5 (entget en))))

 

However, the setq variable isn't working when trying to place it into the attribute block.

 

(defun c:test ( / area en nm pt )
(if (setq en (ssget "_:S" '((0 . "LWPOLYLINE") (70 . 1))))
 (if (vl-catch-all-error-p
      (setq area (vl-catch-all-apply 'vlax-curve-getarea (list (ssname en 0))))
     )
   (princ "\nInvalid Object.")
   )
  (setq handle (cdr (assoc 5 (entget en))))
  )
 
(setq area (rtos (/ area 144.0) 2 2))

 (if (setq block (ssget "_:S" '((0 . "INSERT"))))
(progn
 (setq block (ssname block 0))
 (LM:vl-SetAttributeValue (vlax-ename->vla-object block) "NET_SQ_FEET" area)
 (LM:vl-SetAttributeValue (vlax-ename->vla-object block) "ACAD_HANDLE" handle)
) 
)
 
   (princ)
)
(vl-load-com) (princ)

;;----------------=={ Set Attribute Value }==-----------------;;
;;                                                            ;;
;;  Populates the first attribute matching the tag specified  ;;
;;  found within the block supplied with the value specified, ;;
;;  if present.                                               ;;
;;------------------------------------------------------------;;
;;  Author: Lee Mac, Copyright © 2010 - www.lee-mac.com       ;;
;;------------------------------------------------------------;;
;;  Arguments:                                                ;;
;;  block - VLA Block Reference Object                        ;;
;;  tag   - Attribute TagString                               ;;
;;  value - Value to which the Attribute will be set          ;;
;;------------------------------------------------------------;;
;;  Returns:  Value the attribute was set to, else nil        ;;
;;------------------------------------------------------------;;

(defun LM:vl-SetAttributeValue ( block tag value )
   (setq tag (strcase tag))
   (vl-some
       (function
           (lambda ( attrib )
               (if (eq tag (strcase (vla-get-TagString attrib)))
                   (progn
                       (vla-put-TextString attrib value)
                       value
                   )
               )
           )
       )
       (vlax-invoke block 'GetAttributes)
   )
)

Posted

Please take care that en variable is storing a selection set, not an entity; also to enclose more than one statement in an IF test, check the use of PROGN.

 (if (setq en (ssget "_:S" '((0 . "LWPOLYLINE") (70 . 1))))
[color=red]  (progn
  (setq thePline (ssname en 0))[/color]
  (if (vl-catch-all-error-p
      (setq area (vl-catch-all-apply 'vlax-curve-getarea (list [color=red]thePline[/color])))
     )
   (princ "\nInvalid Object.")
  )
  (setq handle (cdr (assoc 5 (entget [color=red]thePline[/color]))))
[color=red]  ) ;< PROGN[/color]
)

Posted

Awesome! Thank you for your assistance. This is setup just how I need it.

Posted

Sound that you have finished your code, that's very good. Glad I could help you! You're entirely welcomed!

Posted

I'm pleased that you are able to make use of my functions Ohnoto :)

 

For this particular task, you may want to consider using my 'Set Attribute Values' function, which could be called in the following way:

 

(LM:vl-SetAttributeValues (vlax-ename->vla-object block) (list (cons "NET_SQ_FEET" area) (cons "ACAD_HANDLE" handle)))

 

@Mircea: some very detailed and informative advice, well done :thumbsup:

Posted

  '((0 . "LWPOLYLINE") (70 . 1))

 

 

Perhaps it is better to use Vlax-curve-isClosed, or consider Plinegen.

:)

Posted

I will appreciate if you can detail how that function will improve the selection process.

Second, the PLINEGEN system variable had nothing to do with OP’s task - select closed polylines.

Posted
Second, the PLINEGEN system variable had nothing to do with OP’s task - select closed polylines.

 

Consider the case in which a Closed LWPolyline has Linetype Generation set to ON ;)

 

'((0 . "LWPOLYLINE") (-4 . "&=") (70 . 1))

Posted

You are right; I understand now the issue; that may come also from overriding the system variable in Properties or by PEDIT command.

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...