Catching Error While Opening ODBX File

Catching Error While Opening ODBX File

ebsoares
Collaborator Collaborator
1,699 Views
14 Replies
Message 1 of 15

Catching Error While Opening ODBX File

ebsoares
Collaborator
Collaborator

Hi, everyone.

I realized I had previously posted this question on the wrong forum (which is I why I was receiving no response...)

I'm pretty new to coding error catching (and ObjectDBX as well), and have been trying to fix a possible error that happens in this routine:

 

; Checks if it is possible to insert block
(defun checkBlock (chkBlock chkFile / )
    (vl-load-com)
    
    ; Check block:
    (if (tblsearch "block" chkBlock) ; checks whether block exists in current drawing
        (insertBlock chkBlock) ; insert if block already exists in current file
        (progn ; if block does not exist in current file, move on to next step
            (if (findfile chkFile) ; check if file exists
                (progn ; if found, insert block from drawing
                    (borrowBlockDBX chkBlock chkFile)
                    (insertBlock chkBlock)
                )
                (princ "\nBlock container file not found")
            )
        )
    )
)

; Insert block:
(defun insertBlock (blockName / )
    (command "-INSERT" blockName PAUSE "1" "1")
    (while (> (getvar 'CMDACTIVE) 0)
        (command PAUSE)
    )
)

(defun borrowBlockDBX (dbxBlock dbxFile / borrowDBX)
    (setq borrowDBX (openFileDBX dbxFile))
    
    (vla-CopyObjects borrowDBX
        (vlax-safearray-fill
            (vlax-make-safearray vlax-vbObject '(0 . 0))
            (list (vla-item (vla-get-blocks borrowDBX) dbxBlock))
        )
        (vla-get-blocks (vla-get-activedocument (vlax-get-acad-object)))
    )
    
    (vlax-release-object borrowDBX) ; Clean-up
)

(defun openFileDBX (dbxFile / dbxOpen)
    (if (setq dbxOpen
            (vlax-create-object
                (strcat    "ObjectDBX.AxDbDocument." (substr (getvar "ACADVER") 1 2) )
            )
        )
        (if (vl-catch-all-apply 'vla-open (list dbxOpen dbxFile))
            (not (vlax-release-object dbxOpen))
            dbxOpen
        )
        (princ "\nUnable to create object")
    )
)

 

The pseudo-code is basically this:

  1. check if desired block (chkBlock) is already defined in current drawing
  2. if it is there, just go through the insert command
  3. if it is not, check if provided filepath drawing (chkFile) exists
  4. if it exists, try to open that file in the background (DBX), and copy that block's definition from that file to the current one and close the background file - then go through the insert command
  5. if it can't open the file, warn the user that the file is opened by someone else

So far, it works like a charm - unless the background file is in use by someone else, then it stops and gives me error messages. I already put an error catch in the openFileDBX function, but it doesn't quite work and I can't understand why...

 

Thanks in advance,

 

Edgar

0 Likes
Accepted solutions (1)
1,700 Views
14 Replies
Replies (14)
Message 2 of 15

Moshe-A
Mentor
Mentor

@ebsoares  hi,

 

>> (vla-open) method <<

 

The 3th argument of (vla-open) method called [, Readonly] by default it's False which means open the file in read-write (sounds weird? Smiley LOL).  if you change it to True it will open the file in read mode only so maybe this could solve your problem?

 

moshe

 

0 Likes
Message 3 of 15

ebsoares
Collaborator
Collaborator

Hi, @Moshe-A 

Always opening the file as "read-only" would be the best solution for this routine (cause then it would never care if the file is editable or not) - but I don't understand VBA or how to change the current vla-open function to "True".

Could you guide me there?

Thanks,

Edgar

0 Likes
Message 4 of 15

dgorsman
Consultant
Consultant

Something else.  When you call the function to get the ODBX document, it returns nil if the file cannot be opened.  But you don't test for that prior to use.

----------------------------------
If you are going to fly by the seat of your pants, expect friction burns.
"I don't know" is the beginning of knowledge, not the end.


0 Likes
Message 5 of 15

Moshe-A
Mentor
Mentor

correct this line:

 

(vl-catch-all-apply 'vla-open (list dbxOpen dbxFile :vlax-true)

 

As said, by default it is vlax-false which mean read-write

0 Likes
Message 6 of 15

Moshe-A
Mentor
Mentor

i sorry this is wrong i will fix it shortly

 

0 Likes
Message 7 of 15

Moshe-A
Mentor
Mentor

after little testing here is my results:

 

the (openfileDBX) should be corrected like the attached but unfortunately it still does not work, meaning if the target dwg is open by another AutoCAD session even with read only mode, it false to open the file (so there is no need do to apply the correction).

 

moshe

 

 

(defun openFileDBX (dbxFile / var dbxOpen)
 (setq var (vlax-make-variant :vlax-true vlax-vbBoolean))
  
  (if (setq dbxOpen
            (vlax-create-object
                (strcat    "ObjectDBX.AxDbDocument." (substr (getvar "ACADVER") 1 2) )
            )
      )
   (if (vl-catch-all-apply 'vla-open (list dbxOpen dbxFile var))
    (not (vlax-release-object dbxOpen))
    dbxOpen
   )
   (princ "\nUnable to create object")
  ); if
)
0 Likes
Message 8 of 15

Moshe-A
Mentor
Mentor

@ebsoares ,

 

here is your solution Smiley LOL

if (openfiledbx) returns nil (vl-file-copy) it to a temp folder and continue from there

 

moshe

 

0 Likes
Message 9 of 15

Moshe-A
Mentor
Mentor

@ebsoares 

 

if you got an answer? please mark it as your solution

 

thank you

moshe

 

0 Likes
Message 10 of 15

ebsoares
Collaborator
Collaborator

Hi, @Moshe-A . Thanks for the comments!

I've been out over the weekend, but will try your options today/tomorrow during my lunchtime - will definitely let you know how it goes Smiley Very Happy

0 Likes
Message 11 of 15

dgorsman
Consultant
Consultant

The inability to open a DWG file using ODBX when it's already open is a known issue.  If it is open, taking a copy should be done cautiously as the contents are being modified.  You can also quickly check for a matching DWL file before trying to open.

----------------------------------
If you are going to fly by the seat of your pants, expect friction burns.
"I don't know" is the beginning of knowledge, not the end.


0 Likes
Message 12 of 15

ebsoares
Collaborator
Collaborator

@Moshe-A, the addition of that extra variable seemed to help when file is read-only (but not actually opened by someone) - thanks!

Still, I'd like to check if the file in question is open, like you said. Wanted to try your "if (openfiledbx) returns nil", but right now, my if statement never returns nil (instead, it returns either an error or the file itself)

(if (vl-catch-all-apply 'vla-open (list dbxOpen dbxFile var))
    (not (vlax-release-object dbxOpen))
    dbxOpen
)

I tried to remove the "vl-catch-all-apply", but I probably had something incorrect as the function stopped working altogether...

Could you help me with that extra check? Perhaps help me re-write this last if statement?

Thanks

 

0 Likes
Message 13 of 15

Moshe-A
Mentor
Mentor
Accepted solution

@ebsoares  hi,

 


@Moshe-A, the addition of that extra variable seemed to help when file is read-only (but not actually opened by someone) - thanks!

yes that's right but that's not helping you

 

Still, I'd like to check if the file in question is open, like you said. Wanted to try your "if (openfiledbx) returns nil", but right now, my if statement never returns nil (instead, it returns either an error or the file itself)

do not make changes to the (openFileDBX) function use the origin.

here the fix you should take to (borrowBlockDBX) function (in red)

still leave to you to define the tmpfile (full path) to be temporary copied.

 

enjoy

moshe

(defun borrowBlockDBX (dbxBlock dbxFile / borrowDBX tmpFile)
    (if (not (setq borrowDBX (openFileDBX dbxFile)))
     (progn
(setq tmpFile ".......") ; define tmpFile to full path (if (vl-file-copy dbxFile tmpFile) (setq borrowDBX (openFileDBX tmpFile)))
) ) )
(if borrowDBX (progn (vla-CopyObjects borrowDBX (vlax-safearray-fill (vlax-make-safearray vlax-vbObject '(0 . 0)) (list (vla-item (vla-get-blocks borrowDBX) dbxBlock)) ) (vla-get-blocks (vla-get-activedocument (vlax-get-acad-object))) ) (vlax-release-object borrowDBX) ; Clean-up ) ) ) (defun openFileDBX (dbxFile / dbxOpen) (if (setq dbxOpen (vlax-create-object (strcat "ObjectDBX.AxDbDocument." (substr (getvar "ACADVER") 1 2) ) ) ) (if (vl-catch-all-apply 'vla-open (list dbxOpen dbxFile)) (not (vlax-release-object dbxOpen)) dbxOpen ) (princ "\nUnable to create object") ) )
0 Likes
Message 14 of 15

ebsoares
Collaborator
Collaborator

Fantastic, @Moshe-A! Works just as expected!

Thank you so much for your help Smiley Very Happy

Edgar

0 Likes
Message 15 of 15

Moshe-A
Mentor
Mentor

Edgar,

 

Thanks you, happy i could help.

 

have a nice day

Moshe

 

0 Likes