Visual LISP, AutoLISP and General Customization
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Insert block from another drawing?

8 REPLIES 8
Reply
Message 1 of 9
CADdaddy.com
8080 Views, 8 Replies

Insert block from another drawing?

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
8 REPLIES 8
Message 2 of 9
_gile
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
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

Tags (1)
Message 3 of 9
CADdaddy.com
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
Message 4 of 9
Anonymous
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'~
Message 5 of 9
CADdaddy.com
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
Message 6 of 9
Eatmode
in reply to: CADdaddy.com

This seems the best thread to possibly get some help.

 

I am running AutoCAD 2015 SP2 and whenever VisualLISP calls:

 

(vlax-get-or-create-object (strcat "ObjectDBX.AxDbDocument." (substr (getvar "ACADVER") 1 2)))

 

I get an "Automation error. Description not provided." Repaired, Reinstalled, Uninstall/Reinstall, Uninstall/Delete all AutoCAD folders/Reinstall. Nothing seems to help. And it worked before today.

 

Any chance you guys run into this?

 

Thanks for any help.

Message 7 of 9
msarqui
in reply to: _gile

Hi guys,

 

It is OK If the file is on c: but I am wondering why is not working if the file is on the server? 

I get this error: Error: Automation Error. Description was not provided

 

Thanks!

Marcelo

Message 8 of 9
miodrag.jovanovic
in reply to: msarqui

I solved this error by changing the path from:

K:/Folder/Folder/.../Library1.dwg

to:

K://Folder//Folder//...//Library1.dwg

Double // is the problem, it seems for Server Locations...

Message 9 of 9
Sea-Haven
in reply to: CADdaddy.com

Or K:\\\\Folder\\\\Folder\\\\...\\\\Library1.dwg the dbl dbl back bracket will get around problems sometimes of directory having a space in name when using a server name note also the dbl bracket for sub directory as they would normally only have one forward slash. Hope that makes sense.

 

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk Design & Make Report

”Boost