. NET块例程
AutoCAD块的库线程鼓励成员在中发布有关
AutoCAD块的任何函数、方法和片段。NET : C#、VB、F#、Python等
请随意添加注释、描述性注释、限制和图片来记录您的帖子。
请以常规主题发布问题。
**** Hidden Message ***** 下面是一个非常基本的例子,如何正确创建块,我希望
using System;
using System.Collections.Generic;
using System.Text;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.GraphicsInterface;
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.ApplicationServices;
using AcadApp = Autodesk.AutoCAD.ApplicationServices.Application;
using Autodesk.AutoCAD.EditorInput;
.................................................
public static ObjectId CreateLabelBlock(string blockname)
{
ObjectId blkid = ObjectId.Null;
try
{
Database db = HostApplicationServices.WorkingDatabase;
using (Transaction tr = db.TransactionManager.StartTransaction())
{
BlockTable bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForWrite, false);
if (bt.Has(blockname))
{
blkid = bt;
}
else
{
BlockTableRecord btr = new BlockTableRecord();
btr.Name = blockname;
btr.Explodable = true;
btr.Origin = new Point3d(0, 0, 0);
btr.Units = UnitsValue.Inches;
btr.BlockScaling = BlockScaling.Any;
Line line = new Line(new Point3d(-2, -0.4, 0), new Point3d(2, -0.4, 0));
line.Layer = "0";
line.ColorIndex = 14;
btr.AppendEntity(line);
line = new Line(new Point3d(-2, 0.4, 0), new Point3d(2, 0.4, 0));
line.Layer = "0";
line.ColorIndex = 14;
btr.AppendEntity(line);
line = new Line(new Point3d(2, -0.4, 0), new Point3d(2, 0.4, 0));
line.Layer = "0";
line.ColorIndex = 14;
btr.AppendEntity(line);
line = new Line(new Point3d(-2, -0.4, 0), new Point3d(-2, 0.4, 0));
line.Layer = "0";
line.ColorIndex = 14;
btr.AppendEntity(line);
AcadApp.SetSystemVariable("CECOLOR", "ByBlock");
AttributeDefinition ad = new AttributeDefinition();
ad.Layer = "0";
//by default applied a current text style
ad.Tag = "DETAIL";
ad.TextString = "X-Ladder";
ad.Prompt = "Detail name";
ad.Position = new Point3d(0, 0, 0);
ad.HorizontalMode = TextHorizontalMode.TextMid;
ad.VerticalMode = TextVerticalMode.TextVerticalMid;
ad.AlignmentPoint = ad.Position;
btr.AppendEntity(ad);
blkid = bt.Add(btr);
AcadApp.SetSystemVariable("CECOLOR", "ByLayer");
tr.AddNewlyCreatedDBObject(btr, true);
}
tr.Commit();
}
}
catch (Autodesk.AutoCAD.Runtime.Exception ex)
{
AcadApp.ShowAlertDialog("ERROR: " + "\n" + ex.Message + "\nSOURCE: " + ex.StackTrace);
}
return blkid;
}
~'J'~ 这是一个用于在布局中按布局名称插入块的方法。我现在会稍微更改一下,但这是一个很好的例子。
using System;
using System.Drawing;
using System.Windows.Forms;
using System.Collections;
using System.IO;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.Geometry;
public static ObjectId InsertBlock ( Database db, string loName, string blkName, Point3d insPt ) {
ObjectId RtnObjId = ObjectId.Null;
using ( Transaction Trans = db.TransactionManager.StartTransaction( ) ) {
DBDictionary LoDict = Trans.GetObject( db.LayoutDictionaryId, OpenMode.ForRead ) as DBDictionary;
foreach ( DictionaryEntry de in LoDict ) {
if ( string.Compare( ( string )de.Key, loName, true ).Equals( 0 ) ) {
Layout Lo = Trans.GetObject( ( ObjectId )de.Value, OpenMode.ForWrite ) as Layout;
BlockTable BlkTbl = Trans.GetObject( db.BlockTableId, OpenMode.ForRead ) as BlockTable;
BlockTableRecord LoRec = Trans.GetObject( Lo.BlockTableRecordId, OpenMode.ForRead ) as BlockTableRecord;
ObjectId BlkTblRecId = GetNonErasedTableRecordId( BlkTbl.Id, blkName );
if ( BlkTblRecId.IsNull ) {
string BlkPath = HostApplicationServices.Current.FindFile( blkName + ".dwg", db, FindFileHint.Default );
if ( string.IsNullOrEmpty( BlkPath ) )
return RtnObjId;
BlkTbl.UpgradeOpen( );
using ( Database tempDb = new Database( false, true ) ) {
tempDb.ReadDwgFile( BlkPath, FileShare.Read, true, null );
db.Insert( blkName, tempDb, false );
}
BlkTblRecId = GetNonErasedTableRecordId( BlkTbl.Id, blkName );
}
LoRec.UpgradeOpen( );
BlockReference BlkRef = new BlockReference( insPt, BlkTblRecId );
LoRec.AppendEntity( BlkRef );
Trans.AddNewlyCreatedDBObject( BlkRef, true );
BlockTableRecord BlkTblRec = Trans.GetObject( BlkTblRecId, OpenMode.ForRead ) as BlockTableRecord;
if ( BlkTblRec.HasAttributeDefinitions ) {
foreach ( ObjectId objId in BlkTblRec ) {
AttributeDefinition AttDef = Trans.GetObject( objId, OpenMode.ForRead ) as AttributeDefinition;
if ( AttDef != null ) {
AttributeReference AttRef = new AttributeReference( );
AttRef.SetAttributeFromBlock( AttDef, BlkRef.BlockTransform );
BlkRef.AttributeCollection.AppendAttribute( AttRef );
Trans.AddNewlyCreatedDBObject( AttRef, true );
}
}
}
Trans.Commit( );
}
}
}
return RtnObjId;
}
谢谢Oleg。忘记添加Tony T.
public static ObjectId GetNonErasedTableRecordId( ObjectId TableId, string Name )
// Posted by Tony Tanzillo 01Sept2006
{
ObjectId id = ObjectId.Null;
using( Transaction tr = TableId.Database.TransactionManager.StartTransaction() )
{
SymbolTable table = (SymbolTable) tr.GetObject( TableId, OpenMode.ForRead );
if( table.Has( Name ) )
{
id = table;
if( !id.IsErased )
return id;
foreach( ObjectId recId in table )
{
if( ! recId.IsErased )
{
SymbolTableRecord rec = (SymbolTableRecord) tr.GetObject( recId, OpenMode.ForRead );
if( string.Compare( rec.Name, Name, true ) == 0 )
return recId;
}
}
}
}
return id;
}
此代码将现有块放置在 ModelSpace 中,添加属性并将其放置在正确的层上。如果块具有注释性,它还会管理当前注释比例。
感谢 fro2001 的这段伟大的代码!
' This procedure will insert a block into the current drawing. It also controls the defined attributes and it will
' add the current Annotation Scale if the block is Annotative.
' Code contribution:
' - fro2001 - via TheSwamp.org
Public Sub hzInsertBlockMSWithAttributes(ByVal pntInsert As Geometry.Point3d,
ByVal strBlockName As String,
ByVal dScale As Double,
ByVal strLayerName As String,
ByVal arrAttrValues As ArrayList)
Dim db As Database = HostApplicationServices.WorkingDatabase
Using tr As Transaction = db.TransactionManager.StartTransaction
Dim bt As BlockTable = db.BlockTableId.GetObject(OpenMode.ForRead)
Dim btrMS As BlockTableRecord = bt(BlockTableRecord.ModelSpace).GetObject(OpenMode.ForRead)
If Not bt.Has(strBlockName) Then
Exit Sub
Else
btrMS.UpgradeOpen()
End If
Dim btr As BlockTableRecord = bt(strBlockName).GetObject(OpenMode.ForRead)
Dim bref As New BlockReference(pntInsert, btr.ObjectId)
btrMS.AppendEntity(bref)
tr.AddNewlyCreatedDBObject(bref, True)
' set annotation scale if block is annotative
If btr.Annotative = AnnotativeStates.True Then
Dim ocm As ObjectContextManager = db.ObjectContextManager
Dim occ As ObjectContextCollection = ocm.GetContextCollection("ACDB_ANNOTATIONSCALES")
Internal.ObjectContexts.AddContext(bref, occ.CurrentContext)
End If
' set attributes and values
' TODO: Set attribute to layer of block or layer of original definition, now it will be placed on layer 0
' TODO: Check if attribute is annotative, it is possible to create non-annotative blocks with annotative attributes
Dim ccAttCounter As Integer = 0
For Each objId As ObjectId In btr
Dim ent As Entity = objId.GetObject(OpenMode.ForRead)
If TypeOf ent Is AttributeDefinition Then
ent.UpgradeOpen()
Dim attDef As AttributeDefinition = CType(ent, AttributeDefinition)
Dim attRef As New AttributeReference
attRef.SetAttributeFromBlock(attDef, bref.BlockTransform)
' check if there is a value to add
If arrAttrValues.Count - 1 >= ccAttCounter Then
attRef.TextString = arrAttrValues(ccAttCounter).ToString.Trim
Else
attRef.TextString = ""
End If
bref.AttributeCollection.AppendAttribute(attRef)
tr.AddNewlyCreatedDBObject(attRef, True)
ccAttCounter += 1
End If
Next
' set layer
' TODO: Check if layername exist
bref.Layer = strLayerName
' commit
tr.Commit()
End Using
End Sub
嗨,
试图帮助某人 http://www.acadnetwork.com/,谁想删除重复的块引用。
被视为重复块,具有相同的名称,图层,插入点,旋转和比例的块。
我首先使用“Duplicate”扩展方法编写了一个C#例程,我认为它是改进我非常新的F#学习的一个很好的练习。
下面是两种实现。
using System;
using System.Collections.Generic;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.Runtime;
namespace DuplicateTest
{
public static class BlockRefExtension
{
public static bool Duplicate(this BlockReference blk1, BlockReference blk2)
{
Tolerance tol = new Tolerance(1e-6, 1e-6);
return
blk1.OwnerId == blk2.OwnerId &&
blk1.Name == blk2.Name &&
blk1.Layer == blk2.Layer &&
Math.Round(blk1.Rotation, 5) == Math.Round(blk2.Rotation, 5) &&
blk1.Position.IsEqualTo(blk2.Position, tol) &&
blk1.ScaleFactors.IsEqualTo(blk2.ScaleFactors, tol);
}
}
public class Commands
{
public void DelDupBlkRef()
{
try
{
int del = DeleteDuplicatedBlockRef();
Application.ShowAlertDialog(del.ToString() + " duplicated block(s) have been erased");
}
catch (System.Exception e)
{
Application.ShowAlertDialog("\nError: " + e.Message);
}
}
private int DeleteDuplicatedBlockRef()
{
Document doc = Application.DocumentManager.MdiActiveDocument;
Database db = doc.Database;
int result = 0;
using (Transaction tr = db.TransactionManager.StartTransaction())
{
BlockTable bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead);
foreach (ObjectId id in bt)
{
BlockTableRecord btr =
(BlockTableRecord)tr.GetObject(id, OpenMode.ForWrite);
ObjectIdCollection idCol = btr.GetBlockReferenceIds(true, false);
for (int i = 0; iBlockTableRecord
for oId in btr.GetBlockReferenceIds(true, false) do
lstBlockReference :: lst
lst
let rec findDups acc blks =
match blks with
| [] -> acc
| h :: t -> let pair = List.partition (fun x -> Duplicate x h) t
findDups (acc @ (fst pair)) (snd pair)
let delBlk lst =
List.iter (fun (x: BlockReference) -> x.Erase()) lst
lst.Length
let cnt = tr.GetObject(db.BlockTableId, OpenMode.ForRead) :?> BlockTable
|> getRefs |> findDups [] |> delBlk
tr.Commit()
cnt
[]
let Test() =
try
let del = DeleteDuplicatedBlockRef()
Application.ShowAlertDialog(del.ToString() + " duplicated block(s) have been erased")
with
|ex -> Application.ShowAlertDialog(ex.Message)
一个简单的小程序,它将改变基于动态块的所有块引用的Visibilty参数代码6] 这个函数将按名称获取所有动态块。
通常这是一个简单的过滤器,但动态块一旦更改动态属性就会变得匿名。
public static ObjectIdCollection GetDynamicBlocksByName(string BlkName)
{
ObjectIdCollection res = new ObjectIdCollection();
Database db = Application.DocumentManager.MdiActiveDocument.Database;
using (Transaction trans = db.TransactionManager.StartTransaction())
{
//get the blockTable and iterate through all block Defs
BlockTable bt = (BlockTable)trans.GetObject(db.BlockTableId, OpenMode.ForRead);
foreach (ObjectId btrId in bt)
{
//get the block Def and see if it is anonymous
BlockTableRecord btr = (BlockTableRecord)trans.GetObject(btrId, OpenMode.ForRead);
if (btr.IsDynamicBlock && btr.Name.Equals(BlkName))
{
//get all anonymous blocks from this dynamic block
ObjectIdCollection anonymousIds = btr.GetAnonymousBlockIds();
ObjectIdCollection dynBlockRefs = new ObjectIdCollection();
foreach (ObjectId anonymousBtrId in anonymousIds)
{
//get the anonymous block
BlockTableRecord anonymousBtr = (BlockTableRecord)trans.GetObject(anonymousBtrId, OpenMode.ForRead);
//and all references to this block
ObjectIdCollection blockRefIds = anonymousBtr.GetBlockReferenceIds(true, true);
foreach (ObjectId id in blockRefIds) dynBlockRefs.Add(id);
}
res = dynBlockRefs;
break;
}
}
trans.Commit();
}
return res;
}
嗨,
这是属性提取的小例子。
我尝试使用Linq扩展方法和扩展类中定义的其他一些方法以“声明性”风格编写它(感谢Thorsten 'kaefer' @ TheSwamp的“邪恶”方法)。
提取收集在 System.Data.DataTable 中,以便可以轻松地将其转换为 AutoCAD 表、Exel 工作表等。
DataTable.WriteXls() 扩展方法在与 Excel 应用程序交互时使用后期绑定,以避免版本引用依赖关系。
BlockAttribute 类,它定义了一个新类型,其主要属性为:
- Block:块(有效)名称 ;
- 属性:块属性的字典,其中Key是标签,Value是文本字符串。
BlockAttributeEqualityComparer 类实现了 IEqualityComparer
接口,以便 BlockAttribute 集合可以与某些 Linq 扩展方法一起使用,如 GroupBy()。
using System;
using System.Collections.Generic;
using System.Linq;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using AcAp = Autodesk.AutoCAD.ApplicationServices.Application;
namespace AttributeExtraction
{
public class BlockAttribute
{
private string _name;
private Dictionary _atts;
// Public read only properties
public string Name
{
get { return _name; }
}
public Dictionary Attributes
{
get { return _atts; }
}
public string this
{
get { return _atts; }
}
// Constructors
public BlockAttribute(BlockReference br)
{
SetProperties(br);
}
public BlockAttribute(ObjectId id)
{
Document doc = AcAp.DocumentManager.MdiActiveDocument;
using (Transaction tr = doc.TransactionManager.StartTransaction())
{
SetProperties(tr.GetObject(id, OpenMode.ForRead) as BlockReference);
}
}
// Public method
new public string ToString()
{
if (_atts != null && _atts.Count > 0)
return string.Format("{0}: {1}",
_name,
_atts.Select(a => string.Format("{0}={1}", a.Key, a.Value))
.Aggregate((a, b) => string.Format("{0}; {1}", a, b)));
return _name;
}
// Private method
private void SetProperties(BlockReference br)
{
if (br == null) return;
_name = br.GetEffectiveName();
_atts = new Dictionary();
br.AttributeCollection
.GetObjects()
.Iterate(att => _atts.Add(att.Tag.ToUpper(), att.TextString));
}
}
public class BlockAttributeEqualityComparer : IEqualityComparer
{
public bool Equals(BlockAttribute x, BlockAttribute y)
{
return
x.Name.Equals(y.Name, StringComparison.CurrentCultureIgnoreCase) &&
x.Attributes.SequenceEqual(y.Attributes);
}
public int GetHashCode(BlockAttribute obj)
{
return base.GetHashCode();
}
}
}
扩展类提供了扩展方法,允许以更“声明性”的风格编写代码
,并提供从BlockAttribute集合构建DataTable并将此DataTable转换为xls,csv文件或AutoCAD表的方法。
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Linq;
using Autodesk.AutoCAD.DatabaseServices;
using AcDataTable = Autodesk.AutoCAD.DatabaseServices.DataTable;
namespace AttributeExtraction
{
public static class Extensions
{
// Opens a DBObject in ForRead mode (kaefer @ TheSwamp)
public static T GetObject(this ObjectId id) where T : DBObject
{
return id.GetObject(OpenMode.ForRead);
}
// Opens a DBObject in the given mode (kaefer @ TheSwamp)
public static T GetObject(this ObjectId id, OpenMode mode) where T : DBObject
{
return id.GetObject(mode) as T;
}
// Opens a collection of DBObject in ForRead mode (kaefer @ TheSwamp)
public static IEnumerable GetObjects(this IEnumerable ids) where T : DBObject
{
return ids.GetObjects(OpenMode.ForRead);
}
// Opens a collection of DBObject in the given mode (kaefer @ TheSwamp)
public static IEnumerable GetObjects(this IEnumerable ids, OpenMode mode) where T : DBObject
{
return ids
.Cast()
.Select(id => id.GetObject(mode))
.Where(res => res != null);
}
// Applies the given Action to each element of the collection (mimics the F# Seq.iter function).
public static void Iterate(this IEnumerable collection, Action action)
{
foreach (T item in collection) action(item);
}
// Applies the given Action to each element of the collection (mimics the F# Seq.iteri function).
// The integer passed to the Action indicates the index of element.
public static void Iterate(this IEnumerable collection, Action action)
{
int i = 0;
foreach (T item in collection) action(item, i++);
}
// Gets the block effective name (anonymous dynamic blocs).
public static string GetEffectiveName(this BlockReference br)
{
if (br.IsDynamicBlock)
return br.DynamicBlockTableRecord.GetObject().Name;
return br.Name;
}
// Creates a System.Data.DataTable from a BlockAttribute collection.
public static System.Data.DataTable ToDataTable(this IEnumerable blockAtts, string name)
{
System.Data.DataTable dTable = new System.Data.DataTable(name);
dTable.Columns.Add("Name", typeof(string));
dTable.Columns.Add("Quantity", typeof(int));
blockAtts
.GroupBy(blk => blk, (blk, blks) => new { Block = blk, Count = blks.Count() }, new BlockAttributeEqualityComparer())
.Iterate(row =>
{
System.Data.DataRow dRow = dTable.Rows.Add(row.Block.Name, row.Count);
row.Block.Attributes.Iterate(att =>
{
if (!dTable.Columns.Contains(att.Key))
dTable.Columns.Add(att.Key);
dRow = att.Value;
});
});
return dTable;
}
// Gets the column names collection of the datatable
public static IEnumerable GetColumnNames(this System.Data.DataTable dataTbl)
{
return dataTbl.Columns.Cast().Select(col => col.ColumnName);
}
// Writes an Excel file from the datatable (using late binding)
public static void WriteXls(this System.Data.DataTable dataTbl, string filename, string sheetName, bool visible)
{
object mis = Type.Missing;
object xlApp = LateBinding.GetOrCreateInstance("Excel.Application");
xlApp.Set("DisplayAlerts", false);
object workbooks = xlApp.Get("Workbooks");
object workbook, worksheet;
if (File.Exists(filename))
workbook = workbooks.Invoke("Open", filename);
else
workbook = workbooks.Invoke("Add", mis);
if (string.IsNullOrEmpty(sheetName))
worksheet = workbook.Get("Activesheet");
else
{
object worksheets = workbook.Get("Worksheets");
try
{
worksheet = worksheets.Get("Item", sheetName);
worksheet.Get("Cells").Invoke("Clear");
}
catch
{
worksheet = worksheets.Invoke("Add", mis);
worksheet.Set("Name", sheetName);
}
}
object range = worksheet.Get("Cells");
dataTbl.GetColumnNames()
.Iterate((name, i) => range.Get("Item", 1, i + 1).Set("Value2", name));
dataTbl.Rows
.Cast()
.Iterate((row, i) => row.ItemArray
.Iterate((item, j) => range.Get("Item", i + 2, j + 1).Set("Value2", item)));
xlApp.Set("DisplayAlerts", true);
if (visible)
{
xlApp.Set("Visible", true);
}
else
{
if (File.Exists(filename))
workbook.Invoke("Save");
else
{
int fileFormat =
string.Compare("11.0", (string)xlApp.Get("Version"))string.Format("{0},{1}", s1, s2)));
dataTbl.Rows
.Cast()
.Select(row => row.ItemArray.Aggregate((s1, s2) => string.Format("{0},{1}", s1, s2)))
.Iterate(line => writer.WriteLine(line));
}
}
// Creates an AutoCAD Table from the datatable.
public static Table ToAcadTable(this System.Data.DataTable dataTbl, double rowHeight, double columnWidth)
{
//return dataTbl.Rows.Cast().ToAcadTable(dataTbl.TableName, dataTbl.GetColumnNames(), rowHeight, columnWidth);
Table tbl = new Table();
tbl.Rows.Height = rowHeight;
tbl.Columns.Width = columnWidth;
tbl.InsertColumns(0, columnWidth, dataTbl.Columns.Count - 1);
tbl.InsertRows(0, rowHeight, dataTbl.Rows.Count + 1);
tbl.Cells.Value = dataTbl.TableName;
dataTbl.GetColumnNames()
.Iterate((name, i) => tbl.Cells.Value = name);
dataTbl.Rows
.Cast()
.Iterate((row, i) =>
row.ItemArray.Iterate((item, j) =>
tbl.Cells.Value = item));
return tbl;
}
}
}
LateBinding类提供了帮助程序,以更友好的风格编写后期绑定指令(感谢Thorsten和Tony T)。
using BF = System.Reflection.BindingFlags;
namespace AttributeExtraction
{
public static class LateBinding
{
public static object GetInstance(string appName)
{
return System.Runtime.InteropServices.Marshal.GetActiveObject(appName);
}
public static object CreateInstance(string appName)
{
return System.Activator.CreateInstance(System.Type.GetTypeFromProgID(appName));
}
public static object GetOrCreateInstance(string appName)
{
try { return GetInstance(appName); }
catch { return CreateInstance(appName); }
}
public static object Get(this object obj, string propName, params object[] parameter)
{
return obj.GetType().InvokeMember(propName, BF.GetProperty, null, obj, parameter);
}
public static void Set(this object obj, string propName, params object[] parameter)
{
obj.GetType().InvokeMember(propName, BF.SetProperty, null, obj, parameter);
}
public static object Invoke(this object obj, string methName, params object[] parameter)
{
return obj.GetType().InvokeMember(methName, BF.InvokeMethod, null, obj, parameter);
}
public static void ReleaseInstance(this object obj)
{
System.Runtime.InteropServices.Marshal.ReleaseComObject(obj);
}
}
}
A 测试命令
using System.Linq;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Runtime;
using AcAp = Autodesk.AutoCAD.ApplicationServices.Application;
namespace AttributeExtraction
{
public class Commands
{
public void Test()
{
Document doc = AcAp.DocumentManager.MdiActiveDocument;
Database db = doc.Database;
Editor ed = doc.Editor;
TypedValue[] filter = { new TypedValue(0, "INSERT") };
PromptSelectionResult psr = ed.GetSelection(new SelectionFilter(filter));
if (psr.Status != PromptStatus.OK) return;
PromptPointResult ppr = ed.GetPoint("\nInsertion point: ");
if (ppr.Status != PromptStatus.OK) return;
using (Transaction tr = db.TransactionManager.StartTransaction())
{
System.Data.DataTable dataTable = psr.Value.GetObjectIds()
.Select(id => new BlockAttribute(id.GetObject()))
.ToDataTable("Extraction");
Table tbl = dataTable.ToAcadTable(9.0, 40.0);
tbl.Position = ppr.Value.TransformBy(ed.CurrentUserCoordinateSystem);
BlockTableRecord btr = db.CurrentSpaceId.GetObject(OpenMode.ForWrite);
btr.AppendEntity(tbl);
tr.AddNewlyCreatedDBObject(tbl, true);
try
{
string filename = (string)AcAp.GetSystemVariable("dwgprefix") + "Extraction.xls";
dataTable.WriteXls(filename, null, true);
}
catch
{
AcAp.ShowAlertDialog("Failed to open Excel");
}
tr.Commit();
}
}
}
}
我在上面的例子中添加了一些方法:System。Data.Datatable.WriteCsv(将数据表写入Csv文件)和System。Data.DataTable.WriteXls(将数据表写入Excel表中),它使用后期绑定来避免Excel版本依赖。LateBinding类提供了使后期绑定指令更具可读性的方法。
棒极了,这就是你的小例子:棒极了。
这里有一个基本的F#版本做同样的事情;它从选择集中的块参照中读取属性,对不同的属性集进行计数,将此信息存储在数据表中,并最终将其转换为AutoCAD表格。
我们的目标不是在gile的原创基础上进行改进(这几乎是不可能的),而是说明实现中的典型差异。
-用绑定函数代替扩展方法
-用流水线操作(| >)和函数组合(>>)代替方法链接
-与扩展方法相比,用相反的参数顺序来支持流水线操作
-使用支持IEquatable和IStructuralEquatable的数据类型,避免了对overriden Equals和GetHashCode方法的需要
-尝试“在小范围内”更具命令性,因为
对于bar中的foo...
读起来比
bar | > seq . ITER(fun foo-->...)
代码12]
已编辑: getObjects需要一个类型批注才能成为泛型
页:
[1]
2