.NET

.NET

Reply
Active Contributor
tony.tomison.iii
Posts: 32
Registered: ‎05-12-2014
Message 1 of 5 (121 Views)
Accepted Solution

Change .NET Selection code to specific block

121 Views, 4 Replies
07-21-2014 06:08 AM

Hello All,

 

I found this code at Kean Walmsley's blog [here]

It works just fine, however I'm having some trouble adapting the code.

 

I do not want to pick a block, I want to use a specific named block.
e.g (blk.Name = "MyBlock" or Blk.Name = "MyOtherBlock")

 

I started commenting some of it, but when I get Dim selSet As SelectionSet = res.Value I get lost.

 

How can this be done?

 

Imports Autodesk.AutoCAD
Imports Autodesk.AutoCAD.Runtime
Imports Autodesk.AutoCAD.ApplicationServices
Imports Autodesk.AutoCAD.DatabaseServices
Imports Autodesk.AutoCAD.EditorInput

Namespace MyApplication
    
    Public Class DumpAttributes
        
        <CommandMethod("LISTATT")>  _
        Public Sub ListAttributes()
            Dim ed As Editor = Application.DocumentManager.MdiActiveDocument.Editor
            Dim db As Database = HostApplicationServices.WorkingDatabase
            Dim tr As Transaction = db.TransactionManager.StartTransaction
            ' Start the transaction
            Try 
                ' Build a filt
Spoiler
 

 

er list so that only
                ' block references are selected
                Dim filList() As TypedValue = New TypedValue() {New TypedValue(CType(DxfCode.Start,Integer), "INSERT")}
                Dim filter As SelectionFilter = New SelectionFilter(filList)
                Dim opts As PromptSelectionOptions = New PromptSelectionOptions
                opts.MessageForAdding = "Select block references: "
                Dim res As PromptSelectionResult = ed.GetSelection(opts, filter)
                ' Do nothing if selection is unsuccessful
                If (res.Status <> PromptStatus.OK) Then
                    Return
                End If
                Dim selSet As SelectionSet = res.Value
                Dim idArray() As ObjectId = selSet.GetObjectIds
                For Each blkId As ObjectId In idArray
                    Dim blkRef As BlockReference = CType(tr.GetObject(blkId, OpenMode.ForRead),BlockReference)
                    Dim btr As BlockTableRecord = CType(tr.GetObject(blkRef.BlockTableRecord, OpenMode.ForRead),BlockTableRecord)
                    ed.WriteMessage((""& vbLf&"Block: " + btr.Name))
                    btr.Dispose
                    Dim attCol As AttributeCollection = blkRef.AttributeCollection
                    For Each attId As ObjectId In attCol
                        Dim attRef As AttributeReference = CType(tr.GetObject(attId, OpenMode.ForRead),AttributeReference)
                        Dim str As String = (""& vbLf&"  Attribute Tag: "  _
                                    + (attRef.Tag + (""& vbLf&"    Attribute String: " + attRef.TextString)))
                        ed.WriteMessage(str)
                    Next
                Next
                tr.Commit
            Catch ex As Autodesk.AutoCAD.Runtime.Exception
                ed.WriteMessage(("Exception: " + ex.Message))
            Finally
                tr.Dispose
            End Try
        End Sub
    End Class
End Namespace

 

ok you can try with following code.

 

With the below routine, you can get object ids of all block.

public static ObjectIdCollection BlockReferenceInModelSpace(Editor acEd)
{
//get block reference
TypedValue[] tvs = new TypedValue[1];
tvs.SetValue(new TypedValue(DxfCode.Start, "INSERT"), 0);
SelectionFilter sf = new SelectionFilter(tvs);
PromptSelectionResult psr = acEd.SelectAll(sf);
if (psr.Status == PromptStatus.OK) {
return new ObjectIdCollection(psr.Value.GetObjectIds());
} else {
return new ObjectIdCollection();
}
}

 

main sub:

 

public void TEST_Attribute()
{
Document doc = Application.DocumentManager.MdiActiveDocument;
Database db = doc.Database;
Editor ed = doc.Editor;
//get object id's of all block in the active drawing
ObjectIdCollection objIdColl = BlockReferenceInModelSpace(ed);
//lock document
using (DocumentLock docLock = doc.LockDocument()) {
//start transaction
using (Transaction tx = db.TransactionManager.StartTransaction()) {
//iterate object id
foreach (ObjectId objId in objIdColl) {
//get the obeject
Entity ent = tx.GetObject(objId, OpenMode.ForRead);
if (ent is BlockReference) {
//casting block reference
BlockReference br = ent as BlockReference;
//'now check the block name here
if (br.Name == "MyBlock") {
//' if block name satify then check atttrubute
foreach (ObjectId attId in br.AttributeCollection) {
//do as you like
}
}
}
}
}
}
}

  you can try with this code. hopefully would help to serve your purpose

Mentor
mzakiralam
Posts: 231
Registered: ‎11-09-2012
Message 2 of 5 (112 Views)

Re: Change .NET Selection code to specific block

07-21-2014 07:00 AM in reply to: tony.tomison.iii
Can you explain your Problem more clearly? What do you want from your drawing? you can provide a example as well
Active Contributor
tony.tomison.iii
Posts: 32
Registered: ‎05-12-2014
Message 3 of 5 (109 Views)

Re: Change .NET Selection code to specific block

07-21-2014 07:03 AM in reply to: mzakiralam

I'm trying to automate it to list the attribues from a list of specific blocks.

I dont want it to prompt the user to select a block.

Mentor
mzakiralam
Posts: 231
Registered: ‎11-09-2012
Message 4 of 5 (101 Views)

Re: Change .NET Selection code to specific block

07-21-2014 07:55 AM in reply to: tony.tomison.iii

ok you can try with following code.

 

With the below routine, you can get object ids of all block.

public static ObjectIdCollection BlockReferenceInModelSpace(Editor acEd)
{
	//get block reference 
	TypedValue[] tvs = new TypedValue[1];
	tvs.SetValue(new TypedValue(DxfCode.Start, "INSERT"), 0);
	SelectionFilter sf = new SelectionFilter(tvs);
	PromptSelectionResult psr = acEd.SelectAll(sf);
	if (psr.Status == PromptStatus.OK) {
		return new ObjectIdCollection(psr.Value.GetObjectIds());
	} else {
		return new ObjectIdCollection();
	}
}

 

main sub:

 

public void TEST_Attribute()
{
	Document doc = Application.DocumentManager.MdiActiveDocument;
	Database db = doc.Database;
	Editor ed = doc.Editor;
	//get object id's of all block in the active drawing
	ObjectIdCollection objIdColl = BlockReferenceInModelSpace(ed);
	//lock document
	using (DocumentLock docLock = doc.LockDocument()) {
		//start transaction
		using (Transaction tx = db.TransactionManager.StartTransaction()) {
			//iterate object id
			foreach (ObjectId objId in objIdColl) {
				//get the obeject
				Entity ent = tx.GetObject(objId, OpenMode.ForRead);
				if (ent is BlockReference) {
					//casting block reference
					BlockReference br = ent as BlockReference;
					//'now check the block name here
					if (br.Name == "MyBlock") {
						//' if block name  satify then check atttrubute
						foreach (ObjectId attId in br.AttributeCollection) {
							//do as you like
						}
					}

				}
			}
		}

	}

}

  you can try with this code. hopefully would help to serve your purpose

Active Contributor
tony.tomison.iii
Posts: 32
Registered: ‎05-12-2014
Message 5 of 5 (89 Views)

Re: Change .NET Selection code to specific block

07-21-2014 09:04 AM in reply to: mzakiralam
Thanks! This works perfectly.
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.