Тема: LISP, DCL. Нумерация листов в штампах и названиях layout(a)

Файл программы z_layout_number.lsp

;| ********************************************
* Нумерация листов в штампах и названиях layout(a)
* Штамп должен быть блоком с атрибутом с тэгом "PAGE" или "ЛИСТ"
* Вызов:
* командная строка: z-layout-number
* меню или кнопка: ^C^C_z-layout-number
*
* Copyright ?2005
*           Виталий Зуенко (ZZZ)
*
***********************************************|;
(defun c:z-layout-number (/          dcl_id      what_next
              l_layout    t_nstart      t_ncount
              tg_layout   tg_page      layout_lst
              layout      n          ss
              ent          obj      string
              _z_number_mask
              )
;;;  Функция формирования целого числа по маске
  (defun _z_number_mask    (integer number_count / string)
    (setq string (itoa integer))
    (if    (< (strlen string) number_count)
      (strcat (substr "000000000" 1 (- number_count (strlen string)))
          string
          ) ;_ strcat
      string
      ) ;_ if
    ) ;_ defun
  (vl-load-com)
  (vla-StartUndoMark (vla-Get-ActiveDocument (vlax-Get-Acad-Object)))
  (setvar "cmdecho" 0)
;;;  Составление списка листов
  (setq    layout_lst
     (mapcar
       'car
       (vl-sort
         (mapcar
           '(lambda
          (layout)
           (cons layout
             (vla-get-taborder
               (vla-item
                 (vla-get-layouts
                   (vla-get-activedocument
                 (vlax-get-acad-object)
                 ) ;_ vla-get-activedocument
                   ) ;_ vla-get-layouts
                 layout
                 ) ;_ vla-item
               ) ;_ vla-get-taborder
             ) ;_ cons
           ) ;_ lambda
           (layoutlist)
           ) ;_ mapcar
         '(lambda (a1 a2) (< (cdr a1) (cdr a2)))
         ) ;_ vl-sort
       ) ;_ mapcar
    ) ;_ setq
;;;  Подготовка и вызов диалогового окна
  (setq l_layout "")
  (setq t_nstart "1")
  (setq t_ncount "2")
  (setq tg_layout "1")
  (setq tg_page "1")
  (setvar "cmdecho" 0)
  (setq what_next 10)
  (while (> what_next 1)
    (setq dcl_id (load_dialog "z_layout_number"))
    (if    (null (new_dialog "z_layout_number" dcl_id))
      (progn
    (alert "Dialog box not found")
    (exit)
    ) ;_ progn
      ) ;_ if
    (action_tile "l_layout" "(setq l_layout $value)")
    (start_list "l_layout")
    (mapcar 'add_list layout_lst)
    (end_list)
    (set_tile "l_layout" l_layout)
    (action_tile "t_nstart" "(setq t_nstart $value)")
    (set_tile "t_nstart" t_nstart)
    (action_tile "t_ncount" "(setq t_ncount $value)")
    (set_tile "t_ncount" t_ncount)
    (action_tile "tg_layout" "(setq tg_layout $value)")
    (set_tile "tg_layout" tg_layout)
    (action_tile "tg_page" "(setq tg_page $value)")
    (set_tile "tg_page" tg_page)
    (setq what_next (start_dialog))
    (if    (= what_next 1)
      (cond ((= l_layout "")
         (alert "Выберите листы")
         (setq what_next 10)
         )
        ((and (= tg_layout "0") (= tg_page "0"))
         (alert "Выберите где нумеровать")
         (setq what_next 10)
         )
        ) ;_ cond
      ) ;_ if
    ) ;_ while
;;;  Завершение диалога
  (done_dialog)
  (unload_dialog dcl_id)
;;;  Обработка введённых условий
  (if (= what_next 1)
    (progn
      (setq layout_lst
         (mapcar '(lambda (n) (nth (atoi n) layout_lst))
             (z-string-list-separator " " l_layout)
             ) ;_ mapcar
        ) ;_ setq
      (setq n (atoi t_nstart))
;;;      Нумерация в штампе
;;;      штамп должен быть блоком и содержать атрибут с тегом "PAGE" или "ЛИСТ"
      (if (= tg_page "1")
    (foreach layout    layout_lst
      (if (setq
        ss (ssget
             "x"
             (list
               '(0 . "INSERT")
               '(66 . 1)
               (cons 410
                 (nth (- n (atoi t_nstart)) layout_lst)
                 ) ;_ cons
               ) ;_ list
             ) ;_ ssget
        ) ;_ setq
        (foreach ent
             (vl-remove-if
               '(lambda (a) (listp a))
               (mapcar 'cadr (ssnamex ss))
               ) ;_ vl-remove-if
          (while (setq ent (entnext ent))
        (if (or(= (cdr (assoc 2 (entget ent))) "PAGE")
               (= (cdr (assoc 2 (entget ent))) "ЛИСТ"))
          (progn
            (setq obj (vlax-ename->vla-object ent))
            (vla-put-textstring obj (itoa n))
            (vlax-release-object obj)
            ) ;_ progn
          ) ;_ if
        ) ;_ while
          ) ;_ foreach
        ) ;_ if
      (setq n (1+ n))
      ) ;_ foreach
    ) ;_ if
;;;      Нумерация названий листов(Layout)
      (setq n (atoi t_nstart))
      (if (= tg_layout "1")
    (foreach layout    layout_lst
      (setq    obj
         (vla-item
           (vla-get-layouts
             (vla-get-activedocument
               (vlax-get-acad-object)
               ) ;_ vla-get-activedocument
             ) ;_ vla-get-layouts
           layout
           ) ;_ vla-item
        ) ;_ setq
      (setq string (vla-get-name obj))
      (if (=
        (vl-string-left-trim "0123456789" string)
        (vl-string-left-trim
          " _"
          (vl-string-left-trim "0123456789" string)
          ) ;_ vl-string-left-trim
        ) ;_ =
        (setq string (strcat
               (_z_number_mask n (atoi t_ncount))
               " "
               string
               ) ;_ strcat
          ) ;_ setq
        (setq string
           (strcat
             (_z_number_mask n (atoi t_ncount))
             " "
             (vl-string-left-trim
               " "
               (vl-string-left-trim "0123456789" string)
               ) ;_ vl-string-left-trim
             ) ;_ strcat
          ) ;_ setq
        ) ;_ if
      (vla-put-name obj string)
      (vlax-release-object obj)
      (setq n (1+ n))
      ) ;_ foreach
    ) ;_ if
      (princ " OK ")
      ) ;_ progn
    ) ;_ if
  (vla-EndUndoMark (vla-Get-ActiveDocument (vlax-Get-Acad-Object)))
  (setvar "cmdecho" 1)
  (princ)
  ) ;_ defun
(defun z-string-list-separator (separator string /)
;| Преобразование строки в список строк разделенных неким символом-строкой разделителем |;
;;;(z-string-list-separator "12" "1234567890123456712341")
  (cond
    ((null string) nil)
    ((not (vl-string-search separator string)) (list string))
    (t
     (append
       (list
     (substr string 1 (+ 0 (vl-string-search separator string)))
     ) ;_ list
       (z-string-list-separator
     separator
     (substr
       string
       (+ 1 (strlen separator) (vl-string-search separator string))
       ) ;_ substr
     ) ;_ z-string-list-separator
       ) ;_ append
     )
    ) ;_ cond
  ) ;_ defun

Файл диалогового окна z_layout_number.dcl

z_layout_number : dialog {
    label = "Нумерация листов(layout)";
    :list_box{label="Лист";key="l_layout";multiple_select =true;}
    :edit_box{label="Номер начинается с";key="t_nstart";edit_width=3;fixed_width=true;width=30;}
    :edit_box{label="Количество цифр";key="t_ncount";edit_width=3;fixed_width=true;width=30;}
    :toggle{label="Нумеровать название листов";key="tg_layout";}
    :toggle{label="Нумеровать листы в штампе";key="tg_page";}
    ok_cancel;
    }

Re: LISP, DCL. Нумерация листов в штампах и названиях layout(a)

Вношу некоторые поправки.
Были проблемы с запуском программы, скопированной с форума, из-за переноса строк кода форматом форума. Для лиспа это не сильно важно, а для dcl, как оказалось, имеет большое значение. Привожу правельно отформатированный код для файла диалогового окна.
Файл диалогового окна z_layout_number.dcl

z_layout_number : dialog {
    label = "Нумерация листов(layout)";
    :list_box{
     label="Лист";
     key="l_layout";
     multiple_select =true;
     }
    :edit_box{
     label="Номер начинается с";
     key="t_nstart";
     edit_width=3;
     fixed_width=true;
     width=30;
     }
    :edit_box{
     label="Количество цифр";
     key="t_ncount";
     edit_width=3;
     fixed_width=true;
     width=30;
     }
    :toggle{
     label="Нумеровать название листов";
     key="tg_layout";
     }
    :toggle{
     label="Нумеровать листы в штампе";
     key="tg_page";
     }
    ok_cancel;
    }

Re: LISP, DCL. Нумерация листов в штампах и названиях layout(a)

ОГРОМНОЕ ЧЕЛОВЕЧЕСКОЕ СПАСИБО!!!!!!!!
Очень полезная программа! Все работает прекрасно!

Re: LISP, DCL. Нумерация листов в штампах и названиях layout(a)

Еще парочку команд для работы с листами
LISP. Копирование, сортировка, переименование листов (layout)

Re: LISP, DCL. Нумерация листов в штампах и названиях layout(a)

> ZZZ
1. объясните если штам не блоком как сделать номер листа ТЕГОМ? (тоесть обычный текст)
2. И как можно сделать к примеру если примечание данный лист смотреть совместно с листом Тег-1...Тег+1...,
буду благодарен за консультацию

Re: LISP, DCL. Нумерация листов в штампах и названиях layout(a)

на первый вопрос разобрался!

Re: LISP, DCL. Нумерация листов в штампах и названиях layout(a)

> ZZZ
как сделать dcl файл чтобы галочка никогда не стояла на функции
label="Нумеровать название листов";
а то случайно забыл убрать галочку и вся работа на смарку, лучше чтобы галочки не стояли, а то из за невнимательности приходится по два раза переделывать...

Re: LISP, DCL. Нумерация листов в штампах и названиях layout(a)

> Dextron3
(setq tg_layout "0")
~'J'~

Re: LISP, DCL. Нумерация листов в штампах и названиях layout(a)

> fixo
спасибо,
а есть чтонибудь что разбивает атрибуты, хочу когда на сторону отдавать разбивать их одним движением руки?

Re: LISP, DCL. Нумерация листов в штампах и названиях layout(a)

burst

Re: LISP, DCL. Нумерация листов в штампах и названиях layout(a)

> Кулик Алексей aka kpblc
нет это выбором, а мне нужно чтобы на всем чертеже сразу...

Re: LISP, DCL. Нумерация листов в штампах и названиях layout(a)

burst <enter> _all <enter>
Самое простое и безболезненное решение.

Re: LISP, DCL. Нумерация листов в штампах и названиях layout(a)

> Кулик Алексей aka kpblc
всетаки больно на душе когда случайно в оригинале это проделаешь... и заменишь им дубликат на выдачу, ...

Re: LISP, DCL. Нумерация листов в штампах и названиях layout(a)

> Кулик Алексей aka kpblc
можно сделать один атрибут чтобы количество листов всего показывал? чтобы на листе общих данных функционировал совместно с остальными, тогда было бы вообще супер!!!

Re: LISP, DCL. Нумерация листов в штампах и названиях layout(a)

Количество листов в подшивке или в текущем файле?

Re: LISP, DCL. Нумерация листов в штампах и названиях layout(a)

> Кулик Алексей aka kpblc
блочок который показывает максимальное число из использованных цыфр на лайауте, тоесть, если лайаутов (страниц) 19 то и показывает 19, обычно в проекте на титулке указывают количество чертежей, это было б не плохо, а то пректировщики не любят заполнять эту графу так цыфры постоянно меняются в проекте постоянно увеличивается количество чертежей, лучше ее поэтому не довать, а то попадется прорабу он посмотрит к примеру что там 14 листов а остальные на свои нужды возьмет, а так бы никогда не ошибся и не забыл в ставить заданное количество страниц автоматически....

Re: LISP, DCL. Нумерация листов в штампах и названиях layout(a)

У меня что то не всегда страбатывает, некоторые страницы так и остаются не перенумерованные...

Re: LISP, DCL. Нумерация листов в штампах и названиях layout(a)

Выдает ошибку такую:
Command: z-layout-number
Error:: ActiveX Server returned the error: unknown name: TextString
Command:
не могу сообразить из за чего...

Re: LISP, DCL. Нумерация листов в штампах и названиях layout(a)

(vl-load-com) загружен?

Re: LISP, DCL. Нумерация листов в штампах и названиях layout(a)

> Кулик Алексей aka kpblc
да если по одной в отдельности страницы нумерует а по много и  сразу нет...

Re: LISP, DCL. Нумерация листов в штампах и названиях layout(a)

Просто суперская програмка, пользуюсь ею уже третий год, не нарадуюсь!!!! Спасибо.

Re: LISP, DCL. Нумерация листов в штампах и названиях layout(a)

Добрый день. Подскажите такой вопрос, хотел подгрузить этот лисп в Автокад 2016, но он почему-то не работает. Вылазит ошибка  Dialog box not found. В чем может быть проблема? (в Автокаде 2012 лисп работает)

Re: LISP, DCL. Нумерация листов в штампах и названиях layout(a)

ZZZ пишет:

Вношу некоторые поправки.
Были проблемы с запуском программы, скопированной с форума, из-за переноса строк кода форматом форума. Для лиспа это не сильно важно, а для dcl, как оказалось, имеет большое значение. Привожу правельно отформатированный код для файла диалогового окна.
Файл диалогового окна z_layout_number.dcl

z_layout_number : dialog {
    label = "Нумерация листов(layout)";
    :list_box{
     label="Лист";
     key="l_layout";
     multiple_select =true;
     }
    :edit_box{
     label="Номер начинается с";
     key="t_nstart";
     edit_width=3;
     fixed_width=true;
     width=30;
     }
    :edit_box{
     label="Количество цифр";
     key="t_ncount";
     edit_width=3;
     fixed_width=true;
     width=30;
     }
    :toggle{
     label="Нумеровать название листов";
     key="tg_layout";
     }
    :toggle{
     label="Нумеровать листы в штампе";
     key="tg_page";
     }
    ok_cancel;
    }

Подскажите новичку, что с этим делать. Как мне запустить данные файлы. Я скопировал код в LISP. Сохранил 1-н файл с расширением LSP, другой как dwl. Зазгрузил 1-й в автокад через приложения. Второй загрузить не могу. И как их запустить

(изменено: AmiGO, 14 марта 2020г. 12:52:18)

Re: LISP, DCL. Нумерация листов в штампах и названиях layout(a)

На всякий случай напишу как общее количество листов вставить (выделенных в диалоговом окне).
В штампе, где количество листов указывают добавить поле %<\AcVar.17.0 Lisp.totallayouts>%
И добавить одну строчку в этой части программы (выделено красным):

;;;      штамп должен быть блоком и содержать атрибут с тегом "PAGE" или "ЛИСТ"
      (if (= tg_page "1")
   (foreach layout   layout_lst
     (if (setq
      ss (ssget
           "x"
           (list
             '(0 . "INSERT")
             '(66 . 1)
             (cons 410
              (nth (- n (atoi t_nstart)) layout_lst)
              ) ;_ cons
             ) ;_ list
           ) ;_ ssget
      ) ;_ setq
       (foreach ent
          (vl-remove-if
            '(lambda (a) (listp a))
            (mapcar 'cadr (ssnamex ss))
            ) ;_ vl-remove-if
         (while (setq ent (entnext ent))
      (if (or(= (cdr (assoc 2 (entget ent))) "PAGE")
             (= (cdr (assoc 2 (entget ent))) "ЛИСТ"))
        (progn
          (setq obj (vlax-ename->vla-object ent))
          (vla-put-textstring obj (itoa n))
          (vlax-release-object obj)
          ) ;_ progn
        ) ;_ if
      ) ;_ while
         ) ;_ foreach
       ) ;_ if
     (setq n (1+ n))
     (setq totalLayouts (- n 1))
     ) ;_ foreach
   ) ;_ if

Строчка добавленная: (setq totalLayouts (- n 1))

После выполнения команды z_layout_number и регенирации в поле впишется количество выделенных листов.