丁X的 发表于 2014-6-5 15:55:12

正常程序员的生活啊,问题是为什么有四个孩子?

305341043 发表于 2017-11-23 15:00:53

万丈高楼平地起,向前辈看齐

monsterWu 发表于 2018-8-19 21:20:04

有趣的作者

sxl55 发表于 2019-1-13 22:25:12

大神都是从小兵磨练而来的

雨的节奏 发表于 2019-8-22 14:15:22

学习了,谢谢大佬

echor 发表于 2020-11-30 15:55:47

4个娃,工作之余还有时间带娃,楼主很厉害,娃有个好父亲。

chenbj0 发表于 2021-11-10 15:59:06

第15章- XDATA and XRECORDs

chenbj0 发表于 2021-11-10 15:59:22

第15章- XDATA and XRECORDs

AutoCAD提供了几种在图形中存储非图形化信息的方法。这可以包括各种数据类型,例如数字、文本等等。其中两个最常见的是扩展实体数据Extended Entity Data(EED)和字典Dictionaries。最常见的EED的形式是XDATA,它是所有图形实体以及表格对象的扩展,例如图层和线型。这允许您在(非图形的)实体或表对象中存储隐藏的信息,必要时检索这些信息。
另一种存储非图形化信息的方式是使用XRECORD对象。XRECORD对象是Document对象的一部分,允许您在字典集合中存储字符串信息。
使用XDATA的优点是信息附加到特定的实体或表成员后面。使用XRECORD对象的优点是它们被附加到文档本身,而不是任何特定的实体或表对象。此外,XDATA对可以存储在给定实体或表对象上的数据大小有一定的限制。XRECORD对象对数据存储没有任何大小限制,但是会影响DWG文件大小,以及打开图形时的内存需求。
使用扩展数据XDATA
扩展数据可以附着或检索图形中的任何图元,以及诸多表对象(例如图层、布局和线型)。XDATA根据数据类型分别存储信息,因此无论何时将信息附加到对象,还是尝试检索信息时,都必须知道要存储的信息类型。例如,如果将整数值附加到实体,却尝试将其作为字符串值检索,则不会得到所需的结果。
使用XRECORD对象
XRECORD对象作为字典进行维护,这意味着它们具有唯一的名称,并且可以通过该名称进行访问。它们附加到文档本身,而不是像扩展数据那样附加到任何图形对象或表对象。如果图形被保存回R12,或者转换为不支持XRECORD的其他CAD格式,XRECORD 对象将消失。
由于XRECORD对象附加到文档,因此用户不会随意删除它们。例如,如果将XDATA附加到一个层,而该层被清除,那么XDATA也将被删除。您可以将XDATA附着到“0”层以避免现这种情况,然而XDATA存储的数据类型和数据大小仍然受到限制。
Xrecords只能创建、重命名或删除。没有直接的方法来修改它们。修改Xrecord的唯一方法是检索到其内容,从dictionary对象中删除他们,然后重新创建新的Xrecord。以下函数演示了如何使用AutoLISP执行此操作。
(defun Xrecord-Rebuild (name dat)
(Xrecord-Delete name)
(Xrecord-Add name dat)
)
(defun Xrecord-Get (name / xlist)
(if (setq xlist (dictsearch (namedobjdict) name))
    (cdr (assoc 1 xlist))
)
)
(defun Xrecord-Delete (name)
(dictremove (namedobjdict) name)        ; remove from dictionary
)
(defun Xrecord-Add (name sdata / xrec xname)
(setq        xrec
       (list
           (cons 0 "XRECORD")
           (cons 100 "AcDbXrecord")
           (cons 1 sdata)
           (cons 62 1)
       )
)
(setq xname (entmakex xrec))                        ; rebuild xrecord
(dictadd (namedobjdict) name xname)        ; return to dictionary
(princ)
)
上述表单的问题在于,它使用(entmake),当与某些其他ActiveX函数混合使用时,有时会在AutoCAD中导致问题。更合适的形式是ActiveX方法,如下例所示。
(vl-load-com)
(defun Xrecord-Rebuild (dict name data)
(Xrecord-Delete dict name)
(Xrecord-Add dict name data)
)
(defun Xrecord-Get(dict name / acad doc dcs odc xrec #typ #dat out)
(setq        acad (vlax-get-acad-object)
        doc(vla-get-activedocument acad)
        dcs(vla-get-dictionaries doc)
)
(cond
    ((setq odc (dsx-item dcs dict))
   (cond
       ((setq xrec (dsx-item odc name))
          (vla-getXrecordData xrec '#typ '#dat)
          (setq #typ (vlax-safearray->list #typ)
                 #dat (vlax-safearray->list #dat)
             )
             (setq out (mapcar 'vlax-variant-value #dat))
             (vlax-release-object odc)
       )
   )
   (vlax-release-object dcs)
    )
)
out
)

(defun Xrecord-Delete (dict name / dcs odc xr)
(setq dcs (vla-get-dictionaries active-doc))
(cond
    ((setq odc (dsx-item dcs dict))
   (cond
       ((setq xr (dsx-item odc name))
        (vla-delete xr)
        (vlax-release-object xr)
       )
   )
   (vlax-release-object odc)
    )
)
(vlax-release-object dcs)
)

(defun Xrecord-Add
(dict name data / acad doc dicts dict xrec #typ #dat)
(setq        acad(vlax-get-acad-object)
        doc   (vla-get-activedocument acad)
        dicts (vla-get-Dictionaries doc)
        dict(vlax-invoke-method dicts "Add" dict)
        xrec(vla-AddXrecord dict name)
)
(if (not (listp data))
    (setq data (list data))
)                                        ; ensure list!
(vla-setXrecordData
    xrec
    (List->VariantArray
      (List->IntList data)
      'vlax-vbInteger
    )
    (List->VariantArray data 'vlax-vbVariant)
)
(vla-getXrecordData xrec '#typ '#dat)
(setq        #typ (vlax-safearray->list #typ)
        #dat (vlax-safearray->list #dat)
)
(mapcar 'vlax-variant-value #dat)
)
两个函数(List->VariantArray)和(List->IntList)分别用于定义安全数组safearray的内容和维度。显然,它们的用途远不止这些。(List->VariantArray)的第二个参数必须是单引号的ActiveX数据类型声明,如’vlax-vbString。
(defun List->VariantArray (lst datatype / arraySpace sArray)
(setq        arraySpace
       (vlax-make-safearray
           (eval datatype)
           (cons 0 (1- (length lst)))
       )
)
(setq sArray (vlax-safearray-fill arraySpace lst))
(vlax-make-variant sArray)
)
(defun List->IntList (lst / n)
(setq n 0)
(mapcar (function (lambda (x) (setq n (1+ n)))) lst)
)
另一个函数(dsx-item)用来使用集合的item方法获取(或尝试获取)项。此函数包括在获取失败时捕获错误,这将返回ActiveX错误,而不是像nil这样的错误。在这种情况下,我们捕获一个错误,如果获取失败,则返回nil。否则,我们将从集合中返回对象。
(defun DSX-Item (collection item / out)
(if
    (not
      (vl-catch-all-error-p
        (setq out
             (vl-catch-all-apply 'vla-item (list collection item))
        )
      )
    )
   out                                ; return object or nil
)
)
为了演示如何使用这些东西,我们将在当前图形中保存一个Xrecord,其中包含一些信息,例如当前用户名(假设我们使用的是Windows NT、2000或XP)和一些其他信息。
(setq username (getenv “username")        ; logged on user ID
      machine(getenv “computername") ; NETBIOS computer name
)
(Xrecord-Rebuild "PERSONAL" "UserData" (list username machine))
_$ Returns ("DSTEIN1234" "W2K-1234")
(Xrecord-Get "PERSONAL" "UserData")
_$Returns ("DSTEIN1234" "W2K-1234")
(Xrecord-Rebuild "PERSONAL" "UserData" "1234")
_$Returns ("1234")
那么,你能用Xrecords做什么呢?什么都行。它们对于在图形中存储信息非常有用,因为图形中的信息不直接绑定到任何特定实体或表。如果您习惯于在扩展数据中存储信息,那么您可能知道,如果删除了实体或表项,扩展数据就会丢失。当然,您可以将扩展数据附加到像“0”层之类的东西上,这样它就永远不会被删除。但是,Xdata受到内容限制,可以用Xrecords来减轻这些限制。

fayadetudou 发表于 2022-6-8 08:40:46

学习了,谢谢大佬

丶吟游诗人灬 发表于 2023-4-6 15:39:40

文化传承对作者表示由衷敬佩是我辈学习的目标和方向
页: 1 [2] 3
查看完整版本: 关于作者