Visual LISP, AutoLISP and General Customization

Visual LISP, AutoLISP and General Customization

Reply
Distinguished Contributor
CADdaddy.com
Posts: 208
Registered: ‎04-10-2005
Message 1 of 5 (2,005 Views)

Insert block from another drawing?

2005 Views, 4 Replies
03-29-2007 07:49 PM
Does anyone know if it might be possible to programmatically insert a block from another DWG file?

I am using a lot of dynamic blocks and also creating toolpalettes using Design Center so it is easiest to create a single file with all the blocks in a single file. I have one DWG file "library" for each tab of my toolpalette.

The problem is that occasionally I need to insert a block from my "library" programmatically (using LISP) and I have no way to access it. I might just add here that all this would not be necessary if Autodesk would add a feature to toolpalettes that run a command or macro before and/or after insertion is completed. That would sure save me a lot of reactor programming and other needless complications.

Any ideas would be greatly appreciated.

James LeVieux
*Expert Elite*
_gile
Posts: 2,082
Registered: ‎04-29-2006
Message 2 of 5 (2,005 Views)

Re: Insert block from another drawing?

03-29-2007 10:19 PM in reply to: CADdaddy.com
Hi,

It's possible using ObjectDBX, but in my way, y'd rather wblock your blocks in one folder per library and add the path of each foder in acad support path, all your blocks should be available from each drawing.

To go into a file without opening it :

(defun open_dbx (dwg / dbx)
(if (< (atoi (substr (getvar "ACADVER") 1 2)) 16)
(setq dbx (vlax-create-object "ObjectDBX.AxDbDocument"))
(setq dbx (vlax-create-object
(strcat "ObjectDBX.AxDbDocument."
(substr (getvar "ACADVER") 1 2)
)
)
)
)
(vla-open dbx dwg)
dbx
)

To get "A_block" in 'Library.dwg" file :

(setq Dbx (open_dbx "c:/Library1.dwg")) ; Change the file name here
(vla-CopyObjects
Dbx
(vlax-safearray-fill
(vlax-make-safearray vlax-vbObject '(0 . 0))
(list (vla-item (vla-get-blocks dbx) "A_Block")) ; Change the block name here
)
(vla-get-blocks
(vla-get-activedocument (vlax-get-acad-object))
)
)

Clean-up :

(vlax-release-object dbx)
Gilles Chanteau
Distinguished Contributor
CADdaddy.com
Posts: 208
Registered: ‎04-10-2005
Message 3 of 5 (2,005 Views)

Re: Insert block from another drawing?

03-30-2007 04:24 PM in reply to: CADdaddy.com
Perfect. Thanks so much! Here is my version as a function where you pass the filespec and blockname as arguments.


(defun get-block-in-DWG (filespec blockname / )
(setq Dbx (open_dbx filespec))
(vla-CopyObjects
Dbx
(vlax-safearray-fill
(vlax-make-safearray vlax-vbObject '(0 . 0))
(list (vla-item (vla-get-blocks dbx) blockname))
)
(vla-get-blocks (vla-get-activedocument (vlax-get-acad-object)))
)
(vlax-release-object dbx) ;Clean-up
)

Here is another note for Autodesk while I'm thinking of it. I would LOVE to just right-click on a drawing in Design Center and select "Create Tool palette" but I find that there are so many tweeks "(usually ...auxiliary scale, prompt for rotation, and explode) I have to make to each tool palette item AFTER i've created the tab that I dread re-creating the tool palette. What would be great is if we could store this information into the block itself...then include PRE-insertion and POST-insertion macro support (that allows user interaction like getPoint and entsel that is not supported using reactors). Then maintaining a block libary would EASY and the blocks would be SMART.

James LeVieux
Distinguished Contributor
Fatty
Posts: 1,986
Registered: ‎08-02-2004
Message 4 of 5 (2,005 Views)

Re: Insert block from another drawing?

03-31-2007 04:20 AM in reply to: CADdaddy.com
Hi James

Try another one too

;;========code begin

;; written by Fatty T.O.H (c) 2004
;; all rights removed
;; get ObjectDBX document
;; edited 4/20/06
;; edited 5/28/06 by Jeff M (see commented lines)
;; edited 10/5/06
;; edited 3/19/07
;; edited 3/20/07
(defun odbx-test (/ dbx_doc)
;; edited 5/28/06 by Jeff M
;; modified slightly to work with more versions
(or (vl-load-com))
(if (< (setq dbxver (atoi (getvar "ACADVER"))) 15)
(progn (alert
"ObjectDBX method not applicable\nin this AutoCAD version"
)
(exit)
(princ)
(gc)
)
(progn
(if (= (atoi (getvar "ACADVER")) 15)
(progn

(if (not (vl-registry-read
"HKEY_CLASSES_ROOT\\ObjectDBX.AxDbDocument\\CLSID"
)
)
(startapp "regsvr32.exe"
(strcat "/s \"" (findfile "axdb15.dll") "\"")
)
)

(setq dbx_doc (vla-getinterfaceobject
(vlax-get-acad-object)
"ObjectDBX.AxDbDocument"
)
)
)

(setq dbx_doc (vla-getinterfaceobject
(vlax-get-acad-object)
(strcat "ObjectDBX.AxDbDocument." (itoa (fix dbxver)))
)
)
)
)
)
)

(defun BlockList (dwg / blst bname)
(vlax-for a (vla-get-blocks dwg)
(setq bname (vla-get-name a))
(if
(and (equal :vlax-false (vla-get-isxref a))
(equal :vlax-false (vla-get-islayout a))
(not (wcmatch bname "_*,*$*,*|*" ))
(not (vl-string-search "*" bname))
)
(setq blst (cons bname blst))
)
)
(reverse blst)
)

(defun make-lib-dial ()
(setq fname (vl-filename-mktemp "libris.dcl"))
;(setq fname (strcat (getvar "dwgprefix") "librys.dcl"))
(setq fn (open fname "w"))
(write-line "libres : dialog {" fn)
(write-line (strcat "label = " "\"" "COPY BLOCK" "\"" ";") fn)
(write-line ": boxed_column {" fn)
(write-line (strcat "label = " "\"" "Select Block" "\"" ";") fn)
(write-line ": list_box {" fn)
(write-line (strcat "key = " "\"" "b_list" "\"" ";") fn)
(write-line "width = 30; height = 20;}" fn)
(write-line "}" fn)
(write-line "spacer;" fn)
(write-line "ok_cancel; " fn)
(write-line "}" fn)
(close fn)
)

; ;

(defun set_list (name lst)
(start_list name)
(mapcar 'add_list lst)
(end_list))

; ;
(defun run-lib-dial (blk_lst)

(setq dcl_ex (load_dialog fname))
(new_dialog "libres" dcl_ex)
(set_list "b_list" blk_lst)

(action_tile "b_list" (strcat
"(progn "
"(setq b_name (nth (atoi $value) blk_lst)))"
))

(action_tile "accept" "(done_dialog 1)")
(action_tile "cancel" "(done_dialog 0)")

(setq knock (start_dialog))
(unload_dialog dcl_ex)
(done_dialog)
(vl-file-delete fname)
b_name
)
;; main programm :

(defun C:CBO (/ acapp acsp adoc blk_col blk_lst
b_name cert_blk fn fname ipt knock odbx x)

(vl-load-com)
(or acapp
(setq acapp (vlax-get-acad-object))
)
(or adoc
(setq adoc (vla-get-activedocument acapp))
)
(or acsp
(setq acsp (if (= (getvar "CVPORT") 1)
(vla-get-paperspace
adoc)
(vla-get-modelspace
adoc)
)
)
)

(vla-startundomark adoc)

(setq odbx (odbx-test))
(setq fn (getfiled "Select file to copy block from"
""
"dwg"
16
)
)

(if
(setq fname (findfile fn))
(progn
(vla-open odbx fname)
(setq blk_lst (BlockList odbx))
(make-lib-dial)
(setq b_name (run-lib-dial blk_lst))
(if (= knock 1)
(progn
(setq blk_col (vla-get-blocks odbx))
(if (not (vl-catch-all-error-p
(vl-catch-all-apply
(function (lambda () (vla-item blk_col b_name)))
)
)
)
(progn
(setq cert_blk (vla-item blk_col b_name))
(not
(vl-catch-all-error-p
(vl-catch-all-apply
(function
(lambda ()
(vla-copyobjects
odbx
(vlax-safearray-fill
(vlax-make-safearray vlax-vbobject '(0 . 0))
(list (vla-item
(vla-get-blocks odbx)
b_name
)
)
)
(vla-get-blocks adoc)
)
)
)
)
)
)
)
(princ "\Block Not Found")
)
)
)
)
(princ "\File Not Found")
)
;; check if desired block already in the current database:
(if (not (vl-catch-all-error-p
(vl-catch-all-apply
(function (lambda () (vla-item (vla-get-blocks adoc) b_name)))
)
)
)
;; insert block
(progn
(setq ipt (getpoint "\nSpecify insertion point: "))
(vlax-invoke acsp 'InsertBlock ipt b_name 1 1 1 0)
)
(alert "Problem with block copying"
)
)

(vlax-release-object odbx)
(setq odbx nil)
(mapcar (function (lambda (x)
(vl-catch-all-apply
(function (lambda ()
(vlax-release-object x)
)
)
)
)
)
(list cert_blk blk_col)
)

(vla-endundomark adoc)
(gc)(gc)
(princ)
)
; ;
(princ "\n\t\t***\ttype CBO to execute ...\t***")
(princ)
;;;===========code end

~'J'~
Distinguished Contributor
CADdaddy.com
Posts: 208
Registered: ‎04-10-2005
Message 5 of 5 (2,005 Views)

Re: Insert block from another drawing?

04-02-2007 09:53 AM in reply to: CADdaddy.com
Thanks for that extra suggestion.

I've played with this type of code a bit and found that DBX seems to need a lock on the source file. Does anyone know of an alternative method that can acquire the block even if the source file is open by another user? ...or can a DBX be opened in a "read-only" mode?

James LeVieux
Announcements
Are you familiar with the Autodesk Expert Elites? The Expert Elite program is made up of customers that help other customers by sharing knowledge and exemplifying an engaging style of collaboration. To learn more, please visit our Expert Elite website.
Need installation help?

Start with some of our most frequented solutions or visit the Installation and Licensing Forum to get help installing your software.