Results 1 to 8 of 8

Thread: Long Term outlook for LDATA

  1. #1
    Member jrd.chapman's Avatar
    Join Date
    2000-11
    Location
    Ontario, Canada
    Posts
    49
    Login to Give a bone
    0

    Default Long Term outlook for LDATA

    I commonly use LDATA in my Lisp routines to store various custom settings. The way my brain works, LDATA is the easiest way to code the storage of custom settings. That's not to say that other methods (Dictionary/XRecord functions) aren't better or more logical.

    Robert Bell once told me:
    BTW, I noticed that you are using LData. I would strongly recommend not using LData, but rather use straight Dictionary/XRecord functions. LData cannot be read by VBA, and might not be available via .NET either. Very bad for long-term data storage.
    My questions are:

    1.) If one has no plans to ever use VBA or .NET (regardless of whether that presents limitations), then is it still unwise to continue the use of LDATA?

    2.) Is it at all likely or imminent that LDATA will become obsolete / incompatible within future versions of CAD?

    3.) Is it at all likely or imminent that LISP itself will become obsolete / incompatible within future versions of CAD?

    I love using LISP to tweak the CAD experience, partly because it is the only language I've taken the time to learn, but I love it nontheless. I would be sad to see it phased out of it's functionality with CAD.

    Any opinions?

    ....Robert, your expertise is unquestionable and I would love if you could expand on what you told me originally.

    Thanks in advance!

  2. #2
    All AUGI, all the time
    Join Date
    2015-12
    Location
    Central Oregon
    Posts
    591
    Login to Give a bone
    0

    Default Re: Long Term outlook for LDATA

    In a message posted to the Autodesk newsgroup "autocad.customization" by Tony Tanzillo:
    Quote Originally Posted by Tony
    LDATA is just a way to 'encrypt' your data in a
    dictionary, using a custom object. In fact, in
    some circumstances (opening a file by double-
    clicking in explorer) you can see proxy notices
    when you open a file with LDATA.

    The only thing LDATA offers is that it preserves
    the original list structure, which is something
    that is useful only to entry level programmers.

    The disadvantages is that it is a way to lock
    your data up in a way that can potentially
    render it completely inaccessible, which is
    what happened when R14 drawings were migrated
    to AutoCAD 2000.

    You can use Dictionaries and XRecords to store
    anything you can store in LDATA and can access
    it via any API you might choose to use.

    In short, stay as far away from LDATA as you
    can possibly get.

  3. #3
    Member jrd.chapman's Avatar
    Join Date
    2000-11
    Location
    Ontario, Canada
    Posts
    49
    Login to Give a bone
    0

    Default Re: Long Term outlook for LDATA

    The only thing LDATA offers is that it preserves
    the original list structure, which is something
    that is useful only to entry level programmers.
    Ouch!!! My ego is permananetly scarred.....I jest. I'm certainly not an expert.

    Point taken.

    Now, I don't pretend to know anything about using Xrecords, as I've only scraped the surface. But, If I wanted to make the switch, I would take, for example, 50 custom drawing settings stored as Ldata inside a custom dictionary, and create 50 separate Xrecords. Am I right? For example, storing the text height for multiple different Text Styles would require an Xrecord for each.

    The only way I know how to create Xrecords is like this:
    Code:
       (if (setq xlist (dictsearch (namedobjdict) "TextStyleNameHere"))
      	(entdel (cdr (assoc -1 xlist)))
        )
        (setq xrec (list '(0 . "XRECORD")
     					    '(100 . "AcDbXrecord")
     					    '(1 . "TextStyleNameHere")
      	    			    '(40 . 2.5)
     					    '(blah . blah..if there's more stuff to put.)
      				  )
        )
        (setq xname (entmakex xrec))
        (dictadd (namedobjdict) "TextStyleNameHere" xname)
    The above works for me when adding a new record or changing an existing one (deleteing and re-creating). This is virtually straight from the Visual Lisp Help files.
    If that's the case, I can acheive the same with one line of code using LDATA
    Code:
    (vlax-ldata-put "MyDictionary" "TextStyleNameHere" 2.5)
    I know that I could store multiples inside one Xrecord, but am not sure how I would extract the info to change it. I must be missing something (more like probably).

    I've gone through 5 versions of CAD using LDATA (2000i, 2002, 2004, 2005, and have tested 2006). Drawings that contained LDATA in 2000i have kept it intact the entire way through. However, if there was data loss in migration from 14 to 2000, than I guess the risk is there for it to happen again. Although, for my purposes, if a drawing lost it's LDATA it would not be a catastrophic loss, and easy to re-create.

    For someone that has no intention of using another API, and who does not care if stored data gets lost, it just seems like LDATA is the more logical choice, entry-level or expert alike. But, again, I speak without knowing all the facts and methods for coding the use of Xrecords.

    But, I digress. Back to the original question: Regardless of whether or not some would advise against it's use, I was just curious as to whether or not Robert's comment to me a while back was rooted in some knowledge that LDATA may become obsolete at some point in time.

  4. #4
    Past Vice President / AUGI Volunteer peter's Avatar
    Join Date
    2000-09
    Location
    Honolulu HI
    Posts
    1,109
    Login to Give a bone
    0

    Default Re: Long Term outlook for LDATA

    LDATA is a useful tool.

    Use and program lisp it isn't going away as long as AutoCAD is around. That is the official word from the Autodesk Developers Network and Autodesk.

    Ldata is a very useful, and many times easier method of storing data on graphic entities than xdata or dictionaries. If you like it use it. I use both ldata and xdata and have been trying to use xdata more than ldata lately. Frequently I regret using xdata because ldata is more versitile. Lists are very powerful, and vba is much more difficult to code to do even simple tasks because it doesn't have them. Like there is no mapcar in vba...

    It isn't very difficult to code a lisp module to report or store lisp data back to or from any other language including vba or vb.net. So lisp data can be used with any language. Depending on the data stored their would probably need to be some manipulation of the data before it reported to the other.

    As far as tony's comment that ldata is onlyy for beginners, a would 100% disagree.

    I think I could say that I am an expert lisp programmer, with 20 year of lisp programming experience, and am very familiar with vba and vb.net to say that that statement is simply not true.

    I think the problem is the programmers who stated their opinion that ldata is bad, simply have not developed the lisp tools to interface with it, using other languages.

    LISP is not going away and if you like to use LDATA use it. If you need some of the interface tools for using it with vba let me know and I will cook one for you.

    Peter Jamtgaard P.E.

  5. #5
    All AUGI, all the time CAB2k's Avatar
    Join Date
    2016-01
    Location
    Brandon, Florida
    Posts
    687
    Login to Give a bone
    0

    Default Re: Long Term outlook for LDATA

    Lot's of stuff to get you going.
    Check this out:
    http://tinyurl.com/8rlhb

    I could not find the source of the following so I'll post it.
    Code:
    ;The following Dictionary functions are as posted to the 
    ;Autodesk customization newsgroup by Juerg Menzi...he 
    ;mentions that the origin is unknown..... 
    ; 
    ; -- Function CreateDict 
    ; Creates a new or returns an existing dictionary. 
    ; Arguments [Typ]: 
    ;   Nme = Name of the new dictionary [STR] 
    ; Return [Typ]: 
    ;   > Entity name of new/existing dictionary [ENAME] 
    ; Notes: 
    ;   None 
    ; 
    (defun CreateDict (Nme / DicEnt NewDic TmpLst) 
     (if (not (setq NewDic (GetDictEnt Nme))) 
      (setq TmpLst '((0 . "DICTIONARY") (100 . "AcDbDictionary")) 
            DicEnt (entmakex TmpLst) 
            NewDic (dictadd (namedobjdict) Nme DicEnt) 
      ) 
      NewDic 
     ) 
    ) 
    ; 
    ; -- Function DelDict 
    ; Deletes the specified dictionary. 
    ; Arguments [Typ]: 
    ;   Nme = Name of the dictionary to delete [STR] 
    ; Return [Typ]: 
    ;   > Entity name [ENAME] 
    ; Notes: 
    ;   None 
    ; 
    (defun DelDict (Nme) 
     (dictremove (namedobjdict) Nme) 
    ) 
    ; 
    ; -- Function AddDictRec 
    ; Adds a record to a dictionary. 
    ; Arguments [Typ]: 
    ;   Nme = Name of dictionary to access [STR] 
    ;   Key = Keyname for the record object [STR] 
    ;   Lst = Data list '((Key1 . Value1)...(Keyx . Valuex)) [LIST]
    ; Return [Typ]: 
    ;   > Entity name of modified dictionary [ENAME] 
    ; Notes: 
    ;   None 
    ; 
    (defun AddDictRec (Nme Key Lst / DicEnt TmpLst) 
     (setq TmpLst (append 
                  '((0 . "XRECORD") (100 . "AcDbXrecord") (280 . 0)) 
                   Lst 
                  ) 
           DicEnt (entmakex TmpLst) 
     ) 
     (dictadd (GetDictEnt Nme) Key DicEnt) 
    ) 
    ; 
    ; -- Function GetDictRec 
    ; Retrieves the data list by key from a dictionary. 
    ; Arguments [Typ]: 
    ;   Nme = Name of dictionary to access [STR] 
    ;   Key = Keyname for the record object [STR] 
    ; Return [Typ]: 
    ;   > Data list [LIST]
    ; Notes: 
    ;   None 
    ; 
    (defun GetDictRec (Nme Key) 
     (cdr (cddddr (cddddr (dictsearch (GetDictEnt Nme) Key)))) 
    ) 
    ; 
    ; -- Function ChgDictRec 
    ; Redefines the specified record of a dictionary. 
    ; Arguments [Typ]: 
    ;   Nme = Name of dictionary to access [STR] 
    ;   Key = Keyname for the record object [STR] 
    ;   Lst = Data list '((Key1 . Value1)...(Keyx . Valuex)) [LIST]
    ; Return [Typ]: 
    ;   > Entity name of modified dictionary [ENAME] 
    ; Notes: 
    ;   None 
    ; 
    (defun ChgDictRec (Nme Key Lst) 
     (if (GetDictRec Nme Key) 
      (progn 
       (DelDictRec Nme Key) 
       (AddDictRec Nme Key Lst) 
      ) 
     ) 
    ) 
    ; 
    ; -- Function DelDictRec 
    ; Deletes the specified record from a dictionary. 
    ; Arguments [Typ]: 
    ;   Nme = Name of dictionary to access [STR] 
    ;   Key = Keyname for the record object [STR] 
    ; Return [Typ]: 
    ;   > Entity name of modified dictionary [ENAME] 
    ; Notes: 
    ;   None 
    ; 
    (defun DelDictRec (Nme Key) 
     (dictremove (GetDictEnt Nme) Key) 
    ) 
    ; 
    ; -- Function GetDictKeys 
    ; Returns a list of keynames from the specified dictionary. 
    ; Arguments [Typ]: 
    ;   Nme = Name of dictionary to access [STR] 
    ;   Key = Keyname for the record object [STR] 
    ; Return [Typ]: 
    ;   > Key list [LIST]
    ; Notes: 
    ;   None 
    ; 
    (defun GetDictKeys (Nme / TmpLst) 
     (cond 
      ((setq TmpLst (GetDict Nme)) (GetMassoc 3 TmpLst)) 
      (T nil) 
     ) 
    ) 
    ; 
    ; -- Function GetDictKeysVals 
    ; Returns a list of keynames with associated values from the 
    ; specified dictionary. 
    ; Arguments [Typ]: 
    ;   Nme = Name of dictionary to access [STR] 
    ; Return [Typ]: 
    ;   > Key value list '((Key1 . Value1)...(Keyx . Valuex)) [LIST]
    ; Notes: 
    ;   None 
    ; 
    (defun GetDictKeyVals (Nme) 
     (mapcar 
     '(lambda (l) 
       (cons l (cdar (GetDictRec Nme l))) 
      ) (GetDictKeys Nme) 
     ) 
    ) 
    ; 
    ; -- Function ListDicts 
    ; Returns a list of all dictionaries in the current drawing. 
    ; Arguments [Typ]: 
    ;   --- = 
    ; Return [Typ]: 
    ;   > List of dictionaries [LIST]
    ; Notes: 
    ;   None 
    ; 
    (defun ListDicts () 
     (GetMassoc 3 (entget (namedobjdict))) 
    ) 
    ; 
    ; -- Function GetDict 
    ; Retrieves the entity definition list of the specified dictionary. 
    ; Arguments [Typ]: 
    ;   Nme = Name of the dictionary [STR] 
    ; Return [Typ]: 
    ;   > Entity definition of dictionary [LIST]
    ; Notes: 
    ;   None 
    ; 
    (defun GetDict (Nme) 
     (dictsearch (namedobjdict) Nme) 
    ) 
    ; 
    ; -- Function GetDictEnt 
    ; Retrieves the entity name of the specified dictionary. 
    ; Arguments [Typ]: 
    ;   Nme = Name of the dictionary [STR] 
    ; Return [Typ]: 
    ;   > Entity name of dictionary [ENAME] 
    ; Notes: 
    ;   None 
    ; 
    (defun GetDictEnt (Nme / TmpLst) 
     (cond 
      ((setq TmpLst (GetDict Nme)) (GetAssoc -1 TmpLst)) 
      (T nil) 
     ) 
    ) 
    ; 
    ; -- Function GetMassoc 
    ; Get multiple associative values from a list. 
    ; Arguments [Typ]: 
    ;   Key = Key to search [INT] 
    ;   Lst = Dotted pair list [LIST]
    ; Return [Typ]: 
    ;   > List of values [LIST]
    ; Notes: 
    ;   Published by T.Tanzillo 
    ; 
    (defun GetMassoc (Key Lst) 
     (apply 'append 
      (mapcar 
       '(lambda (l) (if (eq (car l) Key) (list (cdr l)))) Lst 
      ) 
     ) 
    ) 
    ; 
    ; -- Function GetAssoc 
    ; Get associative value from a list. 
    ; Arguments [Typ]: 
    ;   Key = Key to search [INT] 
    ;   Lst = Dotted pair list [LIST]
    ; Return [Typ]: 
    ;   > Value [ALL] 
    ; Notes: 
    ;   None 
    ; 
    (defun GetAssoc (Key Lst) 
     (cdr (assoc Key Lst)) 
    )

  6. #6
    Member jrd.chapman's Avatar
    Join Date
    2000-11
    Location
    Ontario, Canada
    Posts
    49
    Login to Give a bone
    0

    Default Re: Long Term outlook for LDATA

    Peter,

    Thank you very much for your reply! I don't feel alone anymore!! It is good to know that the language we love so much is not going anywhere.

    ab2draft,

    Thanks very much for the nudge in with respect to Xrecords!! Much appreciated!

  7. #7
    Past Vice President / AUGI Volunteer peter's Avatar
    Join Date
    2000-09
    Location
    Honolulu HI
    Posts
    1,109
    Login to Give a bone
    0

    Default Re: Long Term outlook for LDATA

    If you are interested in using dictionaries here are some functions that I had laying around that I cooked a couple years ago.

    It shows both ways of storing and retrieving data (list of strings) in a dictionary.
    Code:
    ; Written By: Peter Jamtgaard  copr 2002
    ;********************************************************************************************
    ; Dictlist2 is the Entity method of creating a dictionary
    ;********************************************************************************************
    (defun DICTLIST (DICTNAM STRLST / BOMDICT CNT DATALST DICT)
     (if (dictsearch (namedobjdict) DICTNAM) (dictremove (namedobjdict) DICTNAM))
     (setq DICT	'((0 . "DICTIONARY") (100 . "AcDbDictionary"))
    	   BOMDICT (dictadd (namedobjdict) DICTNAM (entmakex DICT))
    	   CNT	 0
     )
     (repeat (length STRLST)
      (setq DATALST (list (cons 1 (nth CNT STRLST)))
    		DATALST (append (list '(0 . "XRECORD") '(100 . "AcDbXrecord")) DATALST)
      ) 
      (dictadd (cdr (assoc -1 (dictsearch (namedobjdict) DICTNAM))) (itoa CNT) (entmakex DATALST))
      (setq CNT (1+ CNT))
     )
    )
    ;********************************************************************************************
    ; Dictlist2 is the Activex method of creating a dictionary 
    ; Arguments are a dictionary name and a list of strings
    ;******************************************************************************************** 
    (defun DICTLIST2 (DICTNAM STRLST / CNT INTSA VARSA STRVAR DICTOBJ DICTSOBJ) 
     (setq DICTSOBJ 
      (vla-get-dictionaries
       (vla-get-activedocument
    	(vlax-get-acad-object))))
     (vl-catch-all-apply 
      '(lambda (X)(vla-delete (vla-item DICTSOBJ X)))
       (list DICTNAM)) 
     (setq DICTOBJ (vla-add DICTSOBJ DICTNAM)
    	   CNT	 0
    	   INTSA  (vlax-make-safearray vlax-vbInteger '(0 . 0))
    	   VARSA  (vlax-make-safearray vlax-vbVariant '(0 . 0))
     )
     (vlax-make-variant (vlax-safearray-fill INTSA (list 1)))
     (foreach N STRLST
      (setq XRECOBJ (vla-addxrecord DICTOBJ (itoa CNT))		
    		CNT	 (1+ CNT)
      )
      (vlax-safearray-fill VARSA  (list (vlax-make-variant N vlax-vbString)))
      (vla-setxrecorddata XRECOBJ INTSA VARSA)
     )
    )
    ;********************************************************************************************
    ;Getdict is the way of retrieving data from a dictionary using entity methods
    ;********************************************************************************************
    (defun GET_DICTLIST (DICTNAM / STRLST INTSA VARSA)
     (vl-load-com)
     (if (setq DICT (dictsearch (namedobjdict) DICTNAM))
      (progn
       (setq STRLST (list  (cdr (assoc 1 (dictnext (cdr (assoc -1 DICT)) 't)))))
       (while (setq DICT1 (dictnext (cdr (assoc -1 DICT))))
    	(setq STRLST (cons (cdr (assoc 1 DICT1)) STRLST))
       )
       (reverse STRLST))))
    
    ;********************************************************************************************
    ;Getdict is the way of retrieving data from a dictionary using activeX.
    ;********************************************************************************************
    (defun GET_DICTLIST2 (DICTNAM / STRLST INTSA VARSA)
     (vl-load-com)
     (if (not
    	  (vl-catch-all-error-p
    	   (vl-catch-all-apply 'vla-item 
    						   (list
    								 (vla-get-dictionaries
    								  (vla-get-activedocument
    								   (vlax-get-acad-object)))
    								 DICTNAM))))		   
      (progn
       (vlax-for FOR-ITEM
    	(vla-item
    	 (vla-get-dictionaries
    	  (vla-get-activedocument
    	   (vlax-get-acad-object)))
    	 DICTNAM)
    	(vla-getxrecorddata FOR-ITEM 'INTSA 'VARSA)
    	(setq STRLST (cons (variant-value (car (vlax-safearray->list VARSA))) STRLST)) 
       )
       (reverse STRLST))))
    Attached Files Attached Files

  8. #8
    Member jrd.chapman's Avatar
    Join Date
    2000-11
    Location
    Ontario, Canada
    Posts
    49
    Login to Give a bone
    0

    Default Re: Long Term outlook for LDATA

    Thanks again to ab2draft and Peter. Certainly a great start for getting more involved with the use of Xrecords. Much appreciated!

Similar Threads

  1. 2015: REVIT Model Pausing randomly - Renaming central temporarily fixes - Need long-term solution
    By mnewburn700596 in forum Revit Architecture - General
    Replies: 4
    Last Post: 2015-08-03, 04:41 PM
  2. 2013: Long Term MicroStation user learning AutoCAD 2013
    By blothian in forum AutoCAD General
    Replies: 46
    Last Post: 2013-06-17, 06:44 PM
  3. Buy for the short or long term?
    By ctwith3 in forum Revit - Hardware & Operating Systems
    Replies: 1
    Last Post: 2011-02-21, 08:20 PM
  4. Long term on-going projects
    By DaveP in forum Revit - In Practice
    Replies: 5
    Last Post: 2008-04-24, 04:40 PM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •