| Правила | Регистрация | Пользователи | Поиск | Сообщения за день | Все разделы прочитаны |  Справка по форуму | Файлообменник |

Вернуться   Форум DWG.RU > Программное обеспечение > Программирование > Программная вставка блока с атрибутами в таблицу. Как сохранить установленные значения атрибутов?

Программная вставка блока с атрибутами в таблицу. Как сохранить установленные значения атрибутов?

Ответ
Поиск в этой теме
Непрочитано 21.07.2010, 16:40 #1
Программная вставка блока с атрибутами в таблицу. Как сохранить установленные значения атрибутов?
Кулик Алексей aka kpblc
Moderator
 
LISP, C# (ACAD 200[9,12,13,14])
 
С.-Петербург
Регистрация: 25.08.2003
Сообщений: 39,787

В качестве затравки (Спасибо Nike - напомнил одну старую разработку; тут только немного доделал). Теоретически код вставляет в указанную таблицу блок (невзирая на его аннотативность) и копирует значения атрибутов. Практически - не дай боже выделить вставленный блок, значения атрибутов слетают. Явно где-то что-то я не доделал, но где?
Код:
[Выделить все]
(vl-load-com)

(defun c:b2t ()
  (insert-block-to-table nil nil)
  ) ;_ end of defun

(defun insert-block-to-table (row                 col                 /                   adoc
                              table               block               _kpblc-conv-ent-to-ename
                              _kpblc-conv-ent-to-vla                  _kpblc-conv-vla-to-list
                              attr_lst
                              )

                             ;|
*    Выполняет программную вставку блока внутрь таблицы. Не тестировалась на
* аннотативных и динамических блоках. Проверялась работа на блоках с атрибутами.
*    Параметры вызова:
	row		номер строки таблицы, в которую надо вставлять блок. Нумерация с 0
	col		то же, колонки. Нумерация с 0
*    Примеры вызова:
(insert-block-to-table 2 4)
|;

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

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

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

  (vla-startundomark (setq adoc (vla-get-activedocument (vlax-get-acad-object))))

  (if (and (= (type (setq table (vl-catch-all-apply
                                  (function
                                    (lambda ()
                                      (vlax-ename->vla-object (car (entsel "\nУкажите таблицу <Отмена> : ")))
                                      ) ;_ end of lambda
                                    ) ;_ end of function
                                  ) ;_ end of vl-catch-all-apply
                          ) ;_ end of setq
                    ) ;_ end of type
              'vla-object
              ) ;_ end of =
           (= (vla-get-objectname table) "AcDbTable")
           (= (type (setq block (vl-catch-all-apply
                                  (function
                                    (lambda ()
                                      (vlax-ename->vla-object (car (entsel "\nУкажите блок <Отмена> : ")))
                                      ) ;_ end of lambda
                                    ) ;_ end of function
                                  ) ;_ end of vl-catch-all-apply
                          ) ;_ end of setq
                    ) ;_ end of type
              'vla-object
              ) ;_ end of =
           (= (vla-get-objectname block) "AcDbBlockReference")
           (= (type (setq row (vl-catch-all-apply
                                (function
                                  (lambda ()
                                    (cond
                                      (row)
                                      (t
                                       (initget 4)
                                       (getint "\nНомер строки в таблице, начиная с 0 <Отмена> : ")
                                       )
                                      ) ;_ end of cond
                                    ) ;_ end of lambda
                                  ) ;_ end of function
                                ) ;_ end of vl-catch-all-apply
                          ) ;_ end of setq
                    ) ;_ end of type
              'int
              ) ;_ end of =
           (= (type (setq col (vl-catch-all-apply
                                (function
                                  (lambda ()
                                    (cond
                                      (col)
                                      (t
                                       (initget 4)
                                       (getint "\nНомер колонки в таблице, начиная с 0 <Отмена> : ")
                                       )
                                      ) ;_ end of cond
                                    ) ;_ end of lambda
                                  ) ;_ end of function
                                ) ;_ end of vl-catch-all-apply
                          ) ;_ end of setq
                    ) ;_ end of type
              'int
              ) ;_ end of =
           ) ;_ end of and
    (vl-catch-all-apply
      (function
        (lambda ()
          (vla-setblocktablerecordid
            table
            row
            col
            (vla-get-objectid
              (vla-item (vla-get-blocks (vla-get-activedocument (vlax-get-acad-object)))
                        (vla-get-name block)
                        ) ;_ end of vla-item
              ) ;_ end of vla-get-objectid 
            :vlax-true
            ) ;_ end of vla-setblocktablerecordid
          (if (setq attr_lst (append (_kpblc-conv-vla-to-list (vla-getattributes block))
                                     (_kpblc-conv-vla-to-list (vla-getconstantattributes block))
                                     ) ;_ end of append
                    ) ;_ end of setq
            (progn
              ((lambda (/ inserted_block inserted_block_attr)
                 (setq inserted_block      (vla-objectidtoobject (vla-get-activedocument (vlax-get-acad-object))
                                                                 (vla-getblocktablerecordid table row col)
                                                                 ) ;_ end of vla-objectidtoobject
                       inserted_block_attr ((lambda (/ res)
                                              (vlax-for ent inserted_block
                                                (if (wcmatch (strcase (vla-get-objectname ent)) "*ATTR*")
                                                  (setq res (cons ent res))
                                                  ) ;_ end of if
                                                ) ;_ end of vlax-for
                                              (reverse res)
                                              ) ;_ end of lambda
                                            )
                       ) ;_ end of setq
                 (foreach attr inserted_block_attr
                   (vla-setblockattributevalue table
                                               row
                                               col
                                               (vla-get-objectid attr)
                                               (vla-get-textstring
                                                 (car (vl-remove-if-not
                                                        (function
                                                          (lambda (x)
                                                            (= (vla-get-tagstring attr) (vla-get-tagstring x))
                                                            ) ;_ end of lambda
                                                          ) ;_ end of function
                                                        attr_lst
                                                        ) ;_ end of vl-remove-if-not
                                                      ) ;_ end of car
                                                 ) ;_ end of vla-get-TextString
                                               ) ;_ end of vla-SetBlockAttributeValue
                   ) ;_ end of foreach
                 ) ;_ end of lambda
               )
              ) ;_ end of progn
            ) ;_ end of if
          ) ;_ end of lambda
        ) ;_ end of function
      ) ;_ end of vl-catch-all-apply
    ) ;_ end of if
  (vla-endundomark adoc)
  (princ)
  ) ;_ end of defun

Заранее спасибо.

Вложения
Тип файла: lsp insert-block-to-table.LSP (9.7 Кб, 142 просмотров)

__________________
Моя библиотека lisp-функций
---
Обращение ко мне - на "ты".
Все, что сказано - личное мнение.

Последний раз редактировалось Кулик Алексей aka kpblc, 22.07.2010 в 08:29.
Просмотров: 7420
 
Непрочитано 21.07.2010, 17:13
#2
Дима_

Продуман
 
Регистрация: 22.02.2007
Питер
Сообщений: 2,840


У мнея не слетают (acad 2010). Если слетают при выделении, быть может копать надо в сторону "автокадовских" реакторов?
__________________
Когда в руках молоток все вокруг кажется гвоздями.
Дима_ вне форума  
 
Непрочитано 21.07.2010, 17:41
#3
Nike

Шаражпроектхалтурмонтаж
 
Регистрация: 29.10.2004
Талды-Париж
Сообщений: 5,989


В AutoCAD 2010 вроде не слетают
Nike вне форума  
 
Непрочитано 22.07.2010, 08:21
1 | #4
Do$

AutoCAD/Civil3D LISP/C#
 
Регистрация: 15.08.2008
Санкт-Петербург
Сообщений: 1,702
Отправить сообщение для Do$ с помощью Skype™


Слетают - после первой вставки блока в таблицу и его выделении. А последующие вставки ведут себя прилично. (AutoCAD 2010 Eng)
Код:
[Выделить все]
...
(= (type (setq col (vl-catch-all-apply
                                (function
                                  (lambda ()
                                    (cond
                                      (row) <--- тут явно должно быть что-то другое
                                      (t
                                       (initget 4)
                                       (getint "\nНомер колонки в таблице, начиная с 0 <Отмена> : ")
                                       )
                                      ) ;_ end of cond
                                    ) ;_ end of lambda
                                  ) ;_ end of function
                                ) ;_ end of vl-catch-all-apply
                          ) ;_ end of setq
                    ) ;_ end of type
              'int
              ) ;_ end of =
...

Последний раз редактировалось Do$, 22.07.2010 в 08:26.
Do$ вне форума  
 
Автор темы   Непрочитано 22.07.2010, 08:28
#5
Кулик Алексей aka kpblc
Moderator

LISP, C# (ACAD 200[9,12,13,14])
 
Регистрация: 25.08.2003
С.-Петербург
Сообщений: 39,787


Да, спасибо, копипаст никогда ни к чему хорошему не приводит... Все время об этом забываю
__________________
Моя библиотека lisp-функций
---
Обращение ко мне - на "ты".
Все, что сказано - личное мнение.
Кулик Алексей aka kpblc вне форума  
 
Непрочитано 22.07.2010, 09:13
#6
Do$

AutoCAD/Civil3D LISP/C#
 
Регистрация: 15.08.2008
Санкт-Петербург
Сообщений: 1,702
Отправить сообщение для Do$ с помощью Skype™


Странное дело. По порядку:
- Создаю новый чертеж (абсолютно чистый, шаблон acadiso.dwt)
- Рисую в нем таблицу (стиль Standard, все по умолчанию), ячейки оставляю пустыми.
- Вставляю блок с одним атрибутом.
- Загружаю лисп из vlide, запускаю команду B2T.
Сперва (примерно 3 попытки) атрибут слетал стабильно на первой вставке блока в таблицу. Затем слетать перестал (5-10 попыток). Перезагрузил автокад - при первой попытке слетел, затем снова слетать перестал
Может быть действительно есть какой-то реактор, отслеживающий действия с таблицей? Или глюк vla-метода? Слетал бы он стабильно, или поймать бы закономерность, а так -
Do$ вне форума  
 
Автор темы   Непрочитано 22.07.2010, 10:43
#7
Кулик Алексей aka kpblc
Moderator

LISP, C# (ACAD 200[9,12,13,14])
 
Регистрация: 25.08.2003
С.-Петербург
Сообщений: 39,787


Вот это-то как раз и напрягает...
P.S. Вложение из первого поста пока не скачивайте, там исправления #4 не вносились!
__________________
Моя библиотека lisp-функций
---
Обращение ко мне - на "ты".
Все, что сказано - личное мнение.
Кулик Алексей aka kpblc вне форума  
 
Непрочитано 22.07.2010, 14:32
#8
Do$

AutoCAD/Civil3D LISP/C#
 
Регистрация: 15.08.2008
Санкт-Петербург
Сообщений: 1,702
Отправить сообщение для Do$ с помощью Skype™


Вот балбес, ничего у меня не слетает при выделении ячейки!
Слетало при двойном клике на ячейку, в которой блок с атрибутом. При двойном клике начинается редактирование вставки блока в ячейку, выскакивает диалог "Edit block in a Table Cell", в котором можно выбрать имя блока, масштаб блока и метод выравнивания. Если нажать "ок", то далее запускается диалог назначения значений атрибутам, при этом, атрибут сбрасывается на значение по умолчанию. Лисп-то тут не при чем. Кстати, если attreq=0, второй диалог вообще не выскакивает. И получается такая картина: двойной клик на ячейке с блоком, в диалоге "Edit block in a Table Cell" жмем "ок" и значение атрибута сбрасывается - нетипичное для автокада поведение, вот это-то меня и сбило с толку.
Вложения
Тип файла: flv b2t.flv (6.32 Мб, 153 просмотров)

Последний раз редактировалось Do$, 22.07.2010 в 14:43.
Do$ вне форума  
 
Непрочитано 22.07.2010, 15:01
#9
Nike

Шаражпроектхалтурмонтаж
 
Регистрация: 29.10.2004
Талды-Париж
Сообщений: 5,989



Жена отправляет программиста в магазин, наставляя:
- Купи батон хлеба, а если будут яйца - возми десяток.
Программист в магазине:
- Дайте батон, пожалуйста... А яйца есть?
- Есть!
- Тогда дайте десять батонов...
Nike вне форума  
Ответ
Вернуться   Форум DWG.RU > Программное обеспечение > Программирование > Программная вставка блока с атрибутами в таблицу. Как сохранить установленные значения атрибутов?

Размещение рекламы
Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
LISP. Вставка в таблицу поля, соотвествующего площади примитива Profan Готовые программы 272 06.06.2021 23:12
Извлечение атрибутов блока и вставка атрибутов в формулу andery AutoCAD 38 15.06.2009 02:39
Вставка динамического блока - как изменить параметр? vanAvera Программирование 2 23.10.2008 13:39
Как изменить свойства атрибутов блока ALFMario AutoCAD 15 25.01.2008 00:42
ЮМОР 2006 =) Perezz!! Разное 1122 04.01.2007 00:46