Тема: Цикл, большое количество элементов

Данный код проходит по всем элементам и находит среди них, отвечающие фильтру.

    (setq app (vlax-get-acad-object)
    doc (vla-get-ActiveDocument app)
    mdl (vla-get-ModelSpace doc))

    (vlax-for obj mdl
    (setq ename (vlax-vla-object->ename obj)
      component (at_XData_getFld ename "CLASS" "AT_EXTDATA"))
    
    (if (not (null component))
      (progn
    (if (wcmatch component "*SUPP*")
      (ssadd ename set-sup)) ; if
    (if (wcmatch component "*PIP*")      
        (ssadd ename set-pip)    
      ) ; if
    ) ; progn
      )    
    ) ; vlax-for

Но при этом AutoCAD подвисает, что не айс - пользователи же в панику бросаются сразу.

Есть ли более быстрый способ поиска элементов, отвечающих фильтру?
Как сделать так, чтобы AutoCAD не подвисал? прогрессбар какой-нить может повесить?

Re: Цикл, большое количество элементов

То есть нет быстрого способа прохода по всем элементам?

Re: Цикл, большое количество элементов

Есть. Но я бы серьезно подумал на предмет получения результат at_XData_getFld - возможно, проблема в нем. Код по типу http://communities.autodesk.com/cis/res … sego-faila работает очень быстро.

Re: Цикл, большое количество элементов

Дело в том, что у меня объекты есть группы..они состоят из вхождения блока и из нескольких наборов примитивов, типы которых могут быть различны. поэтому (и еще потому, что не хватает знаний) использую at_xdata_getfld, что с его помощью можно обратиться в группе (в моем случае "AT_EXTDATA") по названию поля ("CLASS"). сейчас разбираю код erase-wipeout, надеюсь что-нить нарою! благодарю за наводку...

Re: Цикл, большое количество элементов

(vl-load-com)
(defun _kpblc-get-groups (/ _kpblc-conv-vla-to-list _kpblc-conv-ent-to-ename _kpblc-conv-ent-to-vla _kpblc-get-groups)

  (defun _kpblc-conv-ent-to-vla (ent_value / res)
                                ;|
*    Функция преобразования полученного значения в vla-указатель.
*    Параметры вызова:
*    ent_value    значение, которое надо преобразовать в указатель. Может
*            быть именем примитива, vla-указателем или просто
*            списком.
*            Если не принадлежит ни одному из указанных типов,
*            возвращается nil
*    Примеры вызова:
(_kpblc-conv-ent-to-vla (entlast))
(_kpblc-conv-ent-to-vla (vlax-ename->vla-object (entlast)))
|;
    (cond
      ((= (type ent_value) 'vla-object) ent_value)
      ((= (type ent_value) 'ename) (vlax-ename->vla-object ent_value))
      ((setq res (_kpblc-conv-ent-to-ename ent_value))
       (vlax-ename->vla-object res)
       )
      ) ;_ end of cond
    ) ;_ end of defun

  (defun _kpblc-conv-ent-to-ename (ent_value /)
                                  ;|
*    Функция преобразования полученного значения в ename
*    Параметры вызова:
*    ent_value    значение, которое надо преобразовать в примитив. Может
*            быть именем примитива, vla-указателем или просто
*            списком.
*            Если не принадлежит ни одному из указанных типов,
*            возвращается nil
*    Примеры вызова:
(_kpblc-conv-ent-to-ename (entlast))
(_kpblc-conv-ent-to-ename (vlax-ename->vla-object (entlast)))
|;
    ;; "_kpblc-conv-ent-to-ename")
    (cond
      ((= (type ent_value) 'vla-object)
       (vlax-vla-object->ename ent_value)
       )
      ((= (type ent_value) 'ename) ent_value)
          ;((= (type ent_value) 'str) (handent ent_value))
      ((= (type ent_value) 'list) (cdr (assoc -1 ent_value)))
      (t nil)
      ) ;_ end of cond
    ) ;_ end of defun

  (defun _kpblc-conv-vla-to-list (value / res)
                                 ;|
*    Преобразовывает vlax-variant или vlax-safearray в список.
|;
    (cond
      ((listp value)
       (mapcar (function _kpblc-conv-vla-to-list) value)
       )
      ((= (type value) 'variant)
       (_kpblc-conv-vla-to-list (vlax-variant-value value))
       )
      ((= (type value) 'safearray)
       (if (>= (vlax-safearray-get-u-bound value 1) 0)
         (_kpblc-conv-vla-to-list (vlax-safearray->list value))
         ) ;_ end of if
       )
      ((and (member (type value) (list 'ename 'str 'vla-object))
            (= (type (_kpblc-conv-ent-to-vla value)) 'vla-object)
            (vlax-property-available-p (_kpblc-conv-ent-to-vla value) 'count)
            ) ;_ end of and
       (vlax-for sub (_kpblc-conv-ent-to-vla value)
         (setq res (cons sub res))
         ) ;_ end of vlax-for
       )
      (t value)
      ) ;_ end of cond
    ) ;_ end of defun

  (mapcar
    (function
      (lambda (x)
        (list (cons "name" (vla-get-name x))
              (cons "obj" (_kpblc-conv-vla-to-list x))
              ) ;_ end of list
        ) ;_ end of lambda
      ) ;_ end of function
    (_kpblc-conv-vla-to-list (vla-get-groups (vla-get-activedocument (vlax-get-acad-object))))
    ) ;_ end of mapcar
  ) ;_ end of defun

(defun test (/ _kpblc-conv-list-to-string ent _lst)
            ;|
*    Получение имени группы, которой принадлежит выбранный объект
|;

  (defun _kpblc-conv-list-to-string (lst sep)
                                    ;|
*    Преобразование списка в строку
*    Параметры вызова:
    lst    обрабатываемй список
    sep    разделитель. nil -> " "
|;
    (if (and lst
             (setq lst (mapcar (function _kpblc-conv-value-to-string) lst))
             (setq sep (if sep
                         sep
                         " "
                         ) ;_ end of if
                   ) ;_ end of setq
             ) ;_ end of and
      (strcat (car lst)
              (apply (function strcat)
                     (mapcar
                       (function
                         (lambda (x)
                           (strcat sep x)
                           ) ;_ end of lambda
                         ) ;_ end of function
                       (cdr lst)
                       ) ;_ end of mapcar
                     ) ;_ end of apply
              ) ;_ end of strcat
      ""
      ) ;_ end of if
    ) ;_ end of defun

  (if (and (= (type
                (setq ent (vl-catch-all-apply (function (lambda () (car (entsel "\nSelect entity <Cancel> : "))))))
                ) ;_ end of type
              'ename
              ) ;_ end of =
           (setq _lst (_kpblc-get-groups))
           ) ;_ end of and
    (princ (strcat "\nGroup name : "
                   (_kpblc-conv-list-to-string (mapcar (function (lambda (x) (cdr (assoc "name" x))))
                                                       (vl-remove-if-not
                                                         (function
                                                           (lambda (x)
                                                             (member (vlax-ename->vla-object ent)
                                                                     (cdr (assoc "obj" x))
                                                                     ) ;_ end of member
                                                             ) ;_ end of lambda
                                                           ) ;_ end of function
                                                         _lst
                                                         ) ;_ end of vl-remove-if-not
                                                       ) ;_ end of mapcar
                                               "; "
                                               ) ;_ end of _kpblc-conv-list-to-string
                   ) ;_ end of strcat
           ) ;_ end of princ
    ) ;_ end of if
  (princ)
  ) ;_ end of defun

Re: Цикл, большое количество элементов

Виталич Круглов пишет:

Дело в том, что у меня объекты есть группы..они состоят из вхождения блока и из нескольких наборов примитивов, типы которых могут быть различны

Можно использовать связку расширенных данные + словари. В фильтре Функции ssget можно использовать группу -3 для выбора примитивов с определенным именем расширенных данных

Пример здесь, начиная с поста #30