Author Topic: (ssget "_X" ...) Vs. (vlax-for ... (vla-get-block ...))  (Read 10360 times)

0 Members and 1 Guest are viewing this topic.

Marc'Antonio Alessi

  • Swamp Rat
  • Posts: 1451
  • Marco
(ssget "_X" ...) Vs. (vlax-for ... (vla-get-block ...))
« on: February 20, 2015, 05:04:44 AM »
1) (ssget "_X" ...) can not be used  in ObjectDBX doc
2) (ssget "_X" ...) is much faster

Question: under normal conditions (activedocument) it is better to use (ssget "_X" ...) or is there a faster method?
Code: [Select]
(setq *AcAcDwg* (vla-get-activedocument (vlax-get-acad-object)))
(defun ALE_Block_GetInserts1 (VlaDoc LayNms BlkNms / OutLst Vl_Tms)
    (setq   Vl_Tms  (car (_vl-times)))
    (vlax-for LayFor (vla-get-layouts VlaDoc)
      (if (wcmatch (strcase (vla-get-name LayFor)) (strcase LayNms))
        (vlax-for ObjFor (vla-get-block LayFor)
          (if
            (and
              (= (vla-get-objectname ObjFor) "AcDbBlockReference")
              (wcmatch (vla-get-Name  ObjFor) BlkNms)
            )
            (setq OutLst (cons ObjFor OutLst))
          )
        )
      )
    )
;  OutLst
    (- (car (_vl-times)) Vl_Tms)
)
(defun ALE_SSGetInserts ( / Vl_Tms)
  (setq   Vl_Tms  (car (_vl-times)))
  (ssget "_X" '((0 . "INSERT") (2 . "FOO*")(410 . "Model")))
  (- (car (_vl-times)) Vl_Tms)
)
Code: [Select]
Command: (ALE_SSGetInserts)
187

Command: (ALE_Block_GetInserts1 *AcAcDwg* "Model" "FOO*")
9422

Lee Mac

  • Seagull
  • Posts: 12913
  • London, England
Re: (ssget "_X" ...) Vs. (vlax-for ... (vla-get-block ...))
« Reply #1 on: February 20, 2015, 07:48:27 AM »
Using vlax-for provides direct access to the vla-object representations of objects in the layout, whereas the required conversion using vlax-ename->vla-object whilst iterating over the selection set returned by ssget can be slow if I recall correctly.

For a better comparison, I would use:

Code: [Select]
(defun ALE_SSGetInserts ( / Vl_Tms sel idx lst )
    (setq Vl_Tms (car (_vl-times)))
    (if (setq sel (ssget "_X" '((0 . "INSERT") (2 . "FOO*") (410 . "Model"))))
        (repeat (setq idx (sslength sel))
            (setq lst (cons (vlax-ename->vla-object (ssname sel (setq idx (1- idx)))) lst))
        )
    )
    (- (car (_vl-times)) Vl_Tms)
)

Marc'Antonio Alessi

  • Swamp Rat
  • Posts: 1451
  • Marco
Re: (ssget "_X" ...) Vs. (vlax-for ... (vla-get-block ...))
« Reply #2 on: February 20, 2015, 09:03:30 AM »
Using vlax-for provides direct access to the vla-object representations of objects in the layout, whereas the required conversion using vlax-ename->vla-object whilst iterating over the selection set returned by ssget can be slow if I recall correctly.
For a better comparison, I would use: ...
I agree but there is not much difference:
Code: [Select]
(ALE_Block_GetInserts1 *AcAcDwg* "Model" "FOO*") => 10577

(ALE_SSGetInserts)    => 359
(ALE_SSGetInsertsLee) => 312
(ALE_SSGetInsertsLee) => 281
(ALE_SSGetInserts)    => 328

(Sslength (ssget "_X" '((0 . "INSERT") (2 . "FOO*") (410 . "Model"))))
=> 252
(Sslength (ssget "_X" '((0 . "INSERT") (2 . "*") (410 . "Model"))))
=> 4146
(Sslength (ssget "_X" '((410 . "Model"))))
=> 108256

Patrick_35

  • Guest
Re: (ssget "_X" ...) Vs. (vlax-for ... (vla-get-block ...))
« Reply #3 on: February 20, 2015, 10:12:21 AM »
Hi

If you want work With (ssget "x") and vlisp, you can use vla-get-activeselectionset

For example
Code - Auto/Visual Lisp: [Select]
  1. (defun c:test(/ blo doc sel)
  2.   (and (ssget "x" (list (cons 0 "insert")))
  3.     (progn
  4.       (vlax-for blo (setq sel (vla-get-activeselectionset doc))
  5.         (princ (strcat "\n" (vla-get-name blo)))
  6.       )
  7.       (vla-delete sel)
  8.     )
  9.   )
  10.   (princ)
  11. )

@+

Marc'Antonio Alessi

  • Swamp Rat
  • Posts: 1451
  • Marco
Re: (ssget "_X" ...) Vs. (vlax-for ... (vla-get-block ...))
« Reply #4 on: February 20, 2015, 10:25:36 AM »
Hi
If you want work With (ssget "x") and vlisp, you can use vla-get-activeselectionset
For example...
@+
Thanks,  I do not want work With (ssget "x") but to know if  (ssget "x") is the best/faster method to get a SelSet or a list of Vla Objects...

Patrick_35

  • Guest
Re: (ssget "_X" ...) Vs. (vlax-for ... (vla-get-block ...))
« Reply #5 on: February 20, 2015, 10:29:28 AM »
Yes, ssget with activeselectionset is the best

Code - Auto/Visual Lisp: [Select]
  1. (defun ALE_SSGetInserts ( / Vl_Tms doc sel)
  2.         Vl_Tms (car (_vl-times))
  3.   )
  4.   (and (ssget "_X" '((0 . "INSERT") (2 . "FOO*") (410 . "Model")))
  5.     (progn
  6.       (vlax-for blo (setq sel (vla-get-activeselectionset doc))
  7.         (setq lst (cons blo lst))
  8.       )
  9.       (vla-delete sel)
  10.     )
  11.   )
  12.   (- (car (_vl-times)) Vl_Tms)
  13. )

@+

Marc'Antonio Alessi

  • Swamp Rat
  • Posts: 1451
  • Marco
Re: (ssget "_X" ...) Vs. (vlax-for ... (vla-get-block ...))
« Reply #6 on: February 20, 2015, 10:43:55 AM »
Yes, ssget with activeselectionset is the best
...
Not much difference:
Code: [Select]
Comando: (ALE_SSGetInsertsLee) 203
Comando: (ALE_SSGetInsertsP35) 343
Comando: (ALE_SSGetInsertsLee) 312
Comando: (ALE_SSGetInsertsP35) 328
Comando: (ALE_SSGetInsertsP35) 374
Comando: (ALE_SSGetInsertsLee) 374
Comando: (ALE_SSGetInsertsP35) 374
Comando: (ALE_SSGetInsertsLee) 359

Marc'Antonio Alessi

  • Swamp Rat
  • Posts: 1451
  • Marco
Re: (ssget "_X" ...) Vs. (vlax-for ... (vla-get-block ...))
« Reply #7 on: February 20, 2015, 11:05:21 AM »
About half the time if executed on the same file opened in ObjectDBX:
Code: [Select]
; DbxDoc > ObjectDBX.AxDbDocument
(ALE_Block_GetInserts1 DbxDoc "Model" "FOO*") => 6630
(ALE_Block_GetInserts1 DbxDoc "Model" "FOO*") => 6833
(ALE_Block_GetInserts1 DbxDoc "Model" "FOO*") => 6896

Lee Mac

  • Seagull
  • Posts: 12913
  • London, England
Re: (ssget "_X" ...) Vs. (vlax-for ... (vla-get-block ...))
« Reply #8 on: February 20, 2015, 12:12:34 PM »
Yes, ssget with activeselectionset is the best

I've had some trouble with the activeselectionset method in the past (an intermittent and inconsistent error: Automation Error. Calling method Clear of interface IAcadSelectionSet failed) and have now abandoned this method entirely.

alanjt

  • Needs a day job
  • Posts: 5352
  • Standby for witty remark...
Re: (ssget "_X" ...) Vs. (vlax-for ... (vla-get-block ...))
« Reply #9 on: February 20, 2015, 10:38:44 PM »
Yes, ssget with activeselectionset is the best

I've had some trouble with the activeselectionset method in the past (an intermittent and inconsistent error: Automation Error. Calling method Clear of interface IAcadSelectionSet failed) and have now abandoned this method entirely.
Precisely why I abandoned its use as well.
Civil 3D 2019 ~ Windohz 7 64bit
Dropbox

pBe

  • Bull Frog
  • Posts: 402
Re: (ssget "_X" ...) Vs. (vlax-for ... (vla-get-block ...))
« Reply #10 on: February 21, 2015, 03:56:25 AM »
Yes, ssget with activeselectionset is the best

I've had some trouble with the activeselectionset method in the past (an intermittent and inconsistent error: Automation Error. Calling method Clear of interface IAcadSelectionSet failed) and have now abandoned this method entirely.
Precisely why I abandoned its use as well.


Why is that again guys?  can you enlighten us more on this issue?

Patrick_35

  • Guest
Re: (ssget "_X" ...) Vs. (vlax-for ... (vla-get-block ...))
« Reply #11 on: February 21, 2015, 04:42:30 AM »
Yes, ssget with activeselectionset is the best

I've had some trouble with the activeselectionset method in the past (an intermittent and inconsistent error: Automation Error. Calling method Clear of interface IAcadSelectionSet failed) and have now abandoned this method entirely.
Precisely why I abandoned its use as well.
I had the same problem that I solved using systematically erasing the selection. Since then, no problems. Now all my lisps use this method.
Look at the two lisps I posted

@+

Lee Mac

  • Seagull
  • Posts: 12913
  • London, England
Re: (ssget "_X" ...) Vs. (vlax-for ... (vla-get-block ...))
« Reply #12 on: February 21, 2015, 08:13:08 AM »
Yes, ssget with activeselectionset is the best

I've had some trouble with the activeselectionset method in the past (an intermittent and inconsistent error: Automation Error. Calling method Clear of interface IAcadSelectionSet failed) and have now abandoned this method entirely.
Precisely why I abandoned its use as well.
I had the same problem that I solved using systematically erasing the selection. Since then, no problems. Now all my lisps use this method.
Look at the two lisps I posted

I would also delete the selection set [ (vla-delete sel) ] after processing, but this did not seem to resolve the issue; or are you referring to something else when you say 'solved using systematically erasing the selection'?

Lee Mac

  • Seagull
  • Posts: 12913
  • London, England
Re: (ssget "_X" ...) Vs. (vlax-for ... (vla-get-block ...))
« Reply #13 on: February 21, 2015, 08:15:48 AM »
Yes, ssget with activeselectionset is the best

I've had some trouble with the activeselectionset method in the past (an intermittent and inconsistent error: Automation Error. Calling method Clear of interface IAcadSelectionSet failed) and have now abandoned this method entirely.
Precisely why I abandoned its use as well.

Why is that again guys?  can you enlighten us more on this issue?

I am unsure exactly why the error occurs, as there appears to be no consistent condition which causes it to fail - in my experience, the same code will sometimes work and sometimes not; and of course, with such unpredictability and with other methods readily available, I abandoned the use of the activeselectionset property.

Marc'Antonio Alessi

  • Swamp Rat
  • Posts: 1451
  • Marco
Re: (ssget "_X" ...) Vs. (vlax-for ... (vla-get-block ...))
« Reply #14 on: February 21, 2015, 08:33:48 AM »
@ Lee:
What do you think of this version? (I had to write it in this form for compatibility with the previous...)
Code: [Select]
; Function: ALE_Block_GetInserts
;
; Version 1.00 - 30/11/2005
; Version 1.01 - 06/12/2005
; Version 2.03 - 22/02/2015
;
; Description:
;   returns a list of all blocks in VlaDoc matching Layout names,
;   Layers names and Block names
;
; Arguments:
;   LayNms: Layout names - Wcmatch string > "Model,Layout1"     or "*" for all
;   LyrNms: Layer  names - Wcmatch string > "Layer1,Layer2*"    or "*" for all
;   BlkNms: Block  names - Wcmatch string > "Block001,BlockNnn" or "*" for all
;                     > "[~*]*"      > no anonimous blocks
;   FlgAtt
;    = :vlax-true  > only with attribs
;    = :vlax-false > only without attribs
;    = nil         > all
;
; Return Values: LIST
;
; Example:
; (ALE_Block_GetInserts
;  (vla-get-activedocument (vlax-get-acad-object)) "*" "*" "*" nil
; )
;
;      Block name  Layer name Layout name
; > (("TITLEBLOCK"  "LAYERX"    "MODEL"
;      #<VLA-OBJECT IAcadBlockReference2 08330c34>) (...) ...)
;
(defun ALE_Block_GetInserts (VlaDoc LayNms LyrNms BlkNms FlgAtt / VlaObj LayNam LyrNam BlkNam OutLst Ss_Tmp Countr EntNam)
  (cond
    ( (not (= 'VLA-OBJECT (type VlaDoc))) )
    ( (vl-catch-all-error-p (vl-catch-all-apply 'vla-get-ActiveLayer (list VlaDoc)))
    ; ActiveLayer it is not a property of a IAxDbDocument: Interface then
    ; I use vla-get-layouts else (ssget "_X" ...) because it is 20 times faster
    ;(vlax-property-available-p VlaDoc 'Layouts) ;da aggiungere in futuro  20140213
      (vlax-for LayFor (vla-get-layouts VlaDoc)
        (if (wcmatch (setq LayNam (strcase (vla-get-name LayFor))) (strcase LayNms))
          (vlax-for ObjFor (vla-get-block LayFor)
            (if
              (and
                (= (vla-get-objectname ObjFor) "AcDbBlockReference")
                (not (vlax-property-available-p ObjFor 'Path))       ; not Xref
                (wcmatch (setq LyrNam (strcase (vla-get-Layer ObjFor))) (strcase LyrNms))
                (wcmatch (setq BlkNam (strcase (vla-get-Name  ObjFor))) (strcase BlkNms))
                (if FlgAtt (= (vla-get-hasattributes ObjFor) FlgAtt) T)
              )
              (setq OutLst (cons (list BlkNam LyrNam LayNam ObjFor) OutLst))
            )
          )
        )
      )
    )
    ( (setq Ss_Tmp
        (ssget "_X"
          (cond
            ( (= :vlax-true  FlgAtt) (list '(0 . "INSERT") (cons 410 LayNms) (cons 8 LyrNms) (cons 2 BlkNms) '(66 . 1)) )
            ( (= :vlax-false FlgAtt) (list '(0 . "INSERT") (cons 410 LayNms) (cons 8 LyrNms) (cons 2 BlkNms) '(66 . 0)) )
            ( T                      (list '(0 . "INSERT") (cons 410 LayNms) (cons 8 LyrNms) (cons 2 BlkNms))           )
          )
        )
      )
      (repeat (setq Countr (sslength Ss_Tmp))
        (and
          (setq VlaObj (vlax-ename->vla-object (setq EntNam (ssname Ss_Tmp (setq Countr (1- Countr))))))
          (not (vlax-property-available-p VlaObj 'Path))       ; not Xref
          (setq OutLst (cons (list (vla-get-Name VlaObj) (vla-get-Layer VlaObj) (DXF 410 (entget EntNam)) VlaObj) OutLst))
        )
      )
    )
  )
  OutLst
)

Patrick_35

  • Guest
Re: (ssget "_X" ...) Vs. (vlax-for ... (vla-get-block ...))
« Reply #15 on: February 23, 2015, 03:50:24 AM »
Yes, ssget with activeselectionset is the best

I've had some trouble with the activeselectionset method in the past (an intermittent and inconsistent error: Automation Error. Calling method Clear of interface IAcadSelectionSet failed) and have now abandoned this method entirely.
Precisely why I abandoned its use as well.
I had the same problem that I solved using systematically erasing the selection. Since then, no problems. Now all my lisps use this method.
Look at the two lisps I posted

I would also delete the selection set [ (vla-delete sel) ] after processing, but this did not seem to resolve the issue; or are you referring to something else when you say 'solved using systematically erasing the selection'?
Sorry if my English is not great.
What I mean is that you make a selection with ssget and then your treatment with activeselectionset.
Then you make a vla-delete on activeselectionset
From what I could deduce is that a stacking selections causes this error and that systematically erasing the selection set, I do not have this problem.
I use it for years, post lisps with this method on other forums.

kruuger

  • Swamp Rat
  • Posts: 635
Re: (ssget "_X" ...) Vs. (vlax-for ... (vla-get-block ...))
« Reply #16 on: February 24, 2015, 05:31:40 AM »

draw few objects.
start XXX

Code: [Select]
(defun c:XXX (/ doc)
  (setq doc (vla-get-ActiveDocument (vlax-get-acad-object)))
  (ssget)
  (vlax-for %
    (vla-get-activeselectionset
      (vla-get-activedocument
        (vlax-get-acad-object)
      )
    )
    (princ %) (princ "\n")
  )
  (princ)
)

make few undo CTRL+Z.
try to run XXX and -> error: Automation Error. Calling method Clear of interface IAcadSelectionSet

as Patrick said. we add vla-delete and so far no more error.

Code: [Select]
(defun c:XXX (/ doc ss)
  (setq doc (vla-get-ActiveDocument (vlax-get-acad-object)))
  (ssget)
  (vlax-for %
    (setq ss
      (vla-get-activeselectionset
        (vla-get-activedocument
          (vlax-get-acad-object)
        )
      )
    )
    (princ %) (princ "\n")
  )
  (vla-delete ss)
  (princ)
)
i noticed that errors occurs very often after undo (when no vle-delete)
k.
« Last Edit: February 24, 2015, 05:37:11 AM by kruuger »

ur_naz

  • Newt
  • Posts: 68
  • Made in Ukraine
Re: (ssget "_X" ...) Vs. (vlax-for ... (vla-get-block ...))
« Reply #17 on: February 24, 2015, 10:12:39 AM »
You may directly select inserts using filters
Code - Auto/Visual Lisp: [Select]
  1.   (setq ss  ( (lambda ( sname sss )
  2.                       ( (if (vl-catch-all-error-p
  3.                               (vl-catch-all-apply 'vla-item
  4.                                                   (list sss sname)
  5.                               )
  6.                             )
  7.                             vla-add
  8.                             vla-item
  9.                         )
  10.                         sss
  11.                         sname
  12.                       )
  13.                     )
  14.                     "SomeSet"
  15.                     (vla-get-selectionsets
  16.                       (vla-get-activedocument (vlax-get-acad-object)))
  17.             )
  18.   )
  19.   (vla-clear ss)
  20.   (setq
  21.     ssflt0 (vlax-make-safearray vlax-vbinteger '(0 . 0))
  22.     ssflt1 (vlax-make-safearray vlax-vbvariant '(0 . 0))
  23.   )
  24.  
  25.     ss
  26.     acselectionsetall
  27.     nil
  28.     nil
  29.     (vlax-safearray-fill ssflt0 '(0))
  30.     (vlax-safearray-fill ssflt1 '("INSERT"))
  31.   )
  32.   ss
  33. )

Marc'Antonio Alessi

  • Swamp Rat
  • Posts: 1451
  • Marco
Re: (ssget "_X" ...) Vs. (vlax-for ... (vla-get-block ...))
« Reply #18 on: February 24, 2015, 12:17:32 PM »
If my test is valid I do not see the convenience:
Code: [Select]
Benchmark.lsp | © 2005 Michael Puckett | All Rights Reserved
    (ALE_SSGETINSERTS).....1388 / 2.4 <fastest>
    (ALE_SSGETINSERTS).....1450 / 2.3
    (P35_SSGETINSERTS).....1482 / 2.25
    (P35_SSGETINSERTS).....1529 / 2.18
    (NAZ_SSGETINSERTS).....2745 / 1.22
    (NAZ_SSGETINSERTS).....3338 / 1 <slowest>
Code: [Select]
(defun ALE_SSGetInserts ( /  sel idx lst )
    (if (setq sel (ssget "_X" '((0 . "INSERT"))))
        (repeat (setq idx (sslength sel))
            (setq lst (cons (vlax-ename->vla-object (ssname sel (setq idx (1- idx)))) lst))
        )
    )
)
(defun naz_SSGetInserts ( /  ss lst)
     (setq ss  ( (lambda ( sname sss )
                         ( (if (vl-catch-all-error-p
                                 (vl-catch-all-apply 'vla-item
                                                     (list sss sname)
                                 )
                               )
                               vla-add
                               vla-item
                           )
                           sss
                           sname
                         )
                       )
                       "SomeSet"
                       (vla-get-selectionsets
                         (vla-get-activedocument (vlax-get-acad-object)))
               )
     )
     (vla-clear ss)
     (setq
       ssflt0 (vlax-make-safearray vlax-vbinteger '(0 . 0))
       ssflt1 (vlax-make-safearray vlax-vbvariant '(0 . 0))
     )
     (vla-select
       ss
       acselectionsetall
       nil
       nil
       (vlax-safearray-fill ssflt0 '(0))
       (vlax-safearray-fill ssflt1 '("INSERT"))
     )
     (if ss (vlax-for blo ss (setq lst (cons blo lst))))
)
(defun P35_SSGetInserts ( /  doc sel lst)
     (setq
       doc (vla-get-activedocument (vlax-get-acad-object))
     )
     (and (ssget "_X" '((0 . "INSERT")))
       (progn
         (vlax-for blo (setq sel (vla-get-activeselectionset doc))
           (setq lst (cons blo lst))
         )
         (vla-delete sel)
       )
     )
     lst
)

ur_naz

  • Newt
  • Posts: 68
  • Made in Ukraine
Re: (ssget "_X" ...) Vs. (vlax-for ... (vla-get-block ...))
« Reply #19 on: February 25, 2015, 01:46:55 AM »
:-( wow, my way is slowest. so, if i have to delete some garbage entities such as points, small lines, blank texts or wipeouts, what is the fastest way to do it?

Marc'Antonio Alessi

  • Swamp Rat
  • Posts: 1451
  • Marco
Re: (ssget "_X" ...) Vs. (vlax-for ... (vla-get-block ...))
« Reply #20 on: February 26, 2015, 01:13:35 PM »
I do not understand the question, it seems to me that there is the solution...