See the top rated post in this thread. Click here

Results 1 to 8 of 8

Thread: Help with freezing a certain layer in a multiple dwgs without opening them.

  1. #1
    Member
    Join Date
    2016-10
    Posts
    6
    Login to Give a bone
    0

    Default Help with freezing a certain layer in a multiple dwgs without opening them.

    I'm trying to stitch some code together but I need some guidance. I've done some research but hopefully some one can funnel me down further more on to the right path. I am trying to make a very simple Lisp routine that opens multiple files in the directory, freezes a layer, and saves them.

    Ive actually found a code that does very close to what i want, except that it does it with one file at a time. (Also this code turns off the layer instead of freezing but I can change that later.)


    This lisp routine asks a user via open file dialog to select a file in current dwg's directory, and turns a layer off that the user typed in earlier.
    Code:
    ;; this program can turn off the layer you enter.
    (defun c:lof ()       
    (vl-load-com)
    (setq dwgfile (getfiled "Select a drawing" "" "dwg" 0))
    (setq lay (getstring "\nENTER A LAYER TO TURN OFF:"))
    (setq cadver(substr (getvar "acadver") 1 2))                       ;; get cad version No.
    (setq id (strcat "objectdbx.AxDbDocument." cadver))           ;; creat prog id
    (setq dbx(vlax-create-object id))                                         ;; creat dbx object
    (vla-open dbx dwgfile)
    (setq layers (vla-get-layers dbx))                 ;; get layer collection set from dbx
               (if (not (vl-catch-all-error-p
                   (setq vlay(vl-catch-all-apply 'vla-item (list layers lay)))))       ;; fild the specified layer in collection   
                   (if (eq (vla-get-layeron vlay) :vlax-true)                          ;; check layer status         
                       (vla-put-layeron vlay :vlax-false)  
                    )   
                    (print "THE LAYER NOT FOUND  ! ")
                 )
    (vla-saveas dbx dwgfile)  
    (vlax-release-object dbx)
    (prin1)
    )
    
    
    ;|
    Pretty neat stuff, and I think this is a good start but I am trying be able to select multiple files. Is there an alternative to '(getfiled )' function that lets you get a list of files? And if so can i just parse through them with a loop?


    This would be my ideal solution. But if not possible (for me atleast) I wouldn't mind just going through the entire directory of the open DWG and turning off the layer in every dwg except for active dwg open.

    Thank you in advance!

  2. #2
    Member
    Join Date
    2017-10
    Posts
    5
    Login to Give a bone
    1

    Default Re: Help with freezing a certain layer in a multiple dwgs without opening them.

    See my attempt at solving your problem, waynebrady.

    Notice that in my solution, your original function is changed to "DBXLAYMOD". This function only contains the logic involved in opening a DWG file and modifying its layers. "DBXLAYMOD" is written to allow it to manipulate any layer property supported by Visual LisP/ActiveX. This means, "DBXLAYMOD" can freeze/thaw layers, turn layers on/off, set/change layer descriptions, set layer colors, set layer lineweights, set layers are plottable, and (un)lock layers.

    Two command functions now exist to demonstrate how "DBXLAYMOD" is to used. These command functions also separate the "processing logic" from the "presentation/user-interface logic".

    The first command function, titled "layfrzdwgdir", will freeze user-specified layers that are in any of the DWG files in the directory of the current drawing.

    The second command function, titled "layfrzstatic", is quickly written with made-up paths and comments explaining how "DBXLAYMOD" can be used.

    Caveats:
    Both the function you posted and the functions below rely on functionality called ObjectDBX (or RealDWG). ObjectDBX can read from and write to DWG files that are not in use by AutoCAD and when you're not trying to access the system variables in that DWG file. Errors will occur in either of these cases.

    The provided command functions use the system variables "DWGPREFIX" and "DWGNAME" to get the file-name and directory-path of the current DWG file. "DBXLAYMOD" may not work correctly with network paths.

    Other considerations:
    You requested multiple file selection with a dialog box. Unfortunately, AutoCAD's Lisp engine does not natively support that functionality. There are options/workarounds though: create a custom Lisp function that uses DCL (dialog control language) to mimic AutoCAD Lisp's "GETFILED" function.

    Code:
    ;; layfrzdwgdir - Command function
    ;; Freezes layers in all DWG files in the current directory, except the current DWG file.
    (defun c:layfrzdwgdir ( / item)
    	(DBXLAYMOD
    		(mapcar
    			'(lambda (item)
    				(strcat (getvar "DWGPREFIX") item)
    			)
    			(vl-remove 
    				(getvar "DWGNAME")
    				(vl-directory-files (getvar "DWGPREFIX") "*.dwg" 1)
    			)
    		)
    		(strexplode (getstring "\nSpecify layers to freeze (Layer1,Layer2,etc):") ",")
    		'Freeze
    		:vlax-true
    	)
    	(princ)
    )
    
    ;; layfrzstatic - Command function
    ;; Freezes layers in a supplied list of DWG files.
    (defun c:layfrzstatic ()
    	(DBXLAYMOD
    		(list "path/to/a.dwg" "path/to/b.dwg" "path/to/c.dwg")
    		;; The above line specifies a list of files. You could replace this line with a call to a
    		;; user LISP function that allows multiple file selections.
    		(strexplode (getstring "\nSpecify layers to freeze (Layer1,Layer2,etc):") ",")
    		;; You can replace the above line with: (list "Layer1 "Layer2" "Layer3")
    		'Freeze ;; or use 'LayerOn or any other supported VLAX layer property
    		:vlax-true ;; the value you want each listed layer to be set to
    	)
    	(princ)
    )
    
    
    ;; DBXLAYMOD
    ;; Modifies specified layers in a list of DWG files.
    ;; Parameters
    ;; ;; FILES - A list of strings specifying fully-pathed DWG files
    ;; ;; LAYERS - A list of string specifying layer names
    ;; ;; PROPN - (Property-name) A VLAX-recognized property that is applicable to a VLAX layer object
    ;; ;; PROPV - (Property-value) The desired value of the property
    (defun DBXLAYMOD (files layers propn propv / layCol layObj item dbx)
    	(vl-load-com)
    	(setq 
    		files 
    		(if (not (listp files)) (list) files)
    		
    		files 
    		(vl-remove-if '
    			(lambda (item) 
    				(or 
    					(not (equal (type item) 'STR)) 
    					(not (equal (strcase (vl-filename-extension item)) ".DWG"))
    				)
    			) 
    			files
    		)
    	)
    	(while (car files)
    		(setq 
    			dbx ;; create dbx object
    			(vlax-create-object 
    				(strcat 
    					"objectdbx.AxDbDocument." 
    					(substr (getvar "acadver") 1 2)
    				)
    			)
    		)
    		(vla-Open dbx (car files))
    		(setq
    			layCol 
    			(vla-get-layers dbx) ;; get layer collection set from dbx
    		)
    		
    		(foreach item layers
    			(if (and
    					(not 
    						(vl-catch-all-error-p
    							(setq 
    								layObj 
    								(vl-catch-all-apply 
    									'vla-item          ;; find the specified layer in collection  
    									(list layCol item)
    								) 
    							) 
    						)
    					)
    					(vlax-property-available-p layObj propn)
    					(not (equal (vlax-get-property layObj propn) propv)) ;; check layer status
    				)
    				(vlax-put-property layObj propn propv)
    			)
    		)
    		(vla-SaveAs dbx (car files))
    		(vlax-release-object dbx)
    		(setq files (cdr files))
    	)
    )
    
    ;; STREXPLODE
    ;; Converts a string into a list using a given delimiting string.
    (defun strexplode (str delim / pos)
        (if (setq pos (vl-string-search delim str))
            (cons 
    			(substr str 1 pos)
    			(strexplode 
    				(substr str (+ pos 1 (strlen delim)))
    				delim
    			)
    		)
            (list str)
        )
    )
    
    (princ)
    Last edited by Encryptium; 2017-10-15 at 02:56 AM. Reason: Proofreading, minor corrections.

  3. #3
    Member
    Join Date
    2016-10
    Posts
    6
    Login to Give a bone
    0

    Default Re: Help with freezing a certain layer in a multiple dwgs without opening them.

    Wow can't believe you just went and decided to do all of the work for me! I actually can not get this to work, I get an error
    Code:
    Command: Error. Unknown command "ERROR.".  Press F1 for help.
    Command: Description Unknown command "DESCRIPTION".  Press F1 for help.
    or
    Code:
    Updating Indexes for block *Model_Space
    Done.
    Updating Indexes for block *Model_Space
    Done.
    Automation Error. Description was not provided.
    Command:
    This is with the 'layfrzdwgdir' command. And I ran this with one DWG open from the directory.

    Either way the comments are great and this is great start for me to break down and study the code! Thanks

  4. #4
    Member
    Join Date
    2017-10
    Posts
    5
    Login to Give a bone
    0

    Default Re: Help with freezing a certain layer in a multiple dwgs without opening them.

    Quote Originally Posted by waynebrady View Post
    Wow can't believe you just went and decided to do all of the work for me! I actually can not get this to work, I get an error
    Code:
    Command: Error. Unknown command "ERROR.".  Press F1 for help.
    Command: Description Unknown command "DESCRIPTION".  Press F1 for help.
    or
    Code:
    Updating Indexes for block *Model_Space
    Done.
    Updating Indexes for block *Model_Space
    Done.
    Automation Error. Description was not provided.
    Command:
    This is with the 'layfrzdwgdir' command. And I ran this with one DWG open from the directory.

    Either way the comments are great and this is great start for me to break down and study the code! Thanks
    The first set of errors appears to be derived from the set below it. For some reason, " ERROR." And "DESCRIPTION" were enter into the command prompt.

    On my end, the LisP code I posted works as expected. Are you at liberty to posted the DWG files you're testing this code on? All the DWG needs to have are layers.

    The LisP code I posted may not work on XREF layers. Also, what version of AutoCAD are you using?

  5. #5
    Administrator BlackBox's Avatar
    Join Date
    2009-11
    Posts
    5,719
    Login to Give a bone
    2

    Default Re: Help with freezing a certain layer in a multiple dwgs without opening them.

    Give this a try -

    BLAYFRZ accepts a case-sensitive WCMATCH string for the Layer name(s) that you want to batch freeze (just like the -LAYER Command), and reports how many layers have been frozen at the command line after the given drawing has been conditionally saved (only if one or more Layers have been frozen).

    Code:
    (vl-load-com)
    
    (defun c:BLAYFRZ () (c:BatchLayerFreeze))
    (defun c:BatchLayerFreeze (/ *error* acApp dwgName oShell oFolder path
                                 dwgs layerName dbxDoc nomutt dwgName i
                                )
    
      (princ "\rBATCHLAYERFREEZE ")
    
      (defun *error* (msg)
        (if nomutt
          (setvar 'nomutt nomutt)
        )
        (if oShell
          (vlax-release-object oShell)
        )
        (if dbxDoc
          (vlax-release-object dbxDoc)
        )
        (cond ((not msg))                                                   ; Normal exit
              ((member msg '("Function cancelled" "quit / exit abort")))    ; <esc> or (quit)
              ((princ (strcat "\n** Error: " msg " ** ")))                  ; Fatal error, display it
        )
        (princ)
      )
    
      (if
        (and
          (setq acApp (vlax-get-acad-object))
          (setq dwgName (getvar 'dwgname))
          (setq oShell (vla-getinterfaceobject
                         acApp
                         "Shell.Application"
                       )
          )
          (setq oFolder (vlax-invoke
                          oShell
                          'BrowseForFolder
                          (vla-get-hwnd acApp)
                          "Select folder to process:"
                          0
                          (+ 1 64 256)
                        )
          )
          (setq path (vlax-get-property
                       (vlax-get-property oFolder 'Self)
                       'Path
                     )
          )
          (setq dwgs (vl-directory-files path "*.dwg" 1))
          (setq layerName
                 (getstring T
                            "\nEnter WCMATCH layer name(s) to freeze: "
                 )
          )
          (princ "\nWorking, please wait...")
          (princ)
          (setq dbxDoc (vla-getinterfaceobject
                         acApp
                         (strcat "ObjectDBX.AxDbDocument."
                                 (substr (getvar 'acadver) 1 2)
                         )
                       )
          )
          (setq nomutt (getvar 'nomutt))
          (setvar 'nomutt 1)
        )
         (progn
           (foreach dwg dwgs
             (if (/= dwg dwgName)
               (progn
                 (vl-catch-all-apply
                   'vla-open
                   (list dbxDoc (setq dwgName (strcat path "\\" dwg)))
                 )
                 (setq i 0)
                 (vlax-for x (vla-get-layers dbxDoc)
                   (if
                     (and
                       (wcmatch (vla-get-name x) layerName)
                       (= (vla-get-freeze x) :vlax-false)
                     )
                     (if
                       (not
                         (vl-catch-all-error-p
                           (vl-catch-all-apply
                             'vla-put-freeze
                             (list x :vlax-true)
                           )
                         )
                       )
                        (setq i (1+ i))
                     )
                   )
                 )
                 (if (< 0 i)
                   (vla-saveas dbxDoc dwgName)
                 )
                 (setvar 'nomutt 0)
                 (prompt
                   (strcat "\n >> "
                           dwg
                           " >> "
                           (itoa i)
                           " layer"
                           (if (= 1 i)
                             ""
                             "s"
                           )
                           " frozen "
                   )
                 )
                 (setvar 'nomutt 1)
               )
             )
           )
           (setvar 'nomutt 0)
           (prompt "\nDone. \n")
           (*error* nil)
         )
         (cond
           (layerName
            (*error*
              "Unable to create \"ObjectDBX.AxDbDocument\" Object"
            )
           )
           (path (*error* "No drawings found"))
           (oShell (*error* "No folder selected"))
           (dwgName
            (*error* "Unable to create \"Shell.Application\" Object")
           )
           ((*error*
              "Unable to create \"AcadApplication Object\" Object"
            )
           )
         )
      )
    )
    Examples:
    Code:
    Command:
    Command: BLAYFRZ
    BATCHLAYERFREEZE
    Enter WCMATCH layer name(s) to freeze: E-*
    Working, please wait...
     >> BLayFrz.Drawing1.dwg >> 99 layers frozen
     >> BLayFrz.Drawing2.dwg >> 99 layers frozen
    Done.
    
    Command:
    Command: BLAYFRZ
    BATCHLAYERFREEZE
    Enter WCMATCH layer name(s) to freeze: E-*
    Working, please wait...
     >> BLayFrz.Drawing1.dwg >> 0 layers frozen
     >> BLayFrz.Drawing2.dwg >> 0 layers frozen
    Done.
    
    Command:
    BLAYFRZ
    BATCHLAYERFREEZE
    Enter WCMATCH layer name(s) to freeze: e-*
    Working, please wait...
     >> BLayFrz.Drawing1.dwg >> 0 layers frozen
     >> BLayFrz.Drawing2.dwg >> 0 layers frozen
    Done.
    
    Command:
    BLAYFRZ
    BATCHLAYERFREEZE
    Enter WCMATCH layer name(s) to freeze: P-*
    Working, please wait...
     >> BLayFrz.Drawing1.dwg >> 100 layers frozen
     >> BLayFrz.Drawing2.dwg >> 100 layers frozen
    Done.
    
    Command:
    Command: BLAYFRZ
    BATCHLAYERFREEZE
    Enter WCMATCH layer name(s) to freeze: 0
    Working, please wait...
     >> BLayFrz.Drawing1.dwg >> 1 layer frozen
     >> BLayFrz.Drawing2.dwg >> 0 layers frozen
    Done.
    
    Command:
    Cheers
    "How we think determines what we do, and what we do determines what we get."

    Sincpac C3D ~ Autodesk Exchange Apps

    Computer Specs:
    Dell Precision 3660, Core i9-12900K 5.2GHz, 64GB DDR5 RAM, PCIe 4.0 M.2 SSD (RAID 0), 16GB NVIDIA RTX A4000

  6. #6
    Member
    Join Date
    2016-10
    Posts
    6
    Login to Give a bone
    0

    Default Re: Help with freezing a certain layer in a multiple dwgs without opening them.

    Encryptium, I am not sure what I did wrong before but you're lisp works 100% of the time now, and on x referenced layers... BlackBox this is amazing code too! Thank you guys, not too proud of my self on how much i put into this but you gave me exactly what i needed, and this will definitely help me write future code.
    Last edited by waynebrady; 2017-10-24 at 01:47 AM.

  7. #7
    Member
    Join Date
    2018-04
    Posts
    2
    Login to Give a bone
    0

    Default Re: Help with freezing a certain layer in a multiple dwgs without opening them.

    Quote Originally Posted by BlackBox View Post
    Give this a try -

    BLAYFRZ accepts a case-sensitive WCMATCH string for the Layer name(s) that you want to batch freeze (just like the -LAYER Command), and reports how many layers have been frozen at the command line after the given drawing has been conditionally saved (only if one or more Layers have been frozen).

    Hello, This code is perfect for freezing layers!

    I am trying to convert it so it also works on Thawing layers, but i cannot manage. I mess it up somewhere.

    Can you or somebody else convert it to be used to thaw layers instead?

    Thank you in advanced!

  8. #8
    Member
    Join Date
    2018-04
    Posts
    2
    Login to Give a bone
    0

    Default Re: Help with freezing a certain layer in a multiple dwgs without opening them.

    Solved this by changing the definition for false and true.

Similar Threads

  1. 2011: Drawings freezing on opening
    By pg731037 in forum AutoCAD General
    Replies: 6
    Last Post: 2016-07-13, 01:39 PM
  2. Opening dwgs/xrefs with Autolisp...
    By brwatts22 in forum AutoLISP
    Replies: 2
    Last Post: 2012-12-26, 11:50 AM
  3. Layer Freezing Problem
    By lilytwining in forum AutoCAD General
    Replies: 0
    Last Post: 2009-04-22, 02:18 PM
  4. Multiple Viewport Freezing
    By s_saldanha in forum AutoCAD Tips & Tricks
    Replies: 3
    Last Post: 2008-11-13, 05:59 AM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •