.NET
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Change .NET Selection code to specific block

4 REPLIES 4
SOLVED
Reply
Message 1 of 5
TTIII
777 Views, 4 Replies

Change .NET Selection code to specific block

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

 

4 REPLIES 4
Message 2 of 5
mzakiralam
in reply to: TTIII

Can you explain your Problem more clearly? What do you want from your drawing? you can provide a example as well
Message 3 of 5
TTIII
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.

Message 4 of 5
mzakiralam
in reply to: TTIII

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

Message 5 of 5
TTIII
in reply to: mzakiralam

Thanks! This works perfectly.

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk DevCon in Munich May 28-29th


Autodesk Design & Make Report

”Boost