Moving blocks to different layers based on a list (csv) / with color change

Moving blocks to different layers based on a list (csv) / with color change

ingo360
Contributor Contributor
1,549 Views
13 Replies
Message 1 of 14

Moving blocks to different layers based on a list (csv) / with color change

ingo360
Contributor
Contributor

Hi,

 

I need a LISP where different blocks (normal and dynamic) are moved to different layers based on a list (csv file). It would also be nice to be able to change the color of individual blocks after or before they are moved to the other layer.

 

For example

 

"blockname1" should be moved to layer "layer1" and get the color "fromlayer"

 

  • blockname1,layer1,color_fromlayer
  • blockname2,layer2,color_fromlayer
  • blockname3,layer1,color_2
  • blockname4,layer4
  • blockanme5,layer2
  • etc.

 

In the drawings are more than 200 blocks from therefore I would like to do the assignment "block,layer,color" in a csv file. If the color change is not possible, I would be satisfied with just moving the blocks.

I am looking forward to your help!
Unfortunately I did not find anything in the forum.

BR

0 Likes
Accepted solutions (1)
1,550 Views
13 Replies
Replies (13)
Message 2 of 14

Moshe-A
Mentor
Mentor

@ingo360 ,

 

if you do that manually (changing the block layer) what is happend? does the color change?

 

Moshe

 

0 Likes
Message 3 of 14

ingo360
Contributor
Contributor

No, the blocks basically all have the color of the layer set.

0 Likes
Message 4 of 14

Moshe-A
Mentor
Mentor

@ingo360 

 

so just to make it clear:

 

if i have a block originally build on 3 layers (LAYER1+color1,LAYER2+color2,LAYER3+color3) that is lay on LAYER4+color4 and you change it to LAYER6+color6 what are expecting to have?

 

Moshe

 

 

0 Likes
Message 5 of 14

ingo360
Contributor
Contributor

I think I have expressed myself in an incomprehensible way. 


The actual state

  • layer1 (color red) --> blocks on this layer got the same color (red)
  • layer2 (color blue) --> blocks on this layer got the same color (blue)
  • layer3 (color green) --> blocks on this layer got the same color (green)


For example, I want to move a block from "Layer1" to "Layer2", but I don't want this block to get the color of the layer but another color.

As I mentioned before, if the color matching issue gets too complicated, simply moving the blocks to the layers would be enough for me. 😉

0 Likes
Message 6 of 14

Moshe-A
Mentor
Mentor

@ingo360 ,

 

i asked you this:

"if you do that manually (changing the block layer) what is happend? does the color change?"

you said NO!

 

so if you change the block layer and it does not get the new color then how could you tell a change made?

i'll tell how autocad behave with blocks

it depend on the layer's of the entities involve.

if an entity lay's on none '0' zero layer (any other layer name but not '0' zero) at insert it stick with that layer no matter what. if an entity lay's on '0' zero layer, at insert it inherit the current layer properties...color, ltype, width (and all other layer properties). now base on this state test one of your blocks that does not change color to understand why?!

 

attached sample1.dwg inside a test block to illustrate you how block works - just change the block to LAYER6 and tell me what were your expectaions and what actually happend?

 

Moshe

 

 

 

 

 

 

 

0 Likes
Message 7 of 14

ingo360
Contributor
Contributor

In the attachment you find a file how it works with me.
Inside the block everything is on layer 0. If I move the block to another layer the color changes.

Next to it you will find the block on the same layer with a different color. This is what I want to achieve.

 

Sorry, it's hard to explain.

0 Likes
Message 8 of 14

Kent1Cooper
Consultant
Consultant

Based on your original example of .csv file lines, some with color entries and some without, perhaps something like this [pieces tested, but use real drawing and .csv file and filepath to really test]:

 

(defun C:BLT ; = Block Layer Transfer
  (/ beforecomma aftercomma file txt ss)

  (defun beforecomma (str) (substr str 1 (vl-string-position 44 str)))

  (defun aftercomma (str) (substr str (+ (vl-string-position 44 str) 2)))

  (setq file (open "X:/Your/File/Path/YourFileName.csv" "r")
  (while (setq txt (read-line file))
    (if (setq ss (ssget "_X" (list '(0 . "INSERT") (cons 2 (beforecomma txt))))); any Blocks by that name?
      (command "_.chprop" ss "" ; then
        "_layer" (beforecomma (setq txt (aftercomma txt)))
        "_color" (if (wcmatch txt "*`,*") (aftercomma txt) ""); accept current if no color entry in txt
        ""
      ); command
    ); if
  ); while
  (close file)

  (prin1)
); defun

 

BUT it needs your end-of-line color thing [where present] to be "ByLayer" [not case-sensitive] when that's what you want, and just a color number [or name] when applicable, so it can just use those.  That is:

  • blockname2,layer2,bylayer
  • blockname3,layer1,2
  • blockname45,layer27,green

If you really want the "color_" part kept in there, it could be accommodated, but it seems more complicated than necessary.

 

EDIT:  And it assumes the Blocks involved are not dynamic.

Kent Cooper, AIA
0 Likes
Message 9 of 14

Moshe-A
Mentor
Mentor

@ingo360 ,

 

ok got you, here you go

the blk2lay.csv is sample data file. you need to create your 😀

 

Moshe

 

 

 

 

(vl-load-com)

(defun c:blk2lay (/ LM:str->lst ; local function
		   fname f rec data dataList ss)

;; String to List  -  Lee Mac
;; Separates a string using a given delimiter
;; str - [str] String to process
;; del - [str] Delimiter by which to separate the string
;; Returns: [lst] List of strings
 
 (defun LM:str->lst ( str del / pos )
    (if (setq pos (vl-string-search del str))
        (cons (substr str 1 pos) (LM:str->lst (substr str (+ pos 1 (strlen del))) del))
        (list str)
    )
 ); LM:str->lst


 ; here start c:cdepth
 (setvar "cmdecho" 0)
 (command "._undo" "_begin")
  
 (if (and
       (setq fname (getfiled "Select csv data file" "" "csv" 8))
       (setq f (open fname "r"))
     )
  (progn
   (setq dataList nil) 
   (while (setq rec (read-line f))
    (setq dataList (cons (LM:str->lst rec ",") dataList))
   ); while

   (setq f (close f)) ; close file
   
   (foreach data (reverse dataList)
    (if (and
	  (>= (vl-list-length data) 2)
	  (setq ss (ssget "_x" (list '(0 . "insert") (cons '2 (car data)))))
	)
     (if (not (caddr data))
      (command "._layer" "_make" (cadr data) "" "._chprop" "_si" ss "_layer" (cadr data) "")
      (command "._layer" "_make" (cadr data) "" "._chprop" "_si" ss "_layer" (cadr data) "_color" (caddr data) "")
     ); if
    ); if
   ); foreach
   
  ); progn
 ); if

 (command "._undo" "_end")
 (setvar "cmdecho" 1)

 (princ)
); blk2lay

 

 

0 Likes
Message 10 of 14

ingo360
Contributor
Contributor

It works, perfect!

The only problem are the dynamic blocks, these are not moved.
As I read, you have to find out the "effectivename" first. Or is there another way to do this?

0 Likes
Message 11 of 14

ingo360
Contributor
Contributor

Of course, "Kent1Cooper"`s solution with the preset path is even nicer.
That saves me the search for the file.

 

(setq file (open "X:/Your/File/Path/YourFileName.csv" "r")

0 Likes
Message 12 of 14

Kent1Cooper
Consultant
Consultant

@ingo360 wrote:

Of course, "Kent1Cooper"`s solution with the preset path is even nicer.  That saves me the search for the file. ....


... provided, of course, that it's always the same file name in the same location.

 

[Did the rest of my suggestion work for you under real conditions?]

Kent Cooper, AIA
0 Likes
Message 13 of 14

Moshe-A
Mentor
Mentor
Accepted solution

@ingo360 ,

 

now, support dynamic blocks 🤣

 

 

;;; move block to layer

(vl-load-com)

(defun c:blk2lay (/ LM:str->lst ; local function
		   fname f rec data dataList ss)

;; String to List  -  Lee Mac
;; Separates a string using a given delimiter
;; str - [str] String to process
;; del - [str] Delimiter by which to separate the string
;; Returns: [lst] List of strings
 
 (defun LM:str->lst ( str del / pos )
    (if (setq pos (vl-string-search del str))
        (cons (substr str 1 pos) (LM:str->lst (substr str (+ pos 1 (strlen del))) del))
        (list str)
    )
 ); LM:str->lst


 ; here start c:cdepth
 (setvar "cmdecho" 0)
 (command "._undo" "_begin")
  
 (if (and
       (setq fname (getfiled "Select csv data file" "" "csv" 8))
       (setq f (open fname "r"))
     )
  (progn
   (setq dataList nil) 
   (while (setq rec (read-line f))
    (setq dataList (cons (LM:str->lst rec ",") dataList))
   ); while

   (setq f (close f)) ; close file
   
   (foreach data (reverse dataList)
    (if (and
	  (>= (vl-list-length data) 2)
	  (setq ss (ssget "_x" (list '(0 . "insert") (cons '2 (strcat (car data) ",`*U*")))))
	)
     (foreach ename (vl-remove-if 'listp (mapcar 'cadr (ssnamex ss)))
      (if (eq (strcase (vla-get-effectivename (vlax-ename->vla-object ename))) (strcase (car data)))
       (if (not (caddr data))
        (command "._layer" "_make" (cadr data) "" "._chprop" "_si" ename "_layer" (cadr data) "")
        (command "._layer" "_make" (cadr data) "" "._chprop" "_si" ename "_layer" (cadr data) "_color" (caddr data) "")
       ); if
      ); if
     ); foreach
    ); if
   ); foreach
   
  ); progn
 ); if

 (command "._undo" "_end")
 (setvar "cmdecho" 1)

 (princ)
); blk2lay

 

 

0 Likes
Message 14 of 14

ingo360
Contributor
Contributor

**** good job!
It works. 🤗

So that it does not get boring:

  • Is it also possible to integrate a color book, because I have a self-created colors
  • The variant with the default file path would still be nice (setq file (open "X:/Your/File/Path/YourFileName.csv" "r")
0 Likes