找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

查看: 1431|回复: 2

[他山之石] 使用Vlisp获取和设置扩展数据

[复制链接]
发表于 2004-10-4 08:13:02 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×
本帖最后由 Free-Lancer 于 2013-5-26 06:38 编辑

Question
I have to access XDatas inside a Visual LISP reactor, but I cannot use (entget)
or (entmod). Is it possible to use the (vla-getxxx) and (vla-setxxx) functions
to do this?
Answer
You can use the (vla-GetXData) and (vla-SetXData) functions. These functions are
not documented (as are most the Visual LISP online help).

To get more information about these functions, look at the function description
of GetXData and SetXData in the ACADAUTO.HLP help file (the AutoCAD ActiveX and
VBA Reference).

Here is a short description of the functions:

(vla-GetXData entity appName 'codes 'datas)

entity:
This is the entity name of an AutoCAD entity.

appName:
This is a string with the application name. The functions returns all XDatas
belonging to the specified application. If appName is "", the functions returns
all XDatas attached to 'entity'.

codes:
This list receives the XData group codes.

datas:
This list receives the datas of the group codes specified in 'codes'

(vla-SetXData entity codes datas)

entity:
This is the entity name of an AutoCAD entity.

codes:
This list defines the XData group codes.

datas:
This list contains the datas for the specified group codes

The following is a sample code which attaches some XData to every entity in
model space.After this, it extracts the XData of every entity from every
application:

  1. (defun c:setandgetxdatas ()
  2.   (vl-load-com)

  3.   ;; Get objects
  4.   (setq acadApp (vlax-get-acad-object)
  5. acadDoc (vla-get-ActiveDocument acadApp)
  6. mspace (vla-get-ModelSpace acadDoc)
  7.   )  ;; Register an application name
  8.   (regapp "MYAPP")  ;; Attach some xdatas:
  9.   ;; 1001: application name  ;; 1000: string ;; 1010: 3D point ;; 1040: real ;; 1070: 16bit integer
  10.   (setq codes  '(1001 1000 1010 1040 1070)
  11. values '("MYAPP" "XDATA String" (1.0 1.0 0.0) 5.0 4)
  12.   )
  13.   ;; Create the Safe and Variant Arrays needed for vla-SetXData
  14.   (setq ListLength (1- (length codes)))
  15.   (setq ArrayTypes
  16.   (vlax-make-safearray
  17.     vlax-vbInteger
  18.     (cons 0 ListLength)
  19.   )
  20.   )
  21.   (setq ArrayValues
  22.   (vlax-make-safearray
  23.     vlax-vbVariant
  24.     (cons 0 ListLength)
  25.   )
  26.   )
  27.   (vlax-safearray-fill ArrayTypes codes)
  28. ; simple list works
  29. ; A more complex list needs to be constructed one element at a time:
  30.   (setq i 0)
  31.   (while (< i ListLength)
  32.     (if (equal (type (setq lstElem (nth i values))) 'LIST)
  33.       (vlax-safearray-put-element
  34. ArrayValues
  35. i
  36. (vlax-3d-point lstElem)
  37.       )
  38.       (vlax-safearray-put-element ArrayValues i (nth i values))
  39.     )
  40.     (setq i (1+ i))
  41.   )
  42.   
  43.   (setq VarTypes (vlax-make-variant ArrayTypes))
  44.   (setq VarValues (vlax-make-variant ArrayValues))
  45.   (vlax-for ent mspace (vla-SetXData ent VarTypes VarValues))
  46.   (princ "\nFinished storing XData on All Drawing entities.\n"
  47.   )
  48.   (setq EntIndx 0)
  49.   ;; Get all xdatas from entities
  50.   (princ "\nReading XData from drawing entities.\n")
  51.   (vlax-for ent mspace
  52.     (princ (strcat "\n\nEntity(" (itoa EntIndx) "): "))
  53.     (princ (vla-get-ObjectName ent))
  54.     (princ "\nXData: ");;; Deconstruct the Variant Array return of vla-GetXData to SafeArrays, and thento a list
  55.     (setq VarDataTypes nil
  56.    VarDataValues nil
  57.     )
  58.     (vla-GetXData ent "" 'VarDataTypes 'VarDataValues)
  59.     (if (/= VarDataTypes nil)
  60.       (progn
  61. (setq LispList nil)
  62. ;; Get the dimension of the safearray
  63. (setq lBound (vlax-safearray-get-l-bound VarDataTypes 1))
  64. (setq uBound (vlax-safearray-get-u-bound VarDataTypes 1))
  65. (setq aCounter lBound)
  66. (while (<= aCounter uBound)
  67.    (setq dataCode (vlax-safearray-get-element
  68.       VarDataTypes
  69.       aCounter
  70.     )
  71.    )
  72.    (setq VarValue (vlax-safearray-get-element
  73.       VarDataValues
  74.       aCounter
  75.     )
  76.    )
  77.    ;; VarValue contains the variant, but we need the Lisp value of it
  78.    (if (and (> dataCode 1009) (< dataCode 1040))
  79.      ;; Test to see if it's a point Variant
  80.      (progn (setq saValue (vlax-variant-value VarValue))
  81.      (setq Value (vlax-safearray->list saValue))
  82.      )
  83.      (setq Value (vlax-variant-value VarValue))
  84.    )
  85.    ;; Create the list
  86.    (setq
  87.      LispList (append LispList (list (cons dataCode Value)))
  88.    )
  89.    (setq aCounter (1+ aCounter))
  90. ) ;_ end of while
  91.       ) ;_ end of progn
  92.       (setq LispList nil)
  93.     ) ;_ end of if
  94.     (if LispList
  95.       (progn (princ "\n\tCodes: ")
  96.       (foreach LstItem LispList
  97.         (princ (car LstItem))
  98.         (princ "  ")
  99.       )
  100.       (princ "\n\tData: ")
  101.       (foreach LstItem LispList
  102.         (princ (cdr LstItem))
  103.         (princ "  ")
  104.       )
  105.       )
  106.     )
  107.     (setq EntIndx (1+ EntIndx))
  108.   )
  109.   (princ)
  110. )(princ
  111.   "\nc:setandgetxdatas2 loaded, type setandgetxdatas2 to run."
  112. )
  113. (princ)
For additional AutoLISP code that creates and reads Xdata using ActiveX, see
the Xdata_Variants.Lsp sample in the
\Acad2000\Sample\VisualLisp directory..
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
发表于 2004-10-4 08:39:40 | 显示全部楼层
楼上的会中文吗?

很多人都看不懂英文,对你所表达的就不懂了

其实我也不懂英文
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

发表于 2004-10-4 08:42:05 | 显示全部楼层
这是AutoLisp方法的版本
[php];----------------------------------------------------------
;  Extended data Utilities and Example of use
;  From 1999 Autodesk University course PR31
;  taught by Bill Kramer
;
; Utilities:
;  X_DATA_GET - get extended data list from entity
;  X_DATA_ADD - add extended data to entity
;  X_DATA_DEL - remove extended data from entity
;  X_DATA_APPIDS - build list of registered applications
;  NTH_SUBST - substitute nth member in list
;
;  C:EST - estimation example application shows use of
;          extended data to house bill of material info
;          about objects.
;----------------------------------------------------------;;
;; X_DATA_GET: Utility to get the extended data
;; list for an entity (EN) for a given application name (APID).
;;
(defun X_DATA_GET (EN APID / EL)
  (setq EL (entget EN (list APID)))
  (cdadr (assoc -3 EL)) ;;return only data items
)
;;---------------------------------------------------------
;; X_DATA_ADD  add extended data list DLST with
;;             application name APID to the entity list
;;             of entity name EN.
;;             Overwrites existing.
;;
(defun X_DATA_ADD (EN APID DLST / EL TMP1)
   (if (null (tblsearch "APPID" APID)) ;;registered?
      (regapp APID)) ;;register it
   (setq EL (entget EN) ;;get Entity list
         TMP1 (list -3 (cons APID DLST))
   )
   (if (< (xdsize TMP1) (xdroom EN)) ;;got enough room?
      (entmod (append EL (list TMP1)))) ;;modify database
)
;;---------------------------------------------------------
;; X_DATA_DEL - Utlity to remove the extended data for
;; an application (APID) from an entity object (EN).
;;
(defun X_DATA_DEL (EN APID / EL TMP1 TMP2)
   (if (setq TMP2 (X_DATA_APPIDS)) ;;find X data?
     (progn
       (setq EL (entget EN TMP2)  ;;get ALL data
             TMP1 (assoc -3 EL)   ;;get X data
       )
       ;;is APID in X data info for object?
       (if (assoc APID (cdr TMP1))
         (progn
          (setq TMP1 (cdr TMP1) ;;take off -3
                TMP1 ;;remove existing X data
                  (append ;;rebuild X data list
                    (list -3)
                    (reverse ;;X data before APID
                      (cdr
                        (member
                          (assoc APID TMP1)
                          (reverse TMP1))))
                    (cdr     ;;X data after APID
                      (member
                        (assoc APID TMP1)
                        TMP1)))
                EL (subst TMP1 (assoc -3 EL) EL)
          )
          (entdel EN) ;;remove previous member
          (entmake EL))))));;add with modified X data
;;---------------------------------------------------------
;; X_DATA_APPIDS - Creates a list of all application
;; names in the current drawing by stepping through
;; the APPID table.
;;
(defun X_DATA_APPIDS ( / TMP1 TMP2)   
   ;;Build list of X data ID's
   (setq TMP1 (tblnext "APPID" 'T)) ;;get 1st APPID
   (while TMP1 ;;loop until no more APPID's in table
     (setq TMP2 (cons ;;add APPID to list
                  (cdr (assoc 2 TMP1))
                  TMP2)
           TMP1 (tblnext "APPID") ;;get next APPID
     )
   )
   TMP2 ;;return TMP2 list
)
;;---------------------------------------------------------
;
; Utility routine for substitution
; in a list at the Nth specified position.
;
(defun NTH_SUBST (NN New Dlist)
  (cond
    ((null Dlist) nil)
    ((= NN 0) (cons New (cdr Dlist)))
    (t (cons
         (car Dlist)
         (NTH_SUBST (1- NN) New (cdr Dlist))))))
;
;;---------------------------------------------------------
;;
;; C:EST - Estimator application example
;;
(defun C:EST ( / TMP DONE)
   (setq APID "ESTIMATOR")
   (prompt "\nESTimator tool for AutoCAD.")
   (while (null DONE)
     (initget 0 "Sum Edit Look Add Del Xit")
     (setq TMP
       (getkword
          "\nEST: Sum/Edit/Look/Add/Del/<Xit>: "))
     (cond
       ((or (null TMP) (= TMP "Xit"))
          (setq DONE 'T))
       ((= TMP "Sum") (EST_SUM APID)) ;;see listing 18
       ((= TMP "Edit") (EST_EDIT APID)) ;;see listing 15
       ((= TMP "Look") (EST_LOOK APID)) ;;see listing 17
       ((= TMP "Add") (EST_ADD APID)) ;;see listing 14
       ((= TMP "Del") (EST_DEL APID)) ;;see listing 16
     )
   )
   (princ)
)
;---------------------------------------------------------
;
; Add new Xdata for the estimator.
;
(defun EST_ADD (APID / EN T1 T2)
  (setq EN (car (entsel "\nSelect object: ")))
  (if EN
    (progn
       (setq T1 (getstring 1 "\nDescription: "))
       (if (/= T1 "")  
         (progn
           (setq T2 (getreal "\nAmount: "))
           (if T2
             (X_DATA_ADD EN APID
               (list (cons 1000 T1)
                     (cons 1040 T2)))))))))
;;---------------------------------------------------------
;
;  Edit description and amount data.
;
(defun EST_EDIT (APID / EN TMP T1 T2)
   (setq EN (car (entsel "\nSelect object: ")))
   (if (setq TMP (X_DATA_GET EN APID))
     (progn
        (setq T1
           (getstring 1
              (strcat "\nDescription <"
                      (cdar TMP) ">: "))
              T2
           (getreal
              (strcat "\nAmount <"
                      (rtos (cdadr TMP)) ">: "))
              TMP
               (list
                 (cons 1000 (if T1 T1 (cdar TMP)))
                 (cons 1040 (if T2 T2 (cdadr TMP))))
        )
        (X_DATA_ADD EN APID TMP))))
;;---------------------------------------------------------
;
; Remove estimator data
;
(defun EST_DEL (APID / EN)
  (setq EN (car (entsel "\nSelect object: ")))
  (if EN (X_DATA_DEL EN APID)))
;;---------------------------------------------------------
;
; Highlight all objects containing extended data
;
(defun EST_LOOK (APID / SS1 TMP)
  (setq SS1 (ssget "X" (list (list -3 (list APID)))))
  (if SS1
    (progn
       (setq TMP (sslength SS1))
       (repeat TMP
         (redraw
            (ssname
               SS1
               (setq TMP (1- TMP)))
            3)))))
;;---------------------------------------------------------
; Sum amount data and output to screen report
;
(defun EST_SUM (APID / TMP SUM SS1)
   (setq SS1 (ssget "X" (list (list -3 (list APID)))))
   (if SS1
     (progn
        (setq TMP (sslength SS1)
              SUM 0.0)
        (repeat TMP
           (setq TMP (1- TMP)
                 T1 (X_DATA_GET (ssname SS1 TMP) APID)
                 SUM (+ SUM (cdadr T1))))
        (prompt
          (strcat
             "\nSum total = "
             (rtos SUM))))))
[/php]
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|申请友链|Archiver|手机版|小黑屋|辽公网安备|晓东CAD家园 ( 辽ICP备15016793号 )

GMT+8, 2025-9-27 11:58 , Processed in 0.254720 second(s), 32 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表