03-01 创建和编辑AutoCAD实体(一) 打开和关闭对象

前端之家收集整理的这篇文章主要介绍了03-01 创建和编辑AutoCAD实体(一) 打开和关闭对象前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

Open and Close Objects 打开和关闭对象

Whether you are working with objects such as lines,circles and polyline or a symbol table and its records,you need to open the object for read or write. When querying an object you want to open the object for read,but if you are going to make changes to the object you will want to open it for write.

不论是使用直线、圆和多段线这样的对象还是使用符号表及符号表记录,我们都需要以读或写的方式打开这些对象。当查询一个对象时要以读的方式打开对象;如果要对一个对象进行修改,就要以写的方式打开对象。

Topics in this section本节主题

· Work with ObjectIds 使用对象标志ObjectId

· Use Transactions with the Transaction Manager 使用事务管理器管理事务

· Open and Close Objects without the Transaction Manager 不使用事务管理器打开和关闭对象

· Upgrade and Downgrade Open Objects升级打开对象与降级打开对象

1、Work with ObjectIds 使用对象标志ObjectId

Each object contained with in the Database object is assigned several unique ids. The unique ways you can access objects are:

Database对象中包含的每个对象都被赋予了几种唯一的标志。可以用来访问对象的唯一方式有:

· Entity handle 通过实体句柄;

· ObjectId 通过ObjectId;

· Instance pointer 通过实例指针;

The most common method is to access an object by its Object Id. Object Ids work well if your projects utilize both COM interop and the managed .NET API. If you create custom AutoLISP functions,you may need to work with entity handles.

最常用方法是通过ObjectId访问对象。ObjectId标志在项目同时使用COM互操作和托管.NET API的情况下都能很好地工作。如果创建自定义AutoLISP函数,就需要使用实体句柄来访问对象。

Handles are persistent between AutoCAD sessions,so they are the best way of accessing objects if you need to export drawing information to an external file which might later need to be used to update the drawing. The ObjectId of an object in a database exists only while the database is loaded into memory. Once the database is closed,the Object Ids assigned to an object no longer exist and maybe different the next time the database is opened.

句柄存在于AutoCAD会话之间,因此,如果我们需要将图形信息导出到一个外部文件,以便随后用于更新图形,这时使用实体句柄访问对象是最好的方式。存在于数据库中的对象ObjectId只在数据库加载到内存中时才存在。一旦数据库关闭,赋予对象的ObjectId就不存在了,并且下次打开数据库时可能为该对象赋予了一个不同的ObjectId。

Obtain an Object Id 获取对象的ObjectId

As you work with objects,you will need to obtain an Object Id first before you can open the object to query or edit it. An Object Id is assigned to an existing object in the database when the drawing file is opened,and new objects are assigned Object Ids when they are first created. An Object ID is commonly obtained for an existing object in the database by:

与对象打交道,需要在打开对象对其进行查询或编辑前先获得该对象的ObjectId。图形文件打开时,数据库中已存在对象就被赋予一个ObjectId,新对象在第一次创建时被赋予ObjectId。数据库中已存在对象的ObjectId通常通过下列方式获得:

· Using a member property of the Database object,such as Clayer which retrieves the Object ID for the current layer 使用Database对象的成员属性,如Clayer属性用来提取当前图层的ObjectId;

· Iterating a symbol table,such as the Layer symbol table 遍历符号表,如图层符号表;

Open an Object 打开对象

Once an Object Id is obtained,the GetObject function is used to open the object assigned the given Object Id. An object can be opened in one of the following modes:

一旦得到ObjectId,就可以使用GetObject函数打开已知ObjectId的对象。打开对象的方式可以使用下列之一:

· Read. Opens an object for read. 以读的方式打开对象;

· Write. Opens an object for write if it is not already open. 对还没打开的对象以写的方式打开;

· Notify. Opens an object for notification when it is closed,open for read,or open for write,but not when it is already open for notify. For more information on notifications,see Use Events. 以通知方式打开对象,用于当对象已经关闭、已经以读的方式打开或已经以写的方式打开时,但已经以通知方式打开了时就不必了。更多关于通知内容,见使用事件一章。

You should open an object in the mode that is best for the situation in which the object will be accessed. opening an object for write introduces additional overhead than you might need due to the creation of undo records. If you are unsure if the object you are opening is the one you want to work with,you should open it for read and then use the UpgradeOpen function to change from read to write mode. For more information on using the UpgradeOpen function,see Upgrade and Downgrade Open Objects.

我们应以对访问对象所处情境最好的方式打开对象。以写的方式打开对象会产生比你可能需要的还多的额外开销,原因是这时会创建撤销记录。如果不能确定正要打开的对象就是你要使用的,应该以读的方式打开,然后使用UpgrateOpen方法将读模式修改为写模式。关于使用UpgrateOpen方法的更多内容,请见升级打开对象与降级打开对象一节。

Both the GetObject and Open functions return an object. When working with some programming languages,you will need to cast the returned value based on the variable the value is being assigned to. If you are using VB.NET,you do not need to worry about casting the returned value as it is done for you. The following examples show obtaining the LayerTableRecord for Layer Zero of the current database:

GetObject方法和Open方法都返回一个对象。使用某些编程言语时,我们可能需要释放掉基于已赋值变量的返回值。如果使用VB.NET,我们就不必考虑释放返回值的问题,因为VB.NET为我们做了这件事。下面的例子演示获取当前数据库的Zero层的LayerTableRecord记录:

VB.NET

The following example manually disposes of the transaction after it is no longer needed.

下例在不再需要时手工处置事务(释放内存)。

Dim acCurDb As Document = Application.DocumentManager.MdiActiveDocument.Database

Dim acTrans As Transaction = acCurDb.TransactionManager.StartTransaction()

Dim acLyrTblRec As LayerTableRecord

acLyrTblRec = acTrans.GetObject(acCurDb.LayerZero,OpenMode.ForRead)

acTrans.Dispose()

The following example uses the Using statement to dispose of the transaction after it is no longer needed. The Using statement is the preferred coding style.

下例在不再需要时使用Using语句处置事务(释放内存)。Using语句是优先选用的编码方式。

Dim acCurDb As Document = Application.DocumentManager.MdiActiveDocument.Database

Using acTrans As Transaction = acCurDb.TransactionManager.StartTransaction()

Dim acLyrTblRec As LayerTableRecord

acLyrTblRec = acTrans.GetObject(acCurDb.LayerZero,OpenMode.ForRead)

End Using

C#

The following example manually disposes of the transaction after it is no longer needed.

下例在不再需要时手工处置事务(释放内存)。

Document acCurDb = Application.DocumentManager.MdiActiveDocument.Database;

Transaction acTrans = acCurDb.TransactionManager.StartTransaction();

LayerTableRecord acLyrTblRec;

acLyrTblRec = acTrans.GetObject(acCurDb.LayerZero,

OpenMode.ForRead) as LayerTableRecord;

acTrans.Dispose();

The following example uses the Using statement to dispose of the transaction after it is no longer needed. The Using statement is the preferred coding style.

下例在不再需要时使用Using语句处置事务(释放内存)。Using语句是优先选用的编码方式。

Document acCurDb = Application.DocumentManager.MdiActiveDocument.Database;

using (Transaction acTrans = acCurDb.TransactionManager.StartTransaction())

{

LayerTableRecord acLyrTblRec;

acLyrTblRec = acTrans.GetObject(acCurDb.LayerZero,

OpenMode.ForRead) as LayerTableRecord;

}

2、Use Transactions with the Transaction Manager使用事务管理器管理事务

Transactions are used to group multiple operations on multiple objects together as a single operation. Transactions are started and managed through the Transaction Manager. Once a transaction is started,you can then use the GetObject function to open an object.

事务用来将对多个对象的多个操作编组为单个操作。事务通过事务管理器启动和管理。启动事务之后,我们就可以用GetObject方法打开对象。

As you work with objects opened with GetObject,the Transaction manager keeps track of the changes that are being made to the object. Any new objects that you create and add to the database should be added to a transaction as well with the AddNewlyCreatedDBObject function. Once the objects have been edited or added to the database,you can save the changes made to the database and close all the open objects with the Commit function on the Transaction object created with the Transaction Manager. Once you are finished with a transaction,call the Dispose function close the transaction.

当我们使用由GetObject打开的对象时,事务管理器会跟踪对该对象的修改。创建及添加数据库的任何新对象也应同时调用AddNewlyCreatedDBObject方法将其添加到事务。对象编辑完并添加数据库后,可以使用由事务管理器创建的事务对象的Commit方法保存对数据库修改关闭所有打开的对象。事务处理完毕后,调用Dispose方法关闭事务。

Topics in this section本小节主题

· Start a New Transaction and Open an Object 启动新事务并打开对象

· Commit and Rollback Changes 提交与回滚修改

· Nest Transactions 嵌套事务

2.1、Start a New Transaction and Open an Object启动新事务并打开对象

The Transaction Manager is accessed from the TransactionManager property of the current database. Once a reference to the Transaction Manager is made,you use the StartTransaction method to start a new transaction. StartTransaction creates an instance of a Transaction object and allows you to open objects with the GetObject method.

事务管理器从当前数据库的TransactionManager属性访问。一旦建立对事务管理器的引用,我们就可以使用StartTransaction方法启动一个新事务。StartTransaction方法创建一个Transaction对象的实例,并允许我们使用GetObject方法打开对象。

All open objects opened during a transaction are closed at the end of the transaction. To end a transaction,call the Dispose method of a transaction object. If you use the Using and End Using keywords to indicate the start and end of a transaction,you do not need to call the Dispose method.

在事务期间打开的所有对象在事务结束时都会被关闭。要结束事务,需调用事务对象的Dispose方法。如果使用了Using和End Using关键字来表示事务的开始和结束,就不需要调用Dispose方法

Prior to disposing of a transaction,you should commit any changes made with the Commit method. If the changes are not committed before a transaction is disposed,any changes made are rolled back to the state their were in prior to the start of the transaction. For more information on committing or rolling back changes made in a transaction,see Commit and Rollback Changes.

关闭事务之前,应使用Commit方法提交所作的任何修改。在关闭事务前如果修改没有被提交,那么可以将任何修改回滚到事务启动之前的状态。更多内容见下一小节。

More than one transaction can be started. The number of active transactions can be retrieved with the NumberOfActiveTransactions property of the TransactionManager object while the top most or latest transaction can be retrieved with the TopTransaction property.

可以启动不止一个事务。活动事务的个数可以用TransactionManager对象的NumberOfActiveTransactions属性获得,最上面的或者说最新的事务可以用TopTransaction属性获得。

Transactions can be nested one inside of another in order to rollback some of the changes made during the execution of a routine. For more information on working with multiple transactions or nesting transactions,see Nest Transactions.

在程序执行过程中,为了回滚所作的部分修改,可以将一个事务嵌套在另一个事务中。更多关于使用多个事务及嵌套事务的内容,见嵌套事务。

Query objects 查询对象

The following example demonstrates how to open and read objects within using a transaction. You use the GetObject method to first open the BlockTable and then the Model space record.

下面的示例演示怎样使用事务打开并读取对象。该示例中,使用GetObject方法先打开了BlockTable,然后打开了模型空间记录。

VB.NET

Imports Autodesk.AutoCAD.Runtime

Imports Autodesk.AutoCAD.ApplicationServices

Imports Autodesk.AutoCAD.DatabaseServices

<CommandMethod("OpenTransactionManager")> _

Public Sub OpenTransactionManager()

'' Get the current document and database

Dim acDoc As Document = Application.DocumentManager.MdiActiveDocument

Dim acCurDb As Database = acDoc.Database

'' Start a transaction

Using acTrans As Transaction = acCurDb.TransactionManager.StartTransaction()

'' Open the Block table for read

Dim acBlkTbl As BlockTable

acBlkTbl = acTrans.GetObject(acCurDb.BlockTableId,OpenMode.ForRead)

'' Open the Block table record Model space for read

Dim acBlkTblRec As BlockTableRecord

acBlkTblRec = acTrans.GetObject(acBlkTbl(BlockTableRecord.ModelSpace),_

OpenMode.ForRead)

'' Step through the Block table record

For Each acObjId As ObjectId In acBlkTblRec

acDoc.Editor.WriteMessage(vbLf & "DXF name: " & acObjId.ObjectClass().DxfName)

acDoc.Editor.WriteMessage(vbLf & "ObjectID: " & acObjId.ToString())

acDoc.Editor.WriteMessage(vbLf & "Handle: " & acObjId.Handle.ToString())

acDoc.Editor.WriteMessage(vbLf)

Next

'' Dispose of the transaction

End Using

End Sub

C#

using Autodesk.AutoCAD.Runtime;

using Autodesk.AutoCAD.ApplicationServices;

using Autodesk.AutoCAD.DatabaseServices;

[CommandMethod("OpenTransactionManager")]

public static void OpenTransactionManager()

{

// Get the current document and database

//获取当前文档及数据库

Document acDoc = Application.DocumentManager.MdiActiveDocument;

Database acCurDb = acDoc.Database;

// Start a transaction启动事务

using (Transaction acTrans = acCurDb.TransactionManager.StartTransaction())

{

// Open the Block table for read以读的方式打开块表

BlockTable acBlkTbl;

acBlkTbl = acTrans.GetObject(acCurDb.BlockTableId,

OpenMode.ForRead) as BlockTable;

// Open the Block table record Model space for read

//以读的方式打开块表中的模型空间记录

BlockTableRecord acBlkTblRec;

acBlkTblRec = acTrans.GetObject(acBlkTbl[BlockTableRecord.ModelSpace],

OpenMode.ForRead) as BlockTableRecord;

// Step through the Block table record遍历块表记录

foreach (ObjectId asObjId in acBlkTblRec)

{

acDoc.Editor.WriteMessage("\nDXF name: " + asObjId.ObjectClass.DxfName);

acDoc.Editor.WriteMessage("\nObjectID: " + asObjId.ToString());

acDoc.Editor.WriteMessage("\nHandle: " + asObjId.Handle.ToString());

acDoc.Editor.WriteMessage("\n");

}

// Dispose of the transaction关闭事务

}

}

Add a new object to the database 向数据库添加新对象

The following example demonstrates how to add a circle object to the database with in a transaction. You use the GetObject method to first open the BlockTable for read and then the Model space record for write. After Model space is opened for write,you use the AppendEntity and AddNewlyCreatedDBObject function to append the new Circle object to Model space as well as the transaction.

下例演示使用事务向数据库添加一个圆。用GetObject方法先以读的方式打开BlockTable块表,然后以写的方式打开模型空间记录。以写的方式打开模型空间后,就可以使用AppendEntity方法和AddNewlyCreatedDBObject方法向模型空间添加一个新的圆对象并同时将操作添加到事务。

VB.NET

Imports Autodesk.AutoCAD.Runtime

Imports Autodesk.AutoCAD.ApplicationServices

Imports Autodesk.AutoCAD.DatabaseServices

Imports Autodesk.AutoCAD.Geometry

<CommandMethod("AddNewCircleTransaction")> _

Public Sub AddNewCircleTransaction()

'' Get the current document and database

Dim acDoc As Document = Application.DocumentManager.MdiActiveDocument

Dim acCurDb As Database = acDoc.Database

'' Start a transaction

Using acTrans As Transaction = acCurDb.TransactionManager.StartTransaction()

'' Open the Block table for read

Dim acBlkTbl As BlockTable

acBlkTbl = acTrans.GetObject(acCurDb.BlockTableId,OpenMode.ForRead)

'' Open the Block table record Model space for write

Dim acBlkTblRec As BlockTableRecord

acBlkTblRec = acTrans.GetObject(acBlkTbl(BlockTableRecord.ModelSpace),_

OpenMode.ForWrite)

'' Create a circle with a radius of 3 at 5,5

Dim acCirc As Circle = New Circle()

acCirc.Center = New Point3d(5,5,0)

acCirc.Radius = 3

'' Add the new object to Model space and the transaction

acBlkTblRec.AppendEntity(acCirc)

acTrans.AddNewlyCreatedDBObject(acCirc,True)

'' Commit the changes and dispose of the transaction

acTrans.Commit()

End Using

End Sub

C#

using Autodesk.AutoCAD.Runtime;

using Autodesk.AutoCAD.ApplicationServices;

using Autodesk.AutoCAD.DatabaseServices;

using Autodesk.AutoCAD.Geometry;

[CommandMethod("AddNewCircleTransaction")]

public static void AddNewCircleTransaction()

{

// Get the current document and database

//获取当前文档及数据库

Document acDoc = Application.DocumentManager.MdiActiveDocument;

Database acCurDb = acDoc.Database;

// Start a transaction启动事务

using (Transaction acTrans = acCurDb.TransactionManager.StartTransaction())

{

// Open the Block table for read以读的方式打开BlockTable块表

BlockTable acBlkTbl;

acBlkTbl = acTrans.GetObject(acCurDb.BlockTableId,

OpenMode.ForRead) as BlockTable;

// Open the Block table record Model space for write

//以写的方式打开模型空间记录

BlockTableRecord acBlkTblRec;

acBlkTblRec = acTrans.GetObject(acBlkTbl[BlockTableRecord.ModelSpace],

OpenMode.ForWrite) as BlockTableRecord;

// Create a circle with a radius of 3 at 5,5

//以半径3圆心5,5画圆

Circle acCirc = new Circle();

acCirc.Center = new Point3d(5,0);

acCirc.Radius = 3;

// Add the new object to Model space and the transaction

//将新对象添加到模型空间及事务

acBlkTblRec.AppendEntity(acCirc);

acTrans.AddNewlyCreatedDBObject(acCirc,true);

// Commit the changes and dispose of the transaction

//提交修改关闭事务

acTrans.Commit();

}

}

2.2、Commit and Rollback Changes提交与回滚修改

When using transactions,you are able to decide when changes to objects are saved to the drawing database. You use the Commit method to save the changes made to the objects opened within a transaction. If your program encounters an error you can rollback any changes made within a transaction with the Abort method.

使用了事务,我们就能决定什么时候将对对象所作的修改保存到图形数据库去。我们使用Commit方法保存对事务中打开的对象所作的修改。如果程序出错,我们可以使用Abort方法回滚事务中所作的修改

If Commit is not called before Dispose is called,all changes made within the transaction are rolled back. Whether Commit or Abort are called,you need to call Dispose to signal the end of the transaction. If the transaction object is started with the Using statement,you do not have to call Dispose.

如果调用Dispose前没有调用Commit,则回滚事务这所作的全部修改。不管调用了Commit方法抑或Abort方法,我们都要电影Dispose方法发出结束事务的信号。(当然啦,)如果是使用Using语句启动的事务对象,就不必调用Dispose方法了。

VB.NET

'' Commit the changes made within the transaction

<transaction>.Commit()

'' Abort the transaction and rollback to the prevIoUs state

<transaction>.Abort()

C#

// Commit the changes made within the transaction

//提交事务内所作修改

<transaction>.Commit();

// Abort the transaction and rollback to the prevIoUs state

//终止事务并回滚到之前的状态

<transaction>.Abort();

2.3、Nest Transactions嵌套事务

Transactions can be nested one inside another. You might have an outer transaction to undo all the changes made by your routine and inner transactions to undo just portions of the changes made. When you work with nested transactions,you start with a top transaction which is also the outer most transaction.

一个事务可以嵌套在另一个事务里。我们可能用外层事务撤销程序所作的所有修改,而用内层事务只撤销部分修改。使用嵌套事务时,我们启动一个顶层事务,也称之为最外层事务。

As you start new transactions,they are added into the prevIoUs transaction. Nested transactions must be committed or aborted in the opposite order in which they are created. So if you have three transactions,you must close the third or innermost one before the second and finally the first. If you abort the first transaction,the changes made by all three transactions is undone.

启动的新事物会被添加进前一个事务里。必须按与创建相反的顺序提交或终止嵌套事务。因此,如果有三个事务,我们必须先关闭第三个或最内层那个,然后是第二个,最后是第一个。如果终止第一个事务,那么三个事务所作的所有修改就都被撤销了。

The following illustration shows how transactions appear when nested.

下图显示了事务嵌套的情形。

Use nested transactions to create and modify objects 使用嵌套事务创建及修改对象

The following example demonstrates using three transactions to create a Circle and Line object,and then change their colors. The color of the circle is changed in the second and third transaction,but since the third transaction is aborted only the changes made in the first and second transactions are saved to the database. Additionally,the number of active transactions is printed in the Command Line window as they are created and closed.

下面这个例子演示使用三个事务创建一个圆和一条直线,然后改变它们的颜色。圆的颜色在第二个和第三个事务中修改,不过,由于终止了第三个事务,因此只有第一个和第二个事务中所作的修改被保存到数据库了。另外,创建和关闭事务时,在命令行窗口显示了活动事务的个数。

VB.NET

Imports Autodesk.AutoCAD.Runtime

Imports Autodesk.AutoCAD.ApplicationServices

Imports Autodesk.AutoCAD.DatabaseServices

Imports Autodesk.AutoCAD.Geometry

Imports Autodesk.AutoCAD.EditorInput

<CommandMethod("NestedTransactions")> _

Public Sub NestedTransactions()

'' Get the current document and database

Dim acDoc As Document = Application.DocumentManager.MdiActiveDocument

Dim acCurDb As Database = acDoc.Database

'' Create a reference to the Transaction Manager

Dim acTransMgr As Autodesk.AutoCAD.DatabaseServices.TransactionManager

acTransMgr = acCurDb.TransactionManager

'' Create a new transaction

Using acTrans1 As Transaction = acTransMgr.StartTransaction()

'' Print the current number of active transactions

acDoc.Editor.WriteMessage(vbLf & "Number of transactions active: " & _

acTransMgr.NumberOfActiveTransactions.ToString())

'' Open the Block table for read

Dim acBlkTbl As BlockTable

acBlkTbl = acTrans1.GetObject(acCurDb.BlockTableId,OpenMode.ForRead)

'' Open the Block table record Model space for write

Dim acBlkTblRec As BlockTableRecord

acBlkTblRec = acTrans1.GetObject(acBlkTbl(BlockTableRecord.ModelSpace),0)

acCirc.Radius = 3

'' Add the new object to Model space and the transaction

acBlkTblRec.AppendEntity(acCirc)

acTrans1.AddNewlyCreatedDBObject(acCirc,True)

'' Create the second transaction

Using acTrans2 As Transaction = acTransMgr.StartTransaction()

acDoc.Editor.WriteMessage(vbLf & "Number of transactions active: " & _

acTransMgr.NumberOfActiveTransactions.ToString())

'' Change the circle's color

acCirc.ColorIndex = 5

'' Get the object that was added to Transaction 1 and set it to the color 5

Dim acLine As Line = New Line(New Point3d(2,0),New Point3d(10,7,0))

acLine.ColorIndex = 3

'' Add the new object to Model space and the transaction

acBlkTblRec.AppendEntity(acLine)

acTrans2.AddNewlyCreatedDBObject(acLine,True)

'' Create the third transaction

Using acTrans3 As Transaction = acTransMgr.StartTransaction()

acDoc.Editor.WriteMessage(vbLf & "Number of transactions active: " & _

acTransMgr.NumberOfActiveTransactions.ToString())

'' Change the circle's color

acCirc.ColorIndex = 3

'' Update the display of the drawing

acDoc.Editor.WriteMessage(vbLf)

acDoc.Editor.Regen()

'' Request to keep or discard the changes in the third transaction

Dim pKeyOpts As PromptKeywordOptions = New PromptKeywordOptions("")

pKeyOpts.Message = vbLf & "Keep color change "

pKeyOpts.Keywords.Add("Yes")

pKeyOpts.Keywords.Add("No")

pKeyOpts.Keywords.Default = "No"

pKeyOpts.AllowNone = True

Dim pKeyRes As PromptResult = acDoc.Editor.GetKeywords(pKeyOpts)

If pKeyRes.StringResult = "No" Then

'' Discard the changes in transaction 3

acTrans3.Abort()

Else

'' Save the changes in transaction 3

acTrans3.Commit()

End If

'' Dispose the transaction

End Using

acDoc.Editor.WriteMessage(vbLf & "Number of transactions active: " & _

acTransMgr.NumberOfActiveTransactions.ToString())

'' Keep the changes to transaction 2

acTrans2.Commit()

End Using

acDoc.Editor.WriteMessage(vbLf & "Number of transactions active: " & _

acTransMgr.NumberOfActiveTransactions.ToString())

'' Keep the changes to transaction 1

acTrans1.Commit()

End Using

End Sub

C#

using Autodesk.AutoCAD.Runtime;

using Autodesk.AutoCAD.ApplicationServices;

using Autodesk.AutoCAD.DatabaseServices;

using Autodesk.AutoCAD.Geometry;

using Autodesk.AutoCAD.EditorInput;

[CommandMethod("NestedTransactions")]

public static void NestedTransactions()

{

// Get the current document and database

//获取当前文档和数据库

Document acDoc = Application.DocumentManager.MdiActiveDocument;

Database acCurDb = acDoc.Database;

// Create a reference to the Transaction Manager

//创建对事务管理器的引用

Autodesk.AutoCAD.DatabaseServices.TransactionManager acTransMgr;

acTransMgr = acCurDb.TransactionManager;

// Create a new transaction新建事务

using (Transaction acTrans1 = acTransMgr.StartTransaction())

{

// Print the current number of active transactions

//打印当前活动事务的个数

acDoc.Editor.WriteMessage("\nNumber of transactions active: " +

acTransMgr.NumberOfActiveTransactions.ToString());

// Open the Block table for read

//以读的方式打开BlockTable块表

BlockTable acBlkTbl;

acBlkTbl = acTrans1.GetObject(acCurDb.BlockTableId,

OpenMode.ForRead) as BlockTable;

// Open the Block table record Model space for write

//以写的方式打开块表的模型空间记录

BlockTableRecord acBlkTblRec;

acBlkTblRec = acTrans1.GetObject(acBlkTbl[BlockTableRecord.ModelSpace],5

//创建半径2圆心5,5的圆

Circle acCirc = new Circle();

acCirc.Center = new Point3d(5,0);

acCirc.Radius = 3;

// Add the new object to Model space and the transaction

//添加新对象到模型空间并添加事务

acBlkTblRec.AppendEntity(acCirc);

acTrans1.AddNewlyCreatedDBObject(acCirc,true);

// Create the second transaction

//创建第二个事务

using (Transaction acTrans2 = acTransMgr.StartTransaction())

{

acDoc.Editor.WriteMessage("\nNumber of transactions active: " +

acTransMgr.NumberOfActiveTransactions.ToString());

// Change the circle's color修改圆的颜色

acCirc.ColorIndex = 5;

// Get the object that was added to Transaction 1 and set it to the color 5

//获取添加到事务1的那个对象并设置其颜色为5(Blue蓝色)

Line acLine = new Line(new Point3d(2,new Point3d(10,0));

acLine.ColorIndex = 3;

// Add the new object to Model space and the transaction

//添加新对象到模型空间并添加事务

acBlkTblRec.AppendEntity(acLine);

acTrans2.AddNewlyCreatedDBObject(acLine,true);

// Create the third transaction

//创建第三个事务

using (Transaction acTrans3 = acTransMgr.StartTransaction())

{

acDoc.Editor.WriteMessage("\nNumber of transactions active: " +

acTransMgr.NumberOfActiveTransactions.ToString());

// Change the circle's color修改圆的颜色

acCirc.ColorIndex = 3;

// Update the display of the drawing更新图形显示

acDoc.Editor.WriteMessage("\n");

acDoc.Editor.Regen();

// Request to keep or discard the changes in the third transaction

//询问保持还是取消第三个事务中的修改

PromptKeywordOptions pKeyOpts = new PromptKeywordOptions("");

pKeyOpts.Message = "\nKeep color change ";

pKeyOpts.Keywords.Add("Yes");

pKeyOpts.Keywords.Add("No");

pKeyOpts.Keywords.Default = "No";

pKeyOpts.AllowNone = true;

PromptResult pKeyRes = acDoc.Editor.GetKeywords(pKeyOpts);

if (pKeyRes.StringResult == "No")

{

// Discard the changes in transaction 3

//取消事务3中的修改

acTrans3.Abort();

}

else

{

// Save the changes in transaction 3

//保存事务3中的修改

acTrans3.Commit();

}

// Dispose the transaction关闭事务3

}

acDoc.Editor.WriteMessage("\nNumber of transactions active: " +

acTransMgr.NumberOfActiveTransactions.ToString());

// Keep the changes to transaction 2保留事务2中的修改

acTrans2.Commit();

}

acDoc.Editor.WriteMessage("\nNumber of transactions active: " +

acTransMgr.NumberOfActiveTransactions.ToString());

// Keep the changes to transaction 1保留事务1中的修改

acTrans1.Commit();

}

}

3、Open and Close Objects without the Transaction Manager不使用事务管理器打开和关闭对象

Transactions make it easier to open and work with multiple objects,but they are not the only way to open and edit objects. Other than using a transaction,you can open and close objects using the Open and Close methods. You still need to obtain an object id to use the Open method. Like the GetObject method used with transactions,you need to specify an open mode and the return value is an object. If you make changes to an object after you opened it with the Open method,you can use the Cancel method to rollback all the changes made since it was opened. Cancel must be called on each object in which you want to rollback.

事务使得打开和使用多个对象变得容易多了,不过这并不是打开和编辑对象的唯一方式。除了使用事务外,我们还可以使用Open方法和Close方法打开和关闭对象。使用Open方法仍然需要先获取对象标志ObjectId,就像使用事务时的GetObject方法一样,我们需要指定打开模式并返回一个对象。使用Open方法打开对象后如果对这个对象进行了修改,我们可以使用Cancel方法回滚对象打开以来的所有修改。当要回滚时,必须对每个对象都调用Cancel方法

Note Objects must be paired with an open and close operation. If you use the Open method on an object,you must close it using either the Close or Cancel method. Failure to close the object will lead to read access violations and cause AutoCAD to become unstable.

注意:打开对象和关闭对象的操作必须成对出现。如果我们对一个对象使用了Open方法,就必须使用Close方法或Cancel方法关闭它。关闭对象失败会导致读取违例并导致AutoCAD不稳定。

If you need to work with a single object,using the Open and Close methods can reduce the number of lines of code that you might otherwise have to write compared to working with the Transaction Manager. However,using transactions is the recommended way of opening and closing objects.

如果我们只使用一个对象,和使用事务管理器相比,使用Open方法及Close方法能减少编写代码的行数。不过,还是推荐使用事务来打开和关闭对象。

Warning You should not use the Open and Close methods when using transactions,as objects might not get opened or closed properly by the Transaction Manager which could cause AutoCAD to crash.

警告:使用事务时不能使用Open和Close方法,事务管理器不能正确打开和关闭对象会导致AutoCAD崩溃。

Query objects 查询对象

The following example demonstrates how to open and close objects without using a transaction and the GetObject method. To see the same example using the Transaction Manager,see Start a New Transaction and Open an Object.

下面的示例演示不使用事务及GetObject方法怎样打开和关闭对象。可以和前面一节使用事务管理器的例子比较一下。

VB.NET

Imports Autodesk.AutoCAD.Runtime

Imports Autodesk.AutoCAD.ApplicationServices

Imports Autodesk.AutoCAD.DatabaseServices

<CommandMethod("OpenCloSEObjectId")> _

Public Sub OpenCloSEObjectId()

'' Get the current document and database

Dim acDoc As Document = Application.DocumentManager.MdiActiveDocument

Dim acCurDb As Database = acDoc.Database

'' Open the Block table for read

Dim acBlkTbl As BlockTable

acBlkTbl = acCurDb.BlockTableId.Open(OpenMode.ForRead)

'' Open the Block table record Model space for read

Dim acBlkTblRec As BlockTableRecord

acBlkTblRec = acBlkTbl(BlockTableRecord.ModelSpace).Open(OpenMode.ForRead)

'' Step through the Block table record

For Each acObjId As ObjectId In acBlkTblRec

acDoc.Editor.WriteMessage(vbLf & "DXF name: " & acObjId.ObjectClass().DxfName)

acDoc.Editor.WriteMessage(vbLf & "ObjectID: " & acObjId.ToString())

acDoc.Editor.WriteMessage(vbLf & "Handle: " & acObjId.Handle.ToString())

acDoc.Editor.WriteMessage(vbLf)

Next

'' Close the Block table record

acBlkTblRec.Close()

acBlkTblRec.Dispose()

'' Close the Block table

acBlkTbl.Close()

acBlkTbl.Dispose()

End Sub

C#

using Autodesk.AutoCAD.Runtime;

using Autodesk.AutoCAD.ApplicationServices;

using Autodesk.AutoCAD.DatabaseServices;

[CommandMethod("OpenCloSEObjectId")]

public static void OpenCloSEObjectId()

{

// Get the current document and database

//获取当前文档及数据库

Document acDoc = Application.DocumentManager.MdiActiveDocument;

Database acCurDb = acDoc.Database;

// Open the Block table for read以读的方式打开块表

BlockTable acBlkTbl;

acBlkTbl = acCurDb.BlockTableId.Open(OpenMode.ForRead) as BlockTable;

// Open the Block table record Model space for read

//以读的方式打开模型空间记录

BlockTableRecord acBlkTblRec;

acBlkTblRec = acBlkTbl[BlockTableRecord.ModelSpace].Open(OpenMode.ForRead) as BlockTableRecord;

// Step through the Block table record遍历块表记录

foreach (ObjectId acObjId in acBlkTblRec)

{

acDoc.Editor.WriteMessage("\nDXF name: " + acObjId.ObjectClass.DxfName);

acDoc.Editor.WriteMessage("\nObjectID: " + acObjId.ToString());

acDoc.Editor.WriteMessage("\nHandle: " + acObjId.Handle.ToString());

acDoc.Editor.WriteMessage("\n");

}

// Close the Block table record关闭块表记录

acBlkTblRec.Close();

acBlkTblRec.Dispose();

// Close the Block table关闭块表

acBlkTbl.Close();

acBlkTbl.Dispose();

}

Add a new object to the database 向数据库添加新对象

This example demonstrates how to create a new object and append it to Model space without using the Transaction manager. To see the same example using the Transaction manager,see Start a New Transaction and Open an Object.

本例演示不使用事务管理器怎样创建新对象并添加到模型空间。可以和前面一节使用事务管理器的例子比较一下。

VB.NET

Imports Autodesk.AutoCAD.Runtime

Imports Autodesk.AutoCAD.ApplicationServices

Imports Autodesk.AutoCAD.DatabaseServices

Imports Autodesk.AutoCAD.Geometry

<CommandMethod("AddNewCircleOpenClose")> _

Public Sub AddNewCircleOpenClose()

'' Get the current document and database

Dim acDoc As Document = Application.DocumentManager.MdiActiveDocument

Dim acCurDb As Database = acDoc.Database

'' Open the Block table for read

Dim acBlkTbl As BlockTable

acBlkTbl = acCurDb.BlockTableId.Open(OpenMode.ForRead)

'' Open the Block table record Model space for write

Dim acBlkTblRec As BlockTableRecord

acBlkTblRec = acBlkTbl(BlockTableRecord.ModelSpace).Open(OpenMode.ForWrite)

'' Create a circle with a radius of 3 at 5,0)

acCirc.Radius = 3

'' Add the new object to Model space and the transaction

acBlkTblRec.AppendEntity(acCirc)

'' Close the circle object

acCirc.Close()

acCirc.Dispose()

'' Close the Block table record

acBlkTblRec.Close()

acBlkTblRec.Dispose()

'' Close the Block table

acBlkTbl.Close()

acBlkTbl.Dispose()

End Sub

C#

using Autodesk.AutoCAD.Runtime;

using Autodesk.AutoCAD.ApplicationServices;

using Autodesk.AutoCAD.DatabaseServices;

using Autodesk.AutoCAD.Geometry;

[CommandMethod("AddNewCircleOpenClose")]

public static void AddNewCircleOpenClose()

{

// Get the current document and database

//获取当前文档及数据库

Document acDoc = Application.DocumentManager.MdiActiveDocument;

Database acCurDb = acDoc.Database;

// Open the Block table for read以读的方式打开块表

BlockTable acBlkTbl;

acBlkTbl = acCurDb.BlockTableId.Open(OpenMode.ForRead) as BlockTable;

// Open the Block table record Model space for write

//以写的方式打开模型空间记录

BlockTableRecord acBlkTblRec;

acBlkTblRec = acBlkTbl[BlockTableRecord.ModelSpace].Open(OpenMode.ForWrite)

as BlockTableRecord;

// Create a circle with a radius of 3 at 5,5

//创建园,半径3、圆心5,5

Circle acCirc = new Circle();

acCirc.Center = new Point3d(5,0);

acCirc.Radius = 3;

// Add the new object to Model space and the transaction

//将新对象添加到模型空间及事务

acBlkTblRec.AppendEntity(acCirc);

// Close the circle object关闭对象园

acCirc.Close();

acCirc.Dispose();

// Close the Block table record关闭块表记录

acBlkTblRec.Close();

acBlkTblRec.Dispose();

// Close the Block table关闭块表

acBlkTbl.Close();

acBlkTbl.Dispose();

}

4、Upgrade and Downgrade Open Objects升级打开对象与降级打开对象

Once an object is opened using either the GetObject or Open methods,you can change the current open mode of an object with the UpgradeOpen and DowngradeOpen methods. The UpgradeOpen method changes an object open for read to write mode,while DowngradeOpen changes an object open for write to read mode. You do not need to pair a call to DowngradeOpen with each UpgradeOpen call,since closing of an object or disposing of a transaction will sufficiently cleanup the open state of an entity.

使用GetObject方法或Open方法打开一个对象后,我们可以使用UpgradeOpen方法与DowngradeOpen方法改变对象当前的打开模式。UpgradeOpen方法将对象的打开模式由读变为写,DowngradeOpen方法将对象的打开模式由写变为读。没有必要为每个UpgradeOpen调用配上一个DowngradeOpen调用,因为对象或事务的关闭更能清除实体的打开状态。

When you go to open an object,open the object in the mode that you will use the object in. Do not just open an object for write when you might only need to query an object. It is more efficient to open an object for read and query the object’s properties than it is to open the object for write and query the object’s properties.

试图打开一个对象时,想怎么使用对象就以相应的模式打开这个对象。当只是查询一个对象时不要以写的模式打开。以读的方式打开对象并查询属性比以写的方式打开对象并查询属性效率高得多。

opening an object for write causes undo filing to start for the object. Undo filing is used to track changes to an object,so any changes made can be rolled back. If you are uncertain if you need to modify an object,it is best to open an object for read and then upgrade it for write. This will help to reduce the overhead of your program.

以写的方式打开对象会启动该对象的撤销队列登记。撤销队列登记用来跟踪对象的修改,这样所做的任何修改都能被回滚。如果不能确定是否需要修改对象,最好以读的方式打开对象,然后再升级为写模式。这样做能帮助减少程序开销。

An example of when you might use UpgradeOpen is when you might be querying objects to see if they match a specific condition,and if the condition is met then you would upgrade the object from read to write mode to make modifications to it.

关于何时使用UpgradeOpen方法的一个例子是,当想查询对象看是否满足某个指定条件,并且如果满足条件就将对象的打开模式由读升级为写并对其进行修改时。

Open Notifications 以通知方式打开

Similarly,if an object is open for notify and you receive a notification,you use UpgradeFromNotify to upgrade the object for write. Then you would use DowngradeToNotify to downgrade the object back to notify. UpgradeFromNotify and DowngradeFromNotify are reserved for use in methods that are intended to be used by an object to change its own open status so that it can safely modify itself.

类似的情形,如果以通知的方式打开对象并接受到一个通知,可以用UpgradeFromNotify方法将对象打开方式升级为写,然后还可以用DowngradeFromNotify方法将对象打开方式降级为通知方式。UpgradeFromNotify和DowngradeFromNotify是为了对象试图修改自己的打开状态以便安全地修改自己的那些方法而保留的。

VB.NET

Imports Autodesk.AutoCAD.Runtime

Imports Autodesk.AutoCAD.ApplicationServices

Imports Autodesk.AutoCAD.DatabaseServices

<CommandMethod("FreezeDoorLayer")> _

Public Sub FreezeDoorLayer()

'' Get the current document and database

Dim acDoc As Document = Application.DocumentManager.MdiActiveDocument

Dim acCurDb As Database = acDoc.Database

'' Start a transaction

Using acTrans As Transaction = acCurDb.TransactionManager.StartTransaction()

'' Open the Layer table for read

Dim acLyrTbl As LayerTable

acLyrTbl = acTrans.GetObject(acCurDb.LayerTableId,OpenMode.ForRead)

'' Step through each layer and update those that start with 'Door'

For Each acObjId As ObjectId In acLyrTbl

'' Open the Layer table record for read

Dim acLyrTblRec As LayerTableRecord

acLyrTblRec = acTrans.GetObject(acObjId,OpenMode.ForRead)

'' Check to see if the layer's name starts with 'Door'

If (acLyrTblRec.Name.StartsWith("Door",_

StringComparison.OrdinalIgnoreCase) = True) Then

'' Check to see if the layer is current,if so then do not freeze it

If acLyrTblRec.ObjectId <> acCurDb.Clayer Then

'' Change from read to write mode

acLyrTblRec.UpgradeOpen()

'' Freeze the layer

acLyrTblRec.IsFrozen = True

End If

End If

Next

'' Commit the changes and dispose of the transaction

acTrans.Commit()

End Using

End Sub

C#

using Autodesk.AutoCAD.Runtime;

using Autodesk.AutoCAD.ApplicationServices;

using Autodesk.AutoCAD.DatabaseServices;

[CommandMethod("FreezeDoorLayer")]

public static void FreezeDoorLayer()

{

// Get the current document and database

//获取当前文档及数据库

Document acDoc = Application.DocumentManager.MdiActiveDocument;

Database acCurDb = acDoc.Database;

// Start a transaction启动事务

using (Transaction acTrans = acCurDb.TransactionManager.StartTransaction())

{

// Open the Layer table for read以读的方式打开图层表

LayerTable acLyrTbl;

acLyrTbl = acTrans.GetObject(acCurDb.LayerTableId,

OpenMode.ForRead) as LayerTable;

// Step through each layer and update those that start with 'Door'

//遍历图层并将图层名以‘Door’开头的图层升级为写打开方式;

foreach (ObjectId acObjId in acLyrTbl)

{

// Open the Layer table record for read以读打开图层表记录

LayerTableRecord acLyrTblRec;

acLyrTblRec = acTrans.GetObject(acObjId,

OpenMode.ForRead) as LayerTableRecord;

// Check to see if the layer's name starts with 'Door'

//检查图层名是否以‘Door’开头

if (acLyrTblRec.Name.StartsWith("Door",

StringComparison.OrdinalIgnoreCase) == true)

{

// Check to see if the layer is current,if so then do not freeze it

//检查是否为当前层,是则不冻结

if (acLyrTblRec.ObjectId != acCurDb.Clayer)

{

// Change from read to write mode升级打开方式

acLyrTblRec.UpgradeOpen();

// Freeze the layer冻结图层

acLyrTblRec.IsFrozen = true;

}

}

}

// Commit the changes and dispose of the transaction

//提交修改关闭事务

acTrans.Commit();

}

}

猜你在找的VB相关文章