Программное создание поля.

В AutoCAD 2005 появился очень интересный объект - поле. Что это такое и с чем его едят, описывать не буду, все это есть в справке. Но вот про создание поля как-то не очень все понятно. Попробую заполнить этот пробел (может, и сам чего еще пойму ;))

Известно, что поле может располагаться в однострочном или многострочном тексте, в атрибуте, а также в ячейке таблицы. Короче, в любом текстоподобном примитиве.
Создадим в пространстве модели всего 3 примитива: отрезок, обычный однострочный текст и однострочник, хранящий в себе поле - длину отрезка. Запустим теперь код, который будет просто печатать в консоли значение текстовой строки и FieldCode:

1
2
3
4
5
6
7
8
9
10
(defun test (/ ent)
  (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 : Простой текст
FieldCode : Простой текст

_$ (test)

TextString : 10.2855
FieldCode : %<\AcObjProp Object(%<\_ObjId 8796083609680>%).Length \f "%lu6">%

Казалось бы, все просто: в качестве текстовой строки надо просто задавать формулу поля, которая определяется как:

%<\AcObjProp Object(%<\_ObjId 'ObjectID объекта'>%).'Свойство объекта' 'Ключи форматирования'>

И все хорошо, пока не встает вопрос об использовании готового и отлаженного lisp'а в AutoCAD другой разрядности. Например, сделали код в 32-разрядной системе, а в 64-разрядном AutoCAD он работать не будет. Все дело именно в ObjectID объекта.

Спасибо Александру Ривилису, он привел решение:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
;;--------------------------------------------------------
;; Функция получает строковое представление 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

Теперь для программного создания поля, отображающего, например, длину указанного отрезка, можно сделать такое:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
(vl-load-com)

(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

Спасибо Александру :)

Размещено в Код LISP, Новости, Функции LISP · Метки:



Комментарии

Есть 3 коммент. к “Программное создание поля.”
  1. Arcon пишет:

    [cc lang="lisp"]
    нужно поставить экранирующий обратный слеш (\) перед (") которая должна войти в строковую переменную "как есть", т.е. фрагмент строки ..."%lu6"... нужно заменить на ...\"%lu6\"...

  2. Кулик Алексей aka kpblc пишет:

    Спасибо, исправил (кажется).

Трэкбэки

Узнайте, что другие говорят про эту заметку...
  1. [...] показанному в статье Программное создание поля, я немного был готов к тому, что получение и [...]



Поделитесь своим мнением


Я не робот.