ENTUPD in VB.NET

ENTUPD in VB.NET

Jedimaster
Collaborator Collaborator
1,746 Views
14 Replies
Message 1 of 15

ENTUPD in VB.NET

Jedimaster
Collaborator
Collaborator

I have a routine that updates text. In lisp there is ENTUPD that allows you to visually update or regenerate an object. Below is the code I have to update the text objects. Right now I have a general REGEN whole drawing at end of routine.  I would like to regen the object on the fly without having to regen whole drawing.

 

Dim CurrentDrawing As Autodesk.AutoCAD.ApplicationServices.Document = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument
CurrentDrawing.LockDocument()
Dim acTypValAr(0) As Autodesk.AutoCAD.DatabaseServices.TypedValue
acTypValAr.SetValue(New Autodesk.AutoCAD.DatabaseServices.TypedValue(Autodesk.AutoCAD.DatabaseServices.DxfCode.Start, "TEXT"), 0)
Dim acSelFtr As Autodesk.AutoCAD.EditorInput.SelectionFilter = New Autodesk.AutoCAD.EditorInput.SelectionFilter(acTypValAr)
Dim ed As Autodesk.AutoCAD.EditorInput.Editor = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.Editor
Dim acSSPrompt As Autodesk.AutoCAD.EditorInput.PromptSelectionResult
acSSPrompt = ed.SelectAll(acSelFtr)
If acSSPrompt.Status = Autodesk.AutoCAD.EditorInput.PromptStatus.OK Then
Dim acSSet As Autodesk.AutoCAD.EditorInput.SelectionSet = acSSPrompt.Value
Using Trans As Autodesk.AutoCAD.DatabaseServices.Transaction = CurrentDrawing.Database.TransactionManager.StartTransaction
For Each selObj In acSSet
Dim x As ObjectId = selObj.ObjectId
Dim textObj As Autodesk.AutoCAD.DatabaseServices.DBText = Trans.GetObject(selObj.ObjectId, Autodesk.AutoCAD.DatabaseServices.OpenMode.ForWrite, False, True)
Dim OldTextString As String = textObj.TextString
Dim NewTextString As String = Replace(OldTextString, CurrentFind, CurrentReplace, 1, -1, CompareMethod.Text)
If OldTextString <> NewTextString Then
textObj.TextString = NewTextString
End If
textObj.Dispose()
Next
Trans.Commit()
End Using
End If

 

Thank in advance for any input.

0 Likes
Accepted solutions (1)
1,747 Views
14 Replies
Replies (14)
Message 2 of 15

ActivistInvestor
Mentor
Mentor
If you can post properly-written code that does not use fully-qualified identifiers, I'll be happy to have a look at it.

It's too hard to read code like that.
0 Likes
Message 3 of 15

Jedimaster
Collaborator
Collaborator

Sorry I do not like to use imports because I clip from application to application. This way I doing have sift through Imports since their are too may ways to skin a cat.

 

 

Imports Autodesk.AutoCAD.ApplicationServices
Imports Autodesk.AutoCAD.DatabaseServices
Imports Autodesk.AutoCAD.EditorInput
Public Class Class1
Public Sub TestFix()
' Get and lock active drawing
Dim CurrentDrawing As Document = Application.DocumentManager.MdiActiveDocument
CurrentDrawing.LockDocument()
' Create Selection set of a Text entities
Dim acTypValAr(0) As Autodesk.AutoCAD.DatabaseServices.TypedValue
acTypValAr.SetValue(New TypedValue(DxfCode.Start, "TEXT"), 0)
Dim acSelFtr As SelectionFilter = New SelectionFilter(acTypValAr)
Dim ed As Editor = Application.DocumentManager.MdiActiveDocument.Editor
Dim acSSPrompt As PromptSelectionResult
acSSPrompt = ed.SelectAll(acSelFtr)
' Check to make sue there is a valid selection set
If acSSPrompt.Status = PromptStatus.OK Then
Dim acSSet As SelectionSet = acSSPrompt.Value
' Start Transaction
Using Trans As Transaction = CurrentDrawing.Database.TransactionManager.StartTransaction
' Enumerate selection set
For Each selObj In acSSet
' Set as DBText object
Dim textObj As DBText = Trans.GetObject(selObj.ObjectId, OpenMode.ForWrite, False, True)
' Get current text string
Dim OldTextString As String = textObj.TextString
Dim NewTextString As String = Replace(OldTextString, CurrentFind, CurrentReplace, 1, -1, CompareMethod.Text)
' Replace old string with new string
If OldTextString <> NewTextString Then
textObj.TextString = NewTextString
End If
textObj.Dispose()
Next
Trans.Commit() ' Complete Tranaction
End Using
End If
End Sub
End Class

0 Likes
Message 4 of 15

ActivistInvestor
Mentor
Mentor

@Jedimaster wrote:

Sorry I do not like to use imports because I clip from application to application. This way I doing have sift through Imports since their are too may ways to skin a cat.

.


 

You also don't use the InsertCode button to insert the code formatted with indentation, which also makes it more difficult to read.

 

You can choose to write code any way you wish, but don't expect too many others to put the effort into trying to read it.

 

Your code doesn't unlock the document (dispose the object returned by LockDocument()), and it doesn't use the TransactionManager of the Document (instead, it uses the TransactionManager of the Database).

Message 5 of 15

Jedimaster
Collaborator
Collaborator

Thanks did not even know that feature was there.

 

Imports Autodesk.AutoCAD.ApplicationServices
Imports Autodesk.AutoCAD.DatabaseServices
Imports Autodesk.AutoCAD.EditorInput
Public Class Class1 Public Sub TestFix() ' Get and lock active drawing Dim CurrentDrawing As Document = Application.DocumentManager.MdiActiveDocument CurrentDrawing.LockDocument() ' Create Selection set of a Text entities Dim acTypValAr(0) As Autodesk.AutoCAD.DatabaseServices.TypedValue acTypValAr.SetValue(New TypedValue(DxfCode.Start, "TEXT"), 0) Dim acSelFtr As SelectionFilter = New SelectionFilter(acTypValAr) Dim ed As Editor = Application.DocumentManager.MdiActiveDocument.Editor Dim acSSPrompt As PromptSelectionResult acSSPrompt = ed.SelectAll(acSelFtr) ' Check to make sue there is a valid selection set If acSSPrompt.Status = PromptStatus.OK Then Dim acSSet As SelectionSet = acSSPrompt.Value ' Start Transaction Using Trans As Transaction = CurrentDrawing.Database.TransactionManager.StartTransaction ' Enumerate selection set For Each selObj In acSSet ' Set as DBText object Dim textObj As DBText = Trans.GetObject(selObj.ObjectId, OpenMode.ForWrite, False, True) ' Get current text string Dim OldTextString As String = textObj.TextString Dim NewTextString As String = Replace(OldTextString, CurrentFind, CurrentReplace, 1, -1, CompareMethod.Text) ' Replace old string with new string If OldTextString <> NewTextString Then textObj.TextString = NewTextString End If textObj.Dispose() Next Trans.Commit() ' Complete Tranaction End Using End If End Sub End Class
0 Likes
Message 6 of 15

Jedimaster
Collaborator
Collaborator

If I don't lock the document it errors saying OpenMode.ForWrite is in the wrong state. I am locking the document to set it active in a multiple document situation. I have the object dispose to release the memory.

 

 

 

 

 

0 Likes
Message 7 of 15

ActivistInvestor
Mentor
Mentor

@Jedimaster wrote:

If I don't lock the document it errors saying OpenMode.ForWrite is in the wrong state. I am locking the document to set it active in a multiple document situation. I have the object dispose to release the memory.

 

 

 

 

 


You need to go back and my reply again. I didn't say your code doesn't lock the document.

 

Go read it again.

0 Likes
Message 8 of 15

Jedimaster
Collaborator
Collaborator

How do you unlock the drawing? This is a small snippet of a larger application. I am opening multiple drawings from a list. The lock is to set the drawing active creating the dwl file in order to edit. It is not setting the file to read-only. Anyhow the code works. The small part that is shown cycles thru all of the text in the drawing to check against a list to find and replace that can be hundreds of lines long. This takes a little while. I have  a progress bar with abort button to assure the user that their is something happening. I want to be able refresh the object changed much like ENTUPD in lisp. I am somewhat new to .vb.net and have history in lisp and vba.

0 Likes
Message 9 of 15

ActivistInvestor
Mentor
Mentor

@Jedimaster wrote:

How do you unlock the drawing? This is a small snippet of a larger application. I am opening multiple drawings from a list. The lock is to set the drawing active creating the dwl file in order to edit. It is not setting the file to read-only. Anyhow the code works. The small part that is shown cycles thru all of the text in the drawing to check against a list to find and replace that can be hundreds of lines long. This takes a little while. I have  a progress bar with abort button to assure the user that their is something happening. I want to be able refresh the object changed much like ENTUPD in lisp. I am somewhat new to .vb.net and have history in lisp and vba.


I didn't write 'unlock the drawing', I wrote unlock the Document.

 

Locking a document has nothing to do with DWL files or file permissions. Where did you get that idea from?

 

The LockDocument() method returns an object. You have to dispose that object to unlock the document.

 

    Using doclock as DocumentLock = document.LockDocument()

      '' document is locked here

    End Using    '' document is unlocked here.



    

0 Likes
Message 10 of 15

Jedimaster
Collaborator
Collaborator

For get the code above. Do you know away to regen an individual object much like ENTUPD?

0 Likes
Message 11 of 15

Jedimaster
Collaborator
Collaborator

here is about 

 

Lock a database before modifying an object

 

http://help.autodesk.com/view/ACD/2016/ENU/?guid=GUID-A2CD7540-69C5-4085-BCE8-2A8ACE16BFDD

0 Likes
Message 12 of 15

Jedimaster
Collaborator
Collaborator

From AutoDesk AutoCAD Help

 

Lock and Unlock a Document (.NET)
Requests to modify objects or access AutoCAD can occur in any context, and coming from any number of applications. To prevent conflicts with other requests, you are responsible for locking a document before you modify it. Failure to lock the document in certain contexts will cause a lock violation during the modification of the database. You want to lock the document when your application:

Interacts with AutoCAD from a modeless dialog box
Accesses a loaded document other than the current document
Used as a COM server
Registers a command with the Session command flag
For example, when adding an entity to Model or Paper space in a document other than the current document, the document needs to be locked. You use the LockDocument method of the Database object you want to lock. When the LockDocument method is called, a DocumentLock object is returned.

Once you are done modifying the locked database, you need to unlock the database. To unlock the database, you call the Dispose method of the DocumentLock object. You can also use the Using statement with the DocumentLock object, once the Using statement ends the database is unlocked.

Note: When working in the context of a command that does not use the Session command flag, you do not need to lock the database for the current document before it is modified.
Lock a database before modifying an object
This example creates a new document and then draws a circle in it. After the document is created, the database for the new document is locked and then a circle is added to it. After the circle is added, the database is unlocked and the associated document window is set current

0 Likes
Message 13 of 15

dgorsman
Consultant
Consultant

I think there may be some misunderstandings here.  (entupd ...) function doesn't REGEN the object, it updates the data which defines the object.  And locking the document doesn't "lock" the file for DWL/DWL2 files, it sets a flag on the drawing database to let other processes know they have to wait to make changes.

----------------------------------
If you are going to fly by the seat of your pants, expect friction burns.
"I don't know" is the beginning of knowledge, not the end.


0 Likes
Message 14 of 15

Jedimaster
Collaborator
Collaborator

Thank you for the responses. I just want to regenerate the object from a selection set I just updated.

 

Autocad is a single thread process. I have multiple documents open calling one document from another if I create (saveas) and open the new drawing. I have to activate that drawing. I know there is and an activedrawing.active under the applications process but believe this an antiquated method. I so I do the more "proper" method  MdiActiveDocument LockDocument. (Back to the too many ways to skin a cat) It does affect the DWL file because I watch the editing directory. I have three files open at a time. I open a base file because batch routines do not like you to close the active file. I open a file file from a list of files. Set the open file active. Do a saveas to a third file. Open the third file set it active. Do my business save. Activate the base file close the other two files and go on tho the next in the list.

 

But I hugely digress, when operating in LISP, yes, ENTUPD  does not regenerate the object it does update the database and therefore regenerate the visual portion drawing on the fly. In .NET it updates the file but does not give the user the warm fuzzy feeling of see something on the screen. My routine is grabbing all the text, mtext, attributes, attribute definitions, and tables. Comparing and replacing when necessary text stings against a tab delimited text file (that can be hundreds of lines lines long). Granted it only take 15 seconds to a minute to process a drawing, when you have hundreds of drawings you are processing that's a long time. So I have  a progress bar ,with an abort button, to assure the user that it has not locked up . As I said earlier the code works. I just do not want the user to have to wait till a split second before the drawing saves an closes to see if anything is happening. If I did not have a regen just before closing you would have thought the drawing had not changed at all.

0 Likes
Message 15 of 15

ActivistInvestor
Mentor
Mentor
Accepted solution

@dgorsman wrote:

I think there may be some misunderstandings here.  (entupd ...) function doesn't REGEN the object, it updates the data which defines the object.  And locking the document doesn't "lock" the file for DWL/DWL2 files, it sets a flag on the drawing database to let other processes know they have to wait to make changes.


(entupd) doesn't 'update the data which defines the object', and it most certainly does 'REGEN the object' (regenerates the object's display graphics), but it also forces AutoCAD to update the display.

 

So, the confusion is that both of you don't seem to understand that updating an entity's display graphics (e.g., 'REGEN the entity) and updating the display, are two different things. (entupd) does both, but there is no managed equivalent to it

 

Getting the display to update requires that the document be unlocked, and also requires that the Transaction used be from the Document's TransactionManager, not the Database's TransactionManager, both of which I made clear to the OP above, but he still doesn't seem to get it.

 

Even if he did both of those things, that alone isn't going to update the display. He also has to call System.Windows.Forms.Application.DoEvents() from his code in order to force AutoCAD to process any pending windows messages, which will also trigger a display refresh.

0 Likes