Author Topic: Quick ODBX Question  (Read 10343 times)

0 Members and 1 Guest are viewing this topic.

Lee Mac

  • Seagull
  • Posts: 12914
  • London, England
Quick ODBX Question
« on: January 15, 2010, 01:59:23 PM »
When iterating through a set of Documents using ObjectDBX, is it best to release the ODBX Document object before opening the next drawing?

jbuzbee

  • Swamp Rat
  • Posts: 851
Re: Quick ODBX Question
« Reply #1 on: January 15, 2010, 02:05:20 PM »
I do.

Once you've created an activex reference to an object it's best to release it.

jb
James Buzbee
Windows 8

Lee Mac

  • Seagull
  • Posts: 12914
  • London, England
Re: Quick ODBX Question
« Reply #2 on: January 15, 2010, 02:08:54 PM »
I do.

Once you've created an activex reference to an object it's best to release it.

jb

I've been reading an AU document, which says:

Quote
How to close a drawing (2 methods)
o (vlax-release-object odoc) ;be sure to save first.
o (vlax-open odoc “filespecification”)
o You basically have an SDI document interface with each ObjectDBX document.

I would, of course, release the ODBX doc after I have finished with all the drawings - but should I release the ODBX doc after each and every drawing is opened?

Sorry if I have repeated my question - just want to be sure  :wink:


T.Willey

  • Needs a day job
  • Posts: 5251
Re: Quick ODBX Question
« Reply #3 on: January 15, 2010, 02:11:49 PM »
I don't.  I don't see a reason to.  It is different than a regular document, as in the ODBX document is more like a application to me, than a document, so I only want one instance of the application open at a time.

Edit:  Adding example code to show what I typically do with ODBX

Code: [Select]
(defun MapDbxDocs ( func dwgList / *error* dbxApp oVer RsltList )
   
    (defun *error* (msg)
       
        (if dbxApp
            (vlax-release-object dbxApp)
        )
        (setq dbxApp nil)
        (if msg
            (prompt (strcat "\n Error--> " msg))
        )
    )
    ;--------------------------------------------
    (setq dbxApp
        (if (< (atoi (setq oVer (substr (getvar "acadver") 1 2))) 16)
            (vla-GetInterfaceObject (vlax-get-acad-object) "ObjectDBX.AxDbDocument")
            (vla-GetInterfaceObject (vlax-get-acad-object) (strcat "ObjectDBX.AxDbDocument." oVer))
        )
    )
    (foreach dwg dwgList
        (if (vl-catch-all-error-p (vl-catch-all-apply 'vla-Open (list dbxApp dwg)))
            (prompt (strcat "\n *** Error opening drawing: " dwg))
            (setq RsltList (cons (cons dwg ((eval func) dbxApp)) RsltList))
        )
    )
    (*error* nil)
    RsltList
)

Found here for a example
http://www.theswamp.org/index.php?topic=29933.0
Tim

I don't want to ' end-up ', I want to ' become '. - Me

Please think about donating if this post helped you.

Lee Mac

  • Seagull
  • Posts: 12914
  • London, England
Re: Quick ODBX Question
« Reply #4 on: January 15, 2010, 02:24:09 PM »
Thanks Tim  8-)

Here is the result of my efforts:

Code: [Select]
(defun c:CheckLayers (/ *error* ObjRelease DirDialog Get_Subs ObjectDBXDocument GetLayers Str-Make

                        DBX DOCLST DWLST FILE FOLDER LAYER_LIST PATH SHELL)
  (vl-load-com)
  ;; Lee Mac  ~  15.01.10
 

  (defun *error* (msg)
    (ObjRelease (list Shell dbx))
    (and ofile (= (type ofile) 'FILE) (close ofile))
   
    (or (wcmatch (strcase msg) "*BREAK,*CANCEL*,*EXIT*")
        (princ (strcat "\n** Error: " msg " **")))
    (princ))


  (defun ObjRelease (lst)
    (mapcar
      (function
        (lambda (x)
          (if (and (eq (type x) 'VLA-OBJECT)
                   (not (vlax-object-released-p x)))
            (vl-catch-all-apply
              (function vlax-release-object) (list x))))) lst))
 

  (defun DirDialog (msg dir flag / Shell Fold Path)
    ;; Lee Mac  ~  07.06.09
   
    (setq Shell (vla-getInterfaceObject *acad "Shell.Application")
          Fold  (vlax-invoke-method Shell 'BrowseForFolder
                  (vla-get-HWND *acad) msg flag dir))
    (vlax-release-object Shell)
   
    (if Fold
      (progn
        (setq Path (vlax-get-property
                     (vlax-get-property Fold 'Self) 'Path))
        (vlax-release-object Fold)
       
        (and (= "\\" (substr Path (strlen Path)))
             (setq Path (substr Path 1 (1- (strlen Path)))))))
   
    Path)


  (defun Get_Subs (folder / file) ;; CAB
    (mapcar
      (function
        (lambda (x) (setq file (strcat folder "\\" x))
                    (cons file (apply (function append) (get_subs file)))))
        (cddr (vl-directory-files folder nil -1))))

 
  (defun ObjectDBXDocument (/ acVer)
   
    (vla-GetInterfaceObject *acad
      (if (< (setq acVer (atoi (getvar "ACADVER"))) 16) "ObjectDBX.AxDbDocument"
        (strcat "ObjectDBX.AxDbDocument." (itoa acVer)))))
 

  (defun GetLayerProperties (doc / lst)
    (vlax-for lay (vla-get-Layers doc)
      (setq lst (cons
                  (mapcar
                    (function
                      (lambda (property)
                        (vl-princ-to-string
                          (vlax-get-property lay property))))

                    '(Name Color Linetype LineWeight))

                  lst)))
   
    (vl-sort lst
      (function
        (lambda (a b) (< (car a) (car b))))))

 
  (defun Str-Make  (lst del / Pad str x i)
    (setq i 10)

    (defun Pad  (Str Del Len)
      (while (>= (strlen Str) Len) (setq Len (+ Len 5)))
      (while (< (strlen Str) Len)
        (setq Str (strcat Str Del)))
      Str)

    (apply (function strcat)
           (reverse
             (cons (last lst)
                   (mapcar
                     (function
                       (lambda ($str)
                         (Pad $str del
                              (setq i (abs (- 40 i))))))

                     (cdr (reverse lst)))))))
   

  (setq *acad (cond (*acad) ((vlax-get-acad-object)))
        *doc  (cond (*doc ) ((vla-get-ActiveDocument *acad))))

  (or *def* (setq *def* "Yes"))
 

  (if (and (setq Path (DirDialog "Select Directory" nil 0))
           (vl-file-directory-p Path)
           (setq outfile (getfiled "Output File" "" "txt" 1)))
    (progn

      (initget "Yes No")
      (setq *def* (cond ((getkword
                           (strcat "\nProcess SubDirectories? <" *def* "> : "))) (*def*)))

      (vlax-for doc (vla-get-Documents *acad)
        (setq DocLst
          (cons (cons (strcase (vla-get-FullName doc)) doc) DocLst)))
     

      (foreach dwg (setq dwLst (apply (function append)
                                       (vl-remove 'nil
                                         (mapcar
                                           (function
                                             (lambda (Path)
                                               (mapcar
                                                 (function
                                                   (lambda (File)
                                                     (strcat Path "\\" File)))
                                                 (vl-directory-files Path "*.dwg" 1))))
                                           (append (list Path)
                                                   (apply (function append)
                                                          (if (= "YES" (strcase *def*))
                                                            (Get_Subs Path))))))))

        (setq dbx (cdr (assoc (strcase dwg) DocLst)))       

        (and (not dbx) (setq dbx (ObjectDBXDocument)))
       

        (if (not (vl-catch-all-error-p
                    (vl-catch-all-apply
                      (function vla-open) (list dbx dwg))))

          (setq Layer_List (cons (cons dwg (GetLayerProperties dbx)) Layer_List))
          (setq Layer_List (cons (cons dwg '(("**Error Opening this Drawing **"))) Layer_List))))
               

      (princ (strcat "\n<< " (itoa (length dwLst)) " Drawings Processed >>")))
   
    (princ "*Cancel*"))

  (ObjRelease (list Shell dbx)) (gc) (gc)

  (if (and Layer_List
          (setq ofile (open outfile "w")))
    (progn
     
      (mapcar
        (function
          (lambda (x)
            (write-line (car x) ofile)
            (write-line (Str-Make '("Name" "Colour" "LineType" "LineWeight") (chr 32)) ofile)
            (mapcar
              (function
                (lambda (y)
                  (write-line
                    (Str-Make y (chr 32)) ofile))) (cdr x))
           
            (write-line "\n" ofile)))

        Layer_List)

      (close ofile))

    (princ "\n*Cancel*"))

  (princ))

Will list all Layers in a Folder of Drawings  :-)
« Last Edit: January 15, 2010, 08:23:09 PM by Lee Mac »

T.Willey

  • Needs a day job
  • Posts: 5251
Re: Quick ODBX Question
« Reply #5 on: January 15, 2010, 03:09:22 PM »
Hard for me to follow your code.   :-)

One thing I did see though that I would change is that you are stepping through the document collection for every file name.  Just step through it once, making an associated list of drawing path and document, and then just see if the path is within the list.  May save a little bit of time.  No sense stepping though something 50 times when you only need to once.
Tim

I don't want to ' end-up ', I want to ' become '. - Me

Please think about donating if this post helped you.

Lee Mac

  • Seagull
  • Posts: 12914
  • London, England
Re: Quick ODBX Question
« Reply #6 on: January 15, 2010, 03:22:29 PM »
Hard for me to follow your code.   :-)

I try to make it clear as possible... :angel:

One thing I did see though that I would change is that you are stepping through the document collection for every file name.  Just step through it once, making an associated list of drawing path and document, and then just see if the path is within the list.  May save a little bit of time.  No sense stepping though something 50 times when you only need to once.

Ahh good point Tim - will do.

Lee Mac

  • Seagull
  • Posts: 12914
  • London, England
Re: Quick ODBX Question
« Reply #7 on: January 15, 2010, 03:29:33 PM »
Code updated to reflect Tim's Idea  :-)

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Re: Quick ODBX Question
« Reply #8 on: January 15, 2010, 03:48:31 PM »
Nice one Lee.
Does not report failed DWGs though. :evil:
I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.

T.Willey

  • Needs a day job
  • Posts: 5251
Re: Quick ODBX Question
« Reply #9 on: January 15, 2010, 03:57:13 PM »
I think it's the indentation you use, but that is person preference, and I can understand it, it just takes me longer than I like.  The hardest part is finding the end of you sub's to me, or any long indentation portion.  If I opened it in an editor, I could check that easier, but then I would have to copy/paste it to an editor.   :wink:

One thing to watch out on is the name of drawings.  You should make the all one case, upper/lower, and then test the name the same way.

ps. This is a perfect example ( idea of code ) of how my MapDbxDocs routine could be used. :wink:
Tim

I don't want to ' end-up ', I want to ' become '. - Me

Please think about donating if this post helped you.

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Re: Quick ODBX Question
« Reply #10 on: January 15, 2010, 04:07:19 PM »
Mod of your subroutine to try out. 8-)
Code: [Select]
(defun Str-Make (lst del / Pad str)

  (defun Pad (pStr pDel Len)
    (while (>= (strlen pStr) len)(setq len (+ len 10)))
    (while (< (strlen pStr) Len)
      (setq pStr (strcat pStr pDel))
    )
    pStr
  )

  (mapcar (function (lambda(str$ len#)
      (cond ((null str) (setq str (Pad str$ del len#)))
    ((setq str (strcat Str (Pad str$ del len#)))))))
  lst '(30 10 30 10))
  str
)
I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.

Lee Mac

  • Seagull
  • Posts: 12914
  • London, England
Re: Quick ODBX Question
« Reply #11 on: January 15, 2010, 04:11:57 PM »
Nice one Lee.
Does not report failed DWGs though. :evil:


Nice catch CAB - code updated.  :-)

Lee Mac

  • Seagull
  • Posts: 12914
  • London, England
Re: Quick ODBX Question
« Reply #12 on: January 15, 2010, 04:19:37 PM »
Mod of your subroutine to try out. 8-)

Thanks Alan,

Its good for this routine - as the del is a space   :-)

Also, the resultant string will end with the delimiter...  but I like the way that it extends the length of the padding  :-)

Lee Mac

  • Seagull
  • Posts: 12914
  • London, England
Re: Quick ODBX Question
« Reply #13 on: January 15, 2010, 04:24:40 PM »
Perhaps this instead?

Code: [Select]
(defun Str-Make  (lst del / Pad str x i)
  (setq i 10)

  (defun Pad  (Str Del Len)
    (while (>= (strlen Str) Len) (setq Len (+ Len 5)))
    (while (<  (strlen Str) Len)
      (setq Str (strcat Str Del)))
    Str)

  (apply (function strcat)
         (reverse (cons (last lst)
                        (mapcar
                          (function
                            (lambda ($str) (Pad $str del (setq i (abs (- 40 i))))))

                          (cdr (reverse lst)))))))

CAB, can you see any way of streamlining this a bit more?  I should imagine the "reverse" takes a bit of time...
« Last Edit: January 15, 2010, 05:05:56 PM by Lee Mac »

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Re: Quick ODBX Question
« Reply #14 on: January 15, 2010, 06:57:08 PM »
How about this?
Code: [Select]
(defun Str-Make (lst del / Pad str)

  (defun Pad (pStr pDel Len)
    (or (zerop len)
        (while (>= (strlen pStr) len) (setq len (+ len 10)))
        (while (< (strlen pStr) Len) (setq pStr (strcat pStr pDel)))
    )
    pStr
  )

  (mapcar (function (lambda(str$ len#)
      (cond ((null str) (setq str (Pad str$ del len#)))
    ((setq str (strcat Str (Pad str$ del len#)))))))
  lst '(30 10 30 0))
  str
)
I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.