AutoCAD Managed .NET API を使用すると、.NET 4.0 で導入された動的言語ランタイム(DLR)を利用できます。
DLR を使用すると、オブジェクトに直接アクセスでき、次のようなことが必要ありません。
DLR の使用時には、オブジェクトの ObjectId を取得すると、そのオブジェクトのプロパティやメソッドに直接アクセスできます。ObjectId を取得した後は、次のデータ型の変数に ObjectId を代入できます。
ObjectId の取得方法は、オブジェクトがデータベースに保存される方法によって異なります。テーブルまたはディクショナリに格納されるオブジェクトの場合は、次のようにして ObjectId にアクセスできます。
次のサンプル コードでは、DLR でテーブルまたはディクショナリに格納されているオブジェクトにアクセスするための両方のオプションを示します。
VB.NET '' Item method Dim acCurDb As Object = HostApplicationServices.WorkingDatabase Dim acMSpace As Object = acCurDb.BlockTableId.Item(BlockTableRecord.ModelSpace) '' Reference an element directly from a collection Dim acCurDb As Object = HostApplicationServices.WorkingDatabase Dim acBlkTbl As Object = acCurDb.BlockTableId Dim acMSpace As Object = acBlkTbl(BlockTableRecord.ModelSpace)
C# // Item method dynamic acCurDb = HostApplicationServices.WorkingDatabase; dynamic acMSpace = acCurDb.BlockTableId.Item(BlockTableRecord.ModelSpace); // Reference an element directly from a collection dynamic acCurDb = HostApplicationServices.WorkingDatabase; dynamic acBlkTbl = acCurDb.BlockTableId; dynamic acMSpace = acBlkTbl[BlockTableRecord.ModelSpace];
DLR で GetEnumerator メソッドを使用するときは、使い終わった列挙子オブジェクトを明示的に破棄する必要があります。次の例では、使い終わった列挙子を破棄する方法を示します。
VB.NET Dim acCurDb As Object = HostApplicationServices.WorkingDatabase Dim acLtypeTbl As Object = acCurDb.LinetypeTableId Dim acTblEnum As Object = acLtypeTbl.GetEnumerator() ... acTblEnum.Dispose()
C# dynamic acCurDb = HostApplicationServices.WorkingDatabase; var acLtypeTbl = acCurDb.LinetypeTableId; var acTblEnum = acLtypeTbl.GetEnumerator(); ... acTblEnum.Dispose();
DLR では、LINQ クエリーを使用して、図面内のテーブルまたはディクショナリの内容をクエリーできます。次の例では、LINQ クエリーを使用して、現在の図面で特定の状態を割り当てられている画層をクエリーする方法を示します。
VB.NET <CommandMethod("LINQ")> _ Public Sub LINQExample() Dim db As Object = HostApplicationServices.WorkingDatabase Dim doc As Object = Application.DocumentManager.MdiActiveDocument Dim layers = db.LayerTableId For i As Integer = 0 To 2 Dim newrec As Object = layers.Add(New LayerTableRecord()) newrec.Name = "Layer" + i.ToString() If i = 0 Then newrec.IsFrozen = True If i = 1 Then newrec.IsOff = True Next Dim OffLayers = From l In CType(CTypeDynamic(layers, GetType(IEnumerable(Of Object))), _ IEnumerable(Of Object)) Where l.IsOff Select l doc.Editor.WriteMessage(vbLf + "Layers Turned Off:") For Each rec As Object In OffLayers doc.Editor.WriteMessage(vbLf + " - " + rec.Name) Next Dim frozenOrOffNames = From l In CType(CTypeDynamic(layers, GetType(IEnumerable(Of Object))), _ IEnumerable(Of Object)) Where l.IsFrozen = True Or l.IsOff = True Select l doc.Editor.WriteMessage(vbLf + "Layers Frozen or Turned Off:") For Each rec As Object In frozenOrOffNames doc.Editor.WriteMessage(vbLf + " - " + rec.Name) Next End Sub
C# [CommandMethod("LINQ")] public static void LINQExample() { dynamic db = HostApplicationServices.WorkingDatabase; dynamic doc = Application.DocumentManager.MdiActiveDocument; var layers = db.LayerTableId; for (int i = 0; i < 2; i++) { var newrec = layers.Add(new LayerTableRecord()); newrec.Name = "Layer" + i.ToString(); if (i == 0) newrec.IsFrozen = true; if (i == 1) newrec.IsOff = true; } var OffLayers = from l in (IEnumerable<dynamic>)layers where l.IsOff select l; doc.Editor.WriteMessage("\nLayers Turned Off:"); foreach (dynamic rec in OffLayers) doc.Editor.WriteMessage("\n - " + rec.Name); var frozenOrOffNames = from l in (IEnumerable<dynamic>)layers where l.IsFrozen == true || l.IsOff == true select l; doc.Editor.WriteMessage("\nLayers Frozen or Turned Off:"); foreach (dynamic rec in frozenOrOffNames) doc.Editor.WriteMessage("\n - " + rec.Name); }
このページのサンプル コードは、次の名前空間を使用します。
Autodesk.AutoCAD.Runtime Autodesk.AutoCAD.ApplicationServices Autodesk.AutoCAD.DatabaseServices Autodesk.AutoCAD.Colors Autodesk.AutoCAD.Geometry
次のサンプル コードでは、現在の空間に線分を追加する方法を、DLR を使用した場合と使用しない場合について示します。
<CommandMethod("ADDLINE")> _ Public Sub AddLine() '' Get the current database Dim acCurDb As Database = HostApplicationServices.WorkingDatabase '' Start a transaction Using acTrans As Transaction = acCurDb.TransactionManager.StartTransaction() '' Open the current space for write Dim acSpace As BlockTableRecord acSpace = acTrans.GetObject(acCurDb.CurrentSpaceId, _ OpenMode.ForWrite) '' Create a line that starts at 5,5 and ends at 12,3 Using acLine As Line = New Line(New Point3d(5, 5, 0), New Point3d(12, 3, 0)) '' Add the new object to the block table record and the transaction acSpace.AppendEntity(acLine) acTrans.AddNewlyCreatedDBObject(acLine, True) End Using '' Save the new object to the database acTrans.Commit() End Using End Sub
<CommandMethod("ADDLINE")> _ Public Sub AddLine() '' Get the current database Dim acCurDb As Object = HostApplicationServices.WorkingDatabase '' Create a dynamic reference to model or paper space Dim acSpace As Object = acCurDb.CurrentSpaceId '' Create a line that starts at 5,5 and ends at 12,3 Dim acLine As Object = New Line(New Point3d(5, 5, 0), New Point3d(12, 3, 0)) '' Add the new object to the current space acSpace.AppendEntity(acLine) End Sub
[CommandMethod("ADDLINE")] public static void AddLine() { // Get the current database Database acCurDb = HostApplicationServices.WorkingDatabase; // 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 write BlockTableRecord acBlkTblRec; acBlkTblRec = acTrans.GetObject(acBlkTbl[BlockTableRecord.ModelSpace], OpenMode.ForWrite) as BlockTableRecord; // Create a line that starts at 5,5 and ends at 12,3 using (Line acLine = new Line(new Point3d(5, 5, 0), new Point3d(12, 3, 0))) { // Add the new object to the block table record and the transaction acBlkTblRec.AppendEntity(acLine); acTrans.AddNewlyCreatedDBObject(acLine, true); } // Save the new object to the database acTrans.Commit(); } }
[CommandMethod("ADDLINE")] public static void AddLine() { // Get the current database dynamic acCurDb = HostApplicationServices.WorkingDatabase; // Create a dynamic reference to model or paper space dynamic acSpace = acCurDb.CurrentSpaceId; // Create a line that starts at 5,5 and ends at 12,3 dynamic acLine = new Line(new Point3d(5, 5, 0), new Point3d(12, 3, 0)); // Add the new object to the current space acSpace.AppendEntity(acLine); }
次のサンプル コードでは、現在のデータベースに画層を追加する方法を、DLR を使用した場合と使用しない場合について示します。
<CommandMethod("ADDLAYER")> _ Public Sub AddLayer() '' Get the current database Dim acCurDb As Database = HostApplicationServices.WorkingDatabase '' Start a transaction Using acTrans As Transaction = acCurDb.TransactionManager.StartTransaction() '' Returns the layer table for the current database Dim acLyrTbl As LayerTable acLyrTbl = acTrans.GetObject(acCurDb.LayerTableId, OpenMode.ForRead) '' Check to see if MyLayer exists in the Layer table If Not acLyrTbl.Has("MyLayer") Then '' Open the Layer Table for write acLyrTbl.UpgradeOpen() '' Create a new layer named "MyLayer" Using acLyrTblRec As LayerTableRecord = New LayerTableRecord() acLyrTblRec.Name = "MyLayer" '' Assign the ACI color 3 to the new layer Dim acClr As Color = Color.FromColorIndex(ColorMethod.ByAci, 3) acLyrTblRec.Color = acClr '' Add the new layer table record to the layer table and the transaction acLyrTbl.Add(acLyrTblRec) acTrans.AddNewlyCreatedDBObject(acLyrTblRec, True) End Using '' Commit the changes acTrans.Commit() End If '' Dispose of the transaction End Using End Sub
<CommandMethod("ADDLAYER")> _ Public Sub AddLayer() '' Get the current database Dim acCurDb As Object = HostApplicationServices.WorkingDatabase Dim acLyrTbl As Object = acCurDb.LayerTableId '' Check to see if MyLayer exists in the Layer table If Not acLyrTbl.Has("MyLayer") Then '' Create a new layer named "MyLayer" Dim acLyrTblRec As LayerTableRecord = New LayerTableRecord() acLyrTblRec.Name = "MyLayer" '' Assign the ACI color 3 to the new layer Dim acClr As Color = Color.FromColorIndex(ColorMethod.ByAci, 3) acLyrTblRec.Color = acClr '' Add the new layer table record to the layer table acLyrTbl.Add(acLyrTblRec) End If End Sub
[CommandMethod("ADDLAYER")] public static void AddLayer() { // Get the current database Database acCurDb = HostApplicationServices.WorkingDatabase; using (Transaction acTrans = acCurDb.TransactionManager.StartTransaction()) { // Returns the layer table for the current database LayerTable acLyrTbl; acLyrTbl = acTrans.GetObject(acCurDb.LayerTableId, OpenMode.ForRead) as LayerTable; // Check to see if MyLayer exists in the Layer table if (acLyrTbl.Has("MyLayer") != true) { // Open the Layer Table for write acLyrTbl.UpgradeOpen(); // Create a new layer named "MyLayer" using (LayerTableRecord acLyrTblRec = new LayerTableRecord()) { acLyrTblRec.Name = "MyLayer"; // Assign the ACI color 3 to the new layer Color acClr = Color.FromColorIndex(ColorMethod.ByAci, 3); acLyrTblRec.Color = acClr; // Add the new layer table record to the layer table and the transaction acLyrTbl.Add(acLyrTblRec); acTrans.AddNewlyCreatedDBObject(acLyrTblRec, true); } // Commit the changes acTrans.Commit(); } // Dispose of the transaction } }
[CommandMethod("ADDLAYER")] public static void AddLayer() { // Get the current database dynamic acCurDb = HostApplicationServices.WorkingDatabase; dynamic acLyrTbl = acCurDb.LayerTableId; // Check to see if MyLayer exists in the Layer table if (acLyrTbl.Has("MyLayer") != true) { // Create a new layer named "MyLayer" dynamic acLyrTblRec = new LayerTableRecord(); acLyrTblRec.Name = "MyLayer"; // Assign the ACI color 3 to the new layer dynamic acClr = Color.FromColorIndex(ColorMethod.ByAci, 3); acLyrTblRec.Color = acClr; // Add the new layer table record to the layer table acLyrTbl.Add(acLyrTblRec); } }
次に、DLR を使用した場合と使用しない場合で、現在の空間内のすべてのオブジェクトを順番に処理して一覧表示する方法を示します。
<CommandMethod("LISTOBJECTS")> _ Public Sub ListObjects() '' Get the current document and database Dim acDoc As Document = Application.DocumentManager.MdiActiveDocument Dim acCurDb As Database = HostApplicationServices.WorkingDatabase '' Start a transaction Using acTrans As Transaction = acCurDb.TransactionManager.StartTransaction() '' Open the Block table record Model space for write Dim acSpace As BlockTableRecord acSpace = acTrans.GetObject(acCurDb.CurrentSpaceId, OpenMode.ForRead) '' Step through the current space For Each objId As ObjectId In acSpace '' Display the class and current layer of the object Dim acEnt As Entity = acTrans.GetObject(objId, OpenMode.ForRead) acDoc.Editor.WriteMessage(vbCrLf + "Object Class: " + acEnt.GetRXClass().Name + _ vbCrLf + "Current Layer: " + acEnt.Layer + _ vbCrLf) Next objId acTrans.Commit() End Using End Sub
<CommandMethod("LISTOBJECTS")> _ Public Sub ListObjects() '' Get the current document and database Dim acDoc As Object = Application.DocumentManager.MdiActiveDocument Dim acCurDb As Object = HostApplicationServices.WorkingDatabase '' Create a dynamic reference to model or paper space Dim acSpace As Object = acCurDb.CurrentSpaceId '' Step through the current space For Each acEnt As Object In CTypeDynamic(acSpace, GetType(System.Collections.IEnumerable)) '' Display the class and current layer of the object acDoc.Editor.WriteMessage(vbCrLf + "Object Class: " + acEnt.GetRXClass().Name + _ vbCrLf + "Current Layer: " + acEnt.Layer + _ vbCrLf) Next acEnt End Sub
[CommandMethod("LISTOBJECTS")] public static void ListObjects() { // Get the current document and database Document acDoc = Application.DocumentManager.MdiActiveDocument; Database acCurDb = HostApplicationServices.WorkingDatabase; using (Transaction acTrans = acCurDb.TransactionManager.StartTransaction()) { // Open the Block table record Model space for write BlockTableRecord acSpace; acSpace = acTrans.GetObject(acCurDb.CurrentSpaceId, OpenMode.ForRead) as BlockTableRecord; // Step through the current space foreach (ObjectId objId in acSpace) { // Display the class and current layer of the object Entity acEnt = (Entity)acTrans.GetObject(objId, OpenMode.ForRead); acDoc.Editor.WriteMessage("\nObject Class: " + acEnt.GetRXClass().Name + "\nCurrent Layer: " + acEnt.Layer + "\n"); } acTrans.Commit(); } }
[CommandMethod("LISTOBJECTS")] public static void ListObjects() { // Get the current document and database dynamic acDoc = Application.DocumentManager.MdiActiveDocument; dynamic acCurDb = HostApplicationServices.WorkingDatabase; // Create a dynamic reference to model or paper space dynamic acSpace = acCurDb.CurrentSpaceId; // Step through the current space foreach (dynamic acEnt in acSpace) { // Display the class and current layer of the object acDoc.Editor.WriteMessage("\nObject Class: " + acEnt.GetRXClass().Name + "\nCurrent Layer: " + acEnt.Layer + "\n"); } }