Copy multiple selected nested blocks from master block to outside.

Copy multiple selected nested blocks from master block to outside.

Anonymous
Not applicable
3,499 Views
13 Replies
Message 1 of 14

Copy multiple selected nested blocks from master block to outside.

Anonymous
Not applicable

Dear Helpers,

I nead a lisp that should copy selected multiple nested blocks from master block. Suppose I have a master block from a Architect, that contains chairs and tables as blocks inside the master block. The  lisp code should copy only the selected nested blocks to outside. Please have a look on attached dwg and image.

I got a lisp code that can copy nested elements from master block, The requirement is instead of copying nested elements the lisp should copy only selected nested blocks  from master block.

(defun c:MCN1 (/ lastent ss)

(setq lastent (entlast))

(setq ss (ssadd))

(command "_.ncopy")

(while (> (getvar "cmdactive") 0)

(command pause "0,0" "0,0")

)

(while (setq lastent (entnext lastent))

(ssadd lastent ss)

)

)

Regards,

T.Brahmanandam

0 Likes
Accepted solutions (3)
3,500 Views
13 Replies
Replies (13)
Message 2 of 14

_gile
Consultant
Consultant
Accepted solution

Hi,

 

Here's a quick and dirty you can get inspiration from.

 

(defun c:cnb (/ nent elst blk)
  (if (setq nent (nentsel "\nSelect a nested block: "))
    (if (= 4 (length nent))
      (if (= "INSERT" (cdr (assoc 0 (setq elst (entget (car (last nent)))))))
        (command "_.insert" (cdr (assoc 2 elst)) pause 1. 1. 0.)
        (prompt "\nSelect object is not a block reference.")
      )
      (prompt "\nSelect object is not a nested entity.")
    )
  )
  (princ)
)


Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

Message 3 of 14

ВeekeeCZ
Consultant
Consultant

Maybe a different approach, you need to pre-select a main block, then run the command.

 

(defun c:CopyNestedObjects (/ enl ss) 
  (if *refedit1st*
    (command "_.-REFEDIT" "_Ok" "_All" "_No")
    (progn
      (setq *refedit1st* T)
      (initdia)
      (command "_.REFEDIT")))
  (setq enl (entlast)
        ss (ssadd))
  (command-s "_.COPY")
  (while (setq enl (entnext enl))
    (ssadd enl ss))
  (if (> (sslength ss) 0)
    (command "_.REFSET" "_R" ss ""))
  (command "_.REFCLOSE" "_Disc" "")
  (princ)
)
0 Likes
Message 4 of 14

Anonymous
Not applicable

Thank you Sir,

But not working properly for copying multiple or single block copy.

0 Likes
Message 5 of 14

Anonymous
Not applicable

Dear Sir,

 

The code is working fine and can you please make it for multiple nested blocks?. The code you provided is working for only single block copy.

0 Likes
Message 6 of 14

ВeekeeCZ
Consultant
Consultant

@Anonymous wrote:

Thank you Sir,

But not working properly for copying multiple or single block copy.


 

OK. Thanks for the feedback.

Since you already have a solution and my routine is working on my side, I'm not going to investigate why is any problem on your side. But for the future , if you ever care about solving the issue, you need to do more then just saying "it's not working". You need to describe all you did, copy-paste the command-line log, copy the error message if the was any... or even record all your doing using SCREENCAST

Message 7 of 14

Anonymous
Not applicable

Sure Sir,

 

May be my autocad version having an issue, So anyway I will make screen sheet will send to you Sir.

0 Likes
Message 8 of 14

Anonymous
Not applicable

Dear Sir,

 

Apologise me for not giving clarification why it's not working for me. Actually this lisp code entering into the "Refedit" mode. It should not enter to Refedit mode for multiple blocks copy. Without entering only it should work for me for multiple nested blocks copies.

 

Thank you Sir,

 

0 Likes
Message 9 of 14

ВeekeeCZ
Consultant
Consultant

I see, you should say that you use some older version. I've made some adjustments... 

 

About entering the refedit mode - Yes, that's the sensational. As far as I know autocad there is no reasonable way to do multiple selection. It that was a case, autocad's NCOPY would have it. 

Yes, @_gile's approach is nice, but imho it stays at single selection mode.

See how my routine should work, HERE

Good luck.

 

(defun c:CopyNestedObjects (/ enl ss) 
  (if *refedit1st*
    (command "_.-REFEDIT" "_Ok" "_All" "_No")
    (progn
      (setq *refedit1st* T)
      (initdia)
      (command "_.REFEDIT")))
  (setq enl (entlast)
        ss (ssadd))
  (command "_.SELECT" PAUSE)
  (command "_.COPY" "_p" "")
  (while (> (getvar 'CMDACTIVE) 0)
    (command PAUSE))
  (while (setq enl (entnext enl))
    (ssadd enl ss))
  (if (> (sslength ss) 0)
    (command "_.REFSET" "_R" ss ""))
  (command "_.REFCLOSE" "_Disc")
  (if (> (getvar 'CMDACTIVE) 0)
    (command ""))
  (princ)
)
0 Likes
Message 10 of 14

Anonymous
Not applicable

Dear Sir,

 

I am using 2014 version, this might having problem to manipulate the code. Again it's working on "REFEDIT" Command and entering into block editing mode. So I agree that my cad 2014 version might have problem. But thank you for your efforts Sir.

0 Likes
Message 11 of 14

_gile
Consultant
Consultant
Accepted solution

Here's another quick and dirty which allows to select multiple nested blocks one by one (making a selection of nested entities is not at all trivial, see this thread at TheSwamp).

As is the routine only allows selecting first level nested blocks in a non scaled parent.

 

(defun c:mcnb (/ *error* ss nent elst copy parent rot)
  (vl-load-com)
  (or *acad* (setq *acad* (vlax-get-acad-object)))
  (or *acdoc* (setq *acdoc* (vla-get-ActiveDocument *acad*)))

  (defun *error* (msg)
    (and msg
         (/=(strcase msg) "FUNCTION CANCELLED")
         (princ (strcat "\nError: " msg))
    )
    (vla-EndUndoMark *acdoc*)
    (princ)
  )

  (vla-StartUndoMark *acdoc*)
  (setq space (if (= 1 (getvar 'cvport))
                (vla-get-PaperSpace *acdoc*)
                (vla-get-ModelSpace *acdoc*)
              )
  )
  (setq ss (ssadd))
  (while (and (setq nent (nentsel "\nSelect a nested block: "))
              (= 4 (length nent))
              (= "INSERT" (cdr (assoc 0 (setq elst (entget (car (last nent)))))))
         )
    (setq copy   (entmakex elst)
          parent (last (last nent))
    )
    (setpropertyvalue copy "Position" (cadddr (caddr nent)))
    (setpropertyvalue copy
                      "Rotation"
                      (+ (getpropertyvalue (last (last nent)) "Rotation")
                         (getpropertyvalue copy "Rotation")
                      )
    )
    (ssadd copy ss)
    (redraw copy 3)
  )
  (command "_.move" ss "")
  (*error* nil)
)

 



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

0 Likes
Message 12 of 14

Anonymous
Not applicable

yes exactly working, But not working for scaled nested blocks as you mentioned. But most of the architectural designs will be in feets and inches units and Other Services will be in meter and millimeter, then sometimes these blocks will be in other than 1 scale factor. So the code should copy even the nested blocks in other than 1 sacle factor. Thanking you in advance Sir.

 

Hoping I will get the solution

0 Likes
Message 13 of 14

_gile
Consultant
Consultant
Accepted solution

This one is a little more robust, it accepts any uniformly scaled block.

 

(defun c:mcnb (/ *error* space ss nent br copy)
  (vl-load-com)
  (or *acad* (setq *acad* (vlax-get-acad-object)))
  (or *acdoc* (setq *acdoc* (vla-get-ActiveDocument *acad*)))

  (defun *error* (msg)
    (and msg
         (/=(strcase msg) "FUNCTION CANCELLED")
         (princ (strcat "\nError: " msg))
    )
    (vla-EndUndoMark *acdoc*)
    (princ)
  )

  (vla-StartUndoMark *acdoc*)
  (setq space (if (= 1 (getvar 'cvport))
                (vla-get-PaperSpace *acdoc*)
                (vla-get-ModelSpace *acdoc*)
              )
  )
  (setq ss (ssadd))
  (while (and (setq nent (nentselp "\nSelect a nested block: "))
              (= 4 (length nent))
              (= "AcDbBlockReference" (vla-get-ObjectName (setq br (vlax-ename->vla-object (car (last nent))))))
              (apply '= (mapcar 'abs (list (vla-get-XScaleFactor br) (vla-get-YScaleFactor br) (vla-get-ZScaleFactor br))))
         )
    (setq copy (vla-insertblock space (vlax-3d-point '(0 0 0)) (vla-get-Name br) 1.0 1.0 1.0 0.0))
    (vla-TransformBy copy (vlax-tmatrix (caddr nent)))
    (vla-Highlight copy :vlax-true)
    (ssadd (vlax-vla-object->ename copy) ss)
  )
  (command "_.move" ss "")
  (*error* nil)
)


Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

Message 14 of 14

Anonymous
Not applicable

Marvellous, came a wonder

0 Likes