Jump to content

Delete Layer and it´s contents


TheRedGuy

Recommended Posts

Hi everyone, here a simple vba code to delete layers. It previously erases all the layer's content in order to make deletion possible. Hope it helps someone.

 

First of all, you need to create a UserForm with a ListBox control named "LBLayers", which must have the MultiSelect property set to "2-fmMultiSelectExtended". Also you´ll need a command button named "CBEraseLayer", and a quit control if you want.

 

Add the following code to the UserForm code

 

Option Explicit

Public Sub LoadLayersList(LList As ListBox)
   Dim tlay As AcadLayer
   
   LList.Clear
   For Each tlay In ThisDrawing.Layers
       Call LList.AddItem(tlay.Name)
   Next tlay
   
   LList.ListIndex = 0
   
End Sub

Private Sub CBEraseLayer_Click()
   Dim tlay As AcadLayer
   Dim sset As AcadSelectionSet
   Dim FilterType(0) As Integer
   Dim FilterData(0) As Variant
   Dim nlays As Integer, i As Integer
   
   nlays = LBLayers.ListCount
   
   If ThisDrawing.SelectionSets.Count >= 1 Then
       For i = ThisDrawing.SelectionSets.Count - 1 To 0 Step -1
           ThisDrawing.SelectionSets.Item(i).Delete
       Next i
   End If
   
   FilterType(0) = 8
   For i = 0 To nlays - 1
       If LBLayers.Selected(i) Then
           FilterData(0) = LBLayers.List(i)
           Set sset = ThisDrawing.SelectionSets.Add("SSAUX01")
           Call sset.Select(acSelectionSetAll, , , FilterType, FilterData)
           Call sset.Erase
           Call sset.Delete
           ThisDrawing.Layers.Item(LBLayers.List(i)).Delete
       End If
   Next i
   Call LoadLayersList(LBLayers)
   Exit Sub

End Sub

Private Sub CBQuit_Click()
   UFEraseLayer.Hide
End Sub

Private Sub UserForm_Activate()
   Call LoadLayersList(LBLayers)
End Sub

 

Also, you will need a module with a sub in order to launch the macro from autocad, the launcher could be something like this

 


Public Sub EraseLayers()
   Load UFEraseLayer
   UFEraseLayer.Show
   Unload UFEraseLayer
End Sub

 

Now, you can call the Form from the macros menu, and erase all the selected layers together with it´s contents.

 

NOTE: Use it carefully! :nuke:

Link to comment
Share on other sites

  • Replies 24
  • Created
  • Last Reply

Top Posters In This Topic

  • Lee Mac

    12

  • TheRedGuy

    6

  • Hunter

    5

  • CADgirl

    1

Top Posters In This Topic

The UserForm loads all the layers names on the ListBox and let´s the user to select which layers are going to be deleted.

Regarding your question, no, it doesn´t check that layer "0" cannot be deleted, so adding an if inside the layers list to avoid this situation that clearly would lead to a runtime error, would improve the code. Also, check if the layer is locked or not and ask if you want to delete it anyway. In that case, unlock the layer and proceed, otherwise don´t try to delete the objects inside the layer, this also would lead to a runtime error.

 

Regards

 

Alejandro

Link to comment
Share on other sites

My apologies, the text I've places few minutes ago is almost unreadable, (I'm out of fit with my english). I hope you can understand what I've tried to say, if you want I can rethink the message, it would be a nice exercise.

 

Regards

 

Alejandro

Link to comment
Share on other sites

The previous message is a mess, I'm sorry. If you're unable to understand what I'm trying to say, I´ll be happy to rewrite it.

 

Regards

 

Alejandro

Link to comment
Share on other sites

For a programming exercise in LISP, note that a layer can be deleted with a simple one-liner:

 

(vl-catch-all-apply 'vla-Delete (list (vlax-ename->vla-object (tblobjname "LAYER" "layername"))))

 

But there are many ways to accomplish the same thing. :P

Link to comment
Share on other sites

Or, with error trappings for layer 0 and current layer... kindly provided by ASMI:

 

(defun DeleteLayer(Name / layCol dLay oVal)
 (vl-load-com)
 (if
   (and
     (/= Name "0") ; Check its not Layer 0
     (/= (strcase Name)(getvar "CLAYER")) ; Check its not Current Layer
     ); end or
   (progn
     (setq layCol(vla-get-Layers
           (vla-get-ActiveDocument
             (vlax-get-acad-object)))) ; Retrieve Current Layer Collection
      (if(vl-catch-all-error-p
          (setq dLay(vl-catch-all-apply 'vla-Item
        (list layCol(strcat Name))))) ; Retrieve Layer Object Name from Layer Collection?
        (princ "\nLayer does not exist! ")
          (if(vl-catch-all-error-p
         (vl-catch-all-apply 'vla-Delete
            (list dLay))) ; If Possible, Delete the Layer
        (princ "\nCan't delete layer in use! ")
      (setq oVal T)
    ); end if
       ); end if
     ); end progn
   (princ "\nCan't delete active layer or layer \"0\"! ")
  ); end if
 oVal
); end of DeleteLayer

Link to comment
Share on other sites

Thanks, Lisp is a pending issue. Despite that I'm able to do some programming using other list oriented languages/programs, such as Mathematica, I´ve never been able to do something using Lisp. Probably the best time investement would be in ObjectARX or something related to .NET, what do you think about?

Link to comment
Share on other sites

Hi,Lee~

 

Is this a subroutine ?

 

Would u please tell me how to run it directly?

 

Thanks ~

 

Or, with error trappings for layer 0 and current layer... kindly provided by ASMI:

 

(defun DeleteLayer(Name / layCol dLay oVal)
 (vl-load-com)
 (if
   (and
     (/= Name "0") ; Check its not Layer 0
     (/= (strcase Name)(getvar "CLAYER")) ; Check its not Current Layer
     ); end or
   (progn
     (setq layCol(vla-get-Layers
           (vla-get-ActiveDocument
             (vlax-get-acad-object)))) ; Retrieve Current Layer Collection
      (if(vl-catch-all-error-p
          (setq dLay(vl-catch-all-apply 'vla-Item
        (list layCol(strcat Name))))) ; Retrieve Layer Object Name from Layer Collection?
        (princ "\nLayer does not exist! ")
          (if(vl-catch-all-error-p
         (vl-catch-all-apply 'vla-Delete
            (list dLay))) ; If Possible, Delete the Layer
        (princ "\nCan't delete layer in use! ")
      (setq oVal T)
    ); end if
       ); end if
     ); end progn
   (princ "\nCan't delete active layer or layer \"0\"! ")
  ); end if
 oVal
); end of DeleteLayer

Link to comment
Share on other sites

Hi Hunter,

 

Yes, it is a sub-function, and requires one argument - namely the layer name.

 

Something like this:

 

(defun DeleteLayer  (Name / layCol dLay oVal)
 (vl-load-com)
 (if (and (/= Name "0")
      (/= (strcase Name) (getvar "CLAYER")))
    (progn
      (setq layCol (vla-get-Layers
             (vla-get-ActiveDocument
           (vlax-get-acad-object))))
      (if (vl-catch-all-error-p
        (setq dLay    (vl-catch-all-apply 'vla-Item
             (list layCol (strcat Name)))))
    (princ "\nLayer does not exist! ")
    (if (vl-catch-all-error-p
          (vl-catch-all-apply 'vla-Delete (list dLay)))
      (princ "\nCan't delete layer in use! ")
      (setq oVal T))))
    (princ "\nCan't delete active layer or layer \"0\"! "))
 oVal)

(defun c:test (/ lay)
 (setq lay (getstring "\nType Name of Layer..."))
 (DeleteLayer lay)
 (princ))

Link to comment
Share on other sites

I suppose you could also include coding to delete everything on that layer before deleting the layer...

 

(defun DeleteLayer  (Name / layCol dLay oVal)
 (vl-load-com)
 (if (and (/= Name "0")
      (/= (strcase Name) (getvar "CLAYER")))
    (progn
      (setq layCol (vla-get-Layers
             (vla-get-ActiveDocument
           (vlax-get-acad-object))))
      (if (vl-catch-all-error-p
        (setq dLay    (vl-catch-all-apply 'vla-Item
             (list layCol (strcat Name)))))
    (princ "\nLayer does not exist! ")
    (if (vl-catch-all-error-p
          (vl-catch-all-apply 'vla-Delete (list dLay)))
      (princ "\nCan't delete layer in use! ")
      (setq oVal T))))
    (princ "\nCan't delete active layer or layer \"0\"! "))
 oVal)

(defun c:test (/ lay ss)
 (setq lay (getstring "\nType Name of Layer..."))
 (setq ss (mapcar 'cadr (ssnamex (ssget "X" (list (cons 8 lay))))))
 (mapcar 'entdel ss)
 (DeleteLayer lay)
 (princ))

Link to comment
Share on other sites

You could compress the code into this:

 

(defun DeleteLayer  (Name / ss)
 (vl-load-com)
 (if (and (/= Name "0") (tblsearch "LAYER" Name)
      (/= (strcase Name) (getvar "CLAYER")))
   (progn
   (if    (setq ss (ssget "X" (list (cons 8 lay))))
     (mapcar 'entdel (mapcar 'cadr (ssnamex ss))))
   (if    (vl-catch-all-error-p
     (vl-catch-all-apply 'vla-Delete
       (list (vlax-ename->vla-object (tblobjname "LAYER" Name)))))
     (princ "\nError Deleting Layer")))
   (princ "\nLayer not found or Current Layer or Layer \"0\"")))

(defun c:test (/ lay)
 (setq lay (getstring "\nSpecify Layer to Delete..."))
 (DeleteLayer lay)
 (princ))

Link to comment
Share on other sites

Yeah, it works fine~

 

And it would be perfect if there would be a dialogue box to selecte the layers:)

 

No Problems Hunter, did my last code function properly? :)
Link to comment
Share on other sites

Haha, you love your Dialog Boxes :)

 

I could create one for it, but, tbh, isn't this the same as just going into the layer manager and deleting the layer from there?

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • Create New...