Очистка файлов от ненужных данных LineStyle DGN в AutoCAD.

Автор Тема: Очистка файлов от ненужных данных LineStyle DGN в AutoCAD.  (Прочитано 106134 раз)

0 Пользователей и 2 Гостей просматривают эту тему.

Оффлайн ElpanovEvgeniyАвтор темы

  • ADN
  • *
  • Сообщений: 8
  • Карма: 2
    • elpanov.com
  • Skype: ElpanovEvgeniy
Столкнулся с проблемой, в AutoCAD 2013-2014 остаются хвосты библиотек после импорта из формата DGN. Выглядит это не очень хорошо, при копировании из такого файла любого объекта через буфер, вся библиотека DGN копируется в новый файл. Причем, если она имеет размер в несколько мегабайт, то новый файл после вставки из буфера одной линии вырастает на эти несколько мегов. Само по себе это не так страшно, но время копирования вырастает во много раз и иногда доходит до получаса.

Autodesk знает о проблеме и выпустил исправление AutoCAD® DGN Hotfix, но его использование не очень удобно - требуется доступ к папке установки AutoCAD (все через админов).

 Александр Ривилис подсказал о статье Purging unwanted DGN linestyle data from an AutoCAD drawing using .NET  , которая помогла разобраться в проблеме и сделать полноценное решение проблемы из лиспа...

Код - Auto/Visual Lisp [Выбрать]
  1. (defun c:d- (/ dgn)
  2.   ;; By ElpanovEvgeniy
  3.   ;; программа удаляет из файла DGN прокси объекты не имеющие графического отображения.
  4.   ;; Программа протестирована в AutoCAD 2013 и 2014, Civil 3D, AutoCAD MEP, AutoCAD Architecture.
  5.   (if (setq dgn (member '(3 . "ACAD_DGNLINESTYLECOMP") (entget (namedobjdict))))
  6.     (progn (setq dgn (cdr (assoc 350 dgn)))
  7.            (entmod
  8.              (append (reverse (cdr (member '(3 . "ACAD_DGNLINESTYLECOMP") (reverse (entget (namedobjdict))))))
  9.                      (cddr (member '(3 . "ACAD_DGNLINESTYLECOMP") (entget (namedobjdict))))
  10.              )
  11.            )
  12.            (entget dgn)
  13.            (foreach a (entget dgn)
  14.              (if (= (car a) 360)
  15.                (entdel (cdr a))
  16.              )
  17.            )
  18.            (entdel dgn)
  19.            ;; При необходимости можно удалить строчки по очистке файла и
  20.            ;; снять комментарии с прекомендацией самостоятельного запуска _purge.
  21.            (vl-load-com)
  22.            (repeat 3 (vla-PurgeAll (vla-get-ActiveDocument (vlax-get-acad-object))))
  23.            ;; (princ "\n Файл очищен от неиспользуемых проксиобъектов, рекомендуется очистить файл командой _purge")
  24.     )
  25.   )
  26.   (princ)
  27. )
  28. (defun c:в- () (c:d-))

ps. Программа протестирована в AutoCAD 2013 и 2014, Civil 3D, AutoCAD MEP, AutoCAD Architecture. Если будут найдены замечания, прошу сообщить мне.
Тот, кто правильно указывает на мои ошибки, — мой учитель
тот, кто правильно отмечает мои верные поступки, — мой друг
тот, кто мне льстит, — мой враг.
/Сунь Цзы/

Оффлайн ElpanovEvgeniyАвтор темы

  • ADN
  • *
  • Сообщений: 8
  • Карма: 2
    • elpanov.com
  • Skype: ElpanovEvgeniy
Как ни странно, весь код можно свести к удалению корневого словаря, после пересохранения файла, все библиотеки сами удалятся.
Код - Auto/Visual Lisp [Выбрать]
  1. (DICTREMOVE (namedobjdict) "ACAD_DGNLINESTYLECOMP")
Тот, кто правильно указывает на мои ошибки, — мой учитель
тот, кто правильно отмечает мои верные поступки, — мой друг
тот, кто мне льстит, — мой враг.
/Сунь Цзы/

Оффлайн Алексей Кулик

  • Administrator
  • *****
  • Сообщений: 1096
  • Карма: 172
А если после удаления такого словаря выполнить проверку файла, что будет?
Все, что сказано - личное мнение.

Правила форума существуют не просто так!

Приводя в сообщении код, не забывайте про его форматирование!

Оффлайн ElpanovEvgeniyАвтор темы

  • ADN
  • *
  • Сообщений: 8
  • Карма: 2
    • elpanov.com
  • Skype: ElpanovEvgeniy
Алексей Кулик, проверил, и после первого и второго варианта _audit выдает одинаковый ответ.
Тот, кто правильно указывает на мои ошибки, — мой учитель
тот, кто правильно отмечает мои верные поступки, — мой друг
тот, кто мне льстит, — мой враг.
/Сунь Цзы/

Оффлайн Подшиваленко Дмитрий

  • ADN Club
  • **
  • Сообщений: 64
  • Карма: 0
Рекомендую очень аккуратно использовать этот лисп или удаление словаря.
У нас админы установили некоторым пользователям AutoCAD® DGN Hotfix и нашлись умельцы, которые стали использовать в Автокаде специфические типы линий, взятые из Microstation. Применение вышеуказанного лиспа или удаление корневого словаря удаляет такие типы линий и в результате они начинают отображаться просто прямыми.
Очистка средствами Autodesk (либо "_.-purge" "_o" для AutoCAD2015, либо "_dgnpurge" для AutoCAD2012-2014 с установленным Hotfix) не удаляет такие типы линий. Правда такая очистка сильно замусоренных файлов от стилей DGN происходит неимоверно долго даже на мощных машинах.
У себя в институте использую такой лисп для очистки от DGN:

Код - Auto/Visual Lisp [Выбрать]
  1. ;очистка непривязанных данных, в частности стили линий DGN
  2. (setq acd_ver (getvar "acadver")) ;получаем версию загруженного AutoCAD
  3. ;если это AutoCAD 2015, то чистим стандартным _-purge
  4. (if (= acd_ver "20.0s (LMS Tech)") (command "_.-purge" "_o"))
  5. ;если AutoCAD 2013 или 2014, то чистим командой _dgnpurge из DGN Hotfix для AutoCAD 2013-2014, появляющейся при загрузке DgnLsPurge.dll
  6. (if (or (= acd_ver "19.0s (LMS Tech)") (= acd_ver "19.1s (LMS Tech)"))
  7.  (progn
  8.   (command "_netload" "\\\\Dc\\it\\ACD\\DGNPurge\\Acad2014\\DgnLsPurge.dll") ;грузим dll из Hotfix
  9.   (command "_dgnpurge") ;и запускаем очистку dgn
  10.  )
  11. )
  12. ;если AutoCAD 2012, то чистим командой _dgnpurge из DGN Hotfix для AutoCAD 2012, появляющейся при загрузке DgnLsPurge.dll
  13. (if (= acd_ver "18.2s (LMS Tech)")
  14.  (progn
  15.   (command "_netload" "\\\\Dc\\it\\ACD\\DGNPurge\\Acad2012\\DgnLsPurge.dll") ;грузим dll из Hotfix
  16.   (command "_dgnpurge") ;и запускаем очистку dgn
  17.  )
  18. )
Файл для примера во вложении. Ситуация, скорее всего, редкая, но, тем не менее, возникла.
« Последнее редактирование: 02-11-2015, 15:13:44 от Подшиваленко Дмитрий »

Оффлайн Алексей Кулик

  • Administrator
  • *****
  • Сообщений: 1096
  • Карма: 172
Ну, во-первых, загрузка .NET-сборки из сетевого каталога не обязательно завершится успехом (если вообще завершится). Во-вторых, кто-то мешает прописать "специфические" типы линий в обычном lin-файле?
Все, что сказано - личное мнение.

Правила форума существуют не просто так!

Приводя в сообщении код, не забывайте про его форматирование!

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Во-вторых, кто-то мешает прописать "специфические" типы линий в обычном lin-файле?
Не получится. Эти DGN-овские типы линий не описываются стандартными типами линий AutoCAD. Если интересны детали, то вот статья: http://through-the-interface.typepad.com/through_the_interface/2012/12/purging-unwanted-dgn-linestyle-data-from-an-autocad-drawing-using-net.html
Если нужно, то могу перевести.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Алексей Кулик

  • Administrator
  • *****
  • Сообщений: 1096
  • Карма: 172
Пока не нужно, попробую самостоятельно продраться :)
Все, что сказано - личное мнение.

Правила форума существуют не просто так!

Приводя в сообщении код, не забывайте про его форматирование!

Оффлайн Подшиваленко Дмитрий

  • ADN Club
  • **
  • Сообщений: 64
  • Карма: 0
Эти DGN-овские типы линий не описываются стандартными типами линий AutoCAD.
Не все DGN-овские типы линий не описываются стандартными типами линий AutoCAD. Первый же тип линий, взятый умельцами из Microstation, который я обнаружил, были обычные кресты, которые легко описать (см. вложение в моём предыдущем посте). Зачем умельцы взяли его из Microstation - сами не умели создавать и проще было взять готовый. Попался из Microstation.
Ну, во-первых, загрузка .NET-сборки из сетевого каталога не обязательно завершится успехом (если вообще завершится). Во-вторых, кто-то мешает прописать "специфические" типы линий в обычном lin-файле?
Загрузка .NET-сборки из сетевого каталога работает нормально, ибо код уже оттестирован. Только вот с количеством обратных слэшей пришлось повозиться.
Прописать специфические типы линий в  lin-файле мысль была и есть, но есть сложности:
1. Нужно понять кто такие нестандартные типы линий использует, собрать полную библиотеку таких типов линий.
2. Насколько это возможно, попытаться описать нестандартные типы линий, взятые из Microstation, стандартными формами Акада из ltypeshp.shx без создания новых форм, чтобы было более-менее похоже. Если найдутся такие, которые нельзя описать  стандартными типами линий AutoCAD, тогда ой.
3. Объяснить 500 человекам, в том числе мало понимающим в автокаде, откуда и как брать эти типы линий, полностью перевести народ на использование типов линий, описанных в lin-файле.
4. На всё это нужна куча времени, а это не совсем моя работа, я тут энтузиазм проявляю :)

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Загрузка .NET-сборки из сетевого каталога работает нормально, ибо код уже оттестирован.
Дело не в коде, а во взаимодействии .NET Framework различных версий и Windows. Почитай: http://adn-cis.org/forum/index.php?topic=1110.msg9968#msg9968 Весьма полезные знания.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Подшиваленко Дмитрий

  • ADN Club
  • **
  • Сообщений: 64
  • Карма: 0
Дело не в коде, а во взаимодействии .NET Framework различных версий и Windows.
Насколько я выяснил у админов, у всех пользователей поголовно стоит одинаковая Win7x64. Тестил код на работе на Win7x64 + Acad 2015, 2014. Всё работает.

Оффлайн Подшиваленко Дмитрий

  • ADN Club
  • **
  • Сообщений: 64
  • Карма: 0
В продолжение темы.
Лисп, который я выложил ранее, благополучно работает и привязан к кнопочке на панели инструментов, которая ставится всем пользователям AutoCAD.
Вернее есть 2 кнопочки. 1-я привязана к варианту удаления словаря (быстрая очисткf), 2-я - к корректной очистке (выложенный ранее лисп).
Вроде народ начал потихоньку вычищать чертежи от DGN, но не все.
Появилась мысль, что народу нужно сделать некое оповещение о присутствии DGN объектов в чертеже.
Можно ли написать небольшой лисп, который бы проверял наличие DGN объектов в чертеже и в случае их присутствия выводил сообщение что-то вроде (alert "В чертеже обнаружены объекты DGN")?
Заранее благодарен за помощь :)

Оффлайн Алексей Кулик

  • Administrator
  • *****
  • Сообщений: 1096
  • Карма: 172
Если установить proxynotice = 1, то сам AutoCAD будет оповещать об этих (и других) прокси-объектах.
С другой стороны, можно создать лисп, выполняемый при открытии документа - он и будет вычищать все что положено. Или прописать командный реактор на сохранение документа - и там выполнять аналогичные действия.
Все, что сказано - личное мнение.

Правила форума существуют не просто так!

Приводя в сообщении код, не забывайте про его форматирование!

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Можно ли написать небольшой лисп, который бы проверял наличие DGN объектов в чертеже и в случае их присутствия выводил сообщение что-то вроде (alert "В чертеже обнаружены объекты DGN")?
Небольшим он не получится. Да и на лиспе врядли это реализуемо. Смысл в том, что для того, чтобы уточнить есть и нет в чертеже "объекты DGN" нужно просканировать весь чертеж (ну или как минимум до первого "объекта DGN").
Если установить proxynotice = 1, то сам AutoCAD будет оповещать об этих (и других) прокси-объектах.
Это прокси-объекты только в старых версиях AutoCAD, в которых объектов DGN небыло (или как минимум DEMANDLOAD в 0 - но так никто работать не сможет). А в нормальном виде это объекты AcDbDgnLS* (там целое семейство классов).
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Алексей Кулик

  • Administrator
  • *****
  • Сообщений: 1096
  • Карма: 172
Добавлю: demandload желательно установить равной 2
Все, что сказано - личное мнение.

Правила форума существуют не просто так!

Приводя в сообщении код, не забывайте про его форматирование!

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Вообще можно попробовать такой код:
Код - Auto/Visual Lisp [Выбрать]
  1. (if (setq dgn (member '(3 . "ACAD_DGNLINESTYLECOMP") (entget (namedobjdict))))
  2.   (alert "В чертеже возможно есть объекты DGN")
  3. )
Но не уверен, что он даст 100%-ый результат.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Подшиваленко Дмитрий

  • ADN Club
  • **
  • Сообщений: 64
  • Карма: 0
Александр Ривилис, спасибо.
В принципе этот код работает, но в связи со спецификой организации (совместное использование Microstation и AutoCAD), окошко вылазит на многих чертежах. Видимо небольшое количество DGN объектов перекочевало в чертежи AutoCAD, но при этом файл весит адекватно и открывается быстро. Но есть файлы, которые весят по 25мегабайт и открываются очень долго, но при этом содержат всего лишь десяток обычных отрезков. Скорее всего придётся попробовать пойти по пути подсчёта количества объектов DGN, как в теме http://forum.dwg.ru/showthread.php?p=1527693#post1527693.

Оффлайн Подшиваленко Дмитрий

  • ADN Club
  • **
  • Сообщений: 64
  • Карма: 0
Написал лисп для подсчёта DGN объектов. На небольших файлах он отрабатывает быстро, а на файле объёмом 25Мб уже минут 20 жду когда же вылезет окошко с количеством DGN объектов... Это даже дольше, чем корректная очистка от DGN средствами AutoDesk. В автозагрузку людям такой лисп пихать нельзя :(
Попутно более подробно выяснил в какой момент исчезают линии DGN после удаления словаря с DGN.
После команды (DICTREMOVE (namedobjdict) "ACAD_DGNLINESTYLECOMP") появляются неиспользуемые блоки с именами *A####. После их очистки стандартным purge и регенерации исчезает визуальное отображение линий DGN и появляются неиспользуемые типы линий.
На файле без единого объекта AutoCAD размером 25Мб Audit проверил 588900 объектов, после удаления словаря и очистки от блоков и типов линий - 410700 объектов.
Может кому эта информация и понадобится.

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
На небольших файлах он отрабатывает быстро, а на файле объёмом 25Мб уже минут 20 жду когда же вылезет окошко с количеством DGN объектов...
А зачем нужно знать точное количество? Скажем если их больше 100 (значение можешь сам прикинуть) то прекращать подсчет и выдавать сообщение.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Подшиваленко Дмитрий

  • ADN Club
  • **
  • Сообщений: 64
  • Карма: 0
А зачем нужно знать точное количество? Скажем если их больше 100 (значение можешь сам прикинуть) то прекращать подсчет и выдавать сообщение.
Логично. Что-то я про это не подумал. Спасибо большое за мысль :). Попробую поправить код на лиспе. Просто я лисп практически не знаю, пишу по примерам из других лисп программ.

Оффлайн Алексей Кулик

  • Administrator
  • *****
  • Сообщений: 1096
  • Карма: 172
Как вариант - во вложении
Все, что сказано - личное мнение.

Правила форума существуют не просто так!

Приводя в сообщении код, не забывайте про его форматирование!

Оффлайн Подшиваленко Дмитрий

  • ADN Club
  • **
  • Сообщений: 64
  • Карма: 0
Как вариант - во вложении
О, Алексей, наконец-то :) То что нужно! Спасибо огромное! :)
А можно ещё небольшую просьбу по этому лиспу?
Надо сравнить количество записей словаря с определенным числом (скажем 1000) и выводить сообщение (лучше alert) только при превышении этого числа?

Оффлайн Алексей Кулик

  • Administrator
  • *****
  • Сообщений: 1096
  • Карма: 172
Да там вроде ничего такого сверх :)
Значение "зашито в код":
Код - Auto/Visual Lisp [Выбрать]
  1. (vl-load-com)
  2.  
  3. (defun checkdgn (doc / dict _val)
  4.   (if (not doc)
  5.     (setq doc (vla-get-activedocument (vlax-get-acad-object)))
  6.     ) ;_ end of if
  7.   (setq _val 100)
  8.   (if (and (= (type (setq dict (vl-catch-all-apply
  9.                                  (function (lambda () (vla-item (vla-get-dictionaries doc) "acad_dgnlinestylecomp")))
  10.                                  ) ;_ end of vl-catch-all-apply
  11.                           ) ;_ end of setq
  12.                     ) ;_ end of type
  13.               'vla-object
  14.               ) ;_ end of =
  15.            (> (vla-get-count dict) _val)
  16.            ) ;_ end of and
  17.     (alert
  18.       (strcat "Обнаружен словарь DGN, количество записей " (vl-princ-to-string (vla-get-count dict)))
  19.       ) ;_ end of princ
  20.     ) ;_ end of if
  21.   (princ)
  22.   ) ;_ end of defun
Пример вызова:
Код - Auto/Visual Lisp [Выбрать]
  1. (checkdgn nil) ; Проверка в текущем документе

Значение передается как один из параметров:
Код - Auto/Visual Lisp [Выбрать]
  1. (vl-load-com)
  2.  
  3. (defun checkdgn (doc value / dict)
  4.   (if (not doc)
  5.     (setq doc (vla-get-activedocument (vlax-get-acad-object)))
  6.     ) ;_ end of if
  7.   (if (not value)
  8.     (setq value 100)
  9.     ) ;_ end of if
  10.   (if (and (= (type (setq dict (vl-catch-all-apply
  11.                                  (function (lambda () (vla-item (vla-get-dictionaries doc) "acad_dgnlinestylecomp")))
  12.                                  ) ;_ end of vl-catch-all-apply
  13.                           ) ;_ end of setq
  14.                     ) ;_ end of type
  15.               'vla-object
  16.               ) ;_ end of =
  17.            (> (vla-get-count dict) value)
  18.            ) ;_ end of and
  19.     (alert
  20.       (strcat "Обнаружен словарь DGN, количество записей " (vl-princ-to-string (vla-get-count dict)))
  21.       ) ;_ end of princ
  22.     ) ;_ end of if
  23.   (princ)
  24.   ) ;_ end of Defun
Пример вызова:
Код - Auto/Visual Lisp [Выбрать]
  1. (checkdgn nil nil) ; проверка текущего документа, сообщение выводится, если записей больше 100
  2. (checkdgn nil 2000) ; проверка текущего документа, сообщение выводится, если записей больше 2000
Все, что сказано - личное мнение.

Правила форума существуют не просто так!

Приводя в сообщении код, не забывайте про его форматирование!

Оффлайн Алексей Кулик

  • Administrator
  • *****
  • Сообщений: 1096
  • Карма: 172
Добавлю: если будет предоставлен образец с тысячами (или десятками тысяч) подобных записей, возможно, появится вариант другого решения. У меня подобных файлов нет - и уже очень давно.
Все, что сказано - личное мнение.

Правила форума существуют не просто так!

Приводя в сообщении код, не забывайте про его форматирование!

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Подшиваленко Дмитрий
У меня есть сомнение в том, что алгоритм Алексея будет работать достаточно быстро. Мне кажется, что ActiveX тут не поможет и нужен другой подход через чистый AutoLISP. Интересно было бы, что бы ты проверил на своём 25Мб-ном файле, если у тебя еще остался оригинал.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Подшиваленко Дмитрий

  • ADN Club
  • **
  • Сообщений: 64
  • Карма: 0
Да там вроде ничего такого сверх
Алексей, для тех кто постоянно пишет на лиспе - да, а для того, кто этот лисп изучал 17 лет назад в институте и больше с ним не сталкивался - ну сам понимаешь :)
Тем более VisualLisp. Я только Basic и иже с ним всякие VBA знаю :)
За второй код спасибо :)
Попутно появились некоторые мысли.
1. Насколько я понял, коду всё равно, какой словарь проверять. То есть ему можно подсунуть тот же ACAD_SCALELIST и он выдаст количество масштабов (только что проверил, результат правильный). В связи с этим мысль. Можно сделать эту функцию универсальной, передавать ей имя словаря, а она будет возвращать количество записей и уже вне функции сравнивать количество записей словаря с адекватным количеством и выдавать alert?
2. Реально ли узнать количество используемых и неиспользуемых записей словаря? (Что-то типа prePurge?) :)
Добавлю: если будет предоставлен образец с тысячами (или десятками тысяч) подобных записей, возможно, появится вариант другого решения. У меня подобных файлов нет - и уже очень давно.
У меня есть сомнение в том, что алгоритм Алексея будет работать достаточно быстро. Мне кажется, что ActiveX тут не поможет и нужен другой подход через чистый AutoLISP. Интересно было бы, что бы ты проверил на своём 25Мб-ном файле, если у тебя еще остался оригинал.
Код отрабатывает мгновенно :) То что нужно! Количество записей словаря acad_dgnlinestylecomp в этом 25-Мб файле - 398993.
P.S. Прикрепить файл не получится, ибо в самом сильно сжатом архиве файл занимает 10,5Мб, а форум не даёт прикрепить больше 10Мб...

Оффлайн Алексей Кулик

  • Administrator
  • *****
  • Сообщений: 1096
  • Карма: 172
Да, можно подставить любой словарь - хоть масштабы, хоть фильтры слоев, хоть что. Имя только менять - и все.
Насчет "используемые-неиспользуемые": не уверен, что это легко реализуемо. Можно попытаться, конечно, удалять объект, и, если это удалось, тут же его восстанавливать - но мне такой подход не нравится на интуитивном уровне.
Все, что сказано - личное мнение.

Правила форума существуют не просто так!

Приводя в сообщении код, не забывайте про его форматирование!

Оффлайн Алексей Кулик

  • Administrator
  • *****
  • Сообщений: 1096
  • Карма: 172
Ну, в принципе, можно сделать и многотомный архив ;)
Все, что сказано - личное мнение.

Правила форума существуют не просто так!

Приводя в сообщении код, не забывайте про его форматирование!

Оффлайн Подшиваленко Дмитрий

  • ADN Club
  • **
  • Сообщений: 64
  • Карма: 0
Ну, в принципе, можно сделать и многотомный архив
Была такая мысль, но это тогда в двух сообщениях только. Первая часть в предыдущем посте.
Да, можно подставить любой словарь - хоть масштабы, хоть фильтры слоев, хоть что. Имя только менять - и все.
Алексей, я имел ввиду, что не мог бы ты сам подкорректировать код на лиспе, чтобы в функцию передавать имя словаря, а функция возвращала бы количество записей :)

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Код отрабатывает мгновенно :) То что нужно! Количество записей словаря acad_dgnlinestylecomp в этом 25-Мб файле - 398993.
Отлично. Значит я ошибался.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Подшиваленко Дмитрий

  • ADN Club
  • **
  • Сообщений: 64
  • Карма: 0
Насчет "используемые-неиспользуемые": не уверен, что это легко реализуемо. Можно попытаться, конечно, удалять объект, и, если это удалось, тут же его восстанавливать - но мне такой подход не нравится на интуитивном уровне.
А если так:
Сохранить копию словаря, удалять объекты, посчитать количество удалённых элементов и восстановить словарь из копии?

Оффлайн Алексей Кулик

  • Administrator
  • *****
  • Сообщений: 1096
  • Карма: 172
"Сохранить копию" - куда? Можно, конечно, скопировать текущий документ в %temp%, открыть его через ObjetDBX, поудалять лишнее, получить результаты и закрыть - но отчет будет не для текущего состояния, а для последнего сохранения. Т.е. тоже "не фонтан".
С именем словаря попробую поиграться, но не сию секунду - просто работы как-то многовато навалили :(
Все, что сказано - личное мнение.

Правила форума существуют не просто так!

Приводя в сообщении код, не забывайте про его форматирование!

Оффлайн Подшиваленко Дмитрий

  • ADN Club
  • **
  • Сообщений: 64
  • Карма: 0
"Сохранить копию" - куда?
Создать пользовательский словарь и туда... А потом обратно и удалить пользовательский словарь. Прошу сильно не пинать за идею...

Оффлайн Алексей Кулик

  • Administrator
  • *****
  • Сообщений: 1096
  • Карма: 172
По-быстрому, без особых проверок:
Код - Auto/Visual Lisp [Выбрать]
  1. (vl-load-com)
  2.  
  3. (defun check-dict (doc name value / dict)
  4.                   ;|
  5. doc   - указатель на обрабатываемый документ. nil -> текущий
  6. name  - имя словаря. Не может быть пустым. Регистронезависимо.
  7. value - максимально допустимое значение, до которого не выводится никакое сообщение.
  8.         nil -> принимается равным 100
  9.  
  10. Примеры вызова:
  11. (check-dict nil "acad_dgnlinestylecomp" nil)
  12. (check-dict nil "
  13. |;
  14.   (if name
  15.     (progn (if (not doc)
  16.              (setq doc (vla-get-activedocument (vlax-get-acad-object)))
  17.              ) ;_ end of if
  18.            (if (not value)
  19.              (setq value 100)
  20.              ) ;_ end of if
  21.            (if (and (= (type
  22.                          (setq dict (vl-catch-all-apply (function (lambda () (vla-item (vla-get-dictionaries doc) name)))))
  23.                          ) ;_ end of type
  24.                        'vla-object
  25.                        ) ;_ end of =
  26.                     (> (vla-get-count dict) value)
  27.                     ) ;_ end of and
  28.              (alert
  29.                (strcat "Обнаружен словарь " name ", количество записей " (vl-princ-to-string (vla-get-count dict)))
  30.                ) ;_ end of alert
  31.              ) ;_ end of if
  32.            ) ;_ end of progn
  33.     (alert (strcat "\n** Error ** : не передано имя обрабатываемого словаря"))
  34.     ) ;_ end of if
  35.   (princ)
  36.   ) ;_ end of defun

В предоставленном файле буду обрабатываться только словари следующих наименований:
"ACAD_CIP_PREVIOUS_PRODUCT_INFO" "ACAD_COLOR" "ACAD_DETAILVIEWSTYLE" "ACAD_DGNLINESTYLECOMP" "ACAD_IMAGE_DICT" "ACAD_MLEADERSTYLE" "ACAD_MLINESTYLE" "ACAD_PLOTSTYLENAME" "ACAD_SCALELIST" "ACAD_SECTIONVIEWSTYLE" "ACAD_TABLESTYLE" "ACAD_VISUALSTYLE" "AEC_CLASSIFICATION_SYSTEM_DEFS" "AEC_PROPERTY_SET_DEFS" "ASE_INDEX_DICTIONARY" "AcDbVariableDictionary" "AcStStandard" "AcadDim" "BNS_VARIABLES"

На самом деле в файле могут быть словари, которые моим кодом обрабатываться не будут (в частности, ACAD_VARIABLES - был такой словарь, если не ошибаюсь).

Код для получения имен всех словарей, которые можно поставить в check-dict:
Код - Auto/Visual Lisp [Выбрать]
  1. (defun get-all-dict-names ()
  2.   (vl-sort (vl-remove nil
  3.                       (mapcar (function (lambda (x)
  4.                                           (if (vlax-property-available-p x 'name)
  5.                                             (vla-get-name x)
  6.                                             ) ;_ end of if
  7.                                           ) ;_ end of lambda
  8.                                         ) ;_ end of function
  9.                               ((lambda (/ lst)
  10.                                  (vlax-for item (vla-get-dictionaries (vla-get-activedocument (vlax-get-acad-object)))
  11.                                    (setq lst (cons item lst))
  12.                                    ) ;_ end of vlax-for
  13.                                  lst
  14.                                  ) ;_ end of LAMBDA
  15.                                )
  16.                               a
  17.                               ) ;_ end of mapcar
  18.                       ) ;_ end of vl-remove
  19.            '<
  20.            ) ;_ end of vl-sort
  21.   ) ;_ end of defun
Все, что сказано - личное мнение.

Правила форума существуют не просто так!

Приводя в сообщении код, не забывайте про его форматирование!

Оффлайн Подшиваленко Дмитрий

  • ADN Club
  • **
  • Сообщений: 64
  • Карма: 0
Алексей, очень извиняюсь, но можно ещё немного отвлеку тебя от работы.
В оригинале идея выглядела так:
"Можно сделать эту функцию универсальной, передавать ей имя словаря, а она будет возвращать количество записей и уже вне функции сравнивать количество записей словаря с адекватным количеством и выдавать alert?"
То есть проверку количества записей вынести вне функции, чтобы я со своим минимальным знанием лиспа мог выполнять какие-то другие действия при превышении адекватного количества записей (диалоговое окно вместо alert, или очистка).
Конструкция вроде:
Код - Auto/Visual Lisp [Выбрать]
  1. (check-dict nil "acad_dgnlinestylecomp" val)
  2. (if (> val 100) ; Если количество больше 100
  3.  (alert (strcat "Этот чертёж содержит "(itoa val)" объектов DGN! "))
  4. )
« Последнее редактирование: 27-04-2016, 12:31:08 от Подшиваленко Дмитрий »

Оффлайн Алексей Кулик

  • Administrator
  • *****
  • Сообщений: 1096
  • Карма: 172
Так, минуту. Можно сделать так, что на выходе будет список из точечных пар: ИмяСловаря - КоличествоЗаписей. И потом его анализировать. Основная проблема - соответствие имени словаря и "вменяемого" (для человека) названия. Подумаю, что и как можно сделать. Надо примерно часа два - у меня тут совещание нарисовывается :(
Пока есть время, задам еще вопрос: а "критическое количество записей" для каждого словаря надо делать отдельным или нет? И, если да, то где и как брать соответствия?
Все, что сказано - личное мнение.

Правила форума существуют не просто так!

Приводя в сообщении код, не забывайте про его форматирование!

Оффлайн Подшиваленко Дмитрий

  • ADN Club
  • **
  • Сообщений: 64
  • Карма: 0
Да я вроде не прошу так сложно. Достаточно того, что я передам функции имя словаря, будь то "acad_dgnlinestylecomp" или "ACAD_SCALELIST", а она мне вернёт количество записей этого словаря. Проверку внутри функции нужно убрать.
"Критическое количество записей"  для каждого словаря уже будет определяться мной вне этой функции.
Идея в том, чтобы просто иметь универсальную функцию, которая просто бы считала количество записей передаваемого ей словаря и возвращала это значение, а уже вне функции пишется обработка в стиле "Если количество записей больше чего-то, то сделать то-то"
« Последнее редактирование: 27-04-2016, 13:54:11 от Подшиваленко Дмитрий »

Оффлайн Алексей Кулик

  • Administrator
  • *****
  • Сообщений: 1096
  • Карма: 172
Как вариант:
Код - Auto/Visual Lisp [Выбрать]
  1. (vl-load-com)
  2.  
  3. (defun check-dict (doc)
  4.   (mapcar (function (lambda (x)
  5.                       (cons (vla-get-name x)
  6.                             (if (vlax-property-available-p x 'count)
  7.                               (vla-get-count x)
  8.                               -1
  9.                               ) ;_ end of if
  10.                             ) ;_ end of cons
  11.                       ) ;_ end of lambda
  12.                     ) ;_ end of function
  13.           (vl-remove-if-not
  14.             (function (lambda (x) (vlax-property-available-p x 'name)))
  15.             ((lambda (/ lst)
  16.                (vlax-for item (vla-get-dictionaries
  17.                                 (cond (doc)
  18.                                       (t (vla-get-activedocument (vlax-get-acad-object)))
  19.                                       ) ;_ end of cond
  20.                                 ) ;_ end of vla-get-dictionaries
  21.                  (setq lst (cons item lst))
  22.                  ) ;_ end of vlax-for
  23.                lst
  24.                ) ;_ end of lambda
  25.              )
  26.             ) ;_ end of vl-remove-if-not
  27.           ) ;_ end of mapcar
  28.   ) ;_ end of defun

doc - указатель на обрабатываемый документ (nil - текущий). Возвращает список из точечных пар  '("ИмяСловаря" . КоличествоЗаписей)
Если количество записей получить невозможно, то в КоличествоЗаписей показывается -1.

Конкретно для предоставленного файла результат:
Код - Auto/Visual Lisp [Выбрать]
  1. _$ (check-dict nil)
  2. '(("BNS_VARIABLES" . 4)
  3.   ("ASE_INDEX_DICTIONARY" . 1)
  4.   ("AEC_PROPERTY_SET_DEFS" . 0)
  5.   ("AEC_CLASSIFICATION_SYSTEM_DEFS" . 0)
  6.   ("AcStStandard" . 0)
  7.   ("AcDbVariableDictionary" . 13)
  8.   ("AcadDim" . -1)
  9.   ("ACAD_VISUALSTYLE" . 26)
  10.   ("ACAD_TABLESTYLE" . 1)
  11.   ("ACAD_SECTIONVIEWSTYLE" . 1)
  12.   ("ACAD_SCALELIST" . 1)
  13.   ("ACAD_PLOTSTYLENAME" . 1)
  14.   ("ACAD_MLINESTYLE" . 1)
  15.   ("ACAD_MLEADERSTYLE" . 1)
  16.   ("ACAD_IMAGE_DICT" . 0)
  17.   ("ACAD_DGNLINESTYLECOMP" . 398993)
  18.   ("ACAD_DETAILVIEWSTYLE" . 1)
  19.   ("ACAD_COLOR" . 0)
  20.   ("ACAD_CIP_PREVIOUS_PRODUCT_INFO" . -1)
  21.   )
Все, что сказано - личное мнение.

Правила форума существуют не просто так!

Приводя в сообщении код, не забывайте про его форматирование!

Оффлайн Алексей Кулик

  • Administrator
  • *****
  • Сообщений: 1096
  • Карма: 172
Вот это я сглупил!.. Сейчас сравню по быстродействию, выложу обновленный вариант
Все, что сказано - личное мнение.

Правила форума существуют не просто так!

Приводя в сообщении код, не забывайте про его форматирование!

Оффлайн Алексей Кулик

  • Administrator
  • *****
  • Сообщений: 1096
  • Карма: 172
Второй вариант, более медленный (как ни странно):
Код - Auto/Visual Lisp [Выбрать]
  1. (vl-load-com)
  2.  
  3. (defun check-dict2 (doc / lst)
  4.   (vlax-for item (vla-get-dictionaries
  5.                    (cond (doc)
  6.                          (t (vla-get-activedocument (vlax-get-acad-object)))
  7.                          ) ;_ end of cond
  8.                    ) ;_ end of vla-get-dictionaries
  9.     (if (vlax-property-available-p item 'name)
  10.       (setq lst (cons (cons (vla-get-name item)
  11.                             (if (vlax-property-available-p item 'count)
  12.                               (vla-get-count item)
  13.                               -1
  14.                               ) ;_ end of if
  15.                             ) ;_ end of cons
  16.                       lst
  17.                       ) ;_ end of cons
  18.             ) ;_ end of setq
  19.       ) ;_ end of vlax-for
  20.     lst
  21.     ) ;_ end of vlax-for
  22.   ) ;_ end of defun
Может, такой код будет более понятен.
Все, что сказано - личное мнение.

Правила форума существуют не просто так!

Приводя в сообщении код, не забывайте про его форматирование!

Оффлайн Подшиваленко Дмитрий

  • ADN Club
  • **
  • Сообщений: 64
  • Карма: 0
Алексей, всё замечательно, только я просил всего лишь возвращать количество записей для конкретного передаваемого словаря, чтобы потом мне с моими знаниями я мог понятными мне командами сотворить обработку типа:
Код - Auto/Visual Lisp [Выбрать]
  1. (check-dict nil "acad_dgnlinestylecomp" val)
  2. (if (> val 100) ; Если количество больше 100
  3.  (alert (strcat "Этот чертёж содержит "(itoa val)" объектов DGN! "))
  4. )
А словари я буду проверять по одному по мере необходимости. Это нужно потому, что после проверки словаря будут разные действия.
Проверил словарь acad_dgnlinestylecomp, если записей больше N1 - alert.
Проверил словарь ACAD_SCALELIST, если записей больше N2 - диалоговое окно или команда с очисткой.
Да и не нужно пока проверять все словари сразу.
« Последнее редактирование: 27-04-2016, 16:11:30 от Подшиваленко Дмитрий »

Оффлайн Алексей Кулик

  • Administrator
  • *****
  • Сообщений: 1096
  • Карма: 172
Код - Auto/Visual Lisp [Выбрать]
  1. (vl-load-com)
  2.  
  3. (defun check-dict2 (doc name / dict)
  4.   ;; doc - Документ (nil - текущий)
  5.   ;; name - имя словаря
  6.   (if (and name
  7.            (= (type (setq dict (vl-catch-all-apply
  8.                                  (function (lambda ()
  9.                                              (vla-item (vla-get-dictionaries
  10.                                                          (cond (doc)
  11.                                                                (t (vla-get-activedocument (vlax-get-acad-object)))
  12.                                                                ) ;_ end of cond
  13.                                                          ) ;_ end of vla-get-Dictionaries
  14.                                                        name
  15.                                                        ) ;_ end of vla-item
  16.                                              ) ;_ end of lambda
  17.                                            ) ;_ end of function
  18.                                  ) ;_ end of VL-CATCH-ALL-APPLY
  19.                           ) ;_ end of setq
  20.                     ) ;_ end of type
  21.               'vla-object
  22.               ) ;_ end of =
  23.            (vlax-property-available-p dict 'count)
  24.            ) ;_ end of and
  25.     (vla-get-count dict)
  26.     ) ;_ end of if
  27.   ) ;_ end of defun
Пример вызова:
Код - Auto/Visual Lisp [Выбрать]
  1. (if (> (check-dict2 nil "ACAD_SCALELIST") 100) (alert "масштабы"))
Все, что сказано - личное мнение.

Правила форума существуют не просто так!

Приводя в сообщении код, не забывайте про его форматирование!

Оффлайн Подшиваленко Дмитрий

  • ADN Club
  • **
  • Сообщений: 64
  • Карма: 0
Алексей, всё супер! То что надо!
Спасибо огромное!!! :)

Оффлайн Алексей Кулик

  • Administrator
  • *****
  • Сообщений: 1096
  • Карма: 172
Отлично :) В качестве оффтопа: лично я бы проходил по всем возможным словарям, получал их имена, сопоставлял с осмысленными названиями, проверял количество записей - и при необходимости формировал бы либо отчет, либо диалог, либо вообще втихаря все сносил ;)
Все, что сказано - личное мнение.

Правила форума существуют не просто так!

Приводя в сообщении код, не забывайте про его форматирование!

Оффлайн Подшиваленко Дмитрий

  • ADN Club
  • **
  • Сообщений: 64
  • Карма: 0
либо вообще втихаря все сносил
Думаю не стоит этого делать.
Я тут пару раз снёс людям "ненужное", а некоторым оно оказалось очень даже нужно (тот же словарь DGN и масштабы аннотаций). Пришлось быстро убирать такие очистки и разгребать последствия. Так что когда чистишь файлы на 600 компах, нужно быть предельно аккуратным. А вот проверять количество записей словаря и доставать людей окошком, чтобы они понимали, что их чертёж замусорен, для начала самое оно. Не поймут - со временем перейти к другим действиям.

Оффлайн Алексей Кулик

  • Administrator
  • *****
  • Сообщений: 1096
  • Карма: 172
Off-Topic: показать
Часть информации по тому, "что можно сносить, а с чем лучше погодить":
http://autolisp.ru/2015/08/26/erase-dictionaries-at-dwg/

Масштабы аннотаций у меня на работе, например, стандартизированы. Если есть возможность - сносятся лишние, а стандартные устанавливаются и настраиваются.
Все, что сказано - личное мнение.

Правила форума существуют не просто так!

Приводя в сообщении код, не забывайте про его форматирование!

Оффлайн Подшиваленко Дмитрий

  • ADN Club
  • **
  • Сообщений: 64
  • Карма: 0
У нас со стандартизацией (в частности с масштабами аннотаций) всё сложно. Из-за специфики института некоторые чертят в метрах, некоторые в миллиметрах. Я столкнулся с тем, что "метровщики" используют свои масштабы аннотаций (например масштаб описан как 1:5000, а единицы 1:5, ибо чертёж в метрах и им так удобнее).
Но это так, оффтоп, поэтому на эту тему  дискутировать в этой ветке наверное не стоит.

Алексей, всё-таки просьба, хотя тоже не совсем по этой теме.
Если будет время, желание и возможность, подумай, пожалуйста, над идеей подсчёта количества неиспользуемых элементов словаря (что-то типа prePurge), чтобы со временем можно было реализовать реакцию не на полное, и именно на неиспользуемое количество записей словаря (если это вообще реализуемо и не слишком медленно будет работать) :)
А так ещё раз огромнейшее спасибо за помощь и предоставленный код :)

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
если это вообще реализуемо и не слишком медленно будет работать
Это нереализуемо на лиспе. А на ObjectARX или .NET реализуемо, но будет работать слишком долго на файлах типа вашего 25Мбайтного мусора и соотвественно не имеет смысла - в автозагрузку такую проверку ни в коем случае ставить нельзя.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Алексей Кулик

  • Administrator
  • *****
  • Сообщений: 1096
  • Карма: 172
Насчет единиц проектирования - ну извините, тут совсем все просто: lunits, insunits, insunitsdefsource, insunitsdeftarget - кто мешает настроить?
По "PrePurge" я смогу реализовать только вариант "по состоянию на последнее сохранение", не больше. Рушить файлы не хочется от слова совсем :)
Все, что сказано - личное мнение.

Правила форума существуют не просто так!

Приводя в сообщении код, не забывайте про его форматирование!

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
По "PrePurge" я смогу реализовать только вариант "по состоянию на последнее сохранение", не больше.
Как ты собираешься на лиспе подсчитывать используемость или неиспользуемость элементов словаря в лиспе? ;)
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Подшиваленко Дмитрий

  • ADN Club
  • **
  • Сообщений: 64
  • Карма: 0
А на ObjectARX или .NET реализуемо, но будет работать слишком долго на файлах типа вашего 25Мбайтного мусора и соотвественно не имеет смысла - в автозагрузку такую проверку ни в коем случае ставить нельзя.
Возможно. Всё будет зависеть от того, сможет ли Алексей вообще реализовать эту идею и с какой скоростью это будет работать. К тому же такую проверку планируется применять не ко всем словарям сразу, а к отдельным и только после тестирования на пачке файлов. Для объектов DGN и ScaleList на данном этапе вполне достаточно проверки полного количества записей словаря.

Оффлайн Алексей Кулик

  • Administrator
  • *****
  • Сообщений: 1096
  • Карма: 172
Я собираюсь скопировать текущий файл в %temp% (возможно, с новым именем) и открыть через ObjectDBX. Поудалять данные для указанных словарей и вернуть разницу. Потом закрыть файл dwg и удалить его. Надеюсь, сработает нормально (прямо сейчас возможности подобное провернуть не имею - работы многовато).
Все, что сказано - личное мнение.

Правила форума существуют не просто так!

Приводя в сообщении код, не забывайте про его форматирование!

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Всё будет зависеть от того, сможет ли Алексей вообще реализовать эту идею и с какой скоростью это будет работать.
Я поясню почему я считаю, что на лиспе это принципиально невозможно. Для того, чтобы определить, что какой-то из объектов словаря используется в чертеже необходимо выполнить проверку не ссылается ли каждый из объектов чертежа на выбранный объект. Для этой цели в лиспе нет средств. Но даже если бы это удалось, то пришлось бы для каждого из объектов словаря сканировать весь чертеж. Представь себе, что у тебя в словаре всего лишь 1000 объектов и в чертеже вообще больше ничего нет (в действительности есть еще хотябы 1000 объектов - слои, типы линий, визуальные стили и т.д. и т.п.). Так вот такая проверка уже будет порядка 1000000 итераций. А если это как в твоём примере > 300000 объектов в словаре, то итераций будет 90000000000 !!!
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Я собираюсь скопировать текущий файл в %temp% (возможно, с новым именем) и открыть через ObjectDBX. Поудалять данные для указанных словарей и вернуть разницу. Потом закрыть файл dwg и удалить его. Надеюсь, сработает нормально
Так ты же удалишь таким образом и используемые элементы...
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Алексей Кулик

  • Administrator
  • *****
  • Сообщений: 1096
  • Карма: 172
Н-да, вариант оказался нерабочим: записи удалить не представляется возможным без предварительной очистки файла (блоки, типы линий, текстовые и размерные стили и т.п.). Даже не знаю, имеет ли смысл показывать свое "чудовище".
Если коротко - то prePurge сделать не удалось.
---
Добавлю: можно, конечно, попробовать создать новый экземпляр AutoCAD, в него загрузить копию, почистить, потом дальше открыть... Но это уже, мне кажется, будет перебор.
Все, что сказано - личное мнение.

Правила форума существуют не просто так!

Приводя в сообщении код, не забывайте про его форматирование!

Оффлайн Подшиваленко Дмитрий

  • ADN Club
  • **
  • Сообщений: 64
  • Карма: 0
Если коротко - то prePurge сделать не удалось.
Не страшно, спасибо и на том что сделал :) Реально очень помог :)
Интересно, а по какому алгоритму сам Акад анализирует список неиспользуемых объектов в команде Purge перед самой очисткой? На адекватных файлах этот анализ происходит не так уж и долго, тем более там анализируются все объекты. Или эти методы недоступны обычными методами программирования?

Оффлайн Алексей Кулик

  • Administrator
  • *****
  • Сообщений: 1096
  • Карма: 172
Так и чистится там текущий документ, а не открытый через ObjectDBX (т.е. достаточно криво ;))
P.S. В Autodesk AppStore есть пакетная чистилка файлов. Названия не помню, но поискать можно.
Все, что сказано - личное мнение.

Правила форума существуют не просто так!

Приводя в сообщении код, не забывайте про его форматирование!

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Или эти методы недоступны обычными методами программирования?
Эти методы недоступны в лиспе, но доступны в ObjectARX.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Подшиваленко Дмитрий

  • ADN Club
  • **
  • Сообщений: 64
  • Карма: 0
Так и чистится там текущий документ
Так и надо, чтобы чистился текущий документ :) Точнее ПреПуржился :)

Оффлайн Алексей Кулик

  • Administrator
  • *****
  • Сообщений: 1096
  • Карма: 172
В принципе, есть еще одна идея: запустить чистку, а потом выполнить откат обратно. Но как файл потом будет работать - не представляю.
Все, что сказано - личное мнение.

Правила форума существуют не просто так!

Приводя в сообщении код, не забывайте про его форматирование!

Оффлайн Подшиваленко Дмитрий

  • ADN Club
  • **
  • Сообщений: 64
  • Карма: 0
Ещё вопрос, правда тоже не совсем по теме, но по поиску на dwg.ru ответа на него не нашёл.
Есть файлы, имеющие большое количество масштабов аннотаций (МА) и неиспользуемых зарегистрированных приложений (НЗП). Если подключить такой файл к другому девственно чистому файлу, вся эта когорта приложений и масштабов переносится на чистый файл. Бороться с последствиями этого понятно как - очистка файла, но!
Очистка реализована только при открытии файла путём загрузки acaddoc.lsp на каждом открываемом чертеже (других идей по очистке файлов на 600 компах не придумал), поэтому ничто не мешает очищенному файлу замусориться при подключении ссылки на другой файл.
Возник вопрос. Можно ли изменить поведение Acad'а, чтобы при подключении ссылки на файл с большим количеством МА и НЗП, эти МА и НЗП не переносились в другой файл?
Ещё у товарища с работы была идея с реакторами (например при подключении ссылки или сохранении файла проверять количество МА и очищать их). Реально ли такое осуществить? (С реакторами вообще не знаком, попробуем с товарищем разобраться).

Оффлайн Алексей Кулик

  • Administrator
  • *****
  • Сообщений: 1096
  • Карма: 172
Стоп-стоп-стоп. Зарегистрированные приложения при подключении внешней ссылки вроде бы не импортируются. Масштабы аннотаций ссылок можно скрыть.
Или ты про вставку стороннего файла как блока / внедрение ссылки?
Все, что сказано - личное мнение.

Правила форума существуют не просто так!

Приводя в сообщении код, не забывайте про его форматирование!

Оффлайн Подшиваленко Дмитрий

  • ADN Club
  • **
  • Сообщений: 64
  • Карма: 0
Зарегистрированные приложения при подключении внешней ссылки вроде бы не импортируются.
Как раз импортируются и как раз просто при подключении ссылки. Могу приложить файл, в котором около 50 тысяч НЗП, подключи его, проверь :) После удаления ссылки на файл с НЗП, эти НЗП всё равно остаются в новом файле. Только что ещё раз сам проверил. Audit такого файла выполняется очень долго.
Масштабы аннотаций ссылок можно скрыть.
А какой толк от их скрытия? Нужно именно, чтобы они не переносились, иначе после переноса такой файл опять будет неимоверно грузиться в качестве ссылки.
Приложу файлы для экспериментов. Если у тебя вдруг при подключении ссылки на файл с НЗП или МА они не перенеслись в новый файл, значит это должно быть в настройках акада и надо будет выяснить где именно это настраивается.
И попутно возник ещё один вопрос: где хранится информация о зарегистрированных приложениях (как узнать количество НЗП)? В словарях я вроде не нашёл.

Оффлайн Алексей Кулик

  • Administrator
  • *****
  • Сообщений: 1096
  • Карма: 172
Н-да, проверил в 2016 - действительно импортируются приложения. Сорри, косяк :)
Не, сделать можно если не все, то очень многое. Правда, возникают вопросы организационного плана: ссылки нередко используются "чтобы не вносились изменения в исходные данные". Потому что любая обработка обязательно потребует сохранения исходнного файла. Мало того, если работать лиспом, то это моментально означает работу через ObjectDBX, сохранение только в текущем формате и еще массу тонкостей. Фактически я вижу два выхода: либо писать самостоятельную очистку, либо использовать приложение для пакетной очистки из AUtodesk AppStore (благо там их полно).
Ну так что, как поступаем? :) Реактор на вставку ссылки? Пакетная очистка? Или еще что-то? ;)
Все, что сказано - личное мнение.

Правила форума существуют не просто так!

Приводя в сообщении код, не забывайте про его форматирование!

Оффлайн Подшиваленко Дмитрий

  • ADN Club
  • **
  • Сообщений: 64
  • Карма: 0
Н-да, проверил в 2016 - действительно импортируются приложения. Сорри, косяк
То есть это никак не отключаемо? И импорт МА тоже? Печаль :( Хорошую подставу в этом плане AutoDesk устроил. Получается, что НЗП и МА валятся в файл как снежный ком из других файлов. Или есть идеи как отключить импорт НЗП и МА?
Ну так что, как поступаем?  Реактор на вставку ссылки? Пакетная очистка? Или еще что-то?
Пакетную очистку уже проходили. Рабочих файлов в сети неимоверное количество, пока в одном месте чистишь, в другом уже намусорили, а потом и намусорили в том месте, где уже почистили :) К тому же многие из них содержат кучу ссылок и долго грузятся. В общем не вариант.
Значит из оставшихся идей только реактор, но я бы сделал его именно на сохранение файла (BeginSave), если такое возможно. То есть перед сохранением либо автоматическая очистка от МА командой (command "_.-purge" "_r" "*" "_n"), либо диалоговое окно с предложением очистить МА (как это сейчас мной реализовано).
Правда и тут засада: в реакторах нельзя применять command, насколько я понял.
И опять же, надо выяснить как узнать количество НЗП, чтобы тоже выводить окошко с предложением очистки. Правда очистка от НЗП выполняется достаточно долго в отличие от очистки МА :(
« Последнее редактирование: 05-05-2016, 12:59:15 от Подшиваленко Дмитрий »

Оффлайн Алексей Кулик

  • Administrator
  • *****
  • Сообщений: 1096
  • Карма: 172
В реакторах - нельзя. Так тебе надо чистить или просто поставить юзера в известность? Если второе - то vla-get-count должно хватить для формирования сообщения.
Все, что сказано - личное мнение.

Правила форума существуют не просто так!

Приводя в сообщении код, не забывайте про его форматирование!

Оффлайн Подшиваленко Дмитрий

  • ADN Club
  • **
  • Сообщений: 64
  • Карма: 0
Так тебе надо чистить или просто поставить юзера в известность?
В идеале бы конечно диалог с предложением почистить файл. Но если нельзя, то хотя бы окошко с предупреждением, хотя это менее эффективно.
Сейчас это выглядит так:
Код - Auto/Visual Lisp [Выбрать]
  1. (setq sc (check-dict nil "ACAD_SCALELIST"))
  2. (if (> sc 100) (scale_c)) ;вывод диалогового окна в случае если количество масштабов больше 100
sc используется для вывода в диалоге количества масштабов.
Если в диалоге "да", то
Код - Auto/Visual Lisp [Выбрать]
  1. (if (= done 1) (command "_-scalelistedit" "_d" "*" "_e") ) ;Если да, то чистим масштабы

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Интересные зарегистрирванные приложения:
Цитировать
Deleting registered application "AUDIT_I_151028172007-0".
Deleting registered application "$RECOVER_150804115203-519".
У меня такое впечатление, что кто-то бездумно удалял эти приложения из файла, а AutoCAD при AUDIT и RECOVER их восстанавливал и множил.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Подшиваленко Дмитрий

  • ADN Club
  • **
  • Сообщений: 64
  • Карма: 0
У меня такое впечатление, что кто-то бездумно удалял эти приложения из файла, а AutoCAD при AUDIT и RECOVER их восстанавливал и множил.
Ну там полно и других, даже, например, таких: Удаление зарегистрированное приложение "架空面积".
Наверное не суть важно как они появились, а важно то, как от них избавиться. Тем более, что они импортируются при подключении ссылки (то есть накапливаются).
Было бы очень неплохо избавиться от механизма импорта этого барахла при подключении ссылки.

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Ну там полно и других, даже, например, таких: Удаление зарегистрированное приложение "架空面积".
Таких - десятки, а тех десятки тысяч.
Наверное не суть важно как они появились
Если они будут продолжать появляться, то ты от них не избавишься. Нужно искать причину.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Алексей Кулик

  • Administrator
  • *****
  • Сообщений: 1096
  • Карма: 172
Сугубо ИМХО: "повесить" предварительную очистку при открытии файла плюс пройтись по серверу с dwg-файлами будет значительно проще, чем выдумывать что-то еще. Ну и прописать требования к файлам, предоставляемым сторонними организациями.
Все, что сказано - личное мнение.

Правила форума существуют не просто так!

Приводя в сообщении код, не забывайте про его форматирование!

Оффлайн Подшиваленко Дмитрий

  • ADN Club
  • **
  • Сообщений: 64
  • Карма: 0
Если они будут продолжать появляться, то ты от них не избавишься. Нужно искать причину.
Наверное это не совсем реально. А потом основная причина большого количества НЗП, что они импортируются при подключении ссылки. Если избавиться от этого, то тогда уже будет проще с очисткой. В новом файле человек вряд ли осознанно или неосознанно сумеет наплодить 50 тысяч НЗП.
Сугубо ИМХО: "повесить" предварительную очистку при открытии файла плюс пройтись по серверу с dwg-файлами будет значительно проще, чем выдумывать что-то еще. Ну и прописать требования к файлам, предоставляемым сторонними организациями.
Вешали предварительную чистку при открытии файла. Проблема в том, что очистка от такого количества НЗП выполняется очень долго. А потом где гарантии, что после чистки человек не подключит файл с НЗП и эти НЗП опять не появятся в чищенном файле? Поэтому и появилась идея с реактором на сохранение.
Про пакетную очистку я уже писал.

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Для массовой очистки зарегистрированных приложений, в том числе и в XREF:
https://knowledge.autodesk.com/support/autocad/troubleshooting/caas/sfdcarticles/sfdcarticles/Excess-unreferenced-regapp-IDs-causing-performance-issues.html
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Подшиваленко Дмитрий

  • ADN Club
  • **
  • Сообщений: 64
  • Карма: 0
Для массовой очистки зарегистрированных приложений, в том числе и в XREF:
За ссылку спасибо, поизучаю на досуге.
С пакетной очисткой была ещё проблема: некоторые люди работают в Civil 3D и после пакетной очистки файлов при помощи AutoCAD, эти файлы перестали открываться в Civil 3D (fatal error), так что с пакетной чисткой надо поаккуратнее, мало ли какие проблемы вылезут. А потом, как я уже писал, файлов настолько много, что пока тут чистишь, там уже намусорили.

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
С пакетной очисткой была ещё проблема: некоторые люди работают в Civil 3D и после пакетной очистки файлов при помощи AutoCAD, эти файлы перестали открываться в Civil 3D (fatal error), так что с пакетной чисткой надо поаккуратнее, мало ли какие проблемы вылезут.
Это приложение чистит только (!!!) неиспользованные зарегистрированные приложения. В этом легко убедится на примере твоего файла НПЗ.dwg. После очистки в нём остаётся 22 приложения, которые реально используются:


Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Алексей Кулик

  • Administrator
  • *****
  • Сообщений: 1096
  • Карма: 172
Наверняка при "чистке" убивались словари, которые использует Civil - вот и результат.
Все, что сказано - личное мнение.

Правила форума существуют не просто так!

Приводя в сообщении код, не забывайте про его форматирование!

Оффлайн Подшиваленко Дмитрий

  • ADN Club
  • **
  • Сообщений: 64
  • Карма: 0
Это приложение чистит только (!!!) неиспользованные зарегистрированные приложения.
Ну так и мы чистили только неиспользованные зарегистрированные приложения командой (command "_.-purge" "_r" "*" "_n").
Наверняка при "чистке" убивались словари, которые использует Civil - вот и результат.
Словари не трогались вроде бы...

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Ну так и мы чистили только неиспользованные зарегистрированные приложения командой (command "_.-purge" "_r" "*" "_n").
AutoCAD (Civil 3D) 2015 SP2? Тогда нужен еще такой Fix: https://knowledge.autodesk.com/support/autocad/downloads/caas/downloads/content/autodesk-C2-AE-autocad-C2-AE-2015-sp2-xref-hotfix.html
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Подшиваленко Дмитрий

  • ADN Club
  • **
  • Сообщений: 64
  • Карма: 0
И всё-таки к пакетной чистке я не готов, тем более это не совсем в моей компетенции (я не админ). Давайте пока остановимся на варианте с реактором и сообщением о большом количестве НЗП и МА. И ещё никто не ответил на вопрос, можно ли отключить импорт НЗП и МА при подключении ссылки?
P.S. Алексей, а какой командой вызывается символьная таблица?

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
И ещё никто не ответил на вопрос, можно ли отключить импорт НЗП и МА при подключении ссылки?
Нельзя. Это принципиальное ограничение.
P.S. Алексей, а какой командой вызывается символьная таблица?

О чем речь? Это вопрос Алексею или всё-таки мне по поводу этой картинки:


 
Если речь о ней, то это утилита ARXDBG, входящая в состав ObjectARX SDK. Взять готовую можно здесь (в зависимости от версии AutoCAD):
http://www.maestrogroup.com.ua/support/ArxDbg2007.zip
http://www.maestrogroup.com.ua/support/ArxDbg2010.zip
http://www.maestrogroup.com.ua/support/ArxDbg2013.zip
http://www.maestrogroup.com.ua/support/ArxDbg2015.zip
http://www.maestrogroup.com.ua/support/ArxDbg2017.zip
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Подшиваленко Дмитрий

  • ADN Club
  • **
  • Сообщений: 64
  • Карма: 0
О чем речь? Это вопрос Алексею или всё-таки мне по поводу этой картинки:
Ой, Александр, извините, точно ваше сообщение было :) Спасибо большое :)
Алексей, можно надеяться на программу с реактором для вывода сообщений про НЗП и МА?  ::)

Оффлайн Алексей Кулик

  • Administrator
  • *****
  • Сообщений: 1096
  • Карма: 172
Реактор сработает только после собственно вставки ссылки / блока, т.е. файл уже выбран и вставлен. "Перед" вставкой, когда файл еще не выбран, смысла в реакторе нет. Отследить, какой файл выбран, лиспом невозможно.
И для режима "после вставки" можно только сообщить о факте загрязнения текущего чертежа (и, возможно, исходного). Ну почистить текущий и вставленный - по желанию. Надо?
P.S. Кстати, такое решение не отследит программную вставку ссылки через механизм ActiveX, учти.
Все, что сказано - личное мнение.

Правила форума существуют не просто так!

Приводя в сообщении код, не забывайте про его форматирование!

Оффлайн Подшиваленко Дмитрий

  • ADN Club
  • **
  • Сообщений: 64
  • Карма: 0
Надо?
Надо, конечно :)
Кстати, такое решение не отследит программную вставку ссылки через механизм ActiveX
Так может логичнее было бы сделать реактор на сохранение файла (именно перед сохранением, вроде BeginSave)? Если возможно... Тогда и не надо отслеживать, хотя не принципиально, думаю народ у нас таким вряд ли пользуется.

Оффлайн Алексей Кулик

  • Administrator
  • *****
  • Сообщений: 1096
  • Карма: 172
Итак, если я правильно понял задачу:
1. После вставки внешней ссылки или блока проверить количество масштабов аннотаций, объектов AcDgnLS, зарегистрированных приложений. Если разница с предыдущим состоянием превышает какое-то значение, вывести alert с предупреждением о необходимости "вотпрямщас" чистить файлы
2. После вызова команды сохранения / закрытия файла или при выходе из AutoCAD опять же, проверить масштабы аннотаций, AcDgnLS, зарегистрированные приложения. Если по какому-то из параметров количество превышает какое-то значение, опять-таки "вотпрямщасгорит!" чистить файл.
Так? Или еще что-то надо добавлять? Честно скажу - очень не хочется по тысяче раз переписывать один и тот же код.
Все, что сказано - личное мнение.

Правила форума существуют не просто так!

Приводя в сообщении код, не забывайте про его форматирование!

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
или при выходе из AutoCAD
Лиспом ты можешь отловить это, но не сможешь отказаться от выхода. Т.е. очистить уже не получится.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Подшиваленко Дмитрий

  • ADN Club
  • **
  • Сообщений: 64
  • Карма: 0
Так? Или еще что-то надо добавлять? Честно скажу - очень не хочется по тысяче раз переписывать один и тот же код.
Алексей, в принципе всё так, только может достаточно будет реактора на сохранение файла (без реактора на ссылки), если он правильно сработает?
Логично будет сделать отдельный алерт на каждое превышение (МА, НЗП, DGN)?
Проверку количества DGN и масштабов аннотаций может сделать вызовом последнего варианта функции проверки словаря (check-dict2)?

Оффлайн Алексей Кулик

  • Administrator
  • *****
  • Сообщений: 1096
  • Карма: 172
Александр Ривилис, так я не собираюсь чистить :) Я собираюсь максимум - проинформировать ;)
Подшиваленко Дмитрий, десятки алертов делать? Неудобно будет. По-быстрому, без тестирования:
Код - Auto/Visual Lisp [Выбрать]
  1. (vl-load-com)
  2.  
  3. (defun adn-save-settings ()
  4.   (setq *adn-doc*      (vla-get-activedocument (vlax-get-acad-object))
  5.         *adn-settings* (append (mapcar (function (lambda (x / o)
  6.                                                    (list (cons "name" (car x))
  7.                                                          (cons "obj" (setq o (vlax-get-property *adn-doc* (car x))))
  8.                                                          (cons "count" (vla-get-count o))
  9.                                                          (cons "crit" (cdr x))
  10.                                                          ) ;_ end of list
  11.                                                    ) ;_ end of lambda
  12.                                                  ) ;_ end of function
  13.                                        ;; Первый элемент в точечной паре - имя свойства документа
  14.                                        ;; Второй - критичная разница между стартом и последним сохранением
  15.                                        '
  16.                                         (("registeredapplications" . 20)
  17.                                          ;; Следующие элементы - для примера
  18.                                          ("textstyles" . 10)
  19.                                          ("dimstyles" . 10)
  20.                                          )
  21.                                        ) ;_ end of mapcar
  22.                                (mapcar (function
  23.                                          (lambda (x / d)
  24.                                            (list (cons "name" (car x))
  25.                                                  (cons "obj"
  26.                                                        (setq d (vl-catch-all-apply (function (lambda () (vla-item (vla-get-dictionaries *adn-doc*) (car x))))))
  27.                                                        ) ;_ end of cons
  28.                                                  (cons "count"
  29.                                                        (if (and (= (type d) 'vla-object) (vlax-property-available-p d 'count))
  30.                                                          (vla-get-count d)
  31.                                                          0
  32.                                                          ) ;_ end of if
  33.                                                        ) ;_ end of cons
  34.                                                  (cons "crit" (cdr x))
  35.                                                  ) ;_ end of list
  36.                                            ) ;_ end of lambda
  37.                                          ) ;_ end of function
  38.                                        ;; Первый элемент в точечной паре - имя словаря
  39.                                        ;; Второй - критичная разница между стартом и последним сохранением
  40.                                        '
  41.                                         (("acad_scalelist" . 15) ("acad_dgnlinestylecomp" . 0))
  42.                                        ) ;_ end of mapcar
  43.                                ) ;_ end of append
  44.         ) ;_ end of setq
  45.   ) ;_ end of defun
  46.  
  47. (adn-save-settings)
  48.  
  49. (if *adn-vlr-cmd*
  50.   (progn (vl-remove *adn-vlr-cmd*) (setq *adn-vlr-cmd* nil))
  51.   ) ;_ end of if
  52.  
  53. (if (not *adn-vlr-cmd*)
  54.   (setq *adn-vlr-cmd* (vlr-command-reactor "adn-cmd-reactor" '((:vlr-commandwillstart . _adn-vlr-cmd-start))))
  55.   ) ;_ end of if
  56.  
  57. (defun _adn-vlr-cmd-start (react cmd / datas)
  58.   (setq cmd (strcase (car cmd)))
  59.   (cond
  60.     ((member cmd '("QSAVE" "SAVE" "SAVEAS"))
  61.      (if (setq datas
  62.                 (vl-remove-if
  63.                   (function (lambda (x) (or (not x) (not (cdr (assoc "count" x))) (< (cdr (assoc "count" x)) 0))))
  64.                   (mapcar (function
  65.                             (lambda (item / o)
  66.                               (cond ((and (= (type (setq o (cdr (assoc "obj" item)))) 'vla-object) (vlax-property-available-p o 'count))
  67.                                      (list (assoc "name" item)
  68.                                            (cons "count" (- (vla-get-count o) (cdr (assoc "count" item)) (cdr (assoc "crit" item))))
  69.                                            ) ;_ end of list
  70.                                      )
  71.                                     ((and (/= (type (cdr (assoc "obj" item))) 'vla-object)
  72.                                           (= (type
  73.                                                (setq o (vl-catch-all-apply
  74.                                                          (function (lambda () (vla-item (vla-get-dictionaries *adn-doc*) (cdr (assoc "name" item)))))
  75.                                                          ) ;_ end of vl-catch-all-apply
  76.                                                      ) ;_ end of setq
  77.                                                ) ;_ end of type
  78.                                              'vla-object
  79.                                              ) ;_ end of =
  80.                                           (vlax-property-available-p o 'count)
  81.                                           ) ;_ end of and
  82.                                      (list (assoc "name" item) (- (cons "count" (vla-get-count o)) (cdr (assoc "crit" item))))
  83.                                      )
  84.                                     ((and (/= (type (cdr (assoc "obj" item))) 'vla-object)
  85.                                           (= (type
  86.                                                (setq o (vl-catch-all-apply (function (lambda () (vlax-get-property *adn-doc* (cdr (assoc "name" item)))))))
  87.                                                ) ;_ end of type
  88.                                              'vla-object
  89.                                              ) ;_ end of =
  90.                                           (vlax-property-available-p o 'count)
  91.                                           ) ;_ end of and
  92.                                      (list (assoc "name" item)
  93.                                            (cons "count"
  94.                                                  (- (vla-get-count o)
  95.                                                     (cond ((cdr (assoc "count" item)))
  96.                                                           (t 0)
  97.                                                           ) ;_ end of cond
  98.                                                     (cdr (assoc "crit" item))
  99.                                                     ) ;_ end of -
  100.                                                  ) ;_ end of cons
  101.                                            ) ;_ end of list
  102.                                      )
  103.                                     ) ;_ end of cond
  104.                               ) ;_ end of lambda
  105.                             ) ;_ end of function
  106.                           *adn-settings*
  107.                           ) ;_ end of mapcar
  108.                   ) ;_ end of vl-remove-if
  109.                ) ;_ end of setq
  110.        (alert
  111.          (strcat "При сохранении файла обнаружены следующие превышения"
  112.                  "\nс момента последнего сохранения"
  113.                  (apply (function strcat)
  114.                         (mapcar (function
  115.                                   (lambda (x / o)
  116.                                     (strcat "\n"
  117.                                             (if (= (type
  118.                                                      (setq o (vl-catch-all-apply
  119.                                                                (function (lambda () (vla-item (vla-get-dictionaries *adn-doc*) (cdr (assoc "name" x)))))
  120.                                                                ) ;_ end of vl-catch-all-apply
  121.                                                            ) ;_ end of setq
  122.                                                      ) ;_ end of type
  123.                                                    'vla-object
  124.                                                    ) ;_ end of =
  125.                                               "Словарь"
  126.                                               "Свойство"
  127.                                               ) ;_ end of if
  128.                                             " \""
  129.                                            (cdr (assoc "name" x))
  130.                                            "\" : "
  131.                                             (itoa (cdr (assoc "count" x)))
  132.                                             ) ;_ end of strcat
  133.                                     ) ;_ end of lambda
  134.                                   ) ;_ end of function
  135.                                 datas
  136.                                 ) ;_ end of mapcar
  137.                         ) ;_ end of apply
  138.                  "\n\n"
  139.                  "Выполните очистку файла!"
  140.                  ) ;_ end of strcat
  141.          ) ;_ end of alert
  142.        ) ;_ end of if
  143.      ;; Если сравнивать надо не с последним сохранением, а с начальным состоянием,
  144.      ;; следующую строку надо будет удалить
  145.      (adn-save-settings)
  146.      )
  147.     ) ;_ end of cond
  148.   ) ;_ end of defun

Обрати внимание на комментарии.
Реактор срабатывает только на начало сохранения, очистка не выполняется.
Все, что сказано - личное мнение.

Правила форума существуют не просто так!

Приводя в сообщении код, не забывайте про его форматирование!

Оффлайн Подшиваленко Дмитрий

  • ADN Club
  • **
  • Сообщений: 64
  • Карма: 0
Алексей, спасибо. :) Сегодня попробую.
Вроде работает :)
Очень сильно извиняюсь, можно одну небольшую поправку?  ::)
Сравнивать превышение надо не с последним сохранением и не с начальным состоянием, а просто с критическим значением. Иначе теряется смысл проверки, если человек открыл уже замусоренный файл, то реактор не оповестит при сохранении, что файл замусорен... :-[
« Последнее редактирование: 06-05-2016, 10:09:01 от Подшиваленко Дмитрий »

Оффлайн Алексей Кулик

  • Administrator
  • *****
  • Сообщений: 1096
  • Карма: 172
В принципе не сложно. Просто есть несколько вопросов (ну это как обычно):
1. Если был вставлен "загаженный" файл (ссылкой или блоком) - что делаем?
2. Критическое количество "на старте" и "с момента последнего сохранения" / "с момента начала" - одинаковое или будет разное? Т.е., например, при старте количество масштабов допускается до 20, а при сохранении изменение на 10 уже не гуд.
Все, что сказано - личное мнение.

Правила форума существуют не просто так!

Приводя в сообщении код, не забывайте про его форматирование!

Оффлайн Подшиваленко Дмитрий

  • ADN Club
  • **
  • Сообщений: 64
  • Карма: 0
В принципе не сложно. Просто есть несколько вопросов (ну это как обычно):
1. Если был вставлен "загаженный" файл (ссылкой или блоком) - что делаем?
2. Критическое количество "на старте" и "с момента последнего сохранения" / "с момента начала" - одинаковое или будет разное? Т.е., например, при старте количество масштабов допускается до 20, а при сохранении изменение на 10 уже не гуд.
1. Ничего не делаем. Если ссылкой вставляется "загаженный" файл, то весь мусор перекочёвывает в новый файл, в котором это всё будет ловиться на этапе сохранения.
2. Критическое количество будет одно на всё время работы с файлом. То есть при сохранении достаточно просто сравнивать текущее количество с критическим и выдавать сообщение.
Немного по коду... Когда я увидел твой код из полутора сотен строк, я немного прибалдел. Я думал что конструкция будет гораздо проще, что-то в духе (если такая конструкция, конечно, возможна):
Код - Auto/Visual Lisp [Выбрать]
  1. (load "check-dict2.lsp")
  2. (реактор на сохранение)
  3.  (if (> (check-dict2 nil "ACAD_SCALELIST") 100) (alert "масштабы"))
  4.  (if (> (check-dict2 nil "ACAD_DGNLINESTYLECOMP") 10000) (alert "DGN"))
  5. )
где check-dict2 - функция отсюда: http://adn-cis.org/forum/index.php?topic=709.msg20101#msg20101
Ну и дописать отдельно функцию определения количества RegApp, поскольку, как я понял, их количество хранится не в словаре, а в символьной таблице.
Правда в этих символьных таблица хранится ещё много чего интересного, поэтому возникает соблазн написать универсальную функцию наподобие check-dict2, в которую передавать имя таблицы, а она будет возвращать количество элементов :)
И ещё хотелка. В твоей статье про реакторы есть фраза "В реакторах не срабатывает обычный command или vl-cmdf. Если "с ножом к горлу" надо использовать командную строку (бывает такое), то следует использовать механизм vla-sendcommand для текущего документа"
Так вот, практически "с ножом к горлу" для масштабов аннотаций нужно выполнить  (if (> (check-dict2 nil "ACAD_SCALELIST") 100) (command "_-scalelistedit" "_d" "*" "_e")), ибо подключение ссылкой чертежа с большим количеством масштабов происходит очень долго. Недавно в сети был обнаружен файл, содержащий 40 тысяч!! масштабов аннотаций. На неслабом компе (Core i7 3.60GHz) он подключался как ссылка 15 минут! После очистки он подключился за 2 секунды.

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Так вот, практически "с ножом к горлу" для масштабов аннотаций нужно выполнить  (if (> (check-dict2 nil "ACAD_SCALELIST") 100) (command "_-scalelistedit" "_d" "*" "_e"))
Не читаешь ты то что я пишу, а жаль. Повторюсь. Средствами lisp на этапе сохранения чертежа можно лишь известить о критическом количестве масштабов аннотаций, но нельзя прервать сохранение и выполнить команду очистки.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Подшиваленко Дмитрий

  • ADN Club
  • **
  • Сообщений: 64
  • Карма: 0
Не читаешь ты то что я пишу, а жаль.
Александр, я читал это. Просто, как я уже написал, я натолкнулся на статью Алексея про реакторы с фразой "Если "с ножом к горлу" надо использовать командную строку (бывает такое), то следует использовать механизм vla-sendcommand для текущего документа", вот и появилась надежда  ::)
Если Алексей скажет, что такое невозможно, значит не судьба и обойдёмся алертом...

Оффлайн Алексей Кулик

  • Administrator
  • *****
  • Сообщений: 1096
  • Карма: 172
Не уверен, что сегодня успею хоть что-то сделать...
Очистка масштабов аннотаций может быть выполнена и без команд:
Код - Auto/Visual Lisp [Выбрать]
  1. (if (getvar "cannoscale")
  2.     (foreach scale (mapcar (function cdr)
  3.                            (vl-remove-if-not
  4.                              (function (lambda (x) (= (car x) 350)))
  5.                              (dictsearch (namedobjdict) "acad_scalelist")
  6.                              ) ;_ end of vl-remove-if-not
  7.                            ) ;_ end of mapcar
  8.         (vl-catch-all-apply
  9.           (function
  10.             (lambda ()
  11.               (vla-delete (vlax-ename->vla-object scale))
  12.               ) ;_ end of lambda
  13.             ) ;_ end of function
  14.           ) ;_ end of vl-catch-all-apply
  15.       ) ;_ end of foreach
  16.     )
Код выдран "с мясом" из другого проекта. А очистка, в частности, у меня на сайте рассматривалась: http://autolisp.ru/2014/03/24/clear-dwg-at-opening/
Все, что сказано - личное мнение.

Правила форума существуют не просто так!

Приводя в сообщении код, не забывайте про его форматирование!

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Александр, я читал это. Просто, как я уже написал, я натолкнулся на статью Алексея про реакторы с фразой "Если "с ножом к горлу" надо использовать командную строку (бывает такое), то следует использовать механизм vla-sendcommand для текущего документа", вот и появилась надежда  ::)
Если Алексей скажет, что такое невозможно, значит не судьба и обойдёмся алертом...
Код будет запущенный SendCommand будет выполнен уже после сохранения файла. Соотвественно его придётся сохранить повторно. Если обработчик BeginSave сработал при закрытии документа, то SendCommand отправит команду неизвестно куда, и документ будет уже закрыт, так что сохранить его в очищенном виде будет невозможно.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Подшиваленко Дмитрий

  • ADN Club
  • **
  • Сообщений: 64
  • Карма: 0
Не уверен, что сегодня успею хоть что-то сделать...
Очистка масштабов аннотаций может быть выполнена и без команд:
Алексей, как будет время, естественно :)
Главное, чтобы этот лисп был аналогичен команде (command "_-scalelistedit" "_d" "*" "_e"), то есть очистке именно неиспользуемых масштабов, а не полному сбросу масштабов, как это делает автокад по-умолчанию при большом количестве масштабов аннотаций.
Код выдран "с мясом" из другого проекта. А очистка, в частности, у меня на сайте рассматривалась: http://autolisp.ru/2014/03/24/clear-dwg-at-opening/
Кстати, как я и писал в этой ветке, принудительная очистка словаря AcDgnLS чревата определёнными последствиями для тех, кто умудряется использовать типы линий DGN (понимаю, что таких случаев может быть мало, но, тем не менее, я напоролся).
Код будет запущенный SendCommand будет выполнен уже после сохранения файла
Алексей же вроде написал, что можно чистить масштабы лиспом... ::)
« Последнее редактирование: 12-05-2016, 12:04:55 от Подшиваленко Дмитрий »

Оффлайн Алексей Кулик

  • Administrator
  • *****
  • Сообщений: 1096
  • Карма: 172
Александр предупредил о возникающих проблемах (возможно, даже фатальных ;)).
Все, что сказано - личное мнение.

Правила форума существуют не просто так!

Приводя в сообщении код, не забывайте про его форматирование!

Оффлайн Подшиваленко Дмитрий

  • ADN Club
  • **
  • Сообщений: 64
  • Карма: 0
Очистка масштабов аннотаций может быть выполнена и без команд:
Алексей, этот лисп удаляет ВСЕ масштабы аннотаций, даже используемые. Так не надо. Надо именно неиспользуемые, или тогда никак, только алерт.
Кстати, если после выполнения этого лиспа зайти в список масштабов, то акад валится с Fatal Error. Проверил 3 раза.
« Последнее редактирование: 12-05-2016, 15:24:20 от Подшиваленко Дмитрий »

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Алексей, этот лисп удаляет ВСЕ масштабы аннотаций, даже используемые. Так не надо. Надо именно неиспользуемые,...
Снова упираемся в ограничения lisp. В нём нет средств проверки "используется/не используется". Нужно сканировать всё базу чертежа.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Подшиваленко Дмитрий

  • ADN Club
  • **
  • Сообщений: 64
  • Карма: 0
Поскольку Алексей, как я понял, немного подзабросил эту тему, пришлось ковыряться самому.
Получился следующий код для реактора с очисткой масштабов:
Код - Auto/Visual Lisp [Выбрать]
  1. (vl-load-com)
  2. (load "check-dict2.lsp") ;функция отсюда: http://adn-cis.org/forum/index.php?topic=709.msg20101#msg20101
  3.  
  4. (if *adn-vlr-cmd*
  5.   (progn (vl-remove *adn-vlr-cmd*) (setq *adn-vlr-cmd* nil))
  6. ) ;_ end of if
  7.  
  8. (if (not *adn-vlr-cmd*)
  9.   (setq *adn-vlr-cmd* (vlr-command-reactor "adn-cmd-reactor" '((:vlr-commandwillstart . _adn-vlr-cmd-start))))
  10. ) ;_ end of if
  11.  
  12. (defun _adn-vlr-cmd-start (react cmd / datas)
  13.  (setq cmd (strcase (car cmd)))
  14.  (cond
  15.   ((member cmd '("QSAVE" "SAVE" "SAVEAS"))
  16.    (setq sc (check-dict2 nil "ACAD_SCALELIST"))
  17.    (if (> sc 100)
  18.     (progn
  19.      (vla-sendcommand (vla-get-activedocument(vlax-get-acad-object)) (strcat "_-scalelistedit _d" "\r" "*" "\r" "_e" "\r")) ;Очистка неиспользуемых масштабов аннотаций
  20.      (vla-sendcommand (vla-get-activedocument(vlax-get-acad-object)) "_QSAVE ") ;сохраняем, ибо очистка происходит после выполнения команды сохранения
  21.      (alert (strcat "ВНИМАНИЕ! Этот чертёж содержал "(itoa sc)" масштабов аннотаций. НЕИСПОЛЬЗУЕМЫЕ масштабы были удалены!"))
  22.     ) ;progn
  23.    ) ;if sc
  24.    (setq dg (check-dict2 nil "ACAD_DGNLINESTYLECOMP"))
  25.    (if (> dg 10000) (alert (strcat "ВНИМАНИЕ! Этот чертёж содержит "(itoa dg)" объектов DGN. Необходима очистка!")))
  26.   )
  27.  ) ;_ end of cond
  28. ) ;_ end of defun
Код потестил, вроде рабочий.
Алексей, если я где-то накосячил в коде, поправь, пожалуйста.
И маленькая просьба напоследок.
Можешь написать отдельно функцию определения количества записей символьной таблицы, наподобие функции check-dict2 ? (в последнем коде у тебя подсчёт присутствует вроде).

Оффлайн Алексей Кулик

  • Administrator
  • *****
  • Сообщений: 1096
  • Карма: 172
Я не забил и не забыл, просто работы была тьма.
В твоем коде ты получишь бесконечный цикл, скорее всего: реактор срабатывает на начало вызова (помимо всего прочего) _qsave, внутри него ты снова вызываешь _qsave и т.д. Далее - ты вводишь соответствующие ограничения прямо в код. С моей точки зрения, это не самое лучшее решение. Идеальным был бы вариант выноса этого богатства во внешний настроечный файл, откуда все и считывается. Но дело твое ;)
P.S. ИМХО код должен быть наподобие:
Код - Auto/Visual Lisp [Выбрать]
  1. (vl-load-com)
  2.  
  3. (defun check-dict2 (doc name / dict)
  4.   ;; doc - Документ (nil - текущий)
  5.   ;; name - имя словаря
  6.   (if (and name
  7.            (= (type (setq dict (vl-catch-all-apply
  8.                                  (function (lambda ()
  9.                                              (vla-item (vla-get-dictionaries
  10.                                                          (cond (doc)
  11.                                                                (t (vla-get-activedocument (vlax-get-acad-object)))
  12.                                                                ) ;_ end of cond
  13.                                                          ) ;_ end of vla-get-dictionaries
  14.                                                        name
  15.                                                        ) ;_ end of vla-item
  16.                                              ) ;_ end of lambda
  17.                                            ) ;_ end of function
  18.                                  ) ;_ end of vl-catch-all-apply
  19.                           ) ;_ end of setq
  20.                     ) ;_ end of type
  21.               'vla-object
  22.               ) ;_ end of =
  23.            (vlax-property-available-p dict 'count)
  24.            ) ;_ end of and
  25.     (vla-get-count dict)
  26.     ) ;_ end of if
  27.   ) ;_ end of defun
  28.  
  29. (if *adn-vlr-cmd*
  30.   (progn (vlr-remove *adn-vlr-cmd*) (setq *adn-vlr-cmd* nil))
  31.   ) ;_ end of if
  32.  
  33. (if (not *adn-vlr-cmd*)
  34.   (setq *adn-vlr-cmd* (vlr-command-reactor "adn-cmd-reactor" '((:vlr-commandwillstart . _adn-vlr-cmd-start))))
  35.   ) ;_ end of if
  36.  
  37. (defun _adn-vlr-cmd-start (react cmd / datas)
  38.   (setq cmd (strcase (car cmd)))
  39.   (cond ((member cmd '("QSAVE" "SAVE" "SAVEAS"))
  40.          (if (> (setq datas (check-dict2 nil "ACAD_SCALELIST")) 100)
  41.            (progn (vla-sendcommand
  42.                     (vla-get-activedocument (vlax-get-acad-object))
  43.                     (strcat "_-scalelistedit _d" "\r" "*" "\r" "_e" "\r")
  44.                     ) ;Очистка неиспользуемых масштабов аннотаций
  45.                   (alert (strcat "ВНИМАНИЕ! Этот чертёж содержал "
  46.                                  (itoa sc)
  47.                                  " масштабов аннотаций. НЕИСПОЛЬЗУЕМЫЕ масштабы были удалены!"
  48.                                  ) ;_ end of strcat
  49.                          ) ;_ end of alert
  50.                   ) ;_ end of progn
  51.            ) ;_ end of if
  52.          (if (> (setq datas (check-dict2 nil "ACAD_DGNLINESTYLECOMP")) 10000)
  53.            (alert (strcat "ВНИМАНИЕ! Этот чертёж содержит " (itoa datas) " объектов DGN. Необходима очистка!"))
  54.            ) ;_ end of if
  55.          )
  56.         ) ;_ end of cond
  57.   ) ;_ end of defun
P.P.S. Будь время и возможность, я бы попробовал вообще выдавать запрос - вычищать сразу DgnLs или нет. Вообще говоря, вариантов тут тьма, вплоть до хранения соответствующих настроек в реестре ;)
Все, что сказано - личное мнение.

Правила форума существуют не просто так!

Приводя в сообщении код, не забывайте про его форматирование!

Оффлайн Алексей Кулик

  • Administrator
  • *****
  • Сообщений: 1096
  • Карма: 172
функцию определения количества записей символьной таблицы
То есть? Уточни, плиз.
Все, что сказано - личное мнение.

Правила форума существуют не просто так!

Приводя в сообщении код, не забывайте про его форматирование!

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
То есть? Уточни, плиз.
Я думаю имеется в вижу таблица слоёв, блоков, типов линий, зарегистрированных приложений и т.д.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Алексей Кулик

  • Administrator
  • *****
  • Сообщений: 1096
  • Карма: 172
Ну, количество записей в этих таблицах не показатель ИМХО. Текстовые / размерные / табличные стили - да, можно, в принципе, прошерстить. Но информировать о превышении какого-то предельного числа, не предлагая ничего взамен - немного неразумно. А проходить по всей базе чертежа, исправляя "кривые" элементы - это задача точно не для лиспа. Мультилинии и мультивыноски - аналогично. Блоки? Количество описаний блоков еще ни о чем не говорит.
Все, что сказано - личное мнение.

Правила форума существуют не просто так!

Приводя в сообщении код, не забывайте про его форматирование!

Оффлайн Подшиваленко Дмитрий

  • ADN Club
  • **
  • Сообщений: 64
  • Карма: 0
Я не забил и не забыл, просто работы была тьма.
В твоем коде ты получишь бесконечный цикл, скорее всего
Бесконечный цикл не получится, потому что _qsave стоит внутри (if (> sc 100) ..). После очистки масштабов происходит сохранение и во второй раз условие уже не выполняется. В этом плане код как раз оттестирован. _QSAVE я добавил после того, как понял, что команда vla-sendcommand выполняется уже после сохранения (и даже после alert). Единственный вариант, когда можно получить бесконечный цикл - это если кто-то реально использует больше 100 масштабов аннотаций и они не очистятся, но думаю столько никто не использует. Зато я точно буду знать, что по команде сохранения файл был не только очищен, а ещё и сохранён.
P.S. ИМХО код должен быть наподобие:
Твой код не очень сильно отличается от моего (убрал сохранение), к тому же содержит мелкий огрех. Ты переименовал sc в datas, а в (itoa sc) не поправил.
P.P.S. Будь время и возможность, я бы попробовал вообще выдавать запрос - вычищать сразу DgnLs или нет.
Собственно говоря это уже сделано, только не в реакторе, а в acaddoc.lsp. Правда диалог написан немного жёсткий, в том плане, что на него нельзя ответить "нет", только выбор варианта очистки - корректная и быстрая (удаление словаря).
Я думаю имеется в вижу таблица слоёв, блоков, типов линий, зарегистрированных приложений и т.д.
Ну примерно так :)
Ну, количество записей в этих таблицах не показатель ИМХО. Текстовые / размерные / табличные стили - да, можно, в принципе, прошерстить. Но информировать о превышении какого-то предельного числа, не предлагая ничего взамен - немного неразумно. А проходить по всей базе чертежа, исправляя "кривые" элементы - это задача точно не для лиспа. Мультилинии и мультивыноски - аналогично. Блоки? Количество описаний блоков еще ни о чем не говорит.
В общем-то я много думал над этим... Пока что эту функцию хотел использовать для подсчёта RegApp, чтобы очищать их при превышении адекватного количества. Для остального - да, большой вопрос. Но универсальность бывает очень удобна, как в случае с check-dict2, так сказать на будущее :)

Оффлайн Алексей Кулик

  • Administrator
  • *****
  • Сообщений: 1096
  • Карма: 172
У тебя еще более интересная ошибка допущена: вместо vlr-remove поставлено vl-remove :)
Есть закон: если какая-то неприятность может случиться, она обязательно случится. Уточнение закона: такая неприятность обязательно случается в самый неподходящий момент.
Смотри, вариант 1: в файле до фига ссылок (пускай 20 шт., включая вложенные). Общий список аннотативных масштабов превышает все разумные пределы - а что делать? И тут при сохранении вываливается Fatal Error...
Или, вариант 2 - человек вызывает SAVEAS, планируя сохранить старый вариант. А тут ему: "Нна! Думал, что не сохранишь? А вот фига!". И как к коду будут относиться?

По поводу "табличных записей" - см. vla-get-textstyles, vla-get-dimstyles, потом понадобится смотреть словарь ACAD_TABLESTYLE, ACAD_MLINESTYLE и т.п.
Все, что сказано - личное мнение.

Правила форума существуют не просто так!

Приводя в сообщении код, не забывайте про его форматирование!

Оффлайн Подшиваленко Дмитрий

  • ADN Club
  • **
  • Сообщений: 64
  • Карма: 0
У тебя еще более интересная ошибка допущена: вместо vlr-remove поставлено vl-remove
Так это же твой кусок кода отсюда: http://adn-cis.org/forum/index.php?topic=709.msg20253#msg20253 :) Я его брал за основу :) Поправить как у тебя в последнем коде?
Смотри, вариант 1: в файле до фига ссылок (пускай 20 шт., включая вложенные). Общий список аннотативных масштабов превышает все разумные пределы - а что делать? И тут при сохранении вываливается Fatal Error...
А как на такую ситуацию влияет _qsave в реакторе?
На всякий случай пишутся логи по очистке. Нашёлся файл, содержащий почти 60 тысяч (59489) масштабов аннотаций.
Или, вариант 2 - человек вызывает SAVEAS, планируя сохранить старый вариант. А тут ему: "Нна! Думал, что не сохранишь? А вот фига!". И как к коду будут относиться?
Ну будет старый вариант, только без огромного количества масштабов :) Нечего их плодить. И опять же как _qsave в реакторе повлияет на эту ситуацию, если в реакторе уже почистились масштабы?
Хотя в принципе _qsave можно и убрать из реактора во избежание других косяков, но тогда не будет уверенности, что сохранён очищенный файл.
Кстати, очистка масштабов сделана и при загрузке. И очень показательно, что один и тот же файл очистился сначала при загрузке, а потом реактором при сохранении, то есть во время работы он успел замусориться.
По поводу "табличных записей" - см. vla-get-textstyles, vla-get-dimstyles, потом понадобится смотреть словарь ACAD_TABLESTYLE, ACAD_MLINESTYLE и т.п.
Ну сделай отдельную функцию только подсчёта RegApp, если не сложно :)
P.S. Заремил _qsave в реакторе с комментарием "Алексей Кулик не одобрил" :)

Оффлайн Алексей Кулик

  • Administrator
  • *****
  • Сообщений: 1096
  • Карма: 172
Я очепятался, а ты не проверил )))
сделай отдельную функцию только подсчёта RegApp, если не сложно
Только их или потом опять будем добавлять функционал? Если только их - то в нужное место вставляй (setq datas (vla-get-count (vla-get-registeredapplications (vla-get-activedocument (vlax-get-acad-object))))) и обрабатывай полученный результат.
Все, что сказано - личное мнение.

Правила форума существуют не просто так!

Приводя в сообщении код, не забывайте про его форматирование!

Оффлайн Подшиваленко Дмитрий

  • ADN Club
  • **
  • Сообщений: 64
  • Карма: 0
Я очепятался, а ты не проверил )))
Чтобы проверить надо знать лисп :) Сейчас глянул разницу :)
Только их или потом опять будем добавлять функционал? Если только их - то в нужное место вставляй (setq datas (vla-get-count (vla-get-registeredapplications (vla-get-activedocument (vlax-get-acad-object))))) и обрабатывай полученный результат.
Да пока видимо только их, поскольку только они цепляются из ссылок и не чистятся стандартным диалогом purge.
Спасибо :)

Оффлайн Подшиваленко Дмитрий

  • ADN Club
  • **
  • Сообщений: 64
  • Карма: 0
Алексей, добрый день.
Снова нужна твоя небольшая помощь.
Всё-таки я решил добавить реактор на присоединение ссылок для очистки от масштабов и приложений.
В принципе я написал его самостоятельно, он рабочий, но есть одна небольшая засада.
Иногда при вставке ссылки обнаруживаются циклические ссылки, и автокад выдаёт запрос в командной строке "Обнаружены циклические ссылки. Продолжить?".
Если нужно почистить масштабы командой (vla-sendcommand (vla-get-activedocument(vlax-get-acad-object)) (strcat "_-scalelistedit _d" "\r" "*" "\r" "_e" "\r")), то акад пытается ответить на запрос строками из этой команды. Вариант решения - добавить в функцию обработки реактора команду (vla-sendcommand (vla-get-activedocument(vlax-get-acad-object)) (strcat "_y" "\r")). Это работает, но при отсутствии запроса акад соответственно пишет: Неизвестная команда "Y". Не критично, но не очень красиво.
Код - Auto/Visual Lisp [Выбрать]
  1. (vl-load-com)
  2. (if adn-vlr-xref (progn (vlr-remove adn-vlr-xref) (setq adn-vlr-xref nil)))
  3. (if (not adn-vlr-xref) (setq adn-vlf-xref (vlr-xref-reactor nil '((:vlr-endAttach . adn-vlr-xref-end)))))
  4.  
  5. (defun adn-vlr-xref-end (_r data / )
  6.  (vla-sendcommand (vla-get-activedocument(vlax-get-acad-object)) (strcat "_y" "\r"))
  7.  (setq ra (vla-get-count (vla-get-registeredapplications (vla-get-activedocument (vlax-get-acad-object)))))
  8.  (if (> ra ra_crit) (vla-sendcommand (vla-get-activedocument(vlax-get-acad-object)) (strcat "_.-purge _r" "\r" "*" "\r" "_n" "\r")))
  9.  (setq sc (check-dict nil "ACAD_SCALELIST"))
  10.  (if (> sc sc_crit) (vla-sendcommand (vla-get-activedocument(vlax-get-acad-object)) (strcat "_-scalelistedit _d" "\r" "*" "\r" "_e" "\r")))
  11. )
Есть ли возможность отключить запрос на загрузку циклических ссылок (чтобы по-умолчанию было всегда "Да")? Лиспом, как я понимаю, отловить появление этого запроса не получится, ибо запрос появляется после окончания функции обработки реактора. Или я ошибаюсь?
В инете долго рылся, ничего адекватного не нашёл. В общем если будет время, ответь, пожалуйста  :)

Оффлайн Алексей Кулик

  • Administrator
  • *****
  • Сообщений: 1096
  • Карма: 172
Как-то не сталкивался с ситуацией циклических ссылок... Встречался с ними, но только в Excel. Как они вообще возникают? Я пробовал когда-то подобное сотворить, но AutoCAD мне не дал возможности вставить циклическую ссылку. Можно пример (хотя бы на словах описать последовательность создания)?
Все, что сказано - личное мнение.

Правила форума существуют не просто так!

Приводя в сообщении код, не забывайте про его форматирование!

Оффлайн Подшиваленко Дмитрий

  • ADN Club
  • **
  • Сообщений: 64
  • Карма: 0
Открываешь файл Свет или Канализация и подключаешь к нему Сводный план сетей.dwg.
Файлы тестовые, с одной надписью. В коде можно убрать проверки и оставить одни команды очистки для теста.
Идея циклических ссылок в том, что файл №1 ссылается файл №2, а файл №2 ссылается файл №1, при этом тип ссылки должен быть "вставленная".
Самая простая последовательность действий:
В файл №1 (например Сводный план сетей) подключаешь файл №2 (например Вода), тип ссылки "вставленная". Потом в файл №2 (Вода) подключаешь файл №1 (Сводный план сетей), при этом тип ссылки уже не важен.

Оффлайн Алексей Кулик

  • Administrator
  • *****
  • Сообщений: 1096
  • Карма: 172
В файле "Вода" уже идет циклическая ссылка. То есть человек сознательно создал эту ситуацию.
В качестве идеи могу предложить следующее: в начале вставки ссылки открывать каждый файл через ObjectDBX, проверять внутри этого документа ссылки, снова открывать и составлять список ссылок. И анализировать его.
Код получится достаточно длинный и замороченный, вдобавок я не уверен в эффективности такого подхода. Попробовать что-либо сотворить смогу только в среду, не раньше :(
Все, что сказано - личное мнение.

Правила форума существуют не просто так!

Приводя в сообщении код, не забывайте про его форматирование!

Оффлайн Подшиваленко Дмитрий

  • ADN Club
  • **
  • Сообщений: 64
  • Карма: 0
Ну если очень сложно, то может и не надо? Переживёт народ неопознанную команду "Y" :)
Я думал может можно отключить сам запрос на циклические ссылки.

Оффлайн Подшиваленко Дмитрий

  • ADN Club
  • **
  • Сообщений: 64
  • Карма: 0
Всё-таки народ напрягает неопознанная команда "Y". Пришлось пока что отключить реактор на ссылки :(
Алексей, а нет более простого способа избавиться от запроса "Обнаружены циклические ссылки. Продолжить?" ?
Может можно в реакторе проверить командную строку на наличие такого запроса и если он есть ответить "_Y" ?
Ну или что-то сделать, чтобы этот запрос не выводился, а по-умолчанию файлы с циклическими ссылками грузились всегда?

Оффлайн Алексей Кулик

  • Administrator
  • *****
  • Сообщений: 1096
  • Карма: 172
Как раз сейчас пробую написать код :)
Все, что сказано - личное мнение.

Правила форума существуют не просто так!

Приводя в сообщении код, не забывайте про его форматирование!

Оффлайн Алексей Кулик

  • Administrator
  • *****
  • Сообщений: 1096
  • Карма: 172
По первым прикидкам вроде работает
Все, что сказано - личное мнение.

Правила форума существуют не просто так!

Приводя в сообщении код, не забывайте про его форматирование!

Оффлайн Подшиваленко Дмитрий

  • ADN Club
  • **
  • Сообщений: 64
  • Карма: 0
По первым прикидкам вроде работает
Спасибо. Потестирую недельки через 3, после отпуска :)

Оффлайн Подшиваленко Дмитрий

  • ADN Club
  • **
  • Сообщений: 64
  • Карма: 0
Доброго дня всем :)
Снова нужна ваша небольшая помощь :)
В общем с реактором на присоединение ссылок было почти всё хорошо, пока не обнаружились некоторые негативные моменты (в особенности сборка комплекта в zip происходит очень долго, ибо акад грузит ссылки и каждую чистит).
Появилась мысль сделать реактор на закрытие. Написал, потестил. Он работает, чистит и сохраняет чертёж после очистки, но есть один момент!
При нажатии на крестик (закрытие файла) до начала работы реактора на закрытие появляется диалог с запросом о сохранении изменений. Можно ли как-нибудь отловить ответ в этом диалоге и передать его реактору на закрытие, чтобы чистить и сохранять чертёж только при ответе "Да"?
Пока в реакторе сделано безусловное сохранение и чертёж сохраняется при любом ответе...
На всякий случай код реактора (в сильном сокращении):
Код - Auto/Visual Lisp [Выбрать]
  1. (if adn-vlr-close (progn (vlr-remove adn-vlr-close) (setq adn-vlr-close nil)))
  2. (if (not adn-vlr-close) (setq adn-vlr-close (VLR-Editor-Reactor nil '((:vlr-beginClose . vlr-close)))))
  3.  
  4. (defun vlr-close (_r data / )
  5.  (vla-sendcommand (vla-get-activedocument(vlax-get-acad-object)) (strcat "_.-purge _r" "\r" "*" "\r" "_n" "\r"))
  6.  (vla-sendcommand (vla-get-activedocument(vlax-get-acad-object)) (strcat "_qsave" "\r"))
  7. )

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Можно ли как-нибудь отловить ответ в этом диалоге и передать его реактору на закрытие, чтобы чистить и сохранять чертёж только при ответе "Да"?
В VisualLisp/AutoLisp??? Нет конечно. Тут нужны Windows hooks, на которые лисп не способен.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Алексей Кулик

  • Administrator
  • *****
  • Сообщений: 1096
  • Карма: 172
Вообще-то я бы не стал в реакторах использовать команды...
Все, что сказано - личное мнение.

Правила форума существуют не просто так!

Приводя в сообщении код, не забывайте про его форматирование!

Оффлайн Подшиваленко Дмитрий

  • ADN Club
  • **
  • Сообщений: 64
  • Карма: 0
В VisualLisp/AutoLisp??? Нет конечно. Тут нужны Windows hooks, на которые лисп не способен.
Печаль :(
Вообще-то я бы не стал в реакторах использовать команды...
Алексей, твою позицию по этому вопросу я помню. Тем не менее другого способа избавиться именно от неиспользуемых масштабов и зарег. приложений, кроме как очистка командой в реакторе, не было найдено/предложено. Напомню, масштабы и зарег. прил. перетекают в текущий чертёж из ссылочного файла (при подключении ссылки). Уже хочется пнуть автодеск, чтобы они сделали возможность отключения перетекания этого барахла из ссылок.

Оффлайн Алексей Кулик

  • Administrator
  • *****
  • Сообщений: 1096
  • Карма: 172
Очистка зарегистрированных приложений:
Код - Auto/Visual Lisp [Выбрать]
  1. (vlax-for app (vla-get-registeredapplications (vla-get-activedocument (vlax-get-acad-object)))
  2.   (vl-catch-all-apply (function (lambda () (vla-delete app))))
  3.   ) ;_ end of vlax-for
И про очистку масштабов аннотаций тоже были подобные решения, мне кажется.
Все, что сказано - личное мнение.

Правила форума существуют не просто так!

Приводя в сообщении код, не забывайте про его форматирование!

Оффлайн Подшиваленко Дмитрий

  • ADN Club
  • **
  • Сообщений: 64
  • Карма: 0
И про очистку масштабов аннотаций тоже были подобные решения, мне кажется.
Нужно чистить именно неиспользуемые масштабы и приложения. Прочитав эту ветку заново, нашёл фразу о том, что лисп на такое не способен.

Оффлайн Алексей Кулик

  • Administrator
  • *****
  • Сообщений: 1096
  • Карма: 172
Теоретически можно попытаться очистить записи в словаре ACAD_SCALELIST, но я не уверен в корректности конечного результата. Надо пробовать, а у меня сейчас другой работы многовато :(
Все, что сказано - личное мнение.

Правила форума существуют не просто так!

Приводя в сообщении код, не забывайте про его форматирование!

Оффлайн Подшиваленко Дмитрий

  • ADN Club
  • **
  • Сообщений: 64
  • Карма: 0
Теоретически можно попытаться очистить записи в словаре ACAD_SCALELIST, но я не уверен в корректности конечного результата. Надо пробовать, а у меня сейчас другой работы многовато
Так это опять же полная очистка словаря. Вся страница 4 этой ветки посвещена тому, что на лиспе нельзя создать механизм очистки неиспользуемых элементов словаря.
А так же:
Снова упираемся в ограничения lisp. В нём нет средств проверки "используется/не используется". Нужно сканировать всё базу чертежа.

Оффлайн Алексей Кулик

  • Administrator
  • *****
  • Сообщений: 1096
  • Карма: 172
Хорошо, уговорил :) Не стану спорить.
P.S. На прошлой работе очистку масштабов аннотаций я повесил на "загрузку" документа. Там команды применять можно совершенно спокойно.
Все, что сказано - личное мнение.

Правила форума существуют не просто так!

Приводя в сообщении код, не забывайте про его форматирование!

Оффлайн Подшиваленко Дмитрий

  • ADN Club
  • **
  • Сообщений: 64
  • Карма: 0
P.S. На прошлой работе очистку масштабов аннотаций я повесил на "загрузку" документа. Там команды применять можно совершенно спокойно.
Так на загрузке она и так у меня висит. Проблема в том, что при подключении ссылки они опять липнут и толку от того что ты их почистил при загрузке никакого :( Поэтому и пошла тема реакторов.
Собственно vla-sendcommand нормально отрабатывает в реакторе на событие vlr-beginClose. Он посылает команду как раз не в никуда, а в чертёж перед событием vlr-beginSave. Вот только бы отловить значение этого диалога... Но до хуков мне далеко... Почитал про них уже...
Блин, по-ходу vla-sendcommand не перед vlr-beginSave. Была мысль убрать команду сохранения в реакторе, оставить очистку, а акад уже сам сохранит очищенный файл. Не прокатило. Чистит, но не сохраняет :(
« Последнее редактирование: 16-02-2018, 15:07:41 от Подшиваленко Дмитрий »

Оффлайн Алексей Кулик

  • Administrator
  • *****
  • Сообщений: 1096
  • Карма: 172
А если использовать vla-save? :) Правда, как быть с абсолютно новым файлом - еще вопрос.
Все, что сказано - личное мнение.

Правила форума существуют не просто так!

Приводя в сообщении код, не забывайте про его форматирование!

Оффлайн Подшиваленко Дмитрий

  • ADN Club
  • **
  • Сообщений: 64
  • Карма: 0
А если использовать vla-save?  Правда, как быть с абсолютно новым файлом - еще вопрос.
Так вопрос в том, что надо сохранять (да и чистить тоже) только при ответе "Да" в диалоге на закрытие. А это, как сказал Александр, только хуками ловить. Я думал, может есть реактор какой-нибудь на тему этих диалоговых окон, но не нашёл.

Оффлайн Подшиваленко Дмитрий

  • ADN Club
  • **
  • Сообщений: 64
  • Карма: 0
Очистка зарегистрированных приложений:
Код - Auto/Visual Lisp [Выбрать]
  1. (vlax-for app (vla-get-registeredapplications (vla-get-activedocument (vlax-get-acad-object)))
  2.   (vl-catch-all-apply (function (lambda () (vla-delete app))))
  3.   ) ;_ end of vlax-for
И про очистку масштабов аннотаций тоже были подобные решения, мне кажется.
Решил потестить этот код. Сначала подумал что акад подвис. В итоге дождался. В общем код выполнялся 11 минут (для сравнения команда "purge _r" выполняется 22 секунды). Но результат заставил задуматься. С помощью ArxDbg (огромное спасибо Александру Ривилису) посмотрел содержимое RegApp Table. В принципе лисп оставил в ней почти то же самое, что и команда "purge _r", то есть вычистил неиспользуемые приложения (несколько штук не вычистил). Поэтому закралось сомнение в утверждении Александра о том, что на лиспе нельзя очищать неиспользуемые элементы.
Алексей, огромная просьба, если вдруг вспомнишь где были такие решения, кинь, пожалуйста, ссылку, буду очень благодарен :)
На моей памяти все решения, которые я находил, приводили к полному сбросу списка масштабов (и внедрению своих). Такой у меня есть. Нужен лисп, который бы давал результат, аналогичный команде (command "_-scalelistedit" "_d" "*" "_e"), то есть очищал именно неиспользуемые масштабы аннотаций.
Естественно это не горит :)
Понимаю, что мы тут уже не совсем в теме, поэтому создал ветку http://forum.dwg.ru/showthread.php?p=1712142#post1712142.

Оффлайн Подшиваленко Дмитрий

  • ADN Club
  • **
  • Сообщений: 64
  • Карма: 0
Нарыл https://forums.autodesk.com/t5/autocad-civil-3d-customization/scale-list-cleanup-lisp/td-p/5645436
Взял оттуда очистку ссылочных масштабов, повесил на реактор команды закрытия. Всё работает как надо :) Всем огромное спасибо :)

Оффлайн axl_slash

  • ADN OPEN
  • Сообщений: 2
  • Карма: 0
Ребята, всем привет! Прошу помощи, есть файлы (ссылка на один из них https://cloud.mail.ru/public/AFBc/zZCknLJSH) которые дико тормозят и чистки которые вшиты в акад18 и двг пурж и чистка лиспом прокси никак не помогают. Если начертить полилинию и начать двигать контрольную точку, то комп начинает просто висеть, особенно когда это файл сборки состоящий из нескольких (внешние ссылки) подобных файлов с большим размером. В чём проблема то?

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
axl_slash,
1. К данной теме этот вопрос не имеет никакого отношения, т.к. никаких типов линий DGN в чертеже нет. Поэтому обсуждаться здесь этот вопрос больше не будет.
2. Деинсталлируй SPDS Extension и проверь как работает. У меня никаких "тормозов" при изменении положения ручек полилинии не возникает.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн axl_slash

  • ADN OPEN
  • Сообщений: 2
  • Карма: 0
Спасибо за оперативный ответ. К сожалению не помогло. попробую в другом разделе задать вопрос