.NET

.NET

Reply
*mp
Message 1 of 8 (392 Views)

simple example of iterating a collection (eg blocks)

392 Views, 7 Replies
09-08-2009 10:11 AM
Hi,
just starting to transition from vb to dotnet...i know late in the
game...anyway,
i've looked at the obj arx samples, searched the group archives and help etc
but havent' found a simple genric explanation of exactly how to iterate any
given collection...i know it's probable there somewhere and i'm just missing
it but if anyone here knows or has a link to get me started i'd appreciate

for example
for each block in blocks
'query block for properties...name, whatever
For each ent in block
'query ent...etc
I used this sample i found that iterates db.currentspaceid but when i
changed it to db.blocktableid i thought i'd get the blocks collection but
got an error instead
_

Public Sub IterateBlocks()


Dim tr As Transaction, count As Integer

Dim db As Database = HostApplicationServices.WorkingDatabase

Dim doc As Document = Application.DocumentManager.MdiActiveDocument

Dim btr As BlockTableRecord

tr = db.TransactionManager.StartTransaction()

Using (tr)

'this was the original line which did work

'btr = tr.GetObject(db.CurrentSpaceId, OpenMode.ForRead)

'then i tried to get the blocktable instead and got this error

'Unable to cast object of type
'Autodesk.AutoCAD.DatabaseServices.BlockTable' to type
'Autodesk.AutoCAD.DatabaseServices.BlockTableRecord'.

btr = tr.GetObject(db.BlockTableId, OpenMode.ForRead)

If (Not btr Is Nothing) Then

Dim id As ObjectId

For Each id In btr

Dim e As Entity = tr.GetObject(id, 0)

doc.Editor.WriteMessage(vbCrLf & TypeName(e))


count += 1

Next

doc.Editor.WriteMessage("{0} items in block {1}", count, btr.Name)


End If

tr.Commit()

End Using

End Sub
*Paul Richardson
Message 2 of 8 (391 Views)

Re: simple example of iterating a collection (eg blocks)

09-08-2009 11:03 AM in reply to: *mp
Mark - Search for 'loop thru entity in a block'. I posted simple code to
recursivly iterate a block and Tony shows how to do it with Linq which is
very cool. It's in c# but the idea is the same in both languages. Might be
time to just switch to c# - you'll like it!

Basically you have a collection of ObjectIds which you loop through. To
check what type of entity the id belongs to open it for read and check it.

//find all circles in a block
{code}
private static void
NestedCircles(Transaction tr, BlockReference br, ref int count)
{

BlockTableRecord btr =
(BlockTableRecord)tr.GetObject(br.BlockTableRecord,
OpenMode.ForRead);

if (btr != null)
foreach (ObjectId id in btr)
{

Entity e =
(Entity)tr.GetObject(id, OpenMode.ForRead);

if (e is Circle)
{
count++;
continue;
}

//2010 way - no need to open entity to check its type
RXClass rxClass = id.ObjectClass;
if (rxClass.DxfName == "Circle")
{
count++;
continue;
}

//recursive call if nested block ref is found.
if (e is BlockReference)
NestedCircles(tr, (BlockReference)e, ref count);
}
}
{code}
"mp" wrote in message
news:6250772@discussion.autodesk.com...
Hi,
just starting to transition from vb to dotnet...i know late in the
game...anyway,
i've looked at the obj arx samples, searched the group archives and help etc
but havent' found a simple genric explanation of exactly how to iterate any
given collection...i know it's probable there somewhere and i'm just missing
it but if anyone here knows or has a link to get me started i'd appreciate

for example
for each block in blocks
'query block for properties...name, whatever
For each ent in block
'query ent...etc
I used this sample i found that iterates db.currentspaceid but when i
changed it to db.blocktableid i thought i'd get the blocks collection but
got an error instead
_

Public Sub IterateBlocks()


Dim tr As Transaction, count As Integer

Dim db As Database = HostApplicationServices.WorkingDatabase

Dim doc As Document = Application.DocumentManager.MdiActiveDocument

Dim btr As BlockTableRecord

tr = db.TransactionManager.StartTransaction()

Using (tr)

'this was the original line which did work

'btr = tr.GetObject(db.CurrentSpaceId, OpenMode.ForRead)

'then i tried to get the blocktable instead and got this error

'Unable to cast object of type
'Autodesk.AutoCAD.DatabaseServices.BlockTable' to type
'Autodesk.AutoCAD.DatabaseServices.BlockTableRecord'.

btr = tr.GetObject(db.BlockTableId, OpenMode.ForRead)

If (Not btr Is Nothing) Then

Dim id As ObjectId

For Each id In btr

Dim e As Entity = tr.GetObject(id, 0)

doc.Editor.WriteMessage(vbCrLf & TypeName(e))


count += 1

Next

doc.Editor.WriteMessage("{0} items in block {1}", count, btr.Name)


End If

tr.Commit()

End Using

End Sub
*mp
Message 3 of 8 (391 Views)

Re: simple example of iterating a collection (eg blocks)

09-08-2009 06:22 PM in reply to: *mp
Thanks Paul,
actually it was your code i had found and tried to modify to look at blocks
collection
that's where i got stuck because i didn't guess right how to convert from
iterating the current space to iterating the blocks collection
now that i read the error message more closely i think i see what i did
wrong, will try again to see if i can figure it out.
so you like c# better? what are some of your reasons. I haven't played
much in c# . I notice a lot of the examples like the adesk through the
interface seem to lean to c as well.
thanks
mark
"Paul Richardson" wrote in message
news:6250830@discussion.autodesk.com...
Mark - Search for 'loop thru entity in a block'. I posted simple code to
recursivly iterate a block and Tony shows how to do it with Linq which is
very cool. It's in c# but the idea is the same in both languages. Might be
time to just switch to c# - you'll like it!

Basically you have a collection of ObjectIds which you loop through. To
check what type of entity the id belongs to open it for read and check it.

//find all circles in a block
{code}
private static void
NestedCircles(Transaction tr, BlockReference br, ref int count)
{

BlockTableRecord btr =
(BlockTableRecord)tr.GetObject(br.BlockTableRecord,
OpenMode.ForRead);

if (btr != null)
foreach (ObjectId id in btr)
{

Entity e =
(Entity)tr.GetObject(id, OpenMode.ForRead);

if (e is Circle)
{
count++;
continue;
}

//2010 way - no need to open entity to check its type
RXClass rxClass = id.ObjectClass;
if (rxClass.DxfName == "Circle")
{
count++;
continue;
}

//recursive call if nested block ref is found.
if (e is BlockReference)
NestedCircles(tr, (BlockReference)e, ref count);
}
}
{code}
"mp" wrote in message
news:6250772@discussion.autodesk.com...
Hi,
just starting to transition from vb to dotnet...i know late in the
game...anyway,
i've looked at the obj arx samples, searched the group archives and help etc
but havent' found a simple genric explanation of exactly how to iterate any
given collection...i know it's probable there somewhere and i'm just missing
it but if anyone here knows or has a link to get me started i'd appreciate

for example
for each block in blocks
'query block for properties...name, whatever
For each ent in block
'query ent...etc
I used this sample i found that iterates db.currentspaceid but when i
changed it to db.blocktableid i thought i'd get the blocks collection but
got an error instead
_

Public Sub IterateBlocks()


Dim tr As Transaction, count As Integer

Dim db As Database = HostApplicationServices.WorkingDatabase

Dim doc As Document = Application.DocumentManager.MdiActiveDocument

Dim btr As BlockTableRecord

tr = db.TransactionManager.StartTransaction()

Using (tr)

'this was the original line which did work

'btr = tr.GetObject(db.CurrentSpaceId, OpenMode.ForRead)

'then i tried to get the blocktable instead and got this error

'Unable to cast object of type
'Autodesk.AutoCAD.DatabaseServices.BlockTable' to type
'Autodesk.AutoCAD.DatabaseServices.BlockTableRecord'.

btr = tr.GetObject(db.BlockTableId, OpenMode.ForRead)

If (Not btr Is Nothing) Then

Dim id As ObjectId

For Each id In btr

Dim e As Entity = tr.GetObject(id, 0)

doc.Editor.WriteMessage(vbCrLf & TypeName(e))


count += 1

Next

doc.Editor.WriteMessage("{0} items in block {1}", count, btr.Name)


End If

tr.Commit()

End Using

End Sub
*Paul Richardson
Message 4 of 8 (391 Views)

Re: simple example of iterating a collection (eg blocks)

09-08-2009 07:41 PM in reply to: *mp
I like c# because of the less verbose syntax and the better code samples
floating
around!

There are many online converters from c# to vb and vice versa. Also get
yourself
a copy of Reflector from Red gate and learn to use it! It can be use to
convert
code and also allow you to look inside assemblies.

This will loop all block records but also check the use of the 'has' method
to just
check for a specific block.
{code}
[CommandMethod("ioo")]
static public void Ioo()
{

Database db =
Application.DocumentManager.MdiActiveDocument.Database;

using (Transaction tr =
db.TransactionManager.StartTransaction())
{

//grab the block table
BlockTable bt =
(BlockTable) tr.GetObject(db.BlockTableId, OpenMode.ForRead);

//loop the table
foreach (ObjectId id in bt)
{
//grab the next record
BlockTableRecord btr =
(BlockTableRecord) tr.GetObject(id, OpenMode.ForRead);

//Print the record name
Debug.Print(btr.Name);

//loop the record itself
foreach (ObjectId id1 in btr)
{
Entity e =
(Entity) tr.GetObject(id1, OpenMode.ForRead);
Debug.Print(e.ToString());
}
}

//or just check the blocktable for a specific block
if (bt.Has("blockname"))
{
BlockTableRecord btr =
(BlockTableRecord)(tr.GetObject(bt["blockname"],
OpenMode.ForRead));

foreach (ObjectId entId in btr)
{
Entity e = (Entity)tr.GetObject(entId, OpenMode.ForRead);

if (e is DBText)
{
DBText t = (DBText)e;
//do t stuff...
break;
}
}
}

//no need to commit in this case but it's the norm
tr.Commit();
}
}
{code}
"mp" wrote in message
news:6251031@discussion.autodesk.com...
Thanks Paul,
actually it was your code i had found and tried to modify to look at blocks
collection
that's where i got stuck because i didn't guess right how to convert from
iterating the current space to iterating the blocks collection
now that i read the error message more closely i think i see what i did
wrong, will try again to see if i can figure it out.
so you like c# better? what are some of your reasons. I haven't played
much in c# . I notice a lot of the examples like the adesk through the
interface seem to lean to c as well.
thanks
mark
"Paul Richardson" wrote in message
news:6250830@discussion.autodesk.com...
Mark - Search for 'loop thru entity in a block'. I posted simple code to
recursivly iterate a block and Tony shows how to do it with Linq which is
very cool. It's in c# but the idea is the same in both languages. Might be
time to just switch to c# - you'll like it!

Basically you have a collection of ObjectIds which you loop through. To
check what type of entity the id belongs to open it for read and check it.

//find all circles in a block
{code}
private static void
NestedCircles(Transaction tr, BlockReference br, ref int count)
{

BlockTableRecord btr =
(BlockTableRecord)tr.GetObject(br.BlockTableRecord,
OpenMode.ForRead);

if (btr != null)
foreach (ObjectId id in btr)
{

Entity e =
(Entity)tr.GetObject(id, OpenMode.ForRead);

if (e is Circle)
{
count++;
continue;
}

//2010 way - no need to open entity to check its type
RXClass rxClass = id.ObjectClass;
if (rxClass.DxfName == "Circle")
{
count++;
continue;
}

//recursive call if nested block ref is found.
if (e is BlockReference)
NestedCircles(tr, (BlockReference)e, ref count);
}
}
{code}
"mp" wrote in message
news:6250772@discussion.autodesk.com...
Hi,
just starting to transition from vb to dotnet...i know late in the
game...anyway,
i've looked at the obj arx samples, searched the group archives and help etc
but havent' found a simple genric explanation of exactly how to iterate any
given collection...i know it's probable there somewhere and i'm just missing
it but if anyone here knows or has a link to get me started i'd appreciate

for example
for each block in blocks
'query block for properties...name, whatever
For each ent in block
'query ent...etc
I used this sample i found that iterates db.currentspaceid but when i
changed it to db.blocktableid i thought i'd get the blocks collection but
got an error instead
_

Public Sub IterateBlocks()


Dim tr As Transaction, count As Integer

Dim db As Database = HostApplicationServices.WorkingDatabase

Dim doc As Document = Application.DocumentManager.MdiActiveDocument

Dim btr As BlockTableRecord

tr = db.TransactionManager.StartTransaction()

Using (tr)

'this was the original line which did work

'btr = tr.GetObject(db.CurrentSpaceId, OpenMode.ForRead)

'then i tried to get the blocktable instead and got this error

'Unable to cast object of type
'Autodesk.AutoCAD.DatabaseServices.BlockTable' to type
'Autodesk.AutoCAD.DatabaseServices.BlockTableRecord'.

btr = tr.GetObject(db.BlockTableId, OpenMode.ForRead)

If (Not btr Is Nothing) Then

Dim id As ObjectId

For Each id In btr

Dim e As Entity = tr.GetObject(id, 0)

doc.Editor.WriteMessage(vbCrLf & TypeName(e))


count += 1

Next

doc.Editor.WriteMessage("{0} items in block {1}", count, btr.Name)


End If

tr.Commit()

End Using

End Sub
*Paul Richardson
Message 5 of 8 (391 Views)

Re: simple example of iterating a collection (eg blocks)

09-08-2009 08:29 PM in reply to: *mp
Here is a vdeo showing how to use reflector to convert code.
http://www.screencast.com/t/KWWCdmmH

"Paul Richardson" wrote in message
news:6251072@discussion.autodesk.com...
I like c# because of the less verbose syntax and the better code samples
floating
around!

There are many online converters from c# to vb and vice versa. Also get
yourself
a copy of Reflector from Red gate and learn to use it! It can be use to
convert
code and also allow you to look inside assemblies.

This will loop all block records but also check the use of the 'has' method
to just
check for a specific block.
{code}
[CommandMethod("ioo")]
static public void Ioo()
{

Database db =
Application.DocumentManager.MdiActiveDocument.Database;

using (Transaction tr =
db.TransactionManager.StartTransaction())
{

//grab the block table
BlockTable bt =
(BlockTable) tr.GetObject(db.BlockTableId, OpenMode.ForRead);

//loop the table
foreach (ObjectId id in bt)
{
//grab the next record
BlockTableRecord btr =
(BlockTableRecord) tr.GetObject(id, OpenMode.ForRead);

//Print the record name
Debug.Print(btr.Name);

//loop the record itself
foreach (ObjectId id1 in btr)
{
Entity e =
(Entity) tr.GetObject(id1, OpenMode.ForRead);
Debug.Print(e.ToString());
}
}

//or just check the blocktable for a specific block
if (bt.Has("blockname"))
{
BlockTableRecord btr =
(BlockTableRecord)(tr.GetObject(bt["blockname"],
OpenMode.ForRead));

foreach (ObjectId entId in btr)
{
Entity e = (Entity)tr.GetObject(entId, OpenMode.ForRead);

if (e is DBText)
{
DBText t = (DBText)e;
//do t stuff...
break;
}
}
}

//no need to commit in this case but it's the norm
tr.Commit();
}
}
{code}
"mp" wrote in message
news:6251031@discussion.autodesk.com...
Thanks Paul,
actually it was your code i had found and tried to modify to look at blocks
collection
that's where i got stuck because i didn't guess right how to convert from
iterating the current space to iterating the blocks collection
now that i read the error message more closely i think i see what i did
wrong, will try again to see if i can figure it out.
so you like c# better? what are some of your reasons. I haven't played
much in c# . I notice a lot of the examples like the adesk through the
interface seem to lean to c as well.
thanks
mark
"Paul Richardson" wrote in message
news:6250830@discussion.autodesk.com...
Mark - Search for 'loop thru entity in a block'. I posted simple code to
recursivly iterate a block and Tony shows how to do it with Linq which is
very cool. It's in c# but the idea is the same in both languages. Might be
time to just switch to c# - you'll like it!

Basically you have a collection of ObjectIds which you loop through. To
check what type of entity the id belongs to open it for read and check it.

//find all circles in a block
{code}
private static void
NestedCircles(Transaction tr, BlockReference br, ref int count)
{

BlockTableRecord btr =
(BlockTableRecord)tr.GetObject(br.BlockTableRecord,
OpenMode.ForRead);

if (btr != null)
foreach (ObjectId id in btr)
{

Entity e =
(Entity)tr.GetObject(id, OpenMode.ForRead);

if (e is Circle)
{
count++;
continue;
}

//2010 way - no need to open entity to check its type
RXClass rxClass = id.ObjectClass;
if (rxClass.DxfName == "Circle")
{
count++;
continue;
}

//recursive call if nested block ref is found.
if (e is BlockReference)
NestedCircles(tr, (BlockReference)e, ref count);
}
}
{code}
"mp" wrote in message
news:6250772@discussion.autodesk.com...
Hi,
just starting to transition from vb to dotnet...i know late in the
game...anyway,
i've looked at the obj arx samples, searched the group archives and help etc
but havent' found a simple genric explanation of exactly how to iterate any
given collection...i know it's probable there somewhere and i'm just missing
it but if anyone here knows or has a link to get me started i'd appreciate

for example
for each block in blocks
'query block for properties...name, whatever
For each ent in block
'query ent...etc
I used this sample i found that iterates db.currentspaceid but when i
changed it to db.blocktableid i thought i'd get the blocks collection but
got an error instead
_

Public Sub IterateBlocks()


Dim tr As Transaction, count As Integer

Dim db As Database = HostApplicationServices.WorkingDatabase

Dim doc As Document = Application.DocumentManager.MdiActiveDocument

Dim btr As BlockTableRecord

tr = db.TransactionManager.StartTransaction()

Using (tr)

'this was the original line which did work

'btr = tr.GetObject(db.CurrentSpaceId, OpenMode.ForRead)

'then i tried to get the blocktable instead and got this error

'Unable to cast object of type
'Autodesk.AutoCAD.DatabaseServices.BlockTable' to type
'Autodesk.AutoCAD.DatabaseServices.BlockTableRecord'.

btr = tr.GetObject(db.BlockTableId, OpenMode.ForRead)

If (Not btr Is Nothing) Then

Dim id As ObjectId

For Each id In btr

Dim e As Entity = tr.GetObject(id, 0)

doc.Editor.WriteMessage(vbCrLf & TypeName(e))


count += 1

Next

doc.Editor.WriteMessage("{0} items in block {1}", count, btr.Name)


End If

tr.Commit()

End Using

End Sub
*mp
Message 6 of 8 (391 Views)

Re: simple example of iterating a collection (eg blocks)

09-09-2009 10:20 AM in reply to: *mp
Thanks again

mark

"Paul Richardson" wrote in message
news:6251112@discussion.autodesk.com...
Here is a vdeo showing how to use reflector to convert code.
http://www.screencast.com/t/KWWCdmmH

snip
*mp
Message 7 of 8 (391 Views)

Re: simple example of iterating a collection (eg blocks)

09-10-2009 08:14 AM in reply to: *mp
Hey cool video, did you do that? That looks like an awesome little tool to
convert languages, very helpful,
thanks for the tip.
mark

"Paul Richardson" wrote in message
news:6251112@discussion.autodesk.com...
Here is a vdeo showing how to use reflector to convert code.
http://www.screencast.com/t/KWWCdmmH

snip
*Paul Richardson
Message 8 of 8 (391 Views)

Re: simple example of iterating a collection (eg blocks)

09-10-2009 07:21 PM in reply to: *mp
Np - Yes I did create the video - "camtasia" is a nice tool to record
applications. Reflector is invaluable. Open up the autocad assemblies and
look inside - fun stuff!
"mp" wrote in message
news:6252307@discussion.autodesk.com...
Hey cool video, did you do that? That looks like an awesome little tool to
convert languages, very helpful,
thanks for the tip.
mark

"Paul Richardson" wrote in message
news:6251112@discussion.autodesk.com...
Here is a vdeo showing how to use reflector to convert code.
http://www.screencast.com/t/KWWCdmmH

snip
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.