TheSwamp
Code Red => AutoLISP (Vanilla / Visual) => Topic started by: csgoh on February 27, 2006, 05:43:20 AM
-
Hi guys,
Need to get feedback from you guys. I am not sure how to store non graphical data in the dwg via lisp. Say for example, I have data for State,County,Township,Receipt No etc. What is the best way to store these data in - dictionaries, ldata or xdata or xrecord? apart from storing it in a ascii file?
-
Hi
My preferred solution:
Dictionary with Xrecords...
-
My preferred solution:
Dictionary with Xrecords...
Haven't tried that one...
Is it as easy as LDATA?:
(vlax-ldata-put dictname key value)
(setq value (vlax-ldata-get dictname key))
-
sinc,
before you decide, consider ;
- Do you want the data on a specific type of entity, or just saved anywhere in the drawing
- If on entity, is it one per allotment
- How much data and what type
- Is the format consistant
- Do you Xref
- Do you wblock allotments
- Which version of Acad
- Do you want the Data graphically visible also, ie Text, attributes, Table Fields
- Do you need to audit the info in any way, or store it in an external DB
-
Is it as easy as LDATA?:
(vlax-ldata-put dictname key value)
(setq value (vlax-ldata-get dictname key))
No, Xrecords need to add/get a dictionary object first:
(setq DicObj (vla-Add
(vla-get-Dictionaries
(vla-get-ActiveDocument
(vlax-get-acad-object)
)
DicNme
)
)
)
(vla-SetXrecordData
(vla-AddXrecord DicObj RecKey)
FldArr ValArr
)
(setq DicObj (vla-Item
(vla-get-Dictionaries
(vla-get-ActiveDocument
(vlax-get-acad-object)
)
)
DicNme
)
)
(vla-GetXrecordData
(vla-GetObject DicObj RecKey)
'FldArr 'ValArr
)
It's also necessary to convert the field and value datas into an array (same as Xdata).
But, in opposite to ldata you can use this dict's in VBA also.
-
I am not very familiar with xrecords and dictionaries and am trying to learn to write some codes on this.
I got this from the help section
Xrecord objects are used to store and manage arbitrary data. They are composed of DXF group codes with normal object groups (that is, non-xdata group codes), ranging from 1 through 369 for supported ranges. These objects are similar in concept to xdata but is not limited by size or order.
And in the group codes in numerical order of the help section, there are further codes from 370 to 1071.
So what group code should be used if it is to represent a certain data? And can new group codes be created to represent other data?
-
Ok, I have come up with this and I want some comments from you guys.
(defun ListToSafearray (symVariableType lstValues / safValues)
(setq safValues (vlax-make-safearray symVariableType
(cons 0 (1- (length lstValues)))))
(vlax-safearray-fill safValues lstValues)
) ;listToSafeArray
;; Add Xrecord into the dictionary object in dictionary collection
;; USAGE
;; Arguments
;; dict - :<string> dictionary object
;; name - :<string> name of the dictionary
;; data - :<List of dotted pairs>
;; eg (list '(2000 . "A")'(2001 . "B")
;; '(2004 . "C")'(2003 . "D")
;; )
;;
(defun Xrecord-Add( dict name data / dict xrec safDXFCodes safDXFValues
lstDXFCodes lstDXFValues
filter_codelist filter_valuelist
filter_code filter_value )
(vl-load-com)
(or GB:objDictionaries
(setq GB:objDictionaries
(vla-get-Dictionaries
(vla-get-Activedocument (vlax-get-acad-object))))
)
(setq dict (vlax-invoke-method GB:objDictionaries "Add" dict)
xrec (vla-AddXrecord dict name)
)
(if (not (listp data))(setq data (list data))) ; ensure list
(setq filter_codelist (mapcar '(lambda (x) (car x)) data)
filter_valuelist (mapcar '(lambda (x) (cdr x)) data)
filter_code (ListtoSafearray 2 filter_codelist)
filter_value (ListtoSafearray 12 filter_valuelist)
)
(vla-setXrecordData xrec filter_code filter_value)
);Xrecord-Add
(defun List->CodesList (lst / n)
(setq n -1)
(mapcar '(lambda(x) (setq n(1+ n))) lst)
);List->Codeslist
;;
;; Xrecord-Delete
;;
(defun Xrecord-Delete ( dict name / dcs odc xr )
(cond
((setq odc (CheckItemExist GB:objDictionaries dict))
(cond
((setq xr (CheckItemExist odc name))
(vla-delete xr)
(vlax-release-object xr)
);xr
);cond
(vlax-release-object odc)
);odc
);cond
);Xrecord-Delete
;;
;; Checkitem in collection
;;
;; To Check if certain item in a collection exists
;;
(defun CheckItemExist( 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
);if
)
;;
;;
(defun Xrecord-Rebuild( dict name data)
(Xrecord-Delete dict name)
(Xrecord-Add dict name data)
)
;;
;; Retrieve Xrecord from the dictionary object in dictionary collection
;; USAGE
;; Arguments
;; dict - :<string>
;; name - :<string>
;; Returns - :<list dotted pairs (list '(lstDXFCodes . lstDXFValues) .....)>
;;
(defun Xrecord-Get ( dict name / odc xrec safDXFCodes safDXFValues
lstDXFCodes lstDXFValues )
(cond
((setq odc (CheckItemExist GB:objDictionaries dict))
(cond
((setq xrec (CheckItemExist odc name))
(vla-getXrecordData xrec 'safDXFCodes 'safDXFValues)
(if (and safDXFCodes
safDXFValues
)
(progn
(setq lstDXFCodes (vlax-safearray->list safDXFCodes)
lstDXFValues (mapcar 'variant-value
(vlax-safearray->list safDXFValues))
)
)
)
(vlax-release-object xrec)
);xrec
);cond
(vlax-release-object odc)
); odc
);cond
(mapcar 'cons lstdxfcodes lstdxfvalues)
);Xrecord-Get
(defun SortList (lstOfLists intItem)
(vl-sort lstOfLists '(lambda (n1 n2) (<= (nth intItem n1) (nth intItem n2))))
)
When I try to use a number 2000 for the code, it gives me an error. So I presume that we have to use those defined codes and correct me if I am wrong. Thanks.
-
Refer to the help:
Group codes: 1–369 (except 5 and 105)
The meaning of the group codes you will find in:
AutoCAD Developer Help -> DXF Reference -> DXF Format -> Group Code Value Types / Group Codes in Numerical Order
Arrrgh, forgot to say: group codes can be multiple, eg. '((1 . "MyText1") (1 . "MyText2")...)