select all items in the selectionset

select all items in the selectionset

flowerpapa
Enthusiast Enthusiast
9,229 Views
28 Replies
Message 1 of 29

select all items in the selectionset

flowerpapa
Enthusiast
Enthusiast

I have initialized a AcadSelectionset, and have added few items in the selectionset.
Now i want to select all items present in the particular selectionset only

0 Likes
Accepted solutions (2)
9,230 Views
28 Replies
Replies (28)
Message 2 of 29

Ed__Jobe
Mentor
Mentor

By definition, if they're in the ss, they are selected. The ss does have a Highlight method, but it doesn't behave like regular acad, i.e. if you end the command they don't unhighlight. You have to do that by setting the Highlight property to False. Just use the ss as a grouping entity to iterate the objects you want to work on. For example, if you want to change their color, use For..Each to change the color property of each entity.

 

How did you put ents in the ss? Typically, you use one of the Select method, e.g. SelectOnScreen.

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 3 of 29

flowerpapa
Enthusiast
Enthusiast

Hello Ed.Joe,

Thanks for your reply
 I just created Ent as array of objects, then by using additems, objects added to ss selectionset, 
Now I have Items(objects) in ss.list,
I struggling to select(not highlight) only those objects in the CAD window(modelspace).

 

--

 

0 Likes
Message 4 of 29

Ed__Jobe
Mentor
Mentor

@flowerpapa wrote:

I struggling to select(not highlight) only those objects in the CAD window(modelspace).


 

What are you expecting to happen?  The purpose of "selecting" is to get entities into the SelectionSet.
Normally, you would let the user select the items by calling one of the SelectionSet.Select* methods. If you know what items are to be selected, you can add them to the SelectionSet by calling the AddItems method, which you did. Once they are in the ss, they are "selected". You can now use the ss to work with the items. e.g.

 

ss.AddItems entArray
Dim ent As AcadEntity
For Each ent in ss
   ent.Color = ByLayer
Next ent

 

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 29

flowerpapa
Enthusiast
Enthusiast

Hello Ed.Joe, 
I have placed my code below for your reference, 
I want to either select that selectionset (oss2) in the model space after i have additems nor set oss2 selectionset as activeselectionset

can you please advise me on the same?

i = 1
j = 0
On Error Resume Next
Set oss2 = ThisDrawing.SelectionSets.Add("Temp2")
If Err.Number <> 0 Then
ThisDrawing.SelectionSets.Item("Temp2").Delete
Set oss2 = ThisDrawing.SelectionSets.Add("Temp2")
End If

For Each oAcadobject In ThisDrawing.ModelSpace
If (TypeOf oAcadobject Is AeccPipeLabel) Then
Set oPipeLabel = oAcadobject
oTemp = oPipeLabel.LabelStyle.Name
oTemp1 = oPipeLabel.Handle
If InStr(LCase(oTemp), LCase("niet")) <> 0 Then
ReDim Preserve oPipeLabelNA(j)
Set oPipeLabelNA(j) = oPipeLabel
j = j + 1
End If
i = i + 1
'MsgBox oTemp
End If
Next
oss2.AddItems oPipeLabelNA

Debug.Print oss2.Count

-- 
Thanks

 

0 Likes
Message 6 of 29

norman.yuan
Mentor
Mentor
Accepted solution

If your purpose is to turn a programmatically selected entities in your AcadSelectionSet into a visually selected in AUtoCAD editor, as if they are selected by user manually, so that further command execution can be applied to them, then you can try following code (where I use code to select all circles, but in your case it is AeccPipeLabels):

 

Option Explicit

Public Sub SelectCircleVisually()

    Dim ss As AcadSelectionSet
    Set ss = GetCircleSelectionSet()
    If Not ss Is Nothing Then
        ThisDrawing.SendCommand "Select p " & vbCrLf
        ss.Delete     '' optional
    End If
    
End Sub

Private Function GetCircleSelectionSet() As AcadSelectionSet

    '' Create selection set
    Dim ss As AcadSelectionSet
    Dim setName As String
    setName = "MySel"
    
    For Each ss In ThisDrawing.SelectionSets
        If ss.Name = setName Then
            ss.Delete
            Exit For
        End If
    Next
    
    Set ss = ThisDrawing.SelectionSets.Add(setName)
    
    '' Add all circles into the selection set
    Dim i As Integer
    Dim ent As AcadEntity
    Dim ents() As AcadEntity
    
    For Each ent In ThisDrawing.ModelSpace
        If TypeOf ent Is AcadCircle Then
            ReDim Preserve ents(i)
            Set ents(i) = ent
            i = i + 1
        End If
    Next
    
    If i > 0 Then
        ss.AddItems ents
    End If
    
    Set GetCircleSelectionSet = ss
    
End Function

Norman Yuan

Drive CAD With Code

EESignature

Message 7 of 29

flowerpapa
Enthusiast
Enthusiast

Hi Norman.Yuvan, 

It worked,
Big Thanks for your answer, Smiley Happy

 

 

--

Thanks

0 Likes
Message 8 of 29

norman.yuan
Mentor
Mentor

It looked like I was only partially right in previous code: it only works for a newly opened drawing where user never selected anything. That is, the Previous SelectionSet in AutoCAD is only updated with VBA code when the code-created selectionset calls Select()/SelectOnScrceen() method; if the selectionset is fill with AddItems(), the Previous SelectionSet in AutoCAD does not get updated, thus the code I showed does not work.

 

Actually I discussed this in an old thread on the same topic, and suggested a way of solving this (see my reply posted on Oct. 16th, 2018 in that thread), but never actually got time to materialize it with code. Now that facing the same issue, I wrote some VBA code in the logic as I suggested there, and as I expected: it works. The key issue here for re-use "Previous" selection set in SendCommand, we need to build an AcadSelectionSet and call its Select()/SelectOnScreen() method, so that the "Previous" selection set (actually ThisDrawing.ActiveSelectionSet) would be updated. However, you cannot directly change ThisDrawing.ActiveSelectionSet (with Add/RemoveItems()).

 

See code and attached video clip below.

 

Option Explicit

Private Const XDATA_APP As String = "MySelApp"

Public Sub DoSelection()

    '' MsgBox "Prev Selected count: " & ThisDrawing.ActiveSelectionSet.Count
    
    Dim i As Integer
    
    '' Select all circles
    Dim ents As Variant
    ents = CollectTargetEntities()
    If UBound(ents) < 0 Then Exit Sub
    
    MsgBox "Targetted entity count: " & UBound(ents) + 1
    
    '' attach XData as selection filter
    SetSelectionXData ents, True
    
    SelectByXData
    
    '' detach Xdata as selection filter
    SetSelectionXData ents, False

    '' MsgBox "Prev Selected count: " & ThisDrawing.ActiveSelectionSet.Count
    
    ThisDrawing.SendCommand "SELECT" & vbCr & "P" & vbCr & vbCr
    
End Sub

Private Function CollectTargetEntities() As Variant
    
    Dim ent As AcadEntity
    Dim i As Integer
    Dim ents() As AcadEntity
    
    For Each ent In ThisDrawing.ModelSpace
        If TypeOf ent Is AcadCircle Then
            ReDim Preserve ents(i)
            Set ents(i) = ent
            i = i + 1
        End If
    Next
    
    CollectTargetEntities = ents
    
End Function

Private Sub AttachSelectionXData(ent As AcadEntity)

    Dim dataType(0 To 1) As Integer
    Dim data(0 To 1) As Variant
    
    dataType(0) = 1001: dataType(1) = 1000
    data(0) = XDATA_APP: data(1) = "Xdata for selection"
    
    ent.SetXData dataType, data
    
End Sub

Private Sub DetachSelectionXData(ent As AcadEntity)

    Dim dataType(0) As Integer
    Dim data(0) As Variant
    
    dataType(0) = 1001
    data(0) = XDATA_APP
    
    ent.SetXData dataType, data

End Sub

Private Sub SelectByXData()

    Dim groupCode(0) As Integer
Dim dataCode(0) As Variant

groupCode(0) = 1001
dataCode(0) = XDATA_APP

ThisDrawing.ActiveSelectionSet.Select acSelectionSetAll, , , groupCode, dataCode

'' MsgBox "Selected: " & ss.Count End Sub Private Sub SetSelectionXData(ents As Variant, attach As Boolean) Dim i As Integer Dim ent As AcadEntity For i = 0 To UBound(ents) Set ent = ents(i) If attach Then AttachSelectionXData ent Else DetachSelectionXData ent End If Next End Sub

 

 

 

 

 

 

Norman Yuan

Drive CAD With Code

EESignature

Message 9 of 29

norman.yuan
Mentor
Mentor
Accepted solution

It looked like I was only partially right in previous code: it only works for a newly opened drawing where user never selected anything. That is, the Previous SelectionSet in AutoCAD is only updated with VBA code when the code-created selectionset calls Select()/SelectOnScrceen() method; if the selectionset is fill with AddItems(), the Previous SelectionSet in AutoCAD does not get updated, thus the code I showed does not work.

 

Actually I discussed this in an old thread on the same topic, and suggested a way of solving this (see my reply posted on Oct. 16th, 2018 in that thread), but never actually got time to materialize it with code. Now that facing the same issue, I wrote some VBA code in the logic as I suggested there, and as I expected: it works. The key issue here for re-use "Previous" selection set in SendCommand, we need to build an AcadSelectionSet and call its Select()/SelectOnScreen() method, so that the "Previous" selection set (actually ThisDrawing.ActiveSelectionSet) would be updated. However, you cannot directly change ThisDrawing.ActiveSelectionSet (with Add/RemoveItems()).

 

See code and attached video clip below.

 

Option Explicit

Private Const XDATA_APP As String = "MySelApp"

Public Sub DoSelection()

    '' MsgBox "Prev Selected count: " & ThisDrawing.ActiveSelectionSet.Count
    
    Dim i As Integer
    
    '' Select all circles
    Dim ents As Variant
    ents = CollectTargetEntities()
    If UBound(ents) < 0 Then Exit Sub
    
    MsgBox "Targetted entity count: " & UBound(ents) + 1
    
    '' attach XData as selection filter
    SetSelectionXData ents, True
    
    SelectByXData
    
    '' detach Xdata as selection filter
    SetSelectionXData ents, False

    '' MsgBox "Prev Selected count: " & ThisDrawing.ActiveSelectionSet.Count
    
    ThisDrawing.SendCommand "SELECT" & vbCr & "P" & vbCr & vbCr
    
End Sub

Private Function CollectTargetEntities() As Variant
    
    Dim ent As AcadEntity
    Dim i As Integer
    Dim ents() As AcadEntity
    
    For Each ent In ThisDrawing.ModelSpace
        If TypeOf ent Is AcadCircle Then
            ReDim Preserve ents(i)
            Set ents(i) = ent
            i = i + 1
        End If
    Next
    
    CollectTargetEntities = ents
    
End Function

Private Sub AttachSelectionXData(ent As AcadEntity)

    Dim dataType(0 To 1) As Integer
    Dim data(0 To 1) As Variant
    
    dataType(0) = 1001: dataType(1) = 1000
    data(0) = XDATA_APP: data(1) = "Xdata for selection"
    
    ent.SetXData dataType, data
    
End Sub

Private Sub DetachSelectionXData(ent As AcadEntity)

    Dim dataType(0) As Integer
    Dim data(0) As Variant
    
    dataType(0) = 1001
    data(0) = XDATA_APP
    
    ent.SetXData dataType, data

End Sub

Private Sub SelectByXData()

    Dim groupCode(0) As Integer
    Dim dataCode(0) As Variant
    
    groupCode(0) = 1001
    dataCode(0) = XDATA_APP
    
    ThisDrawing.ActiveSelectionSet.Select acSelectionSetAll, , , groupCode, dataCode
    
    '' MsgBox "Selected: " & ss.Count
    
End Sub

Private Sub SetSelectionXData(ents As Variant, attach As Boolean)

    Dim i As Integer
    Dim ent As AcadEntity
    
    For i = 0 To UBound(ents)
        Set ent = ents(i)
        If attach Then
            AttachSelectionXData ent
        Else
            DetachSelectionXData ent
        End If
    Next
    
End Sub

 

 

Norman Yuan

Drive CAD With Code

EESignature

Message 10 of 29

flowerpapa
Enthusiast
Enthusiast

Hello Norman.Yuvan, 
Thanks for your effort, This what i needSmiley Happy

--

Thanks

0 Likes
Message 11 of 29

george1985
Collaborator
Collaborator

Hi @norman.yuan ,

Thank you very much for the code!

I am trying to replicate it in C#.

What does XDATA_APP represent? It is an instance of which class?

dataCode(0) = XDATA_APP

 

When I try to use it as a string: "XDATA_APP", I get an error.
Thank you very much for the help.

0 Likes
Message 12 of 29

Ed__Jobe
Mentor
Mentor

@norman.yuan gave you a code "sample". You need to substitute the name of the xdata app that you want to work with.

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 13 of 29

george1985
Collaborator
Collaborator

Thank you @Ed__Jobe 
Can you give me an example of how to provide any xdata app?

If I try to manually assign XDATA in Autocad (by calling such command), the xdata app, is simply a string:

george1985_0-1699384553695.png

 

0 Likes
Message 14 of 29

norman.yuan
Mentor
Mentor
Since you mentioned that you use C#: are you doing AutoCAD .NET plugin? or automating AutoCAD via its COM API from external app/stand-alone EXE?

If you are doing AutoCAD .NET API plugin, there is no reason/no need to replicate what the VBA code does here.

Norman Yuan

Drive CAD With Code

EESignature

0 Likes
Message 15 of 29

george1985
Collaborator
Collaborator

Hi @norman.yuan 
Thank you for replying back. I am not using NET, but COM API and external WinForms.exe as you mentioned.
Can you tell me what is the type of the XDATA_APP object?

0 Likes
Message 16 of 29

Ed__Jobe
Mentor
Mentor

Yes, the data is a string, but you have to know which app wrote the string, otherwise other apps can mess with your xdata. See this help topic. In your screen captuere, "some_app" is the name of the app. The data you place in the next step is associated with the app.

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 17 of 29

george1985
Collaborator
Collaborator

Thank you @Ed__Jobe ,
But I am not sure I understand.
Writing data is the next step, as you mentioned. But to assign the xdata, I have define the random name for my application? In a form of a string?
For example the VBA code from norman.yuan's code:

dataCode(0) = XDATA_APP

In C# would be:

dataCode[0] = "XDATA_APP";

?

If this is true, then I am getting an error message:

          (COMException): Invalid argument type in SetXData method

 

Interestingly, obtaining the xdata with "GetXData" method, works without issues. But the problem is that I manually assigned that xdata in Autocad with the use of _XDATA command. I would like to do that through COM API instead.

0 Likes
Message 18 of 29

Ed__Jobe
Mentor
Mentor

This is confusing. Norman gave you VBA code. If you are using C#, then post your code. Also, you should be posting in the NET forum. And there are other ways. Norman: "If you are doing AutoCAD .NET API plugin, there is no reason/no need to replicate what the VBA code does here."

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 19 of 29

norman.yuan
Mentor
Mentor
If you read my VBA code carefully (at very top of my posted code), XDATA_APP is declared as "Const" string value, which is used as registered XData app name. It could be any string value, as long as it is not the same with any existing registered XData app name.

Since you indeed do an EXE app to automate AutoCAD, I am wondering what is the point to replicate the VBA code showed here? The OP wanted to run VBA code, so that the entities selected in AcadSelectionSet by VBA code would end up showing highlighted on AutoCAD editor, as if user manually selected these entities. That is, the VBA code only does the simulation of manual selection (I am sure you DO KNOW the different between entities being selected by code and selected by user clicking the entities). That is, after running the VBA code, user is left some entities being highlighted (with grips also shown). Then user are supposed to do something with these entities, such as run a command that accepts "select first" set of entities.

However, in your case, your user runs the EXE app with some action, then AutoCAD in the background has some entities selected/highlighted. Now, your user has to switch active app in windows' desktop to AutoCAD before the user can do anything. So, my point is, why use has to run 2 apps (the Exe and AutoCAD) and switch between them back and forth to do some CAD related work? I'd avoid doing this as much as possible.

Norman Yuan

Drive CAD With Code

EESignature

Message 20 of 29

george1985
Collaborator
Collaborator

@norman.yuan wrote:
If you read my VBA code carefully (at very top of my posted code), XDATA_APP is declared as "Const" string value, which is used as registered XData app name.

Thank you very much @norman.yuan 

Regarding XDATA_APP variable:

XDATA_APP As String = "MySelApp"

 Is "MySelApp" previously defined in Autocad manually, before running your code?

The whole point of using WindowsForms application is, users will not have much interaction with Autocad actually.

One button on WindowsForms will import STEP file. Second button will select specific 3DSolids from that imported STEP file. And third button will drill them. So basically the user will only deal with WindowsForms. Autocad is there just in the background, and user is not going to manually run any commands in it.

0 Likes