Autocad - автоматическое обновление сгенерированного поля lisp (счетчик макетов)

Задача: иметь счетчик листов для использования в полях, которые автоматически обновляют свои значения. Конечной целью является создание текста типа "Таблица {1} из {5}" для каждого макета, где {1} – это имя макета (находится в system variables / ctab), а {5} – общее количество макетов. Последний не встречается во встроенных полях, поэтому единственный способ узнать его — использовать код (length (layoutlist)) на лиспе.

Я создал файл AcadDoc.lsp и поместил его в папку Autodesk. Код LISP выглядит следующим образом:

    (setq *LayoutCount* 
     (length 
      (vl-remove-if 
       (function 
        (lambda (aLayout) (= (strcase aLayout) "MODEL"))) 
      (layoutlist))))

который запускается каждый раз, когда я открываю файл DWG. Печально то, что поле не обновляется до тех пор, пока DWG не будет перезагружен (закрыт и снова открыт). Кто-нибудь знает, как обновлять эту переменную *LayoutCount* каждый раз, когда макет добавляется/удаляется из списка?

NB - я уже проверил возможность регенерации при переключении макетов, и принудительное обновление полей не дало результатов. Я предполагаю, что мой код запускается только при первом открытии DWG, а затем не более.


person Nereo Costacurta    schedule 11.08.2019    source источник


Ответы (1)


Как вы поняли, код, присутствующий в файле acaddoc.lsp, будет оцениваться только при запуске чертежа, поэтому значение вашей переменной *LayoutCount* будет правильным только в момент, когда чертеж впервые открыт.

Одним из возможных способов обойти это может быть использование Visual LISP Reactor для обновления значения этой переменной после определенных действий.

Например, вы можете использовать Miscellaneous Reactor следующим образом для обновления значения переменной при изменении активного макета:

(
    (lambda ( )
        (vl-load-com)
        (foreach grp (vlr-reactors :vlr-miscellaneous-reactor)
            (foreach rtr (cdr grp)
                (if (= "layoutcount-reactor" (vlr-data rtr))
                    (vlr-remove rtr)
                )
            )
        )
        (vlr-set-notification
            (vlr-miscellaneous-reactor "layoutcount-reactor"
               '(
                    (:vlr-layoutswitched . layoutswitched-callback)
                )
            )
            'active-document-only
        )
        (defun layoutswitched-callback ( rtr arg )
            (setq *layoutcount* (length (layoutlist)))
        )
        (layoutswitched-callback nil nil)
        (princ)
    )
)

Скопируйте приведенный выше код в acaddoc.lsp, и переменная *layoutcount* будет определена при запуске чертежа и будет обновляться каждый раз при изменении активного макета.

Кроме того, нет необходимости удалять Model из списка, возвращаемого функцией layoutlist, так как эта функция возвращает только список макетов Paperspace.


Однако недостатком использования глобальных переменных для предоставления этой информации является то, что глобальная переменная будет определена в пространстве имен документа только во время активного сеанса AutoCAD, и ее потребуется переопределять для каждого сеанса<. /сильный>.

Таким образом, если один из ваших коллег или третье лицо откроет файл чертежа, если они также не запустили код, найденный в вашем acaddoc.lsp, переменная *layoutcount* не будет определена, и, следовательно, поле не будет отображаться правильно.

Таким образом, альтернативой является использование того факта, что выражение поля может фактически ссылаться на любое свойство ActiveX, а не только на те, которые отображаются в диалоговом окне команды FIELD.

Я демонстрирую эту технику на своем приложении Layout Field, которое позволяет вам создать выражение поля, ссылающееся на Count свойство коллекции макетов.

Этот подход имеет несколько преимуществ:

  • Содержимое чертежа не зависит от какого-либо внешнего кода.
  • Системная переменная CTAB не указана, что означает, что команда DATAEXTRACTION выведет правильную информацию, а не одно и то же значение для каждого макета.
person Lee Mac    schedule 11.08.2019
comment
впечатляющий! вы ответили действительно быстрее, чем кто-либо, кого я когда-либо видел. большое спасибо, очень четкий и кристальный ответ. не знаю, почему поисковые системы не привели меня сразу к вашему приложению! можете ли вы сказать мне, позволяет ли ваше приложение добавлять поле в mtext? или это просто как гифка и редактировать весь текст? - person Nereo Costacurta; 11.08.2019
comment
неважно, я только что видел код: нет проблем с редактированием текста в корневом коде или после его размещения. - person Nereo Costacurta; 11.08.2019
comment
Добро пожаловать! Спасибо также за положительный отзыв. Дайте мне знать, если вам нужна дополнительная помощь в использовании программы/кода. - person Lee Mac; 11.08.2019