@bsanada hi,
check this XREFOUT command.
Run this only on master.dwg after you exactly placed all your xrefs.
the command starts by asking the folder to save the xrefs. of course you could select the origin folder and override the origin xrefs but it's recommended to place them in a new.
thank you Lee Mac for the amazing (LM:browseforfolder) function.
before run, it is recommended to manually try to bind each xref to reduce failures at run time.
to achieve what you want, xrefout do:
1. set xref scale to 1x1
2. set xref rotation to 0
3. xref bind
4. explode blocks
5. turn all layers on
6. gather all exploded objects to SS selection set.
7. write out block (WBLOCK)
Cause you said i have several hundred xrefs this could be long process... a progress bar is used.
if it work without errors, your master drawing should be left intact 😀
enjoy
Moshe
;; Browse for Folder - Lee Mac
;; Displays a dialog prompting the user to select a folder.
;; msg - [str] message to display at top of dialog
;; dir - [str] [optional] root directory (or nil)
;; bit - [int] bit-coded flag specifying dialog display settings
;; Returns: [str] Selected folder filepath, else nil.
(defun LM:browseforfolder ( msg dir bit / err fld pth shl slf )
(setq err
(vl-catch-all-apply
(function
(lambda ( / app hwd )
(if (setq app (vlax-get-acad-object)
shl (vla-getinterfaceobject app "shell.application")
hwd (vl-catch-all-apply 'vla-get-hwnd (list app))
fld (vlax-invoke-method shl 'browseforfolder (if (vl-catch-all-error-p hwd) 0 hwd) msg bit dir)
)
(setq slf (vlax-get-property fld 'self)
pth (vlax-get-property slf 'path)
pth (vl-string-right-trim "\\" (vl-string-translate "/" "\\" pth))
)
)
)
)
)
)
(if slf (vlax-release-object slf))
(if fld (vlax-release-object fld))
(if shl (vlax-release-object shl))
(if (vl-catch-all-error-p err)
(prompt (vl-catch-all-error-message err))
pth
)
)
; Save xref back to disk to 0,0,0
(defun c:xrefout (/ is_acetutil_modula_exist objects_counter get_last_ent ; local functions
adoc blocks folder ctr pbar_ctr AcDbEntity AcDbBlkTblRec ; local variable
xname xrefname newxrefname ename ss xn xname) ; local variables
; check if aceutil.arx is loaded?
(defun is_acetutil_modula_exist ()
(if (null (member "acetutil.arx" (arx)))
(progn
(setq *isAcetUtil* :vlax-false)
(vlr-beep-reaction)
(prompt "\nacetutil.arx modula is not loaded.")
)
(setq *isAcetUtil* :vlax-true)
)
); is_acetutil_modula_exist
; return cumulate number of objects in xrefs
(defun objects_counter (/ counter AcDbBlkTblRec)
(setq counter -1)
(vlax-for AcDbBlkTblRec blocks
(if (and
(eq (vla-get-isXref AcDbBlkTblRec) :vlax-true)
; make sure it is attached
(ssget "_x" (list '(0 . "insert") (cons '2 (vla-get-name AcDbBlkTblRec))))
)
(setq counter (+ counter (vla-get-count AcDbBlkTblRec)))
)
); vlax-for
counter
); objects_counter
; make sure last entity is exist
; even if drawing is empty
(defun get_last_entity ()
(command "._point" "0,0,0")
(entlast)
); get_last_entity
: Here start c:xrefout
(setq adoc (vla-get-activedocument (vlax-get-acad-object)))
(vla-startundomark adoc)
(setq blocks (vla-get-blocks adoc))
(setvar "cmdecho" 0)
(setvar "expert" 5)
(if (setq folder (LM:browseforfolder "Select a folder" (getvar "dwgprefix") 0))
(progn
(is_acetutil_modula_exist)
(setq ctr (objects_counter))
; init progress meter
(if (eq *isAcetUtil* :vlax-true)
(progn
; progress bar init requires bigger value
(acet-ui-progress-init "Processing" ctr)
(setq pbar_ctr -1) ; progress bar counter
); progn
); if
(vlax-for AcDbEntity (vla-get-modelspace adoc)
(if (and
(eq (vla-get-objectname AcDbEntity) "AcDbBlockReference")
(not (wcmatch (setq xname (vla-get-name AcDbEntity)) "`*U*")) ; not anonymous block
(null (member (strcase xname) lst)) ; not processed yet
(setq AcDbBlkTblRec (vla-item blocks xname)) ; get BTR
(eq (vla-get-isXref AcDbBlkTblRec) :vlax-true) ; is it xref?
(setq xrefname (vla-get-path AcDbBlkTblRec))
(setq newxrefname (strcat folder "\\" (vl-filename-base xrefname) ".dwg"))
)
(progn
(vlax-release-object AcDbBlkTblRec)
(setq AcDbBlkTblRec nil)
; update progress meter
(if (eq *isAcetUtil* :vlax-true)
(progn
(setq pbar_ctr (1+ pbar_ctr)) ; inc progress bar
(acet-ui-progress-safe pbar_ctr)
); progn
); if
(command "._undo" "_begin")
(setq ss (ssadd) ename (get_last_entity))
; make sure the xref will be saved at X=1,Y=1,Z=1,R=0
(vla-put-XScaleFactor AcDbEntity 1.0)
(vla-put-YScaleFactor AcDbEntity 1.0)
(vla-put-ZScaleFactor AcDbEntity 1.0)
(vla-put-rotation AcDbEntity 0.0)
(command "._xref" "_bind" xname)
(command "._explode" (vlax-vla-object->ename AcDbEntity))
; make sure all objects selected
(command "._layer" "_thaw" "*" "_on" "*" "_unlock" "*" "")
; collecting all objects
(while (setq ename (entnext ename))
(ssadd ename ss)
); while
; write out wblock\xref
(command "._wblock" (strcat folder "\\" xname) "" "0,0,0" "_si" ss)
(command "._undo" "_end")
(command "._u") ; restore actions
(setq lst (cons (strcase xname) lst))
); progn
; else
(if (and
AcDbBlkTblRec
(eq (type AcDbBlkTblRec) VLA-Object)
)
(progn
(vlax-release-object AcDbBlkTblRec)
(setq AcDbBlkTblRec nil)
); progn
); if
); if
(vlax-release-object AcDbEntity)
); vlax-for
(if (eq *isAcetUtil* :vlax-true)
(acet-ui-progress-done); close progress meter
)
); progn
); if
(setvar "expert" 0)
(setvar "cmdecho" 1)
(vlax-release-object blocks)
(vla-endundomark adoc)
(vlax-release-object adoc)
(princ "\nDone.")
(princ)
); c:xrefout