Тема: Программа для контроля использованных материалов

По роду работы приходится контролировать объем использованных при строительстве погонажных материалов (труба, кабель, провод, лоток, профиль, световая линия). По результатам проверки прорисовываю то что установленно на чертеже акада. Раньше пользовался функцией подсчета длинн на определенном слое, но теперь появилось немного свободного времени и для еще большего упрощения задачи написал прогу. Для правильной ее работы необходимо каждый материал прорисовывать (линиями, полилиниями, элипсами и прочими примитивами для которых возможно измерение длины) на отдельном слое (называть их например ВВГ3х2.5, кабель 3х1.5 в ПВХ трубе, труба д100, лоток 400, газовая труба, лента и т.п). Ничего страшного если на том же слое будут располагаться примитивы, для которых невозможно измерение длины (например текстовые пояснения). Не располагайте в этом слое всякого рода выноски и т.п. поскольку их длина будет учитываться.

Затем ручками необходимо набить таблицу в том же чертеже где перечислить все материалы что подлежат контролю и создать текстовые строки, в которые будут помещаться длины этих материалов.

Следующий шаг - ассоциация строк со слоями, на которых будет производиться подсчет. для этого в консоли необходимо набрать ASSOCIATE. На запрос "Select text to be associated:" нужно указать мышью строку, предназначенную для хранения длины. На второй запрос "Select object(s) on destination layer(s):" нужно выбрать мышью один (или несколько) объектов на слое (или слоях) с которого(рых) будет считаться длина. Можно здесь указать несколько слоев (тогда и длина будет считаться с нескольких слоев). ПВХ труба например может быть прорисована на слое ПВХтруба и на слое кабель в ПВХ трубе. Ограничение - суммарное количество символов в именах выбранных слоев должно быть в пределах 220 (т.к. больше 256 в тысячную группу не влезает а еще на кавычки и слэши надо место оставить)

Такую ассоциацию нужно произвести по каждой позиции в таблице. Проверить какие слои ассоциированы с конкретной строкой можно набрав в консоли STRINGTEST и на запрос "Select text to be checked:" кликнуть по строке которую необходимо проверить. В ответ получите либо ошибку (что означает что вы либо не попали мышью ни по одному примитиву, либо ни один слой с данной строкой не ассоциирован). Если имеется ассоциация то будет ответ типа "The selected string is associated with layer(s) - кабель в трубе". Если вы ошиблись со слоем при ассоциации, то необходимо сделать это заново с помощью команды ASSOCIATE.

После ассоциации ручная работа закончена. Теперь заданные вами слои связаны с заданными строками. Подсчет длинн и обновление значений происходит при нажатии кнопки SAVE (или командой _QSAVE, или save as - вобщем каждый раз при сохранении файла)

для вызова помощи наберите HELPME

Для работы программы она должна быть подгружена. Это можно сделать либо поместив ее в автозагрузку выбрав в меню tools->load application (там где портфель) либо поместив ее в папку Support и прописав в acad????.lsp или acad????doc.lsp (loadapp "VolumesControl.vlx")

КАЧАТЬ_ТУТ

Re: Программа для контроля использованных материалов

Вторая и окончательная версия. Исправлена пара багов. В архиве в дополнение файл меню для тулбара и 3 картинки для кнопок.
Теперь:
обновление строк по команде TEXT_UPDATE. Макрос для кнопки - ^C^CTEXT_UPDATE
проверка строки по команде STRINGTEST.Макрос для кнопки - ^C^CSTRINGTEST
Ассоциация по команде ASSOCIATE. Макрос для кнопки - ^C^CASSOCIATE
Помощь не ахти, но по команде HELPME

КАЧАТЬ_ТУТ

Re: Программа для контроля использованных материалов

1.Файл меню грузится, но меню не появляется
2.Программа неверно определяет длины следующих примитивов:
-утолщенная полилиния: вместо длины определяется число сегментов полилинии
-окружность,эллипс и их дуги: вместо длины центральный угол в радианах
-сплайн - вместо длины не знаю что - не стал разбираться
-мультилинию не видит
Проверял в AutoCAD 2006
3.Длины отрезков определяет правильно:)
4.Код приложения закрыт...
5.Предлагаю обратить внимание на аналогичные программы для подсчета длин и сравнить с ними результат работы вашей программы:
-Расчет длин
-http://dwg.ru/dnl/2733
-https://www.caduser.ru/forum/topic47563.html

-FDist v1.0 - Расчет дистанций по точкам и элементам.
http://dwg.ru/dnl/486

-VetCAD++ v3.7 - утилиты для AutoCAD (2004-2010)
http://dwg.ru/dnl/206 (демо-версия)

-GeomProps - площадь, длина, объем выбранных примитивов
http://www.maestrogroup.com.ua/support/GeomProps.zip
https://www.caduser.ru/forum/topic36136.html

-Программа расчета длин и площадей генплана в Акаде v.2
http://dwg.ru/dnl/5763

-Программа LSV - предназначена для измерения и расчета длин, площадей, объемов и масс элементов
http://dwg.ru/dnl/1726

-Сумма длин elen.lsp
http://dwg.ru/dnl/5400

Список далеко не полный

(изменено: Денис Лешкив, 10 декабря 2009г. 11:40:24)

Re: Программа для контроля использованных материалов

Ок исправил. Сплайны, полилинии и элипсы теперь правильно считает (вроде). Мультилиния - объект сложный. Даж не знаю как его померять. Прога их все так же игнорирует.

в меню есть только тулбар. Честно говоря настройка меню по-новому (cui файлы) для меня до сих пор сродни битья в бубен возле костра. Для проверки сейчас в 2010-м в меню CUI подгрузил это меню, нажал apply и тулбар появился. Добавил в автозапуск *.vlx  и все заработало.

вот_новая_версия

Re: Программа для контроля использованных материалов

Да, код если кому пригодится:

(if (regapp "VolumeControl") (princ"\nVolumeControl\n")) ; Регистрация приложения
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;Подсчет длины примитивов на указанном слое или списке слоев;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defun Get_Sum_Dist (Layers_List / Sset Sum i Curve old_error StartParam EndParam)
  (setq old_error *error*)
  (defun *error* (msg)
    (setq *error* old_error)
    (mapcar '(lambda (x) (setq x nil)) (list Sset Sum i Curve old_error))
    (gc) (gc)
    (princ (strcat "\nError: " msg " WTF"))
    (princ)
  ); end *error*
  (if (listp Layers_List)
    (progn
      (setq SSet (ssget "_X" (append '((-4 . "<OR")) (mapcar '(lambda (x) (cons 8 x)) Layers_List) '((-4 . "OR>")))))
      (setq Sum 0 i 0)
      (repeat (sslength SSet)
    (setq Curve (vlax-ename->vla-object (ssname SSet i))
              i (1+ i)
          StartParam (vl-catch-all-apply 'vlax-curve-getStartParam (list Curve))
          EndParam (vl-catch-all-apply 'vlax-curve-getEndParam (list Curve))
              Sum (+ Sum (if (not (and (vl-catch-all-error-p StartParam) (vl-catch-all-error-p EndParam))) (vlax-curve-getdistatparam Curve (- EndParam StartParam)) 0))
      ))
      Sum
    )  ;end progn
    0;else expr
  ));end defun
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;Функция обновления значений;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 (defun C:text_upd ate ( / SStext text_with_xdata i old_error)
   (setq old_error *error*)
   (defun *error* (msg)
     (setq *error* old_error)
     (mapcar '(lambda (x) (setq x nil)) (list SStext text_with_xdata i old_error))
     (gc) (gc)
     (princ (strcat "\nError: " msg " WTF"))
     (princ)
   );end error
  (setq SStext (ssget "_X" (append '((-4 . "<OR")) (mapcar '(lambda (x) (cons 0 x)) '("TEXT" "MTEXT")) '((-4 . "OR>"))))
    i 0)
;;;удаление примитивов без xdata и формирование списка e-name
  (repeat (sslength SStext)
       (if (xdata_read (ssname SStext i) 1000 "VolumeControl")
       (setq text_with_xdata (cons (ssname SStext i) text_with_xdata)))
       (setq i (1+ i))
  )
  (foreach i text_with_xdata (vla-put-textstring (vlax-ename->vla-object i) (Get_Sum_Dist (read (xdata_read i 1000 "VolumeControl")))))
  (setq *error* old_error)
  (princ "\nUpd ate complete")
  (princ)
)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;   Ассоциация текстовых строк    ;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defun C:associate ( / text_object set_of_ents index list_of_layers old_error item string)
  (setq old_error *error*)
  (defun *error* (msg)
    (setq *error* old_error)
    (mapcar '(lambda (x) (setq x nil)) (list text_object set_of_ents index list_of_layers old_error item string))
    (gc) (gc)
    (princ (strcat "\nError: " msg " WTF"))
    (princ)
  ); end *error*
  (setq text_object (car (entsel "\nSelect text to be associated:")))
  (if (or (= (cdr (assoc 0 (entget text_object))) "TEXT") (= (cdr (assoc 0 (entget text_object))) "MTEXT"))
    (progn
      (princ "\nSelect object(s) on destination layer(s):")
      (setq set_of_ents (ssget)
            index 0
            list_of_layers '())

      (repeat (sslength set_of_ents)
         (if (not (member (cdr (assoc 8 (entget (ssname set_of_ents index)))) list_of_layers))
           (setq list_of_layers (cons (cdr (assoc 8 (entget (ssname set_of_ents index)))) list_of_layers))
         )
       (setq index (1+ index))
      )
;;;;;;;;;склейка списка в строку
      (setq string "(")
      (foreach item list_of_layers (setq string (strcat string "\"" item "\"")))
      (setq string (strcat string ")"))
;;;;;;;;;Запись в Хdata строки со списком слоев
      (xdata_write text_object 1000 string "VolumeControl")
    )
    (princ "\nThe selected object is not a text\n")
  )
)

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;тест
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defun C:stringTest ( / string)
     (if (setq string (xdata_read (car (entsel "\nSelect text to be checked:")) 1000 "VolumeControl"))
      (princ (strcat "\nThe selected string is associated with layer(s) - " string))
      (princ "\nAssociation not found")
     )
  (princ)
)

(defun C:helpme ( / )
  (princ "\nTo associate text with layer(s) type ASSOCIATE and follow instructions in command line")
  (princ "\nTo check if there is association type STRINGTEST and follow instructions in command line")
  (princ)
)

;;;*********************************************************
;;;
;;;ФУНКЦИЯ ЧТЕНИЯ ИЗ РАСШИРЕННЫХ ДАННЫХ ПРИМИТИВА
;;;
;;; Функция читает расширенные данные из примитива
;;;
;;;*********************************************************
(defun xdata_read (wantedEnt  ;- метка примитива откуда считываються Х-Данные
                   wantedDXF  ;- код DXF группы где хранятся данные
                   App  ;- приложение для которого читаются расширенные данные
                  /)
  (cdr(assoc wantedDXF (cdadr(assoc -3 (entget wantedEnt (list App)))))) ;- считать данные из нужной группы
); end SC_XData_Read

;;;*********************************************************
;;;
;;;  ФУНКЦИЯ ЗАПИСИ В РАСШИРЕННЫЕ ДАННЫЕ ПРИМИТИВОВ
;;;
;;; Функция вносит значениея расширенных данных в примитивы
;;;
;;;*********************************************************
(defun xdata_write (wantedEnt  ;- метка примитива куда вносятся Х-Данные
                    wantedDXF  ;- код DXF группы куда записываются данные
                    writeData  ;- записываемые данные
                    App             ;- приложение для которого читаются расширенные данные
                   / clearDXF  ;- исходный список DXF кодов примитива
                     extData    ;- расширенные данные
                     extList    ;- список расширенных данных без признака и имени приложения
                   )
(setq clearDXF (entget wantedEnt)) ; получить DXF коды примитива
(setq extList (vl-remove App (cadr(assoc -3 (entget wantedEnt (list App)))))) ; выделить данные без  названия приложения
  (if extList ; если данные есть
    (progn
    (if (assoc wantedDXF extList) ; если в данных уже содержиться нужная группа
      (setq extList (append (list (cons wantedDXF writeData)) ; присоединить новые данные
         (vl-remove (assoc wantedDXF extList) extList))); в список с удаленными старыми данными
      (setq extList (append (list (cons wantedDXF writeData)) extList)) ; если нужной группы нет, присоединить ее
      ); end if
      ); end progn
      (se tq extList (list (cons wantedDXF writeData))) ; если данных нет создать их из одной группы
    ); end if
(se tq extData (append (list -3) (list (append (list App) extList)))) ; добавить признак наличия и имя приложения
  (entmod (append clearDXF (list extData))) ; обновить примитив с учетом новых данных
    (princ)
); end of SC_XData_Record

Re: Программа для контроля использованных материалов

Новая версия с новой командой.

http://dwg.ru/dnl/7184

Re: Программа для контроля использованных материалов

Скажите а есть ли возможность немного переделать эту программу. Чтоб ассоциировать линии не с текстовым блоком а с ячейкой таблицы. Заранее благодарен.