user1611961
user1611961

Reputation: 1

vb.net autocad 2007 selection set has no Items

In OS WIn 7 using Autocad 2007 I try to select items then do stuff Problem is that there are no ITEMS in the selection set ssetObj - not sure why!

Code: works in vba but not standalone vb.net

Private Sub CommandButton1_Click()

Dim myapp As AcadApplication
Dim mydoc As AcadDocument
Dim ssetObj As AcadSelectionSet
Dim ent As AcadObject
Dim numVertices As Long

On Error GoTo err:


Set myapp = GetObject(, "AutoCAD.Application.17")
Set mydoc = myapp.ActiveDocument

    If mydoc.SelectionSets.Count > 0 Then
        mydoc.SelectionSets(0).Delete
    End If

Set ssetObj = mydoc.SelectionSets.Add("ss")

list1.Clear


Me.Hide

AppActivate ("Autocad")

ssetObj.SelectOnScreen:'WORKS TO SELECT

Dim numpls As Integer

numpls = ssetObj.Count:'WORKS TO GET COUNT

Dim i As Integer
For i = 0 To numpls - 1


    Set ent = ssetObj.Item(i)':PROBLEM HERE**THERE ARE NO ITEMS THOUGH COUNT IS CORRECT



    If ent.ObjectName = "AcDbLWPolyline" Or ent.ObjectName = "AcDbPolyline" Then

    numVertices = (UBound(ent.Coordinates) + 1) / 2

        list1.AddItem Str(ent.ObjectID) + "\" + Str(numVertices) + " Vertices"

    End If

Next i

Me.Show


Exit Sub

err:

MsgBox err.Description


End Sub

Upvotes: 0

Views: 1495

Answers (2)

I'm just learning to work with VBA for AutoCAD and I encountered the same problem. I don't know why, but we can't directly add an element to a selection set. In order for an element to be added, you had to create an array of AcadEntity (with at least two elements, otherwise it doesn't work either) and add it to the set

Option Base 1
Sub Test()
On Error Resume Next 'use it so that when an error occurs, the sets are deleted and there is no need to change their names for the next run
Dim sset As AcadSelectionSet
Dim sset2 As AcadSelectionSet
Dim entry As AcadEntity
Dim earr(2) As AcadEntity 'at least 2 elements in the array are needed

Set sset = ThisDrawing.SelectionSets.Add("SS5")
Set sset2 = ThisDrawing.SelectionSets.Add("SS6")

AppActivate ThisDrawing.Application.Caption
sset.SelectOnScreen

'sort objects by properties and add to a new set
For Each entry In sset
    If entry.ObjectName = "AcDbMText" Then
        Set earr(1) = entry 'i use Option Base 1, so first index = 1
        sset2.AddItems earr
    End If
Next entry

'here we get a set sset2 with the selected elements
'and we can do with it what we want

'delete the sets to use the same names next time
sset.Delete
sset2.Delete

End Sub

Upvotes: 0

Parrish Husband
Parrish Husband

Reputation: 3178

Edit: Further investigation shows that you should be calling ssetObj(i) if you want to get indexed items of your selection set.

I'd not worry about trying to get the count of the selection set anyway if you plan on iterating through it. A For Each should suffice to walk though it. One of the problems with going from VBA/VB6 to VB.NET is the temptation to use the same methodology, when it can sometimes be invalid (at times it can be excellent, but .NET is very capable). Here's my entire class that I tested your problem with, just to show how I'm connecting to AutoCAD and interfacing with it.

Public Class frmMain

    Private acApp As AcadApplication
    Private polyList As List(Of String)
    Const acProgId As String = "AutoCAD.Application.17"

    <DllImport("User32.dll")> _
    Private Shared Function SetForegroundWindow(ByVal hWnd As IntPtr) As Boolean
    End Function

    Private Sub btnStart_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnStart.Click
        Try
            acApp = DirectCast(Marshal.GetActiveObject(acProgId), AcadApplication)
        Catch
            Try
                Dim acType = Type.GetTypeFromProgID(acProgId)
                acApp = DirectCast(Activator.CreateInstance(acType), AcadApplication)
            Catch ex As Exception
                MsgBox("Unable to create AutoCAD application of type: " & acProgId)
            End Try
        End Try
    End Sub

    Private Sub btnSelect_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnSelect.Click
        If acApp Is Nothing Then Return
        acApp.Visible = True

        Dim acDoc As AcadDocument = acApp.ActiveDocument

        ' Kill all existing selection sets
        While (acDoc.SelectionSets.Count > 0)
            acDoc.SelectionSets(0).Delete()
        End While

        Dim mySS As AcadSelectionSet = acDoc.SelectionSets.Add("ss")
        SetForegroundWindow(acApp.HWND)

        mySS.SelectOnScreen()
        polyList = New List(Of String)
        Dim numVertices As Integer
        For Each ent As AcadEntity In mySS
            If ent.ObjectName = "AcDbLWPolyline" Or
            ent.ObjectName = "AcDbPolyline" Then
                numVertices = (ent.Coordinates.Length) / 2
                polyList.Add(String.Format("{0} \ {1} Vertices", ent.ObjectID, numVertices))
            End If
        Next

    End Sub
End Class

External COM methods like this are going to be slower than you're used to seeing via VBA. Therefore it's definitely worth diving into the in-process AutoCAD .NET stuff to see great performance.

Upvotes: 1

Related Questions