Тема: Можно ли программно вставить поле?

В АКАД 2006 есть команда FIELD. Можно ли из Лиспа без вызова диалога создать поле, для упрощения - нужна ссылка на содержимое текстового примитива.

Re: Можно ли программно вставить поле?

Можно. В качестве поля будет что-то типа: %<\AcObjProp Object(%<\_ObjId XXXXXXXXX>%).TextString>%, где XXXXXXXXX - имя текстового примитива. Осталось вписать вместо XXXXXXXXX имя примитива (точнее его числовое значение в десятичной системе счисления). В 16-ричной получить достоточно просто:

(progn
 (setq en (car (entsel)))
 (setq e  (entget en))
 (setq s  (vl-princ-to-string (cdr (assoc -1 e))))
 (setq s  (substr s (1+ (vl-string-position (ascii ":") s))))
 (setq s  (vl-string-trim " :<>" s))
)

Ну а тебе задание на закуску - преобразование из HEX в DEC... smile

Re: Можно ли программно вставить поле?

Т.е. это нужно поместить в DXF 1 при создании примитива TEXT ?

Re: Можно ли программно вставить поле?

Да.

'(1 . "Ля-Ля-Ля %<\\AcObjProp Object(%<\\_ObjId XXXXXXXXX>%).TextString>% Фа-Фа-Фа")

Но тут не все так просто, как хотелось бы. При создании примитива все работает, а вот при его изменении - нет. Обновление (entupd) примитива не помогает. Только регенерация чертежа. В ObjectARX я нашел функцию, которая обновляет поля в примитивах (называется acdbEvaluateFields), а в VBA/VisualLisp ее или нет, или я ее пока не нашел.
Закуску приготовил сам. На здоровье:

(defun C:ChgTxtFld ( / en s s1)
  (vl-load-com)
  (defun HexToDec (hexstr / n s i a)
   (setq n 0 i 0)
   (setq hexstr (strcase hexstr))
   (while (> (strlen hexstr) 0)
     (setq s (substr hexstr (strlen hexstr) 1) a (ascii s))
     (cond
      ((<= (ascii "0") a (ascii "9")) (setq a (- a (ascii "0"))))
      ((<= (ascii "A") a (ascii "F")) (setq a (+ 10 (- a (ascii "A")))))
     ) ;; (cond
     (setq n (+ n (* a (expt 16 i))) i (1+ i))
     (setq hexstr (substr hexstr 1 (1- (strlen hexstr))))
   )
   (rtos n 2 0)
  )
  (if (setq en (car
         (entsel "\nВыберите текст-источник: " )))(progn
    (setq s  (vl-princ-to-string (cdr (assoc -1 (entget en)))))
    (setq s  (substr s (1+ (vl-string-position (ascii ":") s))))
    (setq s  (vl-string-trim " :<>" s))
    (setq s  (HexToDec s))
    (setq s  (strcat "%<\\AcObjProp Object(%<\\_ObjId " s ">%).TextString>%"))
    (if (setq en (car
         (entsel "\nВыберите текст-приемник: " ))) (progn
      (setq e (entget en))
      (if (setq s1 (cdr (assoc 1 e))) (progn
        (entmod (subst (cons 1 s) (assoc 1 e) e)) (entupd en)
      )) ;; (if (progn
    ))
  )) ;; (if (progn
)

Re: Можно ли программно вставить поле?

Привет!
>При создании примитива все работает,
>а вот при его изменении - нет.
Я в свое время использовал (правда, для другой цели)
удаление/восстановление примитива
(entdel <имя>)(entdel <имя>).
Может, и здесь сработает?
Счастливо, Алексей!

Re: Можно ли программно вставить поле?

Спасибо, попробую.

Re: Можно ли программно вставить поле?

Программа работает. (entdel ..)(entdel ..) - не работает, только regen.
И еще - если поле отредактировать ddedit, то связь теряется, хотя entget - похоже не меняется

Re: Можно ли программно вставить поле?

И ещё. Как вытащить из ПОЛЯ объект, на который оно сслылается (для простоты - исходный текстовый примитив)?

Re: Можно ли программно вставить поле?

> zhuravsky
Все возможные и невозможные трюки я вчера проверил... Мимо... :(
При редактировании поля связь у меня не терялась. Тоже нужно было выполнить REGEN...

> zhuravsky
Проделать обратную операцию. Только тут не годится 1 группа примитива. Тут нужно или пробежаться по связным примитивам или через vla-fieldcode получить текст вместе с полем. Ну а потом из поля вытащить имя примитива и т.д.

Re: Можно ли программно вставить поле?

Со связью так: если поле отредактировать в ddedit и при этом удалить содержимое поля (то, что с темным фоном), то связь теряется. Если добавить к содержимому поля текст, то останутся и текст и связь. По-моему, это не есть гут.

Re: Можно ли программно вставить поле?

А вот так можно вытащить ссылку

(defun find-src-field(en / en1)
  (if (setq en1 (cdr (assoc 360 (entget en))))
    (progn
      (repeat 3
        (setq en1 (cdr (assoc 360 (entget en1))))
      ); repeat
      (setq en1 (cdr (assoc 331 (entget en1))))
      (redraw en1 3) ; ??
    ); progn
  ); if
  en1
)

Т.к. структура словарей неописана, где-то может работать неверно

Re: Можно ли программно вставить поле?

А такая конструкция чуть короче, и преобразований меньше

      (setq s (vla-get-objectid (vlax-ename->vla-object en)))
      (setq s (strcat "%<\\AcObjProp Object(%<\\_ObjId " (itoa id) ">%).TextString>%"))