Reputation: 1
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
Reputation: 1
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
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