Jump to content

Recommended Posts

Posted

If I running a AutoCAD command inside a loop, is it possible to count how many times unsuccessful inside this loops and store into a variable ?

 

Thank you!

Posted

Well, the idea seems possible. You need a variable initialized to 0 before the loop starts, then simply increment it inside an if statement.

 

Though the "problem" may be: "How to test for unsuccessful?" A possible way could be to start a command reactor on :vlr-commandFailed. Then instead of having the if & increment in the loop, you start the reactor before the loop. The reactor call-back would then check if the counting variable is assigned something (i.e. not nil), if so increment it. Of course after the loop you'll need to remove the reactor.

Posted
Well, the idea seems possible. You need a variable initialized to 0 before the loop starts, then simply increment it inside an if statement.

 

Though the "problem" may be: "How to test for unsuccessful?" A possible way could be to start a command reactor on :vlr-commandFailed. Then instead of having the if & increment in the loop, you start the reactor before the loop. The reactor call-back would then check if the counting variable is assigned something (i.e. not nil), if so increment it. Of course after the loop you'll need to remove the reactor.

 

Thank you for your suggestion.

Posted
Well, the idea seems possible. You need a variable initialized to 0 before the loop starts, then simply increment it inside an if statement.

 

Though the "problem" may be: "How to test for unsuccessful?" A possible way could be to start a command reactor on :vlr-commandFailed. Then instead of having the if & increment in the loop, you start the reactor before the loop. The reactor call-back would then check if the counting variable is assigned something (i.e. not nil), if so increment it. Of course after the loop you'll need to remove the reactor.

 

As you said, can I write the code like this ?

 

(defun c:tmp (/ ctr tte sset item r )
  (setq sset (ssget "_a" (LIST '(0 . "*polyline") (cons 410 (getvar "CTAB")))))
  (setq ctr 0 tte 0 r 0)
  (repeat (sslength sset )
    (setq item (ssname sset ctr))

(if (/= sset 0)
   (porgn
   (vl-cmdf "explode" item "")
   (princ "All objects exploded")
   )
   (progn
   (setq r (1+ r))
);end if

(if (/= r 0)
      (alert (strcat "total"(itoa r) "nos of polyline can't explode"))
       (princ "All polyline exploded")
    );end if
);end if


);end defun

Posted

One quick notice:

 

 
...
(if (/= sset 0)
   (progn
   (vl-cmdf "explode" item "")
   (princ "All objects exploded")
   )
...

Posted

Another quick tweak...

 

This exploded all polylines I placed on screen:

 

 
(defun c:tmp (/ ctr sset item r) [color=red]; tte
[/color]  (setq
   sset (ssget "_a"
 (LIST '(0 . "*polyline") (cons 410 (getvar "CTAB")))
 )
 )
 (setq ctr 0 r 0)    [color=red] ; tte 0)[/color]
 (repeat (sslength sset)
   (setq item (ssname sset ctr))
   (if (/= sset 0)
     ([color=red]progn
[/color]        (vl-cmdf "[color=red]_.[/color]explode" item "")
       (princ "[color=red]\nThis[/color] object exploded")
     )     ;end progn
[color=red]  ;;   (progn
[/color]        (setq r (1+ r))
[color=red]  ;;   )     ;end progn
[/color]    )     ;end if
  [color=red] (setq ctr (1+ ctr))
[/color]  )     ;end repeat
 (if (/= r 0)
   (alert
     (strcat "[color=red]\n[/color][color=black]T[/color][color=black]otal[/color]" (itoa r) "nos of polyline can't explode")
   )
   (princ "[color=red]\n[/color][color=black]All[/color] polyline exploded")
 )     ;end if
[color=red]  (princ) ; exit quietly
[/color])     ;end defun

 

The \n starts a new line that make the code easier to read, and the ending (princ) keeps the code from returning the final message twice.

Posted
Another quick tweak...

 

This exploded all polylines I placed on screen:

 

 
(defun c:tmp (/ ctr sset item r) [color=red]; tte[/color]
 (setq
   sset (ssget "_a"
 (LIST '(0 . "*polyline") (cons 410 (getvar "CTAB")))
 )
 )
 (setq ctr 0 r 0)    [color=red] ; tte 0)[/color]
 (repeat (sslength sset)
   (setq item (ssname sset ctr))
   (if (/= sset 0)
     ([color=red]progn[/color]
       (vl-cmdf "[color=red]_.[/color]explode" item "")
       (princ "[color=red]\nThis[/color] object exploded")
     )     ;end progn
[color=red]  ;;   (progn[/color]
       (setq r (1+ r))
[color=red]  ;;   )     ;end progn[/color]
   )     ;end if
  [color=red](setq ctr (1+ ctr))[/color]
 )     ;end repeat
 (if (/= r 0)
   (alert
     (strcat "[color=red]\n[/color][color=black]T[/color][color=black]otal[/color]" (itoa r) "nos of polyline can't explode")
   )
   (princ "[color=red]\n[/color][color=black]All[/color] polyline exploded")
 )     ;end if
[color=red] (princ) ; exit quietly[/color]
)     ;end defun

 

The \n starts a new line that make the code easier to read, and the ending (princ) keeps the code from returning the final message twice.

 

Thank you for your help, but when I try to work on a drawing without polylines. It failed to run. It can't return how many polylines can't explode.

Posted

Unfortunately what you want to do is not going to produce any errors, since the Explode command checks prior to attempting to explode.

 

Just a small alternative: instead of sending each to the explode command, rather check if it is explodable through its ActiveX object:

(vl-load-com)

(defun c:ExpPolys (/ ss eo err res)
 (if (ssget "_a" (LIST '(0 . "*polyline") (cons 410 (getvar "CTAB"))))
   (progn
     (setq err 0
           ss  (vla-get-ActiveSelectionSet (vla-get-ActiveDocument (vlax-get-acad-object)))
     )
     (vlax-for eo ss
       (if (vl-catch-all-error-p (setq res (vl-catch-all-apply 'vla-Explode (list eo))))
         (setq err (1+ err))
       )
     )
     (princ (strcat "\nOff " (itoa (vla-get-Count ss)) " polylines, " (itoa err) " couldn't be exploded."))
     ;; Ensure selection set is cleared from RAM
     (vla-Delete ss)
     (vlax-release-object ss)
     (setq ss nil)
     (gc)
   )
   (princ "\nNo polylines to explode.")
 )
 (princ)
)

However, that code will even explode polylines on LockedLayers. If you need to stick with those on Locked layers, then you need a bit more complex code:

(vl-load-com)

(defun c:ExpPolys (/ ss eo err lck res LckLay)
 ;; Firsth get all the locked layer names
 (vlax-for eo (vla-get-Layers (vla-get-ActiveDocument (vlax-get-acad-object)))
   (if (= (vla-get-Lock eo) :vlax-true)
     (setq LckLay (cons (vla-get-Name eo) LckLay))
   )
 )
 ;; Next select and initialize variables
 (if (ssget "_a" (LIST '(0 . "*polyline") (cons 410 (getvar "CTAB"))))
   (progn
     (setq err 0
           lck 0
           ss  (vla-get-ActiveSelectionSet (vla-get-ActiveDocument (vlax-get-acad-object)))
     )
     ;; Step through all items in the selection set
     (vlax-for eo ss
       ;; Check if on locked layer
       (if (vl-position (vla-get-Layer eo) LckLay)
         (setq lck (1+ lck)) ;If locked increment lck
         ;; Else attempt to explode
         (if (vl-catch-all-error-p (setq res (vl-catch-all-apply 'vla-Explode (list eo))))
           (setq err (1+ err)) ;If failed increment err
         )
       )
     )
     (princ (strcat "\nOff "
                    (itoa (vla-get-Count ss))
                    " polylines, "
                    (itoa lck)
                    " were on locked layers and "
                    (itoa err)
                    " couldn't be exploded."
            )
     )
     ;; Ensure selection set is cleared from RAM
     (vla-Delete ss)
     (vlax-release-object ss)
     (setq ss nil)
     (gc)
   )
   (princ "\nNo polylines to explode.")
 )
 (princ)
)

Posted
Unfortunately what you want to do is not going to produce any errors, since the Explode command checks prior to attempting to explode.

 

Just a small alternative: instead of sending each to the explode command, rather check if it is explodable through its ActiveX object:

(vl-load-com)

(defun c:ExpPolys (/ ss eo err res)
 (if (ssget "_a" (LIST '(0 . "*polyline") (cons 410 (getvar "CTAB"))))
   (progn
     (setq err 0
           ss  (vla-get-ActiveSelectionSet (vla-get-ActiveDocument (vlax-get-acad-object)))
     )
     (vlax-for eo ss
       (if (vl-catch-all-error-p (setq res (vl-catch-all-apply 'vla-Explode (list eo))))
         (setq err (1+ err))
       )
     )
     (princ (strcat "\nOff " (itoa (vla-get-Count ss)) " polylines, " (itoa err) " couldn't be exploded."))
     ;; Ensure selection set is cleared from RAM
     (vla-Delete ss)
     (vlax-release-object ss)
     (setq ss nil)
     (gc)
   )
   (princ "\nNo polylines to explode.")
 )
 (princ)
)

However, that code will even explode polylines on LockedLayers. If you need to stick with those on Locked layers, then you need a bit more complex code:

(vl-load-com)

(defun c:ExpPolys (/ ss eo err lck res LckLay)
 ;; Firsth get all the locked layer names
 (vlax-for eo (vla-get-Layers (vla-get-ActiveDocument (vlax-get-acad-object)))
   (if (= (vla-get-Lock eo) :vlax-true)
     (setq LckLay (cons (vla-get-Name eo) LckLay))
   )
 )
 ;; Next select and initialize variables
 (if (ssget "_a" (LIST '(0 . "*polyline") (cons 410 (getvar "CTAB"))))
   (progn
     (setq err 0
           lck 0
           ss  (vla-get-ActiveSelectionSet (vla-get-ActiveDocument (vlax-get-acad-object)))
     )
     ;; Step through all items in the selection set
     (vlax-for eo ss
       ;; Check if on locked layer
       (if (vl-position (vla-get-Layer eo) LckLay)
         (setq lck (1+ lck)) ;If locked increment lck
         ;; Else attempt to explode
         (if (vl-catch-all-error-p (setq res (vl-catch-all-apply 'vla-Explode (list eo))))
           (setq err (1+ err)) ;If failed increment err
         )
       )
     )
     (princ (strcat "\nOff "
                    (itoa (vla-get-Count ss))
                    " polylines, "
                    (itoa lck)
                    " were on locked layers and "
                    (itoa err)
                    " couldn't be exploded."
            )
     )
     ;; Ensure selection set is cleared from RAM
     (vla-Delete ss)
     (vlax-release-object ss)
     (setq ss nil)
     (gc)
   )
   (princ "\nNo polylines to explode.")
 )
 (princ)
)

 

Thank you so much !

Posted
Thank you so much !
You're welcome!
Posted

I'm not following the code here but when you had to keep purging a drawing to get rid of sub entities I used to QSAVE before the purge and then check the value of DBMOD after the purge. If there had been a change in the drawing database DBMOD will have changed but when all items had been purged there was no change to the database. I'm not sure that it would work with explode but its just another possible route to explore.

Posted

That's a very good suggestion!

 

Unfortunately it won't help in all cases for the OP. He wants to make a command which automatically explodes all polylines in the current space, but lists how many couldn't be exploded (for whatever reason). I suppose you could run the explode command, QSAVE, then run it again and see ...

 

Wait a minute! That just gave me another idea! It's actually extremely simple! :shock::

(defun c:ExpPolys1 (/ ss len)
 (if (and (setq ss (ssget "_a" (LIST '(0 . "*polyline") (cons 410 (getvar "CTAB")))))
          (setq len (sslength ss))
     )
   (progn
     (command "_.EXPLODE" ss "")
     (setq ss nil)
     (gc)
     (if (setq ss (ssget "_a" (LIST '(0 . "*polyline") (cons 410 (getvar "CTAB")))))
       (princ (strcat "\nAttempted to explode "
                      (itoa len)
                      " polylines, but "
                      (itoa (sslength ss))
                      " wouldn't explode."
              )
       )
       (princ (strcat "\nAll of " (itoa len) " polylines were exploded."))
     )
     (setq ss nil)
     (gc)
   )
   (princ "\nThere were no polylines to explode.")
 )
 (princ)
)

Posted
does that mean I helped? :? :D
By all means: Yes!

 

If it wasn't for your suggestion, I'd probably not have thought of doing it in a 2 step process!

 

BTW, I'm probably still overcooking it by clearing selection sets twice. Probably a single gc call anywhere in the defun would have sufficed:

(defun c:ExpPolys1 (/ ss len)
 (gc)
 (if (and (setq ss (ssget "_a" (LIST '(0 . "*polyline") (cons 410 (getvar "CTAB")))))
          (setq len (sslength ss))
     )
   (progn
     (command "_.EXPLODE" ss "")
     (if (setq ss (ssget "_a" (LIST '(0 . "*polyline") (cons 410 (getvar "CTAB")))))
       (princ (strcat "\nAttempted to explode "
                      (itoa len)
                      " polylines, but "
                      (itoa (sslength ss))
                      " wouldn't explode."
              )
       )
       (princ (strcat "\nAll of " (itoa len) " polylines were exploded."))
     )
   )
   (princ "\nThere were no polylines to explode.")
 )
 (princ)
)

You could even have left it out, but it's safer to try and clear selections sets since there's only a finite amount available.

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