Программное создание поля.
В AutoCAD 2005 появился очень интересный объект – поле. Что это такое и с чем его едят, описывать не буду, все это есть в справке. Но вот про создание поля как-то не очень все понятно. Попробую заполнить этот пробел (может, и сам чего еще пойму
)
Известно, что поле может располагаться в однострочном или многострочном тексте, в атрибуте, а также в ячейке таблицы. Короче, в любом текстоподобном примитиве.
Создадим в пространстве модели всего 3 примитива: отрезок, обычный однострочный текст и однострочник, хранящий в себе поле – длину отрезка. Запустим теперь код, который будет просто печатать в консоли значение текстовой строки и FieldCode:
(setq ent (vlax-ename->vla-object (car (entsel))))
(princ (strcat "\nTextString : "
(vla-get-textstring ent)
"\nFieldCode : "
(vla-fieldcode ent)
) ;_ end of strcat
) ;_ end of princ
(princ)
) ;_ end of defun
| Простой текст | Поле |
| _$ (test)
TextString : Простой текст |
_$ (test)
TextString : 10.2855 |
Казалось бы, все просто: в качестве текстовой строки надо просто задавать формулу поля, которая определяется как:
%<\AcObjProp Object(%<\_ObjId 'ObjectID объекта‘>%).’Свойство объекта‘ ‘Ключи форматирования‘>
И все хорошо, пока не встает вопрос об использовании готового и отлаженного lisp’а в AutoCAD другой разрядности. Например, сделали код в 32-разрядной системе, а в 64-разрядном AutoCAD он работать не будет. Все дело именно в ObjectID объекта.
Спасибо Александру Ривилису, он привел решение:
;; Функция получает строковое представление ObjectID
;; вне зависимости от того AutoCAD x86 или x64
;; Источник: https://discussion.autodesk.com/forums/message.jspa?messageID=6172961
;;--------------------------------------------------------
(defun get-objectid-x86-x64 (obj / util)
(setq util (vla-get-utility (vla-get-activedocument (vlax-get-acad-object))))
(if (= (type obj) 'ename)
(setq obj (vlax-ename->vla-object obj))
) ;_ end of if
(if (= (type obj) 'vla-object)
(if (> (vl-string-search "x64" (getvar "platform")) 0)
(vlax-invoke-method util "GetObjectIdString" obj :vlax-false)
(rtos (vla-get-objectid obj) 2 0)
) ;_ end of if
) ;_ end of if
) ;_ end of defun
Теперь для программного создания поля, отображающего, например, длину указанного отрезка, можно сделать такое:
(defun c:insfld (/ adoc ent pt)
(vla-startundomark (setq adoc (vla-get-activedocument (vlax-get-acad-object))))
(if (and (= (type
(setq
ent (vl-catch-all-apply
(function
(lambda ()
(vlax-ename->vla-object
(car
(entsel "\nУкажите отрезок, полилинию или сплайн <Отмена> : ")
) ;_ end of car
) ;_ end of vlax-ename->vla-object
) ;_ end of lambda
) ;_ end of function
) ;_ end of vl-catch-all-apply
) ;_ end of setq
) ;_ end of type
'vla-object
) ;_ end of =
(vlax-property-available-p ent 'length)
(= (type (setq pt (vl-catch-all-apply
(function
(lambda ()
(getpoint "\nУкажите точку для простановки поля <Отмена> : ")
) ;_ end of lambda
) ;_ end of function
) ;_ end of vl-catch-all-apply
) ;_ end of setq
) ;_ end of type
'list
) ;_ end of =
pt
) ;_ end of and
(vla-addtext
(vla-objectidtoobject
adoc
(vla-get-ownerid ent)
) ;_ end of vla-ObjectIDToObject
(strcat "%<\\AcObjProp Object(%<\\_ObjId "
(vl-princ-to-string (get-objectid-x86-x64 ent))
">%).Length \\f \"%lu6\">%"
) ;_ end of strcat
(vlax-3d-point pt)
2.5
) ;_ end of vla-addtext
) ;_ end of if
(vla-endundomark adoc)
(princ)
) ;_ end of defun
Спасибо Александру
Материалы для проектирования, работы и разработки (и не только в AutoCAD)