I'm having some trouble figuring out how to fix this problem I have and I'm not sure what the best way is to attack it. I have a large set of drawings that have these random strings of underscores strewn throughout the drawing (which look like random lines scattered all around when the drawing is printed - and make it confusing to look at), and so I'm trying to write a function that will iterate through the drawing and find all the text strings that contain ONLY underscores and then erase those text strings.
The problem is that some of the text strings are regular text entities and some are block attributes. So - the text entities I would like to erase, and the block attributes I would like to delete from the block.
I'm thinking that once I find a text entity, I could test the first character to see if it is an underscore, and if so, then I can loop through the contents of the whole string and if nothing besides underscores are found, then I can delete the whole entity (or delete from the block if it is a block attribute). What I don't know how to do is loop through the drawing to find those entities and how to do that test on the text string - and then erase them if necessary. It seems to me that the regular text entities might not be too difficult once I wrap my mind around it, but I'm not sure at all how to delete block attributes this way once I find them in the drawing.
I'm using AutoCAD 2012 and I'm coding in C#.
Does anyone have ideas on how to do this? Or could you possibly point me towards some information that could be helpful to solve this? I've been searching all over the internet for the last few hours and I haven't found very much information to help me understand this. So - I would appreciate any help that anyone could give!
In order to select some specific entities, you can do a search for filter entities, as for detect some char or substring in a string, i recomend you to take a look to Regular Expressions, tip: this regex should find underscore (n times or 0): "/_*/".
Some links to check out:
I've attached a sample that contains some of the text and a few blocks that have the attributes I'm trying to remove.
You ask about using the Find command - and yes, I can open the drawing and do a search for the text I'm looking for - but I'm trying to write C# code that does this search for me. How would you write code that performs like this find command?
And then the next problem I have is this - once the program doing the "find" function actually finds an instance of this text, how do I write code to erase the entity that it found? And if the instance it finds is in a block, how do I remove that block attribute?
I've tried playing around with conditional selection (filters) a little - but there's two things I don't understand. 1) I don't know how to use that with block attributes. If it finds an attribute that has my text contained in it, it doesn't seem to add anything to the selection set because I'm guessing it can only add the whole block and not just that specific attribute - unless there's some way of adding just specific block attributes from different blocks to a single selection set. 2) If I search through the drawing and find all the instances of this text, how do I write code that erases everything inside the selection set? I've had trouble finding code that erases my selection set.
Thanks for your input!
For search and destroy text you can use somethimg like this:
Public Sub DelTextWithChar(chr As String) Dim acDoc As Document = Application.DocumentManager.MdiActiveDocument Dim acCurDb As Database = acDoc.Database Using acTrans As Transaction = acCurDb.TransactionManager.StartTransaction() Dim acTypValAr(1) As TypedValue acTypValAr.SetValue(New TypedValue(DxfCode.Start, "TEXT"), 0) acTypValAr.SetValue(New TypedValue(DxfCode.Text, "*" + chr + "*"), 1) Dim acSelFtr As SelectionFilter = New SelectionFilter(acTypValAr) Dim acSSPrompt As PromptSelectionResult Dim ed As Editor = Application.DocumentManager.MdiActiveDocument.Edit
or acSSPrompt = ed.SelectAll(acSelFtr) If acSSPrompt.Status = PromptStatus.OK Then Dim acSSet As SelectionSet = acSSPrompt.Value Dim objids() As ObjectId objids = acSSet.GetObjectIds For Each objid As ObjectId In objids Dim obj As DBObject = acTrans.GetObject(objid, OpenMode.ForWrite) obj.Erase() Next End If acTrans.Commit() End Using End Sub <CommandMethod("DTWU")> _ Public Sub DTWU() DelTextWithChar("_") End Sub End Class
To search and destroy attributes it's more complicated, I suggest you to update the values of the ofenders attribs to a null string, other alternative a lot more complicated with possible many colateral damage is to change the block definitions to eliminate the ofenders attributes. There are others alternatives like replacing the existing blocks references with new insert with specific attribute values but should be even more complicated.
In order to update attribute reference values the following pseudo code could help you, it refers to helpers function from this post from Kean's blog.
1.- Get all block references in a selection set
2.- If the block has attributes (obtained via someblockref.AttributeCollection) iterate the collection to find all the attribs with an underscore in its value, put it's objectIds in some collection
3.- Use UpdateAttributesInDatabase from the mentioned post to set the attrib value to a null string for each objectid in the collection.