Author Topic: merge list_layer to another list_layer  (Read 3832 times)

0 Members and 1 Guest are viewing this topic.

new_mem

  • Newt
  • Posts: 67
merge list_layer to another list_layer
« on: May 22, 2016, 10:10:30 AM »
Hi all

I have lst_lay1 (list "1" "2" "3" "4" "5" "6" "n") and lst_lay2 (list "1new" "2new" "3new" "4new" "5new" "6new" "n_new")

How can i merge list layer1 to list layer2 (1->1new, 2->2new,....)

Can anyone tell me, please?

Thanks

T.Willey

  • Needs a day job
  • Posts: 5251
Re: merge list_layer to another list_layer
« Reply #1 on: May 22, 2016, 10:18:36 AM »
If I understand you, you can use 'mapcar' on the two list to create a single new one from both members.  An issue with length might happen if they are not the same length.

You could use a 'repeat' loop grabbing the indexed values of each list, and them combining them.  Just start a counter variable outside the loop, and then...

That is it for now.
Tim

I don't want to ' end-up ', I want to ' become '. - Me

Please think about donating if this post helped you.

MP

  • Seagull
  • Posts: 17750
  • Have thousands of dwgs to process? Contact me.
Re: merge list_layer to another list_layer
« Reply #2 on: May 22, 2016, 10:21:50 AM »
What are you ultimately trying to achieve? Seems the second list is derivative the first, so constructing it manually serves no value other than to introduce potential errors.

PS: On first coffee, so take that for what it's worth.
Engineering Technologist • CAD Automation Practitioner
Automation ▸ Design ▸ Drafting ▸ Document Control ▸ Client
cadanalyst@gmail.comhttp://cadanalyst.slack.comhttp://linkedin.com/in/cadanalyst

new_mem

  • Newt
  • Posts: 67
Re: merge list_layer to another list_layer
« Reply #3 on: May 22, 2016, 10:25:17 AM »
thanks for repply,

here my code/
(defun c:123 (/ lst1 lst2 e new_name)
  (setq lst1 (list "1" "2" "3" "4" "5" "6"))
  (setq lst2 (list "1new" "2new" "3new" "4new" "5new" "6new"))
  (command "_.LAYMRG")
  (foreach e lst1
    (if (tblsearch "LAYER" e)
      (progn
   (setq new_name (car lst))
   (command "_Name" e "" "_N" new_name "_Y")
   (setq lst (cdr lst))
   );progn
      );if
    );foreach
  (princ)
)

Long time i dont use mapcar. Pls tell me, thanks.

T.Willey

  • Needs a day job
  • Posts: 5251
Re: merge list_layer to another list_layer
« Reply #4 on: May 22, 2016, 10:30:07 AM »
So you are trying to rename a layer if the layer is found, based on two lists?

Code - Lisp: [Select]
  1. (foreach i (mapcar (function cons) list1 list2)
  2.     (if .... search of '(car i)'
  3.         ... rename '(car i)' to '(cdr i)'..
  4.     )
  5. )
  6.  

Typed in message, so be careful, but the idea is there.[/code]
Tim

I don't want to ' end-up ', I want to ' become '. - Me

Please think about donating if this post helped you.

T.Willey

  • Needs a day job
  • Posts: 5251
Re: merge list_layer to another list_layer
« Reply #5 on: May 22, 2016, 10:33:29 AM »
Or even ....

I am so glad I learned 'mapcar' within Lisp.  I am using 'map' within Python code, and it seems no-one else is.  What a waste.

Code - Lisp: [Select]
  1. (mapcar (function (lambda (a b) (if ... layer a is found .... change layer a name to b ) ) ) list1 list2 )
  2.  
Tim

I don't want to ' end-up ', I want to ' become '. - Me

Please think about donating if this post helped you.

MP

  • Seagull
  • Posts: 17750
  • Have thousands of dwgs to process? Contact me.
Re: merge list_layer to another list_layer
« Reply #6 on: May 22, 2016, 10:36:58 AM »
What my caffeine deprived brain thinks ...

Code: [Select]
(progn
    (vl-load-com)
    (vlax-for layer (vla-get-layers (vla-get-activedocument (vlax-get-acad-object)))
        (if (wcmatch (strcase (setq name (vla-get-name layer))) "~*NEW")
            (vl-catch-all-apply 'vla-put-name
                (list layer (strcat name "new"))
            )
        )
    )
    (princ)
)

Subtitle: Mapcar is a great function but not the solution for everything.
Engineering Technologist • CAD Automation Practitioner
Automation ▸ Design ▸ Drafting ▸ Document Control ▸ Client
cadanalyst@gmail.comhttp://cadanalyst.slack.comhttp://linkedin.com/in/cadanalyst

T.Willey

  • Needs a day job
  • Posts: 5251
Re: merge list_layer to another list_layer
« Reply #7 on: May 22, 2016, 10:44:27 AM »
MP,

I thought one should not change the contents of the a collection when stepping through the collection?  I would make a list of the items to change, and then change them after stepping through the collection.  Maybe I am remembering wrong about that though.

Subtitle: Mapcar is a great function but not the solution for everything.

True, but it can be a great tool for applying a function to a whole list of items.
Tim

I don't want to ' end-up ', I want to ' become '. - Me

Please think about donating if this post helped you.

MP

  • Seagull
  • Posts: 17750
  • Have thousands of dwgs to process? Contact me.
Re: merge list_layer to another list_layer
« Reply #8 on: May 22, 2016, 11:05:29 AM »
Hi Tim, if one intends to add or delete items from a collection then it would be ill advised to do so while iterating it. In the code snip I provided I'm merely abusing a collection item's property (name) that has no impact upon the container (aside from potential duplicate key or non modifiable layer, ergo the catch code).

For example, if I were iterating thru the dictionary collection looking to delete any dictionary entry with an "AEC" prefix I'd collect the offending dictionaries in a temporary list and then delete all the items in said temporary list.
Engineering Technologist • CAD Automation Practitioner
Automation ▸ Design ▸ Drafting ▸ Document Control ▸ Client
cadanalyst@gmail.comhttp://cadanalyst.slack.comhttp://linkedin.com/in/cadanalyst

new_mem

  • Newt
  • Posts: 67
Re: merge list_layer to another list_layer
« Reply #9 on: May 22, 2016, 11:15:08 AM »
So you are trying to rename a layer if the layer is found, based on two lists?

Code - Lisp: [Select]
  1. (foreach i (mapcar (function cons) list1 list2)
  2.     (if .... search of '(car i)'
  3.         ... rename '(car i)' to '(cdr i)'..
  4.     )
  5. )
  6.  

Typed in message, so be careful, but the idea is there.[/code]

i dont want rename layer because if layer 1new have in drawing. i mean creat lst layer new then merge layer_old with new. I have not found the answer loop.

(defun c:123 (/ lst1 lst2 n layer1 layer2)
  (setq lst1 (list "1" "2" "3" "4" "5" "6"))
  (setq lst2 (list "1new" "2new" "3new" "4new" "5new" "6new"))
  (setq n 0)
  (repeat
    (SsLength lst1)
    (setq layer1 (nth n lst1))
    (setq layer2 (nth n lst2))
    (if (tblsearch "LAYER" layer1)
      (if (tblsearch "LAYER" layer2)
   (command "_.LAYMRG" "_Name" layer1 "" "_N" layer2 "_Y")
   );if layer2
      );if layer1
    (setq n (+ n 1))
    )
  (princ)
  )

Pls check it.

new_mem

  • Newt
  • Posts: 67
Re: merge list_layer to another list_layer
« Reply #10 on: May 22, 2016, 11:17:57 AM »
What my caffeine deprived brain thinks ...

Code: [Select]
(progn
    (vl-load-com)
    (vlax-for layer (vla-get-layers (vla-get-activedocument (vlax-get-acad-object)))
        (if (wcmatch (strcase (setq name (vla-get-name layer))) "~*NEW")
            (vl-catch-all-apply 'vla-put-name
                (list layer (strcat name "new"))
            )
        )
    )
    (princ)
)

Subtitle: Mapcar is a great function but not the solution for everything.

thanks for repply.

But i mean any layer : 1->abc , 2->dahfds, 3->........

new_mem

  • Newt
  • Posts: 67
Re: merge list_layer to another list_layer
« Reply #11 on: May 22, 2016, 11:45:02 AM »
So you are trying to rename a layer if the layer is found, based on two lists?

Code - Lisp: [Select]
  1. (foreach i (mapcar (function cons) list1 list2)
  2.     (if .... search of '(car i)'
  3.         ... rename '(car i)' to '(cdr i)'..
  4.     )
  5. )
  6.  

Typed in message, so be careful, but the idea is there.[/code]

i dont want rename layer because if layer 1new have in drawing. i mean creat lst layer new then merge layer_old with new. I have not found the answer loop.

(defun c:123 (/ lst1 lst2 n layer1 layer2)
  (setq lst1 (list "1" "2" "3" "4" "5" "6"))
  (setq lst2 (list "1new" "2new" "3new" "4new" "5new" "6new"))
  (setq n 0)
  (repeat
    (SsLength lst1)
    (setq layer1 (nth n lst1))
    (setq layer2 (nth n lst2))
    (if (tblsearch "LAYER" layer1)
      (if (tblsearch "LAYER" layer2)
   (command "_.LAYMRG" "_Name" layer1 "" "_N" layer2 "_Y")
   );if layer2
      );if layer1
    (setq n (+ n 1))
    )
  (princ)
  )

Pls check it.

wrong sslength. i have change length.
It work.
Thank you.

Lee Mac

  • Seagull
  • Posts: 12913
  • London, England
Re: merge list_layer to another list_layer
« Reply #12 on: May 22, 2016, 12:00:49 PM »
If I've correctly understood:
Code - Auto/Visual Lisp: [Select]
  1. (defun renamelayers ( lst / new )
  2.         (if (setq new (cdr (assoc (vla-get-name lay) lst)))
  3.             (vl-catch-all-apply 'vla-put-name (list lay new))
  4.         )
  5.     )
  6. )
Code - Auto/Visual Lisp: [Select]
  1. (renamelayers (mapcar 'cons lst1 lst2))

new_mem

  • Newt
  • Posts: 67
Re: merge list_layer to another list_layer
« Reply #13 on: May 22, 2016, 12:09:53 PM »
If I've correctly understood:
Code - Auto/Visual Lisp: [Select]
  1. (defun renamelayers ( lst / new )
  2.         (if (setq new (cdr (assoc (vla-get-name lay) lst)))
  3.             (vl-catch-all-apply 'vla-put-name (list lay new))
  4.         )
  5.     )
  6. )
Code - Auto/Visual Lisp: [Select]
  1. (renamelayers (mapcar 'cons lst1 lst2))

Thanks for your funtion mapcar
I mean:
1. Creat my layer by import layer_iso (color, linetype, Linewight...)
2. Merge layer current drawing to layer_iso

My project is following ATKIN design. And my boss want to change layer ATK to my office iso.
Thanks again.

LeeMac
How can i merge layer multi drawing in folder but dont open drawing. I saw bfind lisp magic.  :smitten:
« Last Edit: May 22, 2016, 12:46:11 PM by new_mem »

T.Willey

  • Needs a day job
  • Posts: 5251
Re: merge list_layer to another list_layer
« Reply #14 on: May 22, 2016, 12:24:55 PM »
Thanks, MP.  That seems more right than what I was thinking.

Hi Tim, if one intends to add or delete items from a collection then it would be ill advised to do so while iterating it. In the code snip I provided I'm merely abusing a collection item's property (name) that has no impact upon the container (aside from potential duplicate key or non modifiable layer, ergo the catch code).

For example, if I were iterating thru the dictionary collection looking to delete any dictionary entry with an "AEC" prefix I'd collect the offending dictionaries in a temporary list and then delete all the items in said temporary list.

Glad to hear you got something working for yourself, new_mem.
Tim

I don't want to ' end-up ', I want to ' become '. - Me

Please think about donating if this post helped you.

new_mem

  • Newt
  • Posts: 67
Re: merge list_layer to another list_layer
« Reply #15 on: May 22, 2016, 12:39:33 PM »


Glad to hear you got something working for yourself, new_mem.
[/quote]

Thank for your solution.  :smitten:

new_mem

  • Newt
  • Posts: 67
Re: merge list_layer to another list_layer
« Reply #16 on: May 22, 2016, 12:47:06 PM »
LeeMac
How can i merge layer multi drawing in folder but dont open drawing. I saw bfind lisp magic.  :smitten:

ChrisCarlson

  • Guest
Re: merge list_layer to another list_layer
« Reply #17 on: May 23, 2016, 12:56:16 PM »
Look into Lee-Mac's steal routine

http://www.lee-mac.com/steal.html

Code - Auto/Visual Lisp: [Select]
  1. (Steal "C:\\My Folder\\MyDrawing.dwg"
  2.    '(
  3.         (
  4.             "Layers"
  5.             ("Layer1" "Layer2")
  6.         )
  7.         (
  8.             "Dimension Styles"
  9.             ("DimStyle*")
  10.         )
  11.     )

new_mem

  • Newt
  • Posts: 67
Re: merge list_layer to another list_layer
« Reply #18 on: August 26, 2016, 12:30:18 PM »
Thanks for repply,

now i think i will use DBX to merge layer. Can i do it ?

Can i call merge list layer via DBX in multifile? or call acet_laytrans ?

Because cannot call ssget object to put new name layer.

« Last Edit: August 26, 2016, 12:36:43 PM by new_mem »

new_mem

  • Newt
  • Posts: 67
Re: merge list_layer to another list_layer
« Reply #19 on: August 27, 2016, 10:04:52 AM »
i think can do it

Found some code of Lee Mac and write this code:

(defun c:test ( / lst lst_layer)
    (if (setq lst (LM:getfiles "Select Drawings to Process" nil "dwg;dws;dwt"))
      (progn

   (setq lst_layer '(("Layer1" "Arch1") ("Layer2"  "Arch2") ("Layer3" "Arch3")))
   (LM:odbx '(lambda ( doc ) (merge_layer doc lst_layer)) lst t)
        (princ "\n*Cancel*")
   );progn
    )
    (princ)
)
(defun merge_layer (doc lst / layers lay_obj)
  (foreach name lst
    (make_layer doc (cadr name))
    )
  (setq layers (vla-get-layers doc))
  (vlax-for obj (vla-get-modelspace doc)
    (setq lay_obj (vlax-get obj 'Layer))
    (foreach name lst
      (if (wcmatch lay_obj (car name))
   (vla-put-layer obj (cadr name))
   );if
      );foreach name
    );vlax-for obj
  (vla-purgeall doc)
  );defun
(defun make_layer (doc str / )
  (if (not (wcmatch (vla-item lay (vla-get-layers doc) str)))
    (vla-add (vla-get-layers doc) str)
    )
  )

new_mem

  • Newt
  • Posts: 67
Re: merge list_layer to another list_layer
« Reply #20 on: August 27, 2016, 07:45:14 PM »
Wow,

why error: ActiveX Server returned the error: unknown name: PurgeAll

Can someone tell me, pls.!

MP

  • Seagull
  • Posts: 17750
  • Have thousands of dwgs to process? Contact me.
Re: merge list_layer to another list_layer
« Reply #21 on: August 27, 2016, 10:40:18 PM »
ODBX docs do not support the PurgeAll method.

You can achieve a similar effect as purging by rolling your own purger, i.e. error trap attempts to delete collection entries.

Simplified concept:

Code: [Select]
(defun _Items ( collection / items )
    (vlax-for i collection (setq items (cons i items)))
    ;;  Since this is a general function reflect
    ;;  the collection's original item order.
    (reverse items)
)

Code: [Select]
(defun _Purge ( collection n )
    ;;  Try to delete collection entries n times
    ;;  (to deal with intra-entry dependencies).
    (   (lambda ( live n / dead )
            (repeat n
                (foreach i live
                    (vl-catch-all-apply 'vla-delete (list i))
                    (if (vlax-erased-p i) (setq dead (cons i dead)))
                )
                (setq live (vl-remove-if (function (lambda (i) (member i dead))) live))
            )
            (length dead)
        )
        ;;  Process newest entries first.
        (reverse (_Items collection))
        ;;  Idiot proof the n argument.
        (if (eq 'int (type n)) n 1)
    )
)

(_Purge (vla-get-layers doc) 1)

might return 42

Expect sloth-like performance.

Why reverse the list? Latter entries (in collections like blocks) may reference earlier entries, so deleting backwards (i.e. newest entries first) would tend to sport a higher success rate.

Cheers.
Engineering Technologist • CAD Automation Practitioner
Automation ▸ Design ▸ Drafting ▸ Document Control ▸ Client
cadanalyst@gmail.comhttp://cadanalyst.slack.comhttp://linkedin.com/in/cadanalyst

new_mem

  • Newt
  • Posts: 67
Re: merge list_layer to another list_layer
« Reply #22 on: August 28, 2016, 03:06:35 AM »
Cool,

thanks MP  :roll:

I add code then it delete layer and object in layer.

(vlax-for obj (vla-get-paperspace doc)
    (print obj)
    (setq lay_obj (vlax-get obj 'Layer))
    (foreach name lst
      (if (wcmatch lay_obj (car name))
   (vla-put-layer obj (cadr name))
   );if
      );foreach name
    );vlax-for obj
(foreach name lst
      (if (ValidItem layers (car name))
   (vla-delete (vla-item layers (car name)))
   )
      )
;Code found Doug Broad
(defun ValidItem (collection item / res)
  (vl-catch-all-apply
    '(lambda ()
       (setq res (vla-item collection item))
     )
  )
  res
)

Your code have error trap. It still not delete layer if object in paperspace not change another layer. So i used your code in lisp.
One more question: how to put layer all object in paperspace if dwg have >1 layout ?

T.Willey

  • Needs a day job
  • Posts: 5251
Re: merge list_layer to another list_layer
« Reply #23 on: August 28, 2016, 03:32:03 AM »
This code will step through all layouts within the current drawing and print the name of each object type to the command line.

Code - Text: [Select]
  1. (vlax-for i (vla-get-Layouts (vla-get-ActiveDocument  (vlax-get-Acad-Object)))
  2.     (vlax-for j (vla-get-Block i)
  3.         (print (vla-get-ObjectName j))
  4.     )
  5. )
  6.  

If you only want 'paper space' layouts, then the only way I can remember is to check the name of the layout, and if it doesn't equal 'Model' then do your work.  Like:
Code - Text: [Select]
  1. (vlax-for i (vla-get-Layouts (vla-get-ActiveDocument  (vlax-get-Acad-Object)))
  2.     (if (/= (vla-get-Name i) "Model" )
  3.         (vlax-for j (vla-get-Block i)
  4.             (print (vla-get-ObjectName j))
  5.         )
  6.     )
  7. )
  8.  

Hope that helps.
Tim

I don't want to ' end-up ', I want to ' become '. - Me

Please think about donating if this post helped you.

new_mem

  • Newt
  • Posts: 67
Re: merge list_layer to another list_layer
« Reply #24 on: August 28, 2016, 03:40:49 AM »
Okey Tim,

If only way then let me try it.

Thanks for your code.

new_mem

  • Newt
  • Posts: 67
Re: merge list_layer to another list_layer
« Reply #25 on: August 28, 2016, 07:55:30 AM »
Okey right Tim,

Thanks Tim
add 2 loop get all obj.

(vlax-for i (vla-get-Layouts doc)
    (vlax-for j (vla-get-Block i)
      (if (setq lay_obj (vlax-get j 'Layer))
   (foreach name lst
     (if (wcmatch lay_obj (car name))
       (vla-put-layer j (cadr name))
       );if
     );foreach name
   );if
      );vlax-for j
    );vlax-for i
  (foreach name lst
    (_Purge (vla-get-layers doc) (car name))
    )