Jump to content

How to save data attached to a variable


aloy

Recommended Posts

Posted

Aftertouch,

I can see that the routine works when the variable is a string attached to any group code.That is xrecord method works only with strings. Just like writing to a file. To me it looks as if the solution is to convert each character in my list (including the spaces) to ascii code, save each integer as string and then find a way to convert back. Perhaps that is what happens when we cut and paste from one application to another (like cutting from autocad and pasting in notepad, all as strings).

  • Replies 34
  • Created
  • Last Reply

Top Posters In This Topic

  • aloy

    17

  • BIGAL

    6

  • Roy_043

    4

  • Aftertouch

    4

Posted

Aloy,

 

I also use it to store INT and REAL values. Works for everything. ;-)

Posted

Bigal, I think preparing the list lst from my list is not practical as it has to be done manually. Or is there a way to convert them automatically when I have a list containing about hundred such lists, with each list attached to the center line chainage which can be used as the groupcode?.

 

Thanks.

Aloy.

Posted

Aftertouch,

I tried with this list:

((0.0 10.5) (3.0 7.0) (6.0 6.0) (9.0 5.5) (12.0 7.6) (15.0 4.0) (18.0 6.5) (21.0 5.0) (24.0 2.8) (28.0 3.5))

I got error message to say that (0.0 10.5) incorrect groupcode.

Posted

try:

 

(list (cons 0.0 10.5) (cons 3.0 7.0) (cons 6.0 6.0) (cons 9.0 5.5) (cons 12.0 7.6) (cons 15.0 4.0) (cons 18.0 6.5) (cons 21.0 5.0) (cons 24.0 2.0) (cons 28.0 3.5))

Posted

No, it doesn't work. Still says incorrect group code (1 list'(....

Posted (edited)

The data you want to store in an xrecord has to be formatted as a correct DXF assoc list. So what Aftertouch is suggesting will not work.

 

You need the following functions:

 

1.

Functions to create dictionaries and xrecords.

GetOrAddDict and AddOrReplaceXrec from here are fine.

 

2.

A function to retrieve xrecord data.

Something as simple as this will do:

(defun GetXrecData (parentDict xrecName / elst)
 (if (setq elst (dictsearch parentDict xrecName))
   (cdr (member (assoc 280 elst) elst))
 )
)

3.

Functions to encode and decode list data.

I have created these functions for my work:

;;; ======================================================================
;;; Lib function: KGA_Data_DictDataList_To_List
;;; Purpose:      Turn a dictionary data list into a lisp list.
;;; Arguments:    lst - List to convert.
;;; Return value: Lisp list.
;;; Remarks:      The counterpart of (KGA_Data_List_To_DictdataList).
;;;               Compare (kg:DictDataList->List).
;;; Examples:     See (KGA_Data_List_To_DictdataList).
;;; ======================================================================
(defun KGA_Data_DictDataList_To_List (lst / N_Convert N_Decode)
 ;; Only (N_Convert) chops away at lst. (N_Decode) does not.
 (defun N_Convert ( / ret stopP)
   (while (and lst (not stopP))
     (cond
       ((equal (car lst) '(1 . "{"))
         (setq lst (cdr lst))
         (setq ret (append ret (list (N_Convert)))) ; (N_Convert) returns a list.
       )
       ((equal (car lst) '(1 . "}"))
         (setq lst (cdr lst))
         (setq stopP T)
       )
       ((equal (car lst) '(1 . "."))
         (setq ret (apply 'vl-list* (append ret (list (N_Decode (cadr lst)))))) ; (N_Decode) returns an atom.
         (setq lst (cddr lst))
       )
       (T
         (setq ret (append ret (list (N_Decode (car lst)))))
         (setq lst (cdr lst))
       )
     )
   )
   ret
 )
 (defun N_Decode (v)
   (cond
     ((= (car v) 2) ; String to be read (*SUBR,SYM).
       (read (cdr v))
     )
     ((vl-position (car v) '(332 342)) ; Ename to be translated to object.
       (vlax-ename->vla-object (cdr v))
     )
     (T
       (cdr v)
     )
   )
 )
 (car (N_Convert))
)

;;; ======================================================================
;;; Lib function: KGA_Data_List_To_DictdataList
;;; Purpose:      Turn a lisp list into a dictionary data list.
;;; Arguments:    lst              - List to convert.
;;;               useHardPointersP - T or nil:
;;;                                  T    Use hard pointer group codes for
;;;                                       enames and objects.
;;;                                  nil  Use soft pointer group codes for
;;;                                       enames and objects.
;;; Return value: Dictionary data list.
;;; Remarks:      The counterpart of (KGA_Data_DictDataList_To_List). The
;;;               function does not check for deleted enames and objects.
;;;               Compare (kg:List->DictDataList).
;;; Examples:
;;; (KGA_Data_DictDataSet '(nil "MyDict1" "MyXrec1") (KGA_Data_List_To_DictdataList (list 1 2.3 4 '(5 6 (7 . ) (entlast) (vlax-ename->vla-object (entlast)) '(0 0 0) "abcd" 'varA T nil) T))
;;; (KGA_Data_DictdataList_To_List (KGA_Data_DictDataGet '(nil "MyDict1" "MyXrec1")))
;;; => (1 2.3 4 (5 6 (7 . ) <Entity name: 0c434db8> #<VLA-OBJECT IAcadLine 0C4418D8> (0 0 0) "abcd" VARA T NIL)
;;; ======================================================================
;;; Availabe group codes for DictData          1-369 (except 5 and 105).
;;; Preferably do not use these group codes    100, 102, 280, 281, 330 and 350 (are already used by 'standard' dictionaries and xrecords).
;;; Group code ranges for handles              All string ranges and 310-319.
;;; Group code ranges that don't work (?)      320-329 (tested with enames and handles).
;;; Group code ranges for enames:              330-369 (preferably do not use 330 and 350).
;;; Note: Group codes with enames that are no longer in the drawing will be
;;;       dropped completely from Xrecords when the drawing is reopened.
;;;       This means that the result of (KGA_Data_DictDataList_To_List)
;;;       will then not match the sequence of the original list.
;;;       Original list: ("aaa" <Entity name: ???????> "bbb").
;;;       New list:      ("aaa" "bbb").
;;;       Using control strings to organize data is therefore a good idea.
;;;
;;; Group codes for (KGA_Data_List_To_DictdataList) and (KGA_Data_DictDataList_To_List):
;;;          1: Control string and special string: "{", "}", "." (for dotted list) or "*INVALID DATA*".
;;;          2: String to be read (*SUBR,SYM).
;;;          3: String.
;;;         40: Real.
;;;         90: Integer.
;;; 331 or 341: Ename not translated.
;;; 332 or 342: Ename to be translated to object.
;;; 333 or 343: Currently not used, reserved for ename to be translated to handle.
;;; ======================================================================
(defun KGA_Data_List_To_DictdataList (lst useHardPointersP / N_Convert N_Encode ret)
 (defun N_Convert (lst)
   (setq ret (cons '(1 . "{") ret))
   (while lst
     (if (listp (car lst))
       (N_Convert (car lst))
       (setq ret (cons (N_Encode (car lst)) ret))
     )
     (if (and (setq lst (cdr lst)) (atom lst))
       (progn
         (setq ret (vl-list* (N_Encode lst) '(1 . ".") ret))
         (setq lst nil)
       )
     )
   )
   (setq ret (cons '(1 . "}") ret))
 )
 (defun N_Encode (v / typ)
   (setq typ (type v))
   (cond
     ((vl-position typ '(exrxsubr exsubr subr sym usubr)) ; See documentation of (KGA_Type_Function_P).
       (cons 2 (vl-prin1-to-string v))
     )
     ((= typ 'str)
       (cons 3 v)
     )
     ((= typ 'real)
       (cons 40 v)
     )
     ((= typ 'int)
       (cons 90 v)
     )
     ((= typ 'ename)
       (cons (if useHardPointersP 341 331) v)
     )
     ((= typ 'vla-object)
       (cons (if useHardPointersP 342 332) (vlax-vla-object->ename v))
     )
     (T
       '(1 . "*INVALID DATA*")
     )
   )
 )
 (reverse (N_Convert lst))
)

Putting everything together:

(defun c:TestSet ( / lst)
 (setq lst '((0.0 10.5) (3.0 7.0) (6.0 6.0) (9.0 5.5) (12.0 7.6) (15.0 4.0) (18.0 6.5) (21.0 5.0) (24.0 2. (28.0 3.5))) 
 (AddOrReplaceXrec
   (GetOrAddDict (namedobjdict) "MyMainDict")
   "MyRecord"
   (KGA_Data_List_To_DictdataList lst nil)
 )
)

(defun c:TestGet ( / lst)
 (setq lst
   (KGA_Data_DictDataList_To_List
     (GetXrecData
       (GetOrAddDict (namedobjdict) "MyMainDict")
       "MyRecord"
     )
   )
 )
)

Edited by Roy_043
The functions for encoding and decoding were the wrong ones
Posted

Note: I have updated the code in my previous post.

Posted (edited)

If I understand correct each "LIST" is say the co-ords of a Road Chainage then the Vl- will work just repeat for each chainage but you must change the Key name.

 

(vlax-ldata-put "Rdname" "CH0" lst)
(vlax-ldata-put "Rdname" "CH10" lst) ; chainage 10 co-ords
(vlax-ldata-put "Rdname" "CH20" lst) ; chainage 20 co-ords
(vlax-ldata-put "Rdname" "CH23-25" lst) ; chainage 23.25 used - so it looks like a string

 

If your list is a great big list ie everything in it then still do the same but break up the list

 

; something like ; ((Ch0 (0 1) (1 1 )....)(ch20 (1 1)( 2 2 )(3 3).....))
; use (repeat (length lst)
(vlax-ldata-put (nth 0 (nth x lst)) (nth x lst)) 
(setq x (+ x 1))

 

I will check the code again using dxf code method you have to associate like elements to a dxf code a 10 is normally a point co-ords so has a x y z, for text it should be the textstring dxf 1 I would use this also for numbers.

 

Screen grab your list post here, type !lst etc the ! before a variable will display variable value if you dont know about this. It would be best to see exactly what you have. It hopefully will be easy to dummy up or cut and paste the output to here or notepad this is what I did starting with what you posted and used a quick replace to make (0 0 -> (list 0 0

Edited by BIGAL
Posted

Roy_043,

Yes, fantastic. The order I loaded the codes was: MP's 1st code, MP's second code, Your Lib code, your 'getXrecdata' function and your testcode. I got the list back intact. Now I want to know how to recover it after I exit the drawing and open it again.

Regards,

Aloy.

Posted

Bigal,

", type !lst etc the !", Yes this is what I have been doing all along for cut & paste until I got this idea of saving the variable values along with the drawing which will be efficient. I will try your code and come back asap.

Thanks.

Aloy

Posted

Roy_043,

OK, making the variable lst global in your TestGet function made it possible to get value attached permanently. However need to load all the five items of code as before except calling TestSet function after opening the drawing with Xrecords.

Many thanks for posting codes you are using.

Aloy.

Posted

Hi Bigal,

This is a very easy method, just one line solution working on the same principle of dictionaries. I will get back to you with my code and the list later.

Thanks very much for the solution.

Aloy

Posted

Roy_043,

Thanks for the link and guidance. Noted that MP (of the SWAMP) has said as late as Feb 2015 that "LData is never mentioned in polite conversations".

Regards,

Aloy

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • Create New...