Author Topic: Using selectionset with COM  (Read 9218 times)

0 Members and 1 Guest are viewing this topic.

Martin_2

  • Guest
Using selectionset with COM
« on: February 06, 2007, 04:11:41 PM »
Hi

Based on recommendations, from one of you guys, I have been experimenting with "selectionset".

What I do is to open an AutoCAD file, using COM (VB.NET).

I then try to select all objects in this file into a selectionset, based on Autodesks tutorial at
http://usa.autodesk.com/adsk/servlet/item?siteID=123112&id=2768231&linkID=2475176

I had to modify their example to VB.NET, since VBA is not an option. Also I must access the file without using NETLOAD.
For this I used the object browser in Visual Studio.

However, the code does not work. It seems that nothing is entered into the selectionset.
There are no errors reported when I build the project.
A textbox is used to check the content of the selectionset.

The code can be seen below, and I have also added a zip'ed file of the Visual Studio project.
I use Visual Studio 2005 and AutoCAD 2007.

Does anyone have any idea as to why nothing is added to the selectionset?
Or perhaps another way of filling the selectionset?

References:
AutoCAD 2007 Type Library
AutoCAD/ObjectDBX Common 17.0 Type Library

Imports Autodesk.AutoCAD.Interop
Imports Autodesk.AutoCAD.Interop.Common

Quote
Public Class Form1

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Dim filepath As String
        'insert path to your dwg file
        filepath = "C:\test.dwg"

        OpenACADFile(filepath)
    End Sub

    Sub OpenACADFile(ByVal filepath As String)
        Dim AcadApp As Autodesk.AutoCAD.Interop.AcadApplication
        Dim acadDoc As Autodesk.AutoCAD.Interop.AcadDocument

        'Selectionset declarations
        Dim entObj As AcadEntity
        Dim ssetObj As AcadSelectionSet
        Dim mode As Integer
        Dim grpCode(0) As Integer
        Dim dataVal(0) As String
        Dim i As Integer
 
        On Error Resume Next
        'test for existing cad application
        AcadApp = GetObject(, "AutoCAD.Application")
        If Err.Number <> 0 Then
            Err.Clear()
            'opens a new application if none is available
            AcadApp = CreateObject("AutoCAD.Application")
            If Err.Number <> 0 Then
                MsgBox("Error opening AutoCAD")
                Exit Sub
            End If
        End If
        'AcadApp.WindowState = 3 'acMax
        acadDoc = AcadApp.Documents.Open(filepath)
        AcadApp.Application.Visible = True

        ssetObj = acadDoc.SelectionSet.Add("SS01")
        mode = Autodesk.AutoCAD.Interop.Common.AcSelect.acSelectionSetAll
        grpCode(0) = 0
        dataVal(0) = "TEXT"
        ssetObj.Select(mode, , , grpCode, dataVal)

        For i = 0 To 1 'ssetObj.Count
            'entObj = ssetObj.Item(i)
            TextBox1.AppendText(ssetObj.Count.ToString)
            TextBox1.AppendText(dataVal(0))
            TextBox1.AppendText(grpCode(0).ToString)
        Next

        ssetObj.Erase()
        ssetObj.Delete()

        acadDoc = Nothing
        AcadApp = Nothing
    End Sub

    End Sub
End Class

<edit> added code tags ...Mav
« Last Edit: February 06, 2007, 05:15:50 PM by Maverick® »

Nathan Taylor

  • Guest
Re: Using selectionset with COM
« Reply #1 on: February 06, 2007, 05:10:45 PM »
You have an 'On Error Resume Next' which may be masking an unexpected error. Add 'On Error GoTo 0' after this line 'AcadApp = GetObject(, "AutoCAD.Application")'.

Regards - Nathan

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: Using selectionset with COM
« Reply #2 on: February 06, 2007, 10:33:27 PM »
I'm not a vb'er ..

but

This seems suspect < single backslash >
filepath = "C:\test.dwg"

Is the drawing opening for you ?

I'm getting an "ERROR opening AutoCAD" alert ..
and I don't like VB enough to try to follow it through, sorry

kdub, kdub_nz in other timelines.
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.

MickD

  • King Gator
  • Posts: 3636
  • (x-in)->[process]->(y-out) ... simples!
Re: Using selectionset with COM
« Reply #3 on: February 06, 2007, 10:56:05 PM »
I too am not well versed in vb but do you need to create a 'New' (or 'Set' AcadApp in old vb I think) instance of an application and document (allocating memory for them on the heap) or is this memory accounted for within the compiled .exe that you are making?
In my ignorant opinion I don't think they can be pre-allocated as this function may be called many times (i.e. the app and doc are not static).
"Programming is really just the mundane aspect of expressing a solution to a problem."
- John Carmack

"Short cuts make long delays,' argued Pippin.”
- J.R.R. Tolkien

Glenn R

  • Guest
Re: Using selectionset with COM
« Reply #4 on: February 06, 2007, 11:08:56 PM »
As Kerry would say, just a w.a.g. but, try reversing these 2 lines:
Code: [Select]
acadDoc = AcadApp.Documents.Open(filepath)
AcadApp.Application.Visible = True

Also, from memory, trying to Add a selectionset whose 'key' already existed threw an error.
In vba, I would do this:
Code: [Select]
Dim pSS as AcadSelectionSet
Set pSS = ThisDrawing.PickFirstSelectionSet
pSS.Clear
...

Nathan Taylor

  • Guest
Re: Using selectionset with COM
« Reply #5 on: February 07, 2007, 04:55:33 PM »
You have an 'On Error Resume Next' which may be masking an unexpected error. Add 'On Error GoTo 0' after this line 'AcadApp = GetObject(, "AutoCAD.Application")'.

Regards - Nathan

Since your using .NET ditch the On Error syntax and use Try.. Catch statements.

Regards - Nathan

Martin_2

  • Guest
Re: Using selectionset with COM
« Reply #6 on: February 08, 2007, 03:43:21 PM »
You have an 'On Error Resume Next' which may be masking an unexpected error. Add 'On Error GoTo 0' after this line 'AcadApp = GetObject(, "AutoCAD.Application")'.

Regards - Nathan

Hi

Thank you all for replying.

With regards to the opening of the file, it is in fact working. "C:\test" was only to show that a path is required. I did not include any dwg files, with the project.

To try it out, make a AutoCAD 2007 dwg file and replace C:\test with the path of the file.

The memory heap comment I'm afraid I don't understand, but using "Set" in Visual Studio 2005, causes it to reply with:
"Let and Set assignment statements are no longer supported".


The "On Error Goto 0" did help.

ssetObj = acadDoc.SelectionSet.Add("SS01") has to be modified into:

ssetObj = acadDoc.SelectionSets.Add("SS01").

Doing this, allows TextBox1.AppendText(ssetObj.Count.ToString) to work.

It reports 0 objects, in the selectionset.

However, the following code line returns an error:
ssetObj.Select(mode, , , grpCode, dataVal)

(grpCode is the FilterType and dataVal is the FilterData)

The error is:

"Invalid argument FilterType in Select"

I tried replacing the arrays with direct insertion of the values, but that didn't work either.
Changing the name of the selectionset, to avoid reuse did not change anything.

The example, from Autodesk, mentioned in my last post is in VBA, so I tried out a similar code, in VBA, which did work (after I removed the ssetObj.Erase() part which deletes the objects!):

I changed the code to use multiline text instead of text, if someone should wish to try out the code (just create a file containing a couple of multiline text fields and use it with the code):

Code: [Select]
Private Sub CommandButton1_Click()
    Dim entObj As AcadEntity
    Dim ssetObj As AcadSelectionSet
    Dim grpCode(0) As Integer
    Dim dataVal(0) As Variant
    Dim i As Integer
    Dim mode As Integer

    UserForm1.Hide
    grpCode(0) = 0
    dataVal(0) = "MTEXT"
    mode = acSelectionSetAll

    Set ssetObj = ThisDrawing.SelectionSets.Add("SS01")
    ssetObj.Select mode, , , grpCode, dataVal
    TextBox1.Text = ssetObj.Count
    ssetObj.Delete
    UserForm1.Show
End Sub

I tried it out on my file which contains text fields (MTEXT -> TEXT) and it works as well.

Does anyone have any ideas as to why the Filtertype which works in VBA does not in VB.NET?

Could it be that I'm not referencing the AutoCAD document correctly or something like that?

Regards Martin

Nathan Taylor

  • Guest
Re: Using selectionset with COM
« Reply #7 on: February 08, 2007, 04:39:46 PM »

Does anyone have any ideas as to why the Filtertype which works in VBA does not in VB.NET?


In VB6 an integer is 16 bits in VB.NET it is 32 bits. Try changing your varaiable type from integer to int16 or short.

Regards - Nathan

Martin_2

  • Guest
Re: Using selectionset with COM
« Reply #8 on: February 12, 2007, 04:09:08 PM »

Does anyone have any ideas as to why the Filtertype which works in VBA does not in VB.NET?


In VB6 an integer is 16 bits in VB.NET it is 32 bits. Try changing your varaiable type from integer to int16 or short.

Regards - Nathan

Hi

Thank you all, for your help.
I now have a code that works.
I've added it below, for others to use (without using as much time as I have).

Remember that FilterData (dataVal) has to be declared as Object. Declaring it as String will not work. On the other hand FilterType (grpCode) must not be declared as Object. It has to be int16 (perhaps short will work as well, I havn't tried).
Go figure.
Be aware that Integer will not work either.

When working with the content, of the selectionset, remember to cast the type of object you're working with. In this case working with the AcadText objects directly will not work. You have to let the compiler know which type of object it is suppose to handle (late binding, if I'm not mistaken).

Thank you again.
Martin
Code: [Select]
Imports Autodesk.AutoCAD.Interop
Imports Autodesk.AutoCAD.Interop.Common

Public Class Form1
    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Dim filepath As String
        'insert path to your dwg file
        filepath = "C:\test.dwg"
        OpenACADFile(filepath)
    End Sub

    Sub OpenACADFile(ByVal filepath As String)
        Dim AcadApp As Autodesk.AutoCAD.Interop.AcadApplication
        Dim acadDoc As Autodesk.AutoCAD.Interop.AcadDocument

        'Selectionset declarations
        Dim entObj As AcadEntity
        Dim ssetObj As AcadSelectionSet

        Dim mode As Integer
        Dim grpCode(0) As Int16
        Dim dataVal(0) As Object
        Dim i As Integer
        Dim test As AcadText

        On Error Resume Next

        'test for existing cad application
        AcadApp = GetObject(, "AutoCAD.Application")

        If Err.Number <> 0 Then
            Err.Clear()
            'opens a new application if none is available
            AcadApp = CreateObject("AutoCAD.Application")
            If Err.Number <> 0 Then
                MsgBox("Error opening AutoCAD")
                Exit Sub
            End If
        End If

        acadDoc = AcadApp.Documents.Open(filepath)
        AcadApp.Application.Visible = True

        On Error GoTo 0

        ssetObj = acadDoc.SelectionSets.Add("SS02")
        mode = Autodesk.AutoCAD.Interop.Common.AcSelect.acSelectionSetAll
        grpCode(0) = 0

        dataVal(0) = "TEXT"
        ssetObj.Select(mode, , , grpCode, dataVal)

        For i = 0 To ssetObj.Count - 1
            test = CType(ssetObj.Item(i), AcadText)
            If test.TextString <> "" Then
                TextBox1.AppendText(test.TextString & vbCrLf & test.InsertionPoint(0).ToString & vbCrLf)
            End If
        Next

        ssetObj.Delete()
        acadDoc = Nothing
        AcadApp = Nothing
    End Sub
End Class