.NET

.NET

Reply
*James Allen
Message 1 of 14 (2,578 Views)

AcadSelectionSet.AddItems(AcadBlockReference.Explode())

2578 Views, 13 Replies
06-29-2009 03:27 PM
I'm porting a bunch of VBA to VB.Net and came across this. Unchanged,
it fails with "Invalid argument pSelSet in AddItems". My workaround
isn't difficult, just a nuisance for however many times I'll have to
repeat and it seems silly to need to in the first place. I feel like
I'm missing something simple. Is(n't) there a better way?

{code}
Imports Autodesk.AutoCAD.ApplicationServices
Imports Autodesk.AutoCAD.Interop
Imports Autodesk.AutoCAD.Interop.Common
Imports Autodesk.AutoCAD.Runtime

Public Class Class1

'Pick an explodable block before running this.
_
Public Sub AddItemsTest()
Dim Blks As AcadSelectionSet
Dim Dels As AcadSelectionSet
Dim Doc As AcadDocument
Dim Ent As AcadEntity

Doc = Application.AcadApplication.ActiveDocument
Dels = Doc.SelectionSets.Add("Delete")
Blks = Doc.ActiveSelectionSet
For Each Ent In Blks
'Invalid argument pSelSet in AddItems
'Dels.AddItems(Ent.Explode)
'So do the following instead, is there a better way?
Dim Objs() As Object = Ent.Explode
Dim Ents(Objs.Length - 1) As AcadEntity
Objs.CopyTo(Ents, 0)
Dels.AddItems(Ents)
Next
'Do stuff with temp ents to delete
For Each Ent In Dels
Ent.Delete()
Next
Doc.SelectionSets.Item("Delete").Delete()
End Sub

End Class
{/code}

--
James Allen
Malicoat-Winslow Engineers, P.C.
Columbia, MO
*Bobby C. Jones
Message 2 of 14 (2,578 Views)

Re: AcadSelectionSet.AddItems(AcadBlockReference.Explode())

06-30-2009 10:21 AM in reply to: *James Allen
Do you need the entities in a selection set? Can't you just iterate over
the array and " 'Do stuff with temp ents to delete "
--
Bobby C. Jones
http://bobbycjones.spaces.live.com
*James Allen
Message 3 of 14 (2,578 Views)

Re: AcadSelectionSet.AddItems(AcadBlockReference.Explode())

06-30-2009 12:52 PM in reply to: *James Allen
Nope, and yes, of course. But that would mean more change, which I am
trying to avoid as much as possible in the context of initial mass
conversion of nearly 50 working VBA projects to VB.Net. Thank you for
the suggestion though, Bobby. Where I've seen this so far, selection
sets are probably the last thing I would use doing it from scratch or
actually taking time to clean up and optimize. I may go back after I've
got the bigger fish fried...

I suspect the more general problem will come up in other contexts
though, namely anywhere a COM method accepting an AcadEntity() is being
directly fed a System.__ComObject(). I was hoping for someone to reveal
some gem like Option MakeItWork that would just make it work like it did
in VBA... ;-) Or maybe an inline type conversion for an array. I
looked at ConvertAll, but unless I missed something that would add
significantly more code than I already did.

--
James Allen
Malicoat-Winslow Engineers, P.C.
Columbia, MO



Bobby C. Jones wrote:
> Do you need the entities in a selection set? Can't you just iterate over
> the array and " 'Do stuff with temp ents to delete "
>
*Bobby C. Jones
Message 4 of 14 (2,578 Views)

Re: AcadSelectionSet.AddItems(AcadBlockReference.Explode())

06-30-2009 01:26 PM in reply to: *James Allen
My experience in converting VBA code is somewhere south of vbnull.
Hopefully someone with more knowledge than me will post something that's
actually useful.
--
Bobby C. Jones
http://bobbycjones.spaces.live.com
*Tony Tanzillo
Message 5 of 14 (2,578 Views)

Re: AcadSelectionSet.AddItems(AcadBlockReference.Explode())

07-01-2009 03:38 AM in reply to: *James Allen
Someone may have left you with inflated expectations
about the ease of converting VBA to VB.NET.

It's not as simple as some might think. :smileywink:

In this case, you should just use the returned array,
because there's little point to adding the items to a
selection set only to erase them.

More generally, I would lower my expections about
the ease of the conversion process. There's a lot
more to it than just defining a 'ThisDrawing' property.

--
http://www.caddzone.com

AcadXTabs: MDI Document Tabs for AutoCAD 2009
Supporting AutoCAD 2000 through 2009

http://www.acadxtabs.com

Introducing AcadXTabs 2010:
http://www.caddzone.com/acadxtabs/AcadXTabs2010.htm

Email: string.Format("{0}@{1}.com", "tonyt", "caddzone");


"James Allen" wrote in message
news:6211022@discussion.autodesk.com...
Nope, and yes, of course. But that would mean more change, which I am
trying to avoid as much as possible in the context of initial mass
conversion of nearly 50 working VBA projects to VB.Net. Thank you for
the suggestion though, Bobby. Where I've seen this so far, selection
sets are probably the last thing I would use doing it from scratch or
actually taking time to clean up and optimize. I may go back after I've
got the bigger fish fried...

I suspect the more general problem will come up in other contexts
though, namely anywhere a COM method accepting an AcadEntity() is being
directly fed a System.__ComObject(). I was hoping for someone to reveal
some gem like Option MakeItWork that would just make it work like it did
in VBA... ;-) Or maybe an inline type conversion for an array. I
looked at ConvertAll, but unless I missed something that would add
significantly more code than I already did.

--
James Allen
Malicoat-Winslow Engineers, P.C.
Columbia, MO



Bobby C. Jones wrote:
> Do you need the entities in a selection set? Can't you just iterate over
> the array and " 'Do stuff with temp ents to delete "
>
*James Allen
Message 6 of 14 (2,578 Views)

Re: AcadSelectionSet.AddItems(AcadBlockReference.Explode())

07-01-2009 07:21 AM in reply to: *James Allen
Don't worry Tony, no such delusions here. That is certainly a potential
pitfall of how it's been presented though.

I only posted about this one of many breaking changes I've seen because
unlike others it seems to have general implications outside the
immediate context.

And agreed, as Bobby rightly suggested, that is what I should do in this
case. I will post back if/when I come across a more sensible example of
the same underlying issue.

Thank you both,

--
James Allen
Malicoat-Winslow Engineers, P.C.
Columbia, MO



Tony Tanzillo wrote:
> Someone may have left you with inflated expectations
> about the ease of converting VBA to VB.NET.
>
> It's not as simple as some might think. :smileywink:
>
> In this case, you should just use the returned array,
> because there's little point to adding the items to a
> selection set only to erase them.
>
> More generally, I would lower my expections about
> the ease of the conversion process. There's a lot
> more to it than just defining a 'ThisDrawing' property.
>
>
Distinguished Contributor
alex_b
Posts: 405
Registered: ‎08-15-2003
Message 7 of 14 (1,539 Views)

Re: AcadSelectionSet.AddItems(AcadBlockReference.Explode())

09-03-2012 05:09 PM in reply to: *James Allen

Hi

I'm trying to do something similar in an out-of-process C# app, and AcadSelectionSet,AddItems() raises an exception.

//perform a WBLOCK on blockName to tempPath
AcadSelectionSet sset = null; sset = AcadDoc.SelectionSets.Add("BlSet"); sset.Clear(); AcadBlocks blocks = AcadDoc.Blocks; AcadBlock bl = null; bl = blocks.Item(blockName);//gets the block definition of input block name int i = bl.Count;//the number of entities in the block definition AcadEntity ent; Object[] objs = new Object[i]; AcadEntity[] ents = new AcadEntity[i]; int j = 0; for (j = 0; j < i; j++)//iterates thru the block definition {   ent = bl.Item(j);//gets one entity   //add it to the array   objs[j] = ent.Copy();//OK } for (j = 0; j < i; j++) {   ents[j] = (AcadEntity)objs[j]; } sset.AddItems(objs);//exception acApp.ActiveDocument.Wblock(tempPath, sset); sset.Delete();

I've tried a number of ways, with and without copying the array and/or the entities, but it never comes out right.

Even when in the debugger I see the entities were added to the selection set, then the Wblock() method raises an exception.

Any tips will be VERY welcome.

Thanks

alex

*Expert Elite*
Hallex
Posts: 1,569
Registered: ‎10-08-2008
Message 8 of 14 (1,532 Views)

Re: AcadSelectionSet.AddItems(AcadBlockReference.Explode())

09-03-2012 11:32 PM in reply to: alex_b

This one should work:

 

       [CommandMethod("wblocks")]
        public static void WBlocking()
        {
            string tempPath = @"C:\Test\WPART.dwg";
            AcadApplication acApp = new AcadApplicationClass();
            acApp.Documents.Open(@"C:\Test\WorkingDrawing.dwg", Type.Missing, Type.Missing);
            AcadDocument AcadDoc = acApp.ActiveDocument;
            acApp.Visible = true;
            
            AcadSelectionSet sset = null;
            //perform a WBLOCK on blockName to tempPathAcadSelectionSet sset = null;
            sset = AcadDoc.SelectionSets.Add("BlSet");
            List<AcadBlockReference> brefs = new List<AcadBlockReference>();
            AcadBlocks blocks = AcadDoc.Blocks;
            AcadBlock bl = null;
            string blockName = "PART";
            bl = blocks.Item(blockName);//gets the block definition of input block name
            AcadModelSpace AcSpace = AcadDoc.ModelSpace;
           
            //loop through the model space to fill the list of block references
            foreach (AcadEntity acEnt in AcSpace)
            {
                if (acEnt is AcadBlockReference)
                {
                    AcadBlockReference AcBref = acEnt as AcadBlockReference;
                    if (AcBref.EffectiveName == blockName)
                    {
                        brefs.Add(AcBref);
                   
                    }
                }
            }
            // convert list to array of objects
            Object[] objs = brefs.ToArray(); 
            // cast array as single object
            Object pSelSet = (Object)objs;
            sset.AddItems(pSelSet);// select Additems, then click "Go to Definition" to see arguments
            acApp.ActiveDocument.Wblock(tempPath, sset);
            sset.Delete();
            
            AcadDoc.Close(Type.Missing, Type.Missing);
        }

 

~'J'~

_____________________________________
C6309D9E0751D165D0934D0621DFF27919
Distinguished Contributor
alex_b
Posts: 405
Registered: ‎08-15-2003
Message 9 of 14 (1,519 Views)

Re: AcadSelectionSet.AddItems(AcadBlockReference.Explode())

09-04-2012 10:13 AM in reply to: Hallex

Hallex

Thank you for the response.

If I understand your code correctly, it writes to disk all instances of a particular block reference, which is not what I meant.

What I need is to write to disk just the block definition (as in WBLOCK blockName ...)

ANyway, I modified my code as per your suggestion, but I still get an exception on

sset.AddItems(pSelSet);//exception

The exception is:Error HRESULT E_FAIL has been returned from a call to a COM component.

Could you comment on that?

N.B. The code has to be compatible with ACAD 2004. Could this be the problem?

Thanks again

alex

 

*Expert Elite*
Hallex
Posts: 1,569
Registered: ‎10-08-2008
Message 10 of 14 (1,513 Views)

Re: AcadSelectionSet.AddItems(AcadBlockReference.Explode())

09-04-2012 01:07 PM in reply to: alex_b

To write on disk the block definitions you have use CloneObjects method instead,

see VBA help for more, if I can I will try to write an example about

 

~'J'~

_____________________________________
C6309D9E0751D165D0934D0621DFF27919
Post to the Community

Have questions about Autodesk products? Ask the community.

New Post
Announcements
Do you have 60 seconds to spare? The Autodesk Community Team is revamping our site ranking system and we want your feedback! Please click here to launch the 5 question survey. As always your input is greatly appreciated.