Excel VBA - run overkill command on selection set

Excel VBA - run overkill command on selection set

cool.stuff
Collaborator Collaborator
2,162 Views
21 Replies
Message 1 of 22

Excel VBA - run overkill command on selection set

cool.stuff
Collaborator
Collaborator

Hi!!

 

i'm trying to run overkill command on a selection set. This is my current code:

 

*Moderator Edit* changed code language to VB

 

        'select all objects of layer "GapPoints"
        Dim tSelSet As AcadSelectionSet
        
        Dim FromLayer As String
        FromLayer = "GapPoints"
        
        Dim pSelSetName As String
        pSelSetName = "mySelSetGapPoints"
        
        'create SelectionSet
        On Error Resume Next
        Set tSelSet = acadDoc.SelectionSets.Item(pSelSetName)
        If (Not (tSelSet Is Nothing)) Then
            tSelSet.Clear
        Else
            Err.Clear
            Set tSelSet = acadDoc.SelectionSets.Add(pSelSetName)
        End If
   
        'create selection filter
        'Filtering SelectionSet
        Dim tDxfCodes(0) As Integer
        Dim tDxfValues(0) As Variant
        tDxfCodes(0) = 8
        tDxfValues(0) = FromLayer
      
        'create selection
        Call tSelSet.Select(acSelectionSetAll, , , tDxfCodes, tDxfValues)
        
        Dim acadcommand As String
        'acadcommand = """" & "_-overkill" & """" & ", tSelSet, " & """" & """" & ", " & """" & """"
        acadcommand = "_-overkill" & vbCr & "tSelSet" & vbCr & vbCr
        
        ' run overkill command on created selection set previously
        acadApp.ActiveDocument.SendCommand acadcommand & vbCr

 

 

Both lines 32 and 33 give error.

 

Does anybody knows to to run overkill command on a selection set via Excel VBA please?

 

Many thanks! 🙂

 

0 Likes
Accepted solutions (1)
2,163 Views
21 Replies
Replies (21)
Message 2 of 22

wispoxy
Advisor
Advisor

😅I already have this in my script packet set. To run the Overkill command on a selection set using Excel VBA for AutoCAD, you can use the following VBA code snippet. This code assumes you have a selection set defined and you want to apply the Overkill command to it:

Sub RunOverkillOnSelectionSet()
    Dim acadApp As Object
    Set acadApp = GetObject(, "AutoCAD.Application")
    
    ' Ensure AutoCAD is the active window
    acadApp.Activate
    
    ' Define the selection set (replace 'YourSelectionSetName' with your actual selection set name)
    Dim selectionSet As AcadSelectionSet
    Set selectionSet = acadApp.ActiveDocument.SelectionSets.Item("YourSelectionSetName")
    
    ' Check if the selection set is not empty
    If selectionSet.Count > 0 Then
        ' Run the Overkill command on the selection set
        acadApp.ActiveDocument.SendCommand "_.overkill " & vbCrLf
        ' Loop through each item in the selection set and select it for the Overkill command
        Dim item As AcadEntity
        For Each item In selectionSet
            acadApp.ActiveDocument.SendCommand item.Handle & vbCrLf
        Next item
        ' Press Enter to execute the command
        acadApp.ActiveDocument.SendCommand vbCrLf
    Else
        MsgBox "The selection set is empty."
    End If
End Sub

 

This script activates AutoCAD, selects the entities in the specified selection set, and applies the Overkill command to them. The Overkill command removes duplicate or overlapping lines, arcs, and other objects.

Please note that this is a basic example and might need to be adjusted based on your specific requirements and the context in which you’re running the script.

 

0 Likes
Message 3 of 22

cool.stuff
Collaborator
Collaborator

@wispoxythank you for your answer and help 🙂

 

For some reason, when the code gets to line 6, it stops.

I just add a parameter to your code:

 

*Moderator Edit* Put code in Code window.

Sub RunOverkillOnSelectionSet(ByVal selectionSetName As String)
Dim acadApp As Object
Set acadApp = GetObject(, "AutoCAD.Application")

' Ensure AutoCAD is the active window
acadApp.Activate

' Define the selection set (replace 'YourSelectionSetName' with your actual selection set name)
Dim selectionSet As AcadSelectionSet
Set selectionSet = acadApp.ActiveDocument.SelectionSets.item(selectionSetName)

' Check if the selection set is not empty
If selectionSet.Count > 0 Then
' Run the Overkill command on the selection set
acadApp.ActiveDocument.SendCommand "_.overkill " & vbCrLf
' Loop through each item in the selection set and select it for the Overkill command
Dim item As AcadEntity
For Each item In selectionSet
acadApp.ActiveDocument.SendCommand item.Handle & vbCrLf
Next item
' Press Enter to execute the command
acadApp.ActiveDocument.SendCommand vbCrLf
Else
MsgBox "The selection set is empty."
End If
End Sub

 

 

After comment your line for activate AutoCAD, the routine does not run by itself. In the end I have to select all objects and  click enter to run.. Maybe something wrong with what I am doing?

 

Also, I got this from AutoCAD console:

 

Command: _.overkill
Select objects:
Command:
Command: BDA
Unknown command "BDA". Press F1 for help.
Command:
Command: BD9
Unknown command "BD9". Press F1 for help.
Command:
Command: BD8
Unknown command "BD8". Press F1 for help.
Command:
Command: BD7
Unknown command "BD7". Press F1 for help.
Command:

 

that happens when it is looping through selection set items.

 

Thanks 🙂

0 Likes
Message 4 of 22

Ed__Jobe
Mentor
Mentor

You can't pass SendCommand a handle. You can only send command text and lisp. You need to use the (handent) function to convert the handle to an ename. Also, its a bad idea to combine operations into one function. You should handle setting the acadapp object in a different function in order to compartentalize error handling. Give me a few minutes and I will refactor the code for you.

Ed


Did you find this post helpful? Feel free to Like this post.
Did your question get successfully answered? Then click on the ACCEPT SOLUTION button.
How to post your code.

EESignature

Message 5 of 22

wispoxy
Advisor
Advisor

You're right. I would be scared to autorun it on a project because I work with buildings and sometimes the values need to be adjusted for appropriate action. If you're not careful some important lines may disappear. Not something that should be automated because value adjustments are required per project basis. I'm not a script writer, I just hold a massive collection written by ai and I test them to make sure the desired action is performed. I'll try to get it to automate more functions. What tolerance value do you want to start with?

0 Likes
Message 6 of 22

cool.stuff
Collaborator
Collaborator
Thanks for the help 🙂 Maybe a starting value of 0.001.
Thanks again 🙂
0 Likes
Message 7 of 22

Ed__Jobe
Mentor
Mentor

Here is the previous sample refactored, with the help of some of my utility functions.

 

 

 


Sub RunOverkillOnSelectionSet(acadApp As AcadApplication)

    ' Ensure AutoCAD is the active window
    acadApp.Activate
    
    ' Define the selection set
    Dim ss As AcadSelectionSet
    Set ss = AddSelectionSet("okill")
    ss.SelectOnScreen
    
    ' Check if the selection set is not empty
    If ss.Count > 0 Then
        ' Run the Overkill command on the selection set
        acadApp.ActiveDocument.SendCommand "_.overkill " & vbCrLf
        ' Loop through each item in the selection set and select it for the Overkill command
        Dim item As AcadEntity
        For Each item In ss
            acadApp.ActiveDocument.SendCommand Ent2lspEnt(item) & vbCrLf
        Next item
        ' Press Enter to execute the command
        acadApp.ActiveDocument.SendCommand vbCrLf
    Else
        MsgBox "The selection set is empty."
    End If
End Sub

Public Function Ent2lspEnt(entObj As AcadEntity) As String
    'Designed to work with SendCommand, which can't pass objects.
    'This gets an objects handle and converts it to a string
    'of lisp commands that returns an entity name when run in SendCommand.
    Dim entHandle As String
    
    entHandle = entObj.Handle
    Ent2lspEnt = "(handent " & Chr(34) & entHandle & Chr(34) & ")"
End Function

Public Function AddSelectionSet(SetName As String) As AcadSelectionSet
' This routine does the error trapping neccessary for when you want to create a
' selectin set. It takes the proposed name and either adds it to the selectionsets
' collection or sets it.
    On Error Resume Next
    Set AddSelectionSet = ThisDrawing.SelectionSets.Add(SetName)
    If Err.Number <> 0 Then
        Set AddSelectionSet = ThisDrawing.SelectionSets.item(SetName)
        AddSelectionSet.Clear
    End If
End Function


Public Function GetAcad(Optional ver As String) As AcadApplication
    ' support multiple acad versions.
    'Sample ver for AutoCAD 2023 ' ".24.2"
    On Error Resume Next
    Dim acApp As AcadApplication
    Dim clsid As String
    clsid = "AutoCAD.Application"
    If Not ver = "" Then
        clsid = clsid & ver
    End If
    Set acApp = GetObject(, clsid)
    If acApp Is Nothing Then
        Set acApp = CreateObject(clsid)
    End If
    Set GetAcad = acApp
End Function

 

 

 

 

A couple notes on your original code. "p" in front of a variable indicates the data type is a pointer. The data type is a string. You are inconsistent in your naming too. The system I use, if I want to indicate the data type of a variable, I use "o" for objects, e.g. oLine, oDb. For types, I use "str, d, i, etc.", e.g strFileName, dPrice, iCount. There is some flexibility in this system, e.g. if the name fully indicates the content type, I don't use 'o' or 'str', e.g. "entHandle" is sufficient.

 

Using SendCommand or scripts requires the [Enter] key. Going back to typewriter days, that is equal to a carriage return (the cursor comes back to the start of the line) and a LineFeed (the cursor goes to the next line). In vba, this is the vbCrLf command. You just used vbCr. In most cases, you could also use vbLf, but vbCrLf is safer. I mention this because if you venture into creating text files, the same applies.

Ed


Did you find this post helpful? Feel free to Like this post.
Did your question get successfully answered? Then click on the ACCEPT SOLUTION button.
How to post your code.

EESignature

Message 8 of 22

wispoxy
Advisor
Advisor

People better than ai still. I tried to tell it to automate more functions in the script. It tells me "You're asking me to perform something impossible. Ask me something more practical." 😂🤣🤣

I reply "What is that supposed to mean?"

It replies "Shouldn't you be working right now?" 😆

Message 9 of 22

cool.stuff
Collaborator
Collaborator

@Ed__Jobe  thank you for your help 🙂

 

For some reason, then I got to the line acadApp.Activate the code stops...

Any reasons for it?

 

I commented it for run the code further.

But, it does not run overkill by itself.

Is there a way to run all this without user input?

 

Thanks

0 Likes
Message 10 of 22

wispoxy
Advisor
Advisor

What about the LISP method and running it through the startup suite? Then every time you open a project it runs.

0 Likes
Message 11 of 22

Ed__Jobe
Mentor
Mentor

You probably don't need to activate the app. All that does is bring it to the foreground. I'll have to check on the execution. I assumed that @wispoxy had done that.

Ed


Did you find this post helpful? Feel free to Like this post.
Did your question get successfully answered? Then click on the ACCEPT SOLUTION button.
How to post your code.

EESignature

Message 12 of 22

cool.stuff
Collaborator
Collaborator

This is the last part of my code. It performs several calculations and draws some objects and some overlap in the end, the elements that are overlapped are moved to a layer and are eliminated.

 

If there was a way to make it run, it would be awesome 🙂

0 Likes
Message 13 of 22

wispoxy
Advisor
Advisor

I just tested both of ours. Your script runs error free but isn't triggering overkill. My script runs a '438' - not supported error for the acadApp.Activate.

0 Likes
Message 14 of 22

Ed__Jobe
Mentor
Mentor

@wispoxy wrote:

I just tested both of ours. Your script runs error free but isn't triggering overkill. My script runs a '438' - not supported error for the acadApp.Activate.


I don't know what error 438 represents of the top of my head, but your code doesn't allow for the case that AutoCAD isn't running. In that case, you need to use the CreateObject function.

 

Looking at mine, I see that I only created a SelectionSet. I need to execute a selection method. So ss.Count is always 0 and the code drops out of the if statement. @cool.stuff , if you want this to run without user interaction, then create a selectionset filter that gives you the results you want and use it with the Select(acSelectionSetAll,,,,) method. I updated the code in post 7.

Ed


Did you find this post helpful? Feel free to Like this post.
Did your question get successfully answered? Then click on the ACCEPT SOLUTION button.
How to post your code.

EESignature

Message 15 of 22

wispoxy
Advisor
Advisor

Yours works! I was pointing to the wrong ACAD 😬

Well done good sir!

0 Likes
Message 16 of 22

cool.stuff
Collaborator
Collaborator

Sorry I did not understand what you said..

 

My current code is the following one:

 

 

'select all objects of layer "GapPoints"
        Dim tSelSet As AcadSelectionSet
        
        Dim FromLayer As String
        FromLayer = "GapPoints"
        
        Dim pSelSetName As String
        pSelSetName = "mySelSetGapPoints"
        
        'create SelectionSet
        On Error Resume Next
        Set tSelSet = acadDoc.SelectionSets.item(pSelSetName)
        If (Not (tSelSet Is Nothing)) Then
            tSelSet.Clear
        Else
            Err.Clear
            Set tSelSet = acadDoc.SelectionSets.Add(pSelSetName)
        End If
   
        'create selection filter
        'Filtering SelectionSet
        Dim tDxfCodes(0) As Integer
        Dim tDxfValues(0) As Variant
        tDxfCodes(0) = 8
        tDxfValues(0) = FromLayer
      
        'create selection
        Call tSelSet.Select(acSelectionSetAll, , , tDxfCodes, tDxfValues)
        
        Call VBAProject.Module1.RunOverkillOnSelectionSet(acadApp, pSelSetName)

----------------------------

Sub RunOverkillOnSelectionSet(acadApp As AcadApplication, ssName As String)

    ' Ensure AutoCAD is the active window
    'acadApp.Activate
    
    ' Define the selection set
    Dim ss As AcadSelectionSet
    'Set ss = AddSelectionSet(ssName)
    'ss.SelectOnScreen
    Set ss = acadApp.ActiveDocument.SelectionSets.item(ssName)
    
    ' Check if the selection set is not empty
    If ss.Count > 0 Then
        ' Run the Overkill command on the selection set
        acadApp.ActiveDocument.SendCommand "_.overkill " & vbCrLf
        ' Loop through each item in the selection set and select it for the Overkill command
        Dim item As AcadEntity
        For Each item In ss
            acadApp.ActiveDocument.SendCommand Ent2lspEnt(item) & vbCrLf
        Next item
        ' Press Enter to execute the command
        acadApp.ActiveDocument.SendCommand vbCrLf
    Else
        MsgBox "The selection set is empty."
    End If
End Sub

Public Function Ent2lspEnt(entObj As AcadEntity) As String
    'Designed to work with SendCommand, which can't pass objects.
    'This gets an objects handle and converts it to a string
    'of lisp commands that returns an entity name when run in SendCommand.
    Dim entHandle As String
    
    entHandle = entObj.Handle
    Ent2lspEnt = "(handent " & Chr(34) & entHandle & Chr(34) & ")"
End Function

Public Function AddSelectionSet(SetName As String) As AcadSelectionSet
' This routine does the error trapping neccessary for when you want to create a
' selectin set. It takes the proposed name and either adds it to the selectionsets
' collection or sets it.
    On Error Resume Next
    Set AddSelectionSet = acadApp.ActiveDocument.SelectionSets.Add(SetName)
    If Err.Number <> 0 Then
        Set AddSelectionSet = acadApp.ActiveDocument.SelectionSets.item(SetName)
        AddSelectionSet.Clear
    End If
End Function


Public Function GetAcad(Optional ver As String) As AcadApplication
    ' support multiple acad versions.
    'Sample ver for AutoCAD 2023 ' ".24.2"
    On Error Resume Next
    Dim acApp As AcadApplication
    Dim clsid As String
    clsid = "AutoCAD.Application"
    If Not ver = "" Then
        clsid = clsid & ver
    End If
    Set acApp = GetObject(, clsid)
    If acApp Is Nothing Then
        Set acApp = CreateObject(clsid)
    End If
    Set GetAcad = acApp
End Function

 

But overkill does not run without my interaction..

 

Any ideas why, please?

0 Likes
Message 17 of 22

Ed__Jobe
Mentor
Mentor
Accepted solution

In your version of RunOverkillOnSelectionset, you're not using the ss to select anything. Make the following changes to your code.

 

'select all objects of layer "GapPoints"
        Dim tSelSet As AcadSelectionSet
        Set tSelSet = AddSelectionSet("mySelSetGapPoints")  'Add line
        Dim FromLayer As String
        FromLayer = "GapPoints"
        
        'Dim pSelSetName As String
        'pSelSetName = "mySelSetGapPoints"
        
        ''create SelectionSet
        'On Error Resume Next
        'Set tSelSet = acadDoc.SelectionSets.item(pSelSetName)
        'If (Not (tSelSet Is Nothing)) Then
        '    tSelSet.Clear
        'Else
         '   Err.Clear
        '    Set tSelSet = acadDoc.SelectionSets.Add(pSelSetName)
        'End If
   
        'create selection filter
        'Filtering SelectionSet
        Dim tDxfCodes(0) As Integer
        Dim tDxfValues(0) As Variant
        tDxfCodes(0) = 8
        tDxfValues(0) = FromLayer
      
        'create selection
        'Call 'not needed
        tSelSet.Select(acSelectionSetAll, , , tDxfCodes, tDxfValues)
        
        'Call VBAProject.Module1.RunOverkillOnSelectionSet(acadApp, pSelSetName)
        RunOverkillOnSelectionSet(acadApp, tSelSet)

----------------------------
'Sub RunOverkillOnSelectionSet(acadApp As AcadApplication, ssName As String)
Sub RunOverkillOnSelectionSet(acadApp As AcadApplication, ss As AcadSelectionSet)

    ' Ensure AutoCAD is the active window
    'acadApp.Activate
    
    ' Define the selection set
    'Dim ss As AcadSelectionSet
    'Set ss = AddSelectionSet(ssName)
    'ss.SelectOnScreen
    'Set ss = acadApp.ActiveDocument.Select

 

Ed


Did you find this post helpful? Feel free to Like this post.
Did your question get successfully answered? Then click on the ACCEPT SOLUTION button.
How to post your code.

EESignature

Message 18 of 22

cool.stuff
Collaborator
Collaborator

Thank you for your answer @Ed__Jobe  🙂

Could you explain why I am not using ss to select anything please? I am debugging and I get items in my selection set, which I got from ssName.

 

Thanks 🙂

0 Likes
Message 19 of 22

Ed__Jobe
Mentor
Mentor

Are you talking about the code you posted or my code?

Ed


Did you find this post helpful? Feel free to Like this post.
Did your question get successfully answered? Then click on the ACCEPT SOLUTION button.
How to post your code.

EESignature

0 Likes
Message 20 of 22

cool.stuff
Collaborator
Collaborator

About my code. I've debugged the code and I have elements in the selection set.. I am doing something wrong because your code works, it is just to understand what is wrong.

 

many thanks

0 Likes