select an entity in a different space

select an entity in a different space

GilesPhillips
Collaborator Collaborator
1,807 Views
5 Replies
Message 1 of 6

select an entity in a different space

GilesPhillips
Collaborator
Collaborator

Hi all.

 

I've got a variety of scripts that act upon entities of a known location within model-space (or paperspace, or within blocks).  These are currently selected through an iteration in code similar to this:

 

For Each AcadEnt In ThisDrawing.ModelSpace
If TypeOf AcadEnt Is AcadTable Then
Set SelTable = AcadEnt
If SelTable.InsertionPoint(0) = -1000 And SelTable.InsertionPoint(1) = -1000 Then
...
'Do stuff here
Exit For
...
End If
End If
Next AcadEnt

 This is acceptable on smaller drawings, but its inefficiently becomes evident on bigger ones as it's looping through the whole modelspace dataset.

 

I've tried using selection-sets, however these only appear to work in the current space. A lot of this sort of code is executed from paperspace (and sometimes also using object dbx), and I'd prefer not to flip into modelspace or work through viewports.

 

Is there a more efficient way of selecting an entity if it's parameters are known?

 

cheers


G

ACad, MEP, Revit, 3DS Max
0 Likes
Accepted solutions (1)
1,808 Views
5 Replies
Replies (5)
Message 2 of 6

norman.yuan
Mentor
Mentor

AcadSelectionSet.Select does not limit its selection only in current space, unless you supply it a filter for doing so. That is, you can select entities in specific layout by setting a filter with layout name ("Model", or any layout name); if no such a filter is supplied, entities in all layout (including "Model" layout) would be selected.

 

For example, I have a block reference in "Model", "Layout1" and "Layout2". Then I run following code:

 

Option Explicit

Public Sub Test()

    Dim ss As AcadSelectionSet
    
    Set ss = ThisDrawing.SelectionSets.Add("MySet")
    
    Dim code(0) As Integer
    Dim codeValue(0) As Variant
    code(0) = 0
    codeValue(0) = "INSERT"
    
    ss.Select acSelectionSetAll, , , code, codeValue
    MsgBox "Selected count: " & ss.Count
    
    Dim ent As AcadEntity
    For Each ent In ss
        MsgBox "Entity's OwnerID: " & CStr(ent.OwnerID)
    Next
    
    ss.Delete

End Sub

The message box would show 3 entities are in the selection, and each entity has different owner Id (because they are in different layout).

 

Looping through layouts (including Model) would not be significantly, or noticeable slower than using selection set with filter, IMO, at least in most cases. When AutoCAD creates filtered selection set, the algorithm is also some sort of looping through, but maybe a more optimized algorithm than VBA's higher level "For Each...". The difference would only be big enough if the drawing contains very large number of entities. Also, you may want to keep in mind, if the returned selectionset also contains large number of entities, your code also loop through it, meaning to those same entities 2 loops would go through.

 

You also suggested that your code might be used with ObjectDBX. If so, you'd better avoid using AcadSelectionSet and only use code to loop through layouts. Otherwise, the code cannot be share by both running in AutoCAD session for opened AcadDocument and memory-residing AxDbDocument, because AxDbDocument does not support AcadSelectionSet.

 

Whether iterating or using selectionset, if the processing time is long enough, always considering to provide feedback to user, such as progress bar. 

Norman Yuan

Drive CAD With Code

EESignature

Message 3 of 6

GilesPhillips
Collaborator
Collaborator

Thanks this has proved helpful, but the process is still a bit erratic, as it seems to ignore the location set by the two points.

 

The code below is intended to capture a table in modelspace at -1000, 1000 (table is always fixed at 50x100 in size)

 

SSpt1(0) = -1001
SSpt1(1) = -999
SSpt2(0) = -949
SSpt2(1) = -1101
Dim SScode(0) As Integer
Dim SSCodeVal(0) As Variant
SScode(0) = 0
SSCodeVal(0) = "ACAD_TABLE"

Set SSet = SubjDwg.SelectionSets.Add("PanTab")
SSet.Select acSelectionSetAll, SSpt1, SSpt2, SScode, SSCodeVal

The selections set that's returned has tables in paperspace as well, and not in the locations stated.

I can only assume that the two points (SSpt1 and SSpt1) are ignored, and I'll need to add more DXF type codes to refine the filter. would this be correct?

 

Cheers


G

ACad, MEP, Revit, 3DS Max
0 Likes
Message 4 of 6

norman.yuan
Mentor
Mentor
Accepted solution

Well, my previous reply may not be accurate enough, regarding all entities in all layouts (including Model) would be selected - what would be selected depends on, mainly, the first argument of the Select() method, then the other arguments (window points, and then filter).

 

When the selecting mode is acSelectionSetAll, the 2 points passed in would not have effect. Only when the selecting mode is acSelectionSetWindow/Crossing is used as first argument, these 2 points are required and play the role of "geometric filter" (also, the 2 points MUST BE visible in current view of current layout!). 

 

As your original question, you want to select filtered types of entities in all layouts, thus, you do need to use acSelectionSet mode, plus desired filter, but you'll need to ignore the 2 points arguments.

 

 

Norman Yuan

Drive CAD With Code

EESignature

Message 5 of 6

GilesPhillips
Collaborator
Collaborator

@norman.yuan wrote:

 

 (also, the 2 points MUST BE visible in current view of current layout!). 

 


That I was also unaware of! 

 

Most of my scripting is done irrespective of what's displayed on screen, so I'd definitely have to watch out for that.

 

G

ACad, MEP, Revit, 3DS Max
0 Likes
Message 6 of 6

Anonymous
Not applicable

That was useful information.

0 Likes