.NET

.NET

Reply
Active Contributor
kennedyb
Posts: 36
Registered: ‎01-08-2007
Message 1 of 32 (682 Views)
Accepted Solution

Finding & Replacing Mtext in a Block using VB.net?

682 Views, 31 Replies
11-25-2013 11:42 AM

Hi everyone,

 

I've been trying to find help on replacing Mtext in a drawing border of mine. The drawing border is a block that has constant attributes that I have a vb.net dll that can edit the constant attributes.

 

I'm trying to add this to that dll, I would like this to work in such a way as to not have the user involved. My thought was to have the code executed when the form was loaded to edit the values in the titleblock. The code would look to see if the Mtext existed in the border and if so replace it with the correct Mtext. If the correct Mtext is there it would exit the Sub.

 

I'm have a hard time figuring out how to use the Transaction concept. I've tried to modify an exisitng function in the VB.net dll to do this change.

 

As you can see in this example code, I'm not very good at figuring out how to modify it to my needs. I'm still not sure how some of these "BIG PICTURE" concepts work?

 

Do I need one function to read and another function to write? Do I need a Sub to strat to function(s)?  I understand most of  form code.

 

Any pointers in the correct direction would be appreciated....

 

PublicSharedFunction ReadMtextFromBTR(ByVal strName AsMText) AsMTextDim MtxtList AsList(Of Text.StringBuilder)

 

Dim oDwg AsDocument = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument

 

Dim oDB As DatabaseServices.Database= oDwg.Database

 

Dim oTransMgr As DatabaseServices.TransactionManager= oDB.TransactionManager

 

Dim oTrans As DatabaseServices.Transaction= oTransMgr.StartTransaction

 

UsingoTrans

 

Dim oDatabaseObject AsDBObject = oDB.BlockTableId.GetObject(DatabaseServices.OpenMode.ForRead)

 

Dim oBlockTable As DatabaseServices.BlockTable = DirectCast(oDatabaseObject, BlockTable)

 

Dim oBTRE As DatabaseServices.SymbolTableEnumerator= oBlockTable.GetEnumerator

 

WhileoBTRE.MoveNext

 

Dim oDBObject AsDBObject = oBTRE.Current.GetObject(DatabaseServices.OpenMode.ForRead)

 

Dim oBTR As DatabaseServices.BlockTableRecord = DirectCast(oDBObject, BlockTableRecord)

 

If oBTR.Name = strName.Text ThenForEach oObjectID AsObjectIdInoBTR

 

Dim oEnt AsDBObject = oTrans.GetObject(oObjectID, OpenMode.ForRead)

 

'If oEnt.GetType.ToString = "Autodesk.AutoCAD.DatabaseServices.AttributeDefinition" ThenIfTypeOf oEnt Is Autodesk.AutoCAD.DatabaseServices.MTextThen

oEnt.UpgradeOpen()

If oEnt.ToString >= ("FirstEnergy ") ThenSelectCaseCase"FirstEnergy GENERATION CORP."ReturnstrName

 

Case"FirstEnergy _"

GENERATION, LLC"

Return2

 

Case ElseThrowNewException("The border did not match any of the defined types.")

 

EndSelectEndIfEndIfNextEndIfEndWhile'oTrans.Commit()EndUsing

oTrans.Dispose()

oTransMgr.Dispose()

oDB.Dispose()

Return MtxtList

 

 

 

 

 

mzakiralam,

 

After walking away and calming down. I studied the code You and _gile showed me.  I found the error!!!

 

I needed to change the AddHandler from this AddHandler Application.DocumentManager.DocumentCreated, AddressOf ReplaceMtextinTitleBlock to

AddHandler Application.DocumentManager.DocumentActivated, AddressOf ReplaceMtextinTitleBlock.

 

Thanks to everyone for the help!!!!!

 

I will Kudos to all involved!!!!!

 

 

 

THANK YOU THANK YOU THANK YOU!!!!!!!!!!!!

ADN Support Specialist
StephenPreston
Posts: 429
Registered: ‎05-22-2006
Message 2 of 32 (665 Views)

Re: Finding & Replacing Mtext in a Block using VB.net?

11-25-2013 04:49 PM in reply to: kennedyb

So your main question is how to better understand how to better understand and use the .NET API? If so, I recommend you work through the .NET Training Labs we have posted here - www.autodesk.com/developautocad (under the 'Learning' section. Note that there is also a 'DevTV' link to the left of the links to the material that includes a set of videos talking therough each of the training labs. If you're very new to programming, then the 'My First Plug-in' tutorial on the same page may be helpful too.

 

BTW In your code below, you seem to have commented out the 'trans.Commit()' line, which means your transaction will be aborted when it is Disposed and any changes you made to the drawing since you started the transaction will be rolled back. You should also look in the tutorials I mention how you can use For Each...Next instead of GetEnumerator/MoveNext - its a lot simpler.

 

Cheers,

Stephen Preston
Autodesk Developer Network
Mentor
mzakiralam
Posts: 231
Registered: ‎11-09-2012
Message 3 of 32 (643 Views)

Re: Finding & Replacing Mtext in a Block using VB.net?

11-26-2013 03:06 AM in reply to: kennedyb

To get all the mtext in a block, you can use selection filter. Selection filter will accumulate all entity according to your selection. Below I have create a code snip which will gather all the mtext in the model space. Please see below.

 Public Shared Function GetMTextBTR(acEd As Editor) As ObjectIdCollection
        Dim tvs(0) As TypedValue
        tvs.SetValue(New TypedValue(DxfCode.Start, "MTEXT"), 0)
        Dim sf As New SelectionFilter(tvs)
        Dim psr As PromptSelectionResult = acEd.SelectAll(sf)
        If psr.Status = PromptStatus.OK Then
            Return New ObjectIdCollection(psr.Value.GetObjectIds())
        Else
            Return New ObjectIdCollection()
        End If
    End Function
    <CommandMethod("tst")> Public Sub TESTMtext()
        Dim doc As Document = Application.DocumentManager.MdiActiveDocument
        Dim db As Database = doc.Database
        Dim ed As Editor = doc.Editor
        Using tx As Transaction = db.TransactionManager.StartTransaction()
            Dim bt As BlockTable = tx.GetObject(db.BlockTableId, OpenMode.ForRead)
            Dim ms As BlockTableRecord = tx.GetObject(bt(BlockTableRecord.ModelSpace), OpenMode.ForRead)
            Dim objIdColl As ObjectIdCollection = GetMTextBTR(ed)
            For Each objId As ObjectId In objIdColl
                'DO SOMETHING
            Next
            tx.Commit()
        End Using
    End Sub

 

Active Contributor
kennedyb
Posts: 36
Registered: ‎01-08-2007
Message 4 of 32 (634 Views)

Re: Finding & Replacing Mtext in a Block using VB.net?

11-26-2013 06:23 AM in reply to: mzakiralam

mzakiralam

 

Thank you for the Code snippet.

In your example code, I don't have a grasp on what I should be placing for code in the "DO Something" area.

 

I've tried to use a "If statement" to determine if the particular Mtext is what I want to change. I can't seem to unerstand how to do this part. (see below)

 

 

 

The "Lightbulb" is starting to glow :smileylol: I see the function piece in the command sub.

 

 

For some reason your supplied code wasn't liked "as is". I had to change it to this

 

Using tx AsTransaction= db.TransactionManager.StartTransaction()

 

Dim bt AsBlockTable = CType(tx.GetObject(db.BlockTableId, OpenMode.ForRead), BlockTable)

 

Dim ms AsBlockTableRecord = CType(tx.GetObject(bt(BlockTableRecord.ModelSpace), OpenMode.ForRead), BlockTableRecord)

 

Dim objIdColl AsObjectIdCollection = FirstEnergy.AutoCADFunctions.GetMTextBTR(ed)

 

ForEach objId AsObjectIdIn objIdColl 'DO SOMETHING Next If objId.GetObject(ms.Equals("TEST") Then

MsgBox(

"you found it")

 

Else

MsgBox(

"that's not it")

 

EndIfNext 

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

Re: Finding & Replacing Mtext in a Block using VB.net?

11-26-2013 07:02 AM in reply to: kennedyb

I was not sure what you need to do. This is why after  getting the objectId , I have written "Do Something" :smileywink:. Is it now working for you?

 

if not please see my below code and further explanation. Suppose I have created three MTEXT in my drawing and MTEXT are test1, test2 and test3. If test1 is found it will give a message like "found test1" and so on for others. Please see below code

 

 <CommandMethod("tst")> Public Sub TESTMtext()
        Dim doc As Document = Application.DocumentManager.MdiActiveDocument
        Dim db As Database = doc.Database
        Dim ed As Editor = doc.Editor
        Using tx As Transaction = db.TransactionManager.StartTransaction()
            Dim bt As BlockTable = tx.GetObject(db.BlockTableId, OpenMode.ForRead)
            Dim ms As BlockTableRecord = tx.GetObject(bt(BlockTableRecord.ModelSpace), OpenMode.ForRead)
            Dim objIdColl As ObjectIdCollection = GetMTextBTR(ed)
            For Each objId As ObjectId In objIdColl
                'get the Mtext from objectID
                Dim mtxt As MText = tx.GetObject(objId, OpenMode.ForWrite)
                'check mtext content
                If mtxt.Contents = "test1" Then
                    MsgBox("found test1")
                ElseIf mtxt.Contents = "test2" Then
                    MsgBox("found test2")
                ElseIf mtxt.Contents = "test3" Then
                    MsgBox("found test3")
                End If
            Next
            tx.Commit()
        End Using
    End Sub

 

Active Contributor
kennedyb
Posts: 36
Registered: ‎01-08-2007
Message 6 of 32 (619 Views)

Re: Finding & Replacing Mtext in a Block using VB.net?

11-26-2013 07:26 AM in reply to: mzakiralam

No,

 

I'm still gropeing along trying to figure out what to plug into the "Do Something". I kinda understand the Function you supplied. It is collecting object Ids that are Mtext and adding them to the editor? Or is the Function looking for something specifically called "MTEXT"?

 

What I want to do is Find this Mtext ("FirstEnergy GENERATION CORP.") and replace with ("FirstEnergy GENERATION, LLC).

 

There is only one (1) of these Mtext strings in the block reference.

Mentor
mzakiralam
Posts: 231
Registered: ‎11-09-2012
Message 7 of 32 (614 Views)

Re: Finding & Replacing Mtext in a Block using VB.net?

11-26-2013 07:39 AM in reply to: kennedyb

My function will collect all MText entities in the model space. It is not related with something Special. It will only collect objectId which DBObject are MText. After getting objectId, you can get MText . Then you can implement your purpose . According to your Need I have modified above code. Please see below. I did not try this code. But it should work

 

<CommandMethod("tst")> Public Sub TESTMtext()
        Dim doc As Document = Application.DocumentManager.MdiActiveDocument
        Dim db As Database = doc.Database
        Dim ed As Editor = doc.Editor
        Using tx As Transaction = db.TransactionManager.StartTransaction()
            Dim bt As BlockTable = tx.GetObject(db.BlockTableId, OpenMode.ForRead)
            Dim ms As BlockTableRecord = tx.GetObject(bt(BlockTableRecord.ModelSpace), OpenMode.ForRead)
            Dim objIdColl As ObjectIdCollection = GetMTextBTR(ed)
            For Each objId As ObjectId In objIdColl
                'get the Mtext from objectID
                Dim mtxt As MText = tx.GetObject(objId, OpenMode.ForWrite)
                'check mtext content
                If mtxt.Contents = "FirstEnergy GENERATION CORP." Then
                   mtxt.contents = "FirstEnergy GENERATION, LLC"
                End If
            Next
            tx.Commit()
        End Using
    End Sub

 

Active Contributor
kennedyb
Posts: 36
Registered: ‎01-08-2007
Message 8 of 32 (612 Views)

Re: Finding & Replacing Mtext in a Block using VB.net?

11-26-2013 07:43 AM in reply to: mzakiralam

OK!

 

 

Bulb getting a little brighter :smileyembarrassed: So I should be able to find said string, then replace it with new string and commit?

 

SO, if I figure out the FIND replace I can call this "Command" when the FORM loads? It will automatically search and replace if necessary?

Mentor
mzakiralam
Posts: 231
Registered: ‎11-09-2012
Message 9 of 32 (611 Views)

Re: Finding & Replacing Mtext in a Block using VB.net?

11-26-2013 07:43 AM in reply to: kennedyb
To understand properly of that function, you can have a look in below link.

http://exchange.autodesk.com/autocad/enu/online-help/browse#WS1a9193826455f5ff2566ffd511ff6f8c7ca-40...
Mentor
mzakiralam
Posts: 231
Registered: ‎11-09-2012
Message 10 of 32 (610 Views)

Re: Finding & Replacing Mtext in a Block using VB.net?

11-26-2013 07:44 AM in reply to: kennedyb
In that case you do not Need to call this command. Just put that Sub routine in the form loading Event.
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.