Dictionary and vla-copyObjects

Discussion in 'AutoCAD' started by rgood, Oct 13, 2004.

  1. rgood

    rgood Guest

    I am attempting to copy a custom dictionary from another drawing using dbx and vla-copyobjects method.
    After I copy the dictionary to the current drawing, i notice that the dictionary is empty. Im guessing the copyobjects method only copies the dictionary and no information within the dictionary. (unless im missing something.)
    If this is true?

    (vla-copyobjects
    dbxDoc
    (vlax-safearray-fill
    (vlax-make-safearray vlax-vbobject '(0 . 0)) ;_ end of vlax-make-safearray
    (list
    (vla-item (vla-get-dictionaries dbxDoc) "LandQ_Master")
    ) ;_ end of list
    ) ;_ end of vlax-safearray-fill
    (vla-get-dictionaries gActiveDoc) ;_Copy to current doc dictionaries table
    ) ;_ end of vla-CopyObjects



    Robert Good.
     
    rgood, Oct 13, 2004
    #1
  2. rgood

    rgood Guest

    my only guess on this would be how I created the dictionary

    (setq vMasterDict (vla-add (vla-get-dictionaries xDoc) "DataDict"))

    after the dictionary has been created, it does not have an application property, which im guessing might give me the errors I am encountering.

    I try to add the application property after creation:
    (vlax-put-property vMasterDict 'Application (vla-get-application gAcadObject))

    gives me the error 'type mismatch.

    questions:
    1. Are the errors caused by the lack of applcation property?
    2. How do you assign an application property to a dictionary?



    Robert Good.
     
    rgood, Oct 13, 2004
    #2
  3. rgood

    MP Guest

    I'm not positive, but since no one has responded you might double check the
    docs on copyobjects
    I think the new owner should be the target doc, not the dictionaries
    collection
    hth
    Mark

    dictionary is empty. Im guessing the copyobjects method only copies the
    dictionary and no information within the dictionary. (unless im missing
    something.)
     
    MP, Oct 13, 2004
    #3
  4. rgood

    rgood Guest

    Mark,
    I verified that this afternoon. i got an error when I tried copying the dictionary to the target doc instead of the target docs dictionary object

    Thanks for the response.
    Rob.
     
    rgood, Oct 13, 2004
    #4
  5. rgood

    MP Guest

    yep, yer right, I was wrong about that thought.
    Looks like it should work.
    I haven't used dictionaries so don't have any thing I can test with quickly.
    just checked google to see if there was anything there and most of it is
    posts by you in the past few weeks

    what about
    vlaxfor each oRec in oDict
    copyobjects odoc orec oNewDict
    etc
    ?
    dictionary to the target doc instead of the target docs dictionary object
     
    MP, Oct 13, 2004
    #5
  6. rgood

    rgood Guest

    I had an idea last night that I had to test. I created the dictionary in the dbx document with vla functions. when doing this and looking into the dictionary, it did not have an 'appliction property in the dict object. So I created the dictionary by the ole lisp methods and created a dict that did contain the application property.
    After I vla-copyobjects the new dict, I still had the same problem with no records included with the copy.

    Ill attempt your suggestion on copying the records individually with the vlax-for function.

    Thanks.

    Rob.
     
    rgood, Oct 14, 2004
    #6
  7. rgood

    Joe Burke Guest

    Robert,

    Here's a bunch of functions to play with. They are related to your question in
    various ways. They do not include full error checking, though some.

    BTW, I don't think you mentioned what type of data associated with a dictionary you
    are trying to copy to other documents. These functions assume the data type is one or
    more xrecords.

    I played with this about a year ago. I found, as you did, the CopyObects method
    didn't work. In fact, the result was multiple dictionaries added in the target
    document with names like *A1. Not good.

    So while revisting the question, I tried using the blackboard to copy/transfer
    dictionaries to other documents. It seems to do the trick correctly. For
    demonstration purposes only, I'm simply copying the dictionary and associated
    xrecords to all open files. Of course you could extend this to ODBX files.

    HTH and yes I know, it's an odd mix of vanilla lisp and vlisp.
    Joe Burke

    ;; function: copy dictionary name and associated xrecords from
    ;; the active file to all other open files via the blackboard namespace
    ;; returns T if successful, otherwise nil
    (defun c:CopyDictBB ( / documents name dictobj targdicts
    dict newdict ename xrname )
    (princ "\nCopy dictionary from the active file to all open files. ")
    (and
    (setq documents (vla-get-documents (vlax-get-acad-object)))
    (setq name (getstring T "\nEnter dictionary name to copy: "))
    (setq dictobj (GetDictionary name))
    (vl-bb-set 'bbdict dictobj)
    (vlax-for x documents
    (setq targdicts (vla-get-Dictionaries x))
    (setq dict (vl-bb-ref 'bbdict))
    (setq dictname (vlax-get dict 'Name))
    (setq newdict (vlax-invoke targdicts 'Add dictname))
    (setq ename (vlax-vla-object->ename newdict))
    (foreach x (GetXRecords dictname)
    (setq xrname (vlax-get (vlax-ename->vla-object x) 'Name))
    (dictadd ename xrname x)
    )
    ) ;for
    ) ;and
    ) ;end

    ;argument: string - dictionary name
    ;returns: the dictionary as a vla-object, or nil if not found
    (defun GetDictionary ( name / elst res )
    (and
    (setq elst (dictsearch (namedobjdict) name))
    (setq res (vlax-ename->vla-object (cdr (assoc -1 elst))))
    )
    res
    ) ;end

    ;argument: string - dictionary name
    ;returns: a list of xrecord enames found in dictionary, or nil if none found
    (defun GetXRecords ( name / elst xrlst )
    (setq elst (dictsearch (namedobjdict) name))
    (foreach x elst
    (if
    (and
    (= 350 (car x))
    (= "XRECORD" (cdr (assoc 0 (entget (cdr x)))))
    )
    (setq xrlst (cons (cdr x) xrlst))
    )
    )
    (reverse xrlst)
    ) ;end

    ;; ---------------------------------------------------------
    ;; function: add a dictionary to the dictionaries collection
    ;; and add an xrecord to the new dictionary
    ;; arguments:
    ;; dictname: string - dictionary name
    ;; xrname: string - xrecord name
    ;; lst: a quoted association list
    ;; example: '((7 . "Romans") (8 . "LayerName") (40 . 3.0))
    ;; complete example:
    ;; (addxrec2dict "dict1" "xrec1" '((7 . "Romans") (8 . "LayName") (40 . 3.0)))
    ;; returns: the new xrecord vla-object if successful
    (defun AddXrec2Dict (dictname xrname lst / dicts newdict newxrec typlst datalst)
    (setq dicts
    (vla-get-dictionaries
    (vla-get-activedocument
    (vlax-get-acad-object))))
    ;add dictionary
    (setq newdict (vlax-invoke dicts 'Add dictname))
    ;add xrecord to newdict
    (setq newxrec (vlax-invoke newdict 'AddXRecord xrname))
    ;add data to newxrec
    (foreach x lst
    (setq typlst (cons (car x) typlst))
    (setq datalst (cons (cdr x) datalst))
    )
    (setq typlst (reverse typlst) datalst (reverse datalst))
    (vlax-invoke newxrec 'SetXRecordData typlst datalst)
    newxrec
    ) ;end

    ;; function: return the data contained in an xrecord
    ;; argument: an xrecord vla-object
    (defun GetXRData ( xrec / types values ) ;types values need to be local
    (vla-getxrecorddata xrec 'types 'values)
    (if (and types values)
    (mapcar 'cons (vlax-safearray->list types)
    (mapcar 'vlax-variant-value (vlax-safearray->list values))
    )
    )
    ) ;end
     
    Joe Burke, Oct 17, 2004
    #7
  8. rgood

    rgood Guest

    Joe,
    thanks for the code clip.
    I will test the concept when I finish a current deadline.

    Rob Good.
     
    rgood, Oct 19, 2004
    #8
  9. rgood

    Joe Burke Guest

    Rob,

    You're welcome.

    One thing I noticed, but didn't investigate. Apparently the default value of DXF code
    280 as it applies to a dictionary object is zero. If the 280 code is 1 it means, from
    help DXF reference: "indicates that elements of the dictionary are to be treated as
    hard-owned." Question is, would changing the 280 dictionary code to 1 have an effect
    on what the CopyObjects method does, or doesn't do.

    Joe Burke
     
    Joe Burke, Oct 19, 2004
    #9
  10. rgood

    rgood Guest

    Joe,
    I modified the 280 dxf code to (280 . 1) on a dictionary before vla-copyobject to the current open dwg. I still had the "*A1" name issue.

    I am putting your other code sample to the grind stone this morning.

    Thanks,
    Rob.
     
    rgood, Nov 17, 2004
    #10
  11. rgood

    rgood Guest

    Joe,
    Here is what I derived from your code sample:
    I did not need the black board feature so I took it out.
    I tried to convert some features over to vla functions
    I would like to use vla-copyobjects instead of dictadd but I am weary of the copyobjects function due to our previous issues with the *A1 naming kerplunk.

    ;; Copy dictionary and xrecords from given dictionary to a new dictionary
    ;; (g:copydict <Existing Dictionary> <new Dictionary>)
    ;;
    (defun g:CopyDict (xDictObj xNewDictName / vActiveDicts vDictnewObj vDictEnt vXRecName)

    ;; instead of copying dict to black board
    ;; lets just get the info from the original masterdb.

    (setq vActiveDicts (vla-get-dictionaries gActiveDoc)
    vDictNewObj (vla-add vActiveDicts xNewDictName)
    vDictEnt (vlax-vla-object->ename vDictNewObj)
    ) ;_ end of setq

    (foreach x (GetXRecords xDictObj)
    (setq vXRecName (vla-get-name x))
    (dictadd vDictEnt vXRecName (vlax-vla-object->ename x))
    ) ;_ end of foreach

    ) ;end




    ;argument: string - dictionary name
    ;returns: a list of xrecord enames found in dictionary, or nil if none found
    (defun GetXRecords (xDict / vList)
    (vlax-for x xDict
    (if (= (vla-get-objectname x) "AcDbXrecord")
    (setq vList (cons x vList))
    ) ;_end if
    ) ;_ end of vlax-for
    ) ;_ end defun

    thanks for your help.

    rob.
     
    rgood, Nov 17, 2004
    #11
Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.