TheSwamp

Code Red => AutoLISP (Vanilla / Visual) => Topic started by: csgoh on February 27, 2006, 05:43:20 AM

Title: Non graphical data
Post 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?
Title: Re: Non graphical data
Post by: Jürg Menzi on February 27, 2006, 08:31:01 AM
Hi

My preferred solution:
Dictionary with Xrecords...
Title: Re: Non graphical data
Post by: sinc on February 27, 2006, 10:29:18 PM

My preferred solution:
Dictionary with Xrecords...


Haven't tried that one...

Is it as easy as LDATA?:

Code: [Select]
(vlax-ldata-put dictname key value)
(setq value (vlax-ldata-get dictname key))
Title: Re: Non graphical data
Post by: Kerry on February 27, 2006, 10:41:07 PM
sinc,

before you decide, consider ;

Title: Re: Non graphical data
Post by: Jürg Menzi on February 28, 2006, 02:43:26 AM
Is it as easy as LDATA?:
Code: [Select]
(vlax-ldata-put dictname key value)
(setq value (vlax-ldata-get dictname key))
No, Xrecords need to add/get a dictionary object first:
Code: [Select]
(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.
Title: Re: Non graphical data
Post by: csgoh on February 28, 2006, 07:20:21 AM
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
Quote
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?
Title: Re: Non graphical data
Post by: csgoh on February 28, 2006, 07:45:42 AM
Ok, I have come up with this and I want some comments from you guys.
Code: [Select]
(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.

Title: Re: Non graphical data
Post by: Jürg Menzi on February 28, 2006, 08:03:19 AM
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")...)