乐筑天下

搜索
欢迎各位开发者和用户入驻本平台 尊重版权,从我做起,拒绝盗版,拒绝倒卖 签到、发布资源、邀请好友注册,可以获得银币 请注意保管好自己的密码,避免账户资金被盗
查看: 211|回复: 13

. NET块例程

[复制链接]

116

主题

996

帖子

9

银币

顶梁支柱

Rank: 50Rank: 50

铜币
1466
发表于 2010-1-27 03:05:23 | 显示全部楼层 |阅读模式
AutoCAD块的库线程
鼓励成员在中发布有关
AutoCAD块的任何函数、方法和片段。NET : C#、VB、F#、Python等
请随意添加注释、描述性注释、限制和图片来记录您的帖子。
请以常规主题发布问题。

本帖以下内容被隐藏保护;需要你回复后,才能看到!

游客,如果您要查看本帖隐藏内容请回复
回复

使用道具 举报

1

主题

1069

帖子

1050

银币

初露锋芒

Rank: 3Rank: 3Rank: 3

铜币
69
发表于 2010-1-28 07:15:10 | 显示全部楼层
下面是一个非常基本的例子,如何正确创建块,我希望
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Text;
  4. using Autodesk.AutoCAD.DatabaseServices;
  5. using Autodesk.AutoCAD.GraphicsInterface;
  6. using Autodesk.AutoCAD.Runtime;
  7. using Autodesk.AutoCAD.Geometry;
  8. using Autodesk.AutoCAD.ApplicationServices;
  9. using AcadApp = Autodesk.AutoCAD.ApplicationServices.Application;
  10. using Autodesk.AutoCAD.EditorInput;
  11. .................................................  
  12.       public static ObjectId CreateLabelBlock(string blockname)
  13.         {
  14.             ObjectId blkid = ObjectId.Null;
  15.             try
  16.             {
  17.                 Database db = HostApplicationServices.WorkingDatabase;
  18.                 using (Transaction tr = db.TransactionManager.StartTransaction())
  19.                 {
  20.                     BlockTable bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForWrite, false);
  21.                     if (bt.Has(blockname))
  22.                     {
  23.                         blkid = bt[blockname];
  24.                     }
  25.                     else
  26.                     {
  27.                         BlockTableRecord btr = new BlockTableRecord();
  28.                         btr.Name = blockname;
  29.                         btr.Explodable = true;
  30.                         btr.Origin = new Point3d(0, 0, 0);
  31.                         btr.Units = UnitsValue.Inches;
  32.                         btr.BlockScaling = BlockScaling.Any;
  33.                         Line line = new Line(new Point3d(-2, -0.4, 0), new Point3d(2, -0.4, 0));
  34.                         line.Layer = "0";
  35.                         line.ColorIndex = 14;
  36.                         btr.AppendEntity(line);
  37.                         line = new Line(new Point3d(-2, 0.4, 0), new Point3d(2, 0.4, 0));
  38.                         line.Layer = "0";
  39.                         line.ColorIndex = 14;
  40.                         btr.AppendEntity(line);
  41.                         line = new Line(new Point3d(2, -0.4, 0), new Point3d(2, 0.4, 0));
  42.                         line.Layer = "0";
  43.                         line.ColorIndex = 14;
  44.                         btr.AppendEntity(line);
  45.                         line = new Line(new Point3d(-2, -0.4, 0), new Point3d(-2, 0.4, 0));
  46.                         line.Layer = "0";
  47.                         line.ColorIndex = 14;
  48.                         btr.AppendEntity(line);
  49.                         AcadApp.SetSystemVariable("CECOLOR", "ByBlock");
  50.                         
  51.                         AttributeDefinition ad = new AttributeDefinition();
  52.                         ad.Layer = "0";
  53.                         //by default applied a current text style
  54.                         ad.Tag = "DETAIL";
  55.                         ad.TextString = "X-Ladder";
  56.                         ad.Prompt = "Detail name";
  57.                         ad.Position = new Point3d(0, 0, 0);
  58.                         ad.HorizontalMode = TextHorizontalMode.TextMid;
  59.                         ad.VerticalMode = TextVerticalMode.TextVerticalMid;
  60.                         ad.AlignmentPoint = ad.Position;
  61.                         btr.AppendEntity(ad);
  62.                         blkid = bt.Add(btr);
  63.                         AcadApp.SetSystemVariable("CECOLOR", "ByLayer");
  64.                         tr.AddNewlyCreatedDBObject(btr, true);
  65.                     }
  66.                     tr.Commit();
  67.                 }
  68.             }
  69.             catch (Autodesk.AutoCAD.Runtime.Exception ex)
  70.             {
  71.                 AcadApp.ShowAlertDialog("ERROR: " + "\n" + ex.Message + "\nSOURCE: " + ex.StackTrace);
  72.             }
  73.             return blkid;
  74.         }

~'J'~
回复

使用道具 举报

28

主题

249

帖子

7

银币

后起之秀

Rank: 20Rank: 20Rank: 20Rank: 20

铜币
361
发表于 2010-1-28 10:59:26 | 显示全部楼层
这是一个用于在布局中按布局名称插入块的方法。我现在会稍微更改一下,但这是一个很好的例子。
  1. using System;
  2. using System.Drawing;
  3. using System.Windows.Forms;
  4. using System.Collections;
  5. using System.IO;
  6. using Autodesk.AutoCAD.ApplicationServices;
  7. using Autodesk.AutoCAD.DatabaseServices;
  8. using Autodesk.AutoCAD.Runtime;
  9. using Autodesk.AutoCAD.Geometry;
  10. public static ObjectId InsertBlock ( Database db, string loName, string blkName, Point3d insPt ) {
  11.     ObjectId RtnObjId = ObjectId.Null;
  12.     using ( Transaction Trans = db.TransactionManager.StartTransaction( ) ) {
  13.         DBDictionary LoDict = Trans.GetObject( db.LayoutDictionaryId, OpenMode.ForRead ) as DBDictionary;
  14.         foreach ( DictionaryEntry de in LoDict ) {
  15.             if ( string.Compare( ( string )de.Key, loName, true ).Equals( 0 ) ) {
  16.                 Layout Lo = Trans.GetObject( ( ObjectId )de.Value, OpenMode.ForWrite ) as Layout;
  17.                 BlockTable BlkTbl = Trans.GetObject( db.BlockTableId, OpenMode.ForRead ) as BlockTable;
  18.                 BlockTableRecord LoRec = Trans.GetObject( Lo.BlockTableRecordId, OpenMode.ForRead ) as BlockTableRecord;
  19.                 ObjectId BlkTblRecId = GetNonErasedTableRecordId( BlkTbl.Id, blkName );
  20.                 if ( BlkTblRecId.IsNull ) {
  21.                     string BlkPath = HostApplicationServices.Current.FindFile( blkName + ".dwg", db, FindFileHint.Default );
  22.                     if ( string.IsNullOrEmpty( BlkPath ) )
  23.                         return RtnObjId;
  24.                     BlkTbl.UpgradeOpen( );
  25.                     using ( Database tempDb = new Database( false, true ) ) {
  26.                         tempDb.ReadDwgFile( BlkPath, FileShare.Read, true, null );
  27.                         db.Insert( blkName, tempDb, false );
  28.                     }
  29.                     BlkTblRecId = GetNonErasedTableRecordId( BlkTbl.Id, blkName );
  30.                 }
  31.                 LoRec.UpgradeOpen( );
  32.                 BlockReference BlkRef = new BlockReference( insPt, BlkTblRecId );
  33.                 LoRec.AppendEntity( BlkRef );
  34.                 Trans.AddNewlyCreatedDBObject( BlkRef, true );
  35.                 BlockTableRecord BlkTblRec = Trans.GetObject( BlkTblRecId, OpenMode.ForRead ) as BlockTableRecord;
  36.                 if ( BlkTblRec.HasAttributeDefinitions ) {
  37.                     foreach ( ObjectId objId in BlkTblRec ) {
  38.                         AttributeDefinition AttDef = Trans.GetObject( objId, OpenMode.ForRead ) as AttributeDefinition;
  39.                         if ( AttDef != null ) {
  40.                             AttributeReference AttRef = new AttributeReference( );
  41.                             AttRef.SetAttributeFromBlock( AttDef, BlkRef.BlockTransform );
  42.                             BlkRef.AttributeCollection.AppendAttribute( AttRef );
  43.                             Trans.AddNewlyCreatedDBObject( AttRef, true );
  44.                         }
  45.                     }
  46.                 }
  47.                 Trans.Commit( );
  48.             }
  49.         }
  50.     }
  51.     return RtnObjId;
  52. }

谢谢Oleg。忘记添加Tony T.
  1. public static ObjectId GetNonErasedTableRecordId( ObjectId TableId, string Name )
  2.     // Posted by Tony Tanzillo 01Sept2006
  3. {
  4.    ObjectId id = ObjectId.Null;
  5.    using( Transaction tr = TableId.Database.TransactionManager.StartTransaction() )
  6.    {
  7.       SymbolTable table = (SymbolTable) tr.GetObject( TableId, OpenMode.ForRead );
  8.       if( table.Has( Name ) )
  9.       {
  10.          id = table[Name];
  11.          if( !id.IsErased )
  12.             return id;
  13.          foreach( ObjectId recId in table )
  14.          {
  15.             if( ! recId.IsErased )
  16.             {
  17.                SymbolTableRecord rec = (SymbolTableRecord) tr.GetObject( recId, OpenMode.ForRead );
  18.                if( string.Compare( rec.Name, Name, true ) == 0 )
  19.                   return recId;
  20.             }
  21.          }
  22.       }
  23.    }
  24.    return id;
  25. }
回复

使用道具 举报

14

主题

275

帖子

6

银币

后起之秀

Rank: 20Rank: 20Rank: 20Rank: 20

铜币
331
发表于 2010-8-15 09:45:16 | 显示全部楼层
此代码将现有块放置在 ModelSpace 中,添加属性并将其放置在正确的层上。如果块具有注释性,它还会管理当前注释比例。
感谢 fro2001 的这段伟大的代码!
  1.   ' This procedure will insert a block into the current drawing. It also controls the defined attributes and it will
  2.   ' add the current Annotation Scale if the block is Annotative.
  3.   ' Code contribution:
  4.   ' - fro2001 - via TheSwamp.org
  5.   Public Sub hzInsertBlockMSWithAttributes(ByVal pntInsert As Geometry.Point3d,
  6.                                            ByVal strBlockName As String,
  7.                                            ByVal dScale As Double,
  8.                                            ByVal strLayerName As String,
  9.                                            ByVal arrAttrValues As ArrayList)
  10.     Dim db As Database = HostApplicationServices.WorkingDatabase
  11.     Using tr As Transaction = db.TransactionManager.StartTransaction
  12.       Dim bt As BlockTable = db.BlockTableId.GetObject(OpenMode.ForRead)
  13.       Dim btrMS As BlockTableRecord = bt(BlockTableRecord.ModelSpace).GetObject(OpenMode.ForRead)
  14.       If Not bt.Has(strBlockName) Then
  15.         Exit Sub
  16.       Else
  17.         btrMS.UpgradeOpen()
  18.       End If
  19.       Dim btr As BlockTableRecord = bt(strBlockName).GetObject(OpenMode.ForRead)
  20.       Dim bref As New BlockReference(pntInsert, btr.ObjectId)
  21.       btrMS.AppendEntity(bref)
  22.       tr.AddNewlyCreatedDBObject(bref, True)
  23.       ' set annotation scale if block is annotative
  24.       If btr.Annotative = AnnotativeStates.True Then
  25.         Dim ocm As ObjectContextManager = db.ObjectContextManager
  26.         Dim occ As ObjectContextCollection = ocm.GetContextCollection("ACDB_ANNOTATIONSCALES")
  27.         Internal.ObjectContexts.AddContext(bref, occ.CurrentContext)
  28.       End If
  29.       ' set attributes and values
  30.       ' TODO: Set attribute to layer of block or layer of original definition, now it will be placed on layer 0
  31.       ' TODO: Check if attribute is annotative, it is possible to create non-annotative blocks with annotative attributes
  32.       Dim ccAttCounter As Integer = 0
  33.       For Each objId As ObjectId In btr
  34.         Dim ent As Entity = objId.GetObject(OpenMode.ForRead)
  35.         If TypeOf ent Is AttributeDefinition Then
  36.           ent.UpgradeOpen()
  37.           Dim attDef As AttributeDefinition = CType(ent, AttributeDefinition)
  38.           Dim attRef As New AttributeReference
  39.           attRef.SetAttributeFromBlock(attDef, bref.BlockTransform)
  40.           ' check if there is a value to add
  41.           If arrAttrValues.Count - 1 >= ccAttCounter Then
  42.             attRef.TextString = arrAttrValues(ccAttCounter).ToString.Trim
  43.           Else
  44.             attRef.TextString = ""
  45.           End If
  46.           bref.AttributeCollection.AppendAttribute(attRef)
  47.           tr.AddNewlyCreatedDBObject(attRef, True)
  48.           ccAttCounter += 1
  49.         End If
  50.       Next
  51.       ' set layer
  52.       ' TODO: Check if layername exist
  53.       bref.Layer = strLayerName
  54.       ' commit
  55.       tr.Commit()
  56.     End Using
  57.   End Sub

回复

使用道具 举报

15

主题

687

帖子

169

银币

中流砥柱

Rank: 25

铜币
582
发表于 2010-11-23 17:43:48 | 显示全部楼层
嗨,
试图帮助某人 http://www.acadnetwork.com/,谁想删除重复的块引用。
被视为重复块,具有相同的名称,图层,插入点,旋转和比例的块。
我首先使用“Duplicate”扩展方法编写了一个C#例程,我认为它是改进我非常新的F#学习的一个很好的练习。
下面是两种实现。
  1. using System;
  2. using System.Collections.Generic;
  3. using Autodesk.AutoCAD.ApplicationServices;
  4. using Autodesk.AutoCAD.DatabaseServices;
  5. using Autodesk.AutoCAD.EditorInput;
  6. using Autodesk.AutoCAD.Geometry;
  7. using Autodesk.AutoCAD.Runtime;
  8. namespace DuplicateTest
  9. {
  10.     public static class BlockRefExtension
  11.     {
  12.         public static bool Duplicate(this BlockReference blk1, BlockReference blk2)
  13.         {
  14.             Tolerance tol = new Tolerance(1e-6, 1e-6);
  15.             return
  16.                 blk1.OwnerId == blk2.OwnerId &&
  17.                 blk1.Name == blk2.Name &&
  18.                 blk1.Layer == blk2.Layer &&
  19.                 Math.Round(blk1.Rotation, 5) == Math.Round(blk2.Rotation, 5) &&
  20.                 blk1.Position.IsEqualTo(blk2.Position, tol) &&
  21.                 blk1.ScaleFactors.IsEqualTo(blk2.ScaleFactors, tol);
  22.         }
  23.     }
  24.     public class Commands
  25.     {
  26.         [CommandMethod("Test")]
  27.         public void DelDupBlkRef()
  28.         {
  29.             try
  30.             {
  31.                 int del = DeleteDuplicatedBlockRef();
  32.                 Application.ShowAlertDialog(del.ToString() + " duplicated block(s) have been erased");
  33.             }
  34.             catch (System.Exception e)
  35.             {
  36.                 Application.ShowAlertDialog("\nError: " + e.Message);
  37.             }
  38.         }
  39.         private int DeleteDuplicatedBlockRef()
  40.         {
  41.             Document doc = Application.DocumentManager.MdiActiveDocument;
  42.             Database db = doc.Database;
  43.             int result = 0;
  44.             using (Transaction tr = db.TransactionManager.StartTransaction())
  45.             {
  46.                 BlockTable bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead);
  47.                 foreach (ObjectId id in bt)
  48.                 {
  49.                     BlockTableRecord btr =
  50.                         (BlockTableRecord)tr.GetObject(id, OpenMode.ForWrite);
  51.                     ObjectIdCollection idCol = btr.GetBlockReferenceIds(true, false);
  52.                     for (int i = 0; i  BlockTableRecord
  53.             for oId in btr.GetBlockReferenceIds(true, false) do
  54.                 lst  BlockReference :: lst
  55.         lst
  56.     let rec findDups acc blks =
  57.         match blks with
  58.         | [] -> acc
  59.         | h :: t -> let pair = List.partition (fun x -> Duplicate x h) t
  60.                     findDups (acc @ (fst pair)) (snd pair)
  61.     let delBlk lst =
  62.         List.iter (fun (x: BlockReference) -> x.Erase()) lst
  63.         lst.Length
  64.                
  65.     let cnt = tr.GetObject(db.BlockTableId, OpenMode.ForRead) :?> BlockTable
  66.               |> getRefs |> findDups [] |> delBlk
  67.     tr.Commit()
  68.     cnt
  69.         
  70. []
  71. let Test() =
  72.     try
  73.         let del = DeleteDuplicatedBlockRef()
  74.         Application.ShowAlertDialog(del.ToString() + " duplicated block(s) have been erased")
  75.     with
  76.         |ex -> Application.ShowAlertDialog(ex.Message)

回复

使用道具 举报

12

主题

64

帖子

3

银币

初露锋芒

Rank: 3Rank: 3Rank: 3

铜币
112
发表于 2010-12-10 05:26:13 | 显示全部楼层
一个简单的小程序,它将改变基于动态块的所有块引用的Visibilty参数代码6]
回复

使用道具 举报

15

主题

687

帖子

169

银币

中流砥柱

Rank: 25

铜币
582
发表于 2011-2-25 14:05:39 | 显示全部楼层
这个函数将按名称获取所有动态块。
通常这是一个简单的过滤器,但动态块一旦更改动态属性就会变得匿名。
  1.         public static ObjectIdCollection GetDynamicBlocksByName(string BlkName)
  2.         {
  3.             ObjectIdCollection res = new ObjectIdCollection();
  4.             Database db = Application.DocumentManager.MdiActiveDocument.Database;
  5.             using (Transaction trans = db.TransactionManager.StartTransaction())
  6.             {
  7.                 //get the blockTable and iterate through all block Defs
  8.                 BlockTable bt = (BlockTable)trans.GetObject(db.BlockTableId, OpenMode.ForRead);
  9.                 foreach (ObjectId btrId in bt)
  10.                 {
  11.                     //get the block Def and see if it is anonymous
  12.                     BlockTableRecord btr = (BlockTableRecord)trans.GetObject(btrId, OpenMode.ForRead);
  13.                     if (btr.IsDynamicBlock && btr.Name.Equals(BlkName))
  14.                     {
  15.                         //get all anonymous blocks from this dynamic block
  16.                         ObjectIdCollection anonymousIds = btr.GetAnonymousBlockIds();
  17.                         ObjectIdCollection dynBlockRefs = new ObjectIdCollection();
  18.                         foreach (ObjectId anonymousBtrId in anonymousIds)
  19.                         {
  20.                             //get the anonymous block
  21.                             BlockTableRecord anonymousBtr = (BlockTableRecord)trans.GetObject(anonymousBtrId, OpenMode.ForRead);
  22.                             //and all references to this block
  23.                             ObjectIdCollection blockRefIds = anonymousBtr.GetBlockReferenceIds(true, true);
  24.                             foreach (ObjectId id in blockRefIds) dynBlockRefs.Add(id);
  25.                         }
  26.                         res = dynBlockRefs;
  27.                         break;
  28.                     }
  29.                 }
  30.                 trans.Commit();
  31.             }
  32.             return res;
  33.         }

回复

使用道具 举报

15

主题

687

帖子

169

银币

中流砥柱

Rank: 25

铜币
582
发表于 2011-11-5 08:12:21 | 显示全部楼层
嗨,
这是属性提取的小例子。
我尝试使用Linq扩展方法和扩展类中定义的其他一些方法以“声明性”风格编写它(感谢Thorsten 'kaefer' @ TheSwamp的“邪恶”方法)。
提取收集在 System.Data.DataTable 中,以便可以轻松地将其转换为 AutoCAD 表、Exel 工作表等。
DataTable.WriteXls() 扩展方法在与 Excel 应用程序交互时使用后期绑定,以避免版本引用依赖关系。
BlockAttribute 类,它定义了一个新类型,其主要属性为:
- Block:块(有效)名称 ;
- 属性:块属性的字典,其中Key是标签,Value是文本字符串。
BlockAttributeEqualityComparer 类实现了 IEqualityComparer
接口,以便 BlockAttribute 集合可以与某些 Linq 扩展方法一起使用,如 GroupBy()。
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using Autodesk.AutoCAD.ApplicationServices;
  5. using Autodesk.AutoCAD.DatabaseServices;
  6. using AcAp = Autodesk.AutoCAD.ApplicationServices.Application;
  7. namespace AttributeExtraction
  8. {
  9.     public class BlockAttribute
  10.     {
  11.         private string _name;
  12.         private Dictionary _atts;
  13.         // Public read only properties
  14.         public string Name
  15.         {
  16.             get { return _name; }
  17.         }
  18.         public Dictionary Attributes
  19.         {
  20.             get { return _atts; }
  21.         }
  22.         public string this[string key]
  23.         {
  24.             get { return _atts[key.ToUpper()]; }
  25.         }
  26.         // Constructors
  27.         public BlockAttribute(BlockReference br)
  28.         {
  29.             SetProperties(br);
  30.         }
  31.         public BlockAttribute(ObjectId id)
  32.         {
  33.             Document doc = AcAp.DocumentManager.MdiActiveDocument;
  34.             using (Transaction tr = doc.TransactionManager.StartTransaction())
  35.             {
  36.                 SetProperties(tr.GetObject(id, OpenMode.ForRead) as BlockReference);
  37.             }
  38.         }
  39.         // Public method
  40.         new public string ToString()
  41.         {
  42.             if (_atts != null && _atts.Count > 0)
  43.                 return string.Format("{0}: {1}",
  44.                     _name,
  45.                     _atts.Select(a => string.Format("{0}={1}", a.Key, a.Value))
  46.                         .Aggregate((a, b) => string.Format("{0}; {1}", a, b)));
  47.             return _name;
  48.         }
  49.         // Private method
  50.         private void SetProperties(BlockReference br)
  51.         {
  52.             if (br == null) return;
  53.             _name = br.GetEffectiveName();
  54.             _atts = new Dictionary();
  55.             br.AttributeCollection
  56.                 .GetObjects()
  57.                 .Iterate(att => _atts.Add(att.Tag.ToUpper(), att.TextString));
  58.         }
  59.     }
  60.     public class BlockAttributeEqualityComparer : IEqualityComparer[B]
  61.     {
  62.         public bool Equals(BlockAttribute x, BlockAttribute y)
  63.         {
  64.             return
  65.                 x.Name.Equals(y.Name, StringComparison.CurrentCultureIgnoreCase) &&
  66.                 x.Attributes.SequenceEqual(y.Attributes);
  67.         }
  68.         public int GetHashCode(BlockAttribute obj)
  69.         {
  70.             return base.GetHashCode();
  71.         }
  72.     }
  73. }

扩展类提供了扩展方法,允许以更“声明性”的风格编写代码
,并提供从BlockAttribute集合构建DataTable并将此DataTable转换为xls,csv文件或AutoCAD表的方法。
  1. using System;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using System.Data;
  5. using System.IO;
  6. using System.Linq;
  7. using Autodesk.AutoCAD.DatabaseServices;
  8. using AcDataTable = Autodesk.AutoCAD.DatabaseServices.DataTable;
  9. namespace AttributeExtraction
  10. {
  11.     public static class Extensions
  12.     {
  13.         // Opens a DBObject in ForRead mode (kaefer @ TheSwamp)
  14.         public static T GetObject(this ObjectId id) where T : DBObject
  15.         {
  16.             return id.GetObject(OpenMode.ForRead);
  17.         }
  18.         // Opens a DBObject in the given mode (kaefer @ TheSwamp)
  19.         public static T GetObject(this ObjectId id, OpenMode mode) where T : DBObject
  20.         {
  21.             return id.GetObject(mode) as T;
  22.         }
  23.         // Opens a collection of DBObject in ForRead mode (kaefer @ TheSwamp)      
  24.         public static IEnumerable GetObjects(this IEnumerable ids) where T : DBObject
  25.         {
  26.             return ids.GetObjects(OpenMode.ForRead);
  27.         }
  28.         // Opens a collection of DBObject in the given mode (kaefer @ TheSwamp)
  29.         public static IEnumerable GetObjects(this IEnumerable ids, OpenMode mode) where T : DBObject
  30.         {
  31.             return ids
  32.                 .Cast()
  33.                 .Select(id => id.GetObject(mode))
  34.                 .Where(res => res != null);
  35.         }
  36.         // Applies the given Action to each element of the collection (mimics the F# Seq.iter function).
  37.         public static void Iterate(this IEnumerable collection, Action action)
  38.         {
  39.             foreach (T item in collection) action(item);
  40.         }
  41.         // Applies the given Action to each element of the collection (mimics the F# Seq.iteri function).
  42.         // The integer passed to the Action indicates the index of element.
  43.         public static void Iterate(this IEnumerable collection, Action action)
  44.         {
  45.             int i = 0;
  46.             foreach (T item in collection) action(item, i++);
  47.         }
  48.         // Gets the block effective name (anonymous dynamic blocs).
  49.         public static string GetEffectiveName(this BlockReference br)
  50.         {
  51.             if (br.IsDynamicBlock)
  52.                 return br.DynamicBlockTableRecord.GetObject[B]().Name;
  53.             return br.Name;
  54.         }
  55.         // Creates a System.Data.DataTable from a BlockAttribute collection.
  56.         public static System.Data.DataTable ToDataTable(this IEnumerable[B] blockAtts, string name)
  57.         {
  58.             System.Data.DataTable dTable = new System.Data.DataTable(name);
  59.             dTable.Columns.Add("Name", typeof(string));
  60.             dTable.Columns.Add("Quantity", typeof(int));
  61.             blockAtts
  62.                 .GroupBy(blk => blk, (blk, blks) => new { Block = blk, Count = blks.Count() }, new BlockAttributeEqualityComparer())
  63.                 .Iterate(row =>
  64.                 {
  65.                     System.Data.DataRow dRow = dTable.Rows.Add(row.Block.Name, row.Count);
  66.                     row.Block.Attributes.Iterate(att =>
  67.                     {
  68.                         if (!dTable.Columns.Contains(att.Key))
  69.                             dTable.Columns.Add(att.Key);
  70.                         dRow[att.Key] = att.Value;
  71.                     });
  72.                 });
  73.             return dTable;
  74.         }
  75.         // Gets the column names collection of the datatable
  76.         public static IEnumerable GetColumnNames(this System.Data.DataTable dataTbl)
  77.         {
  78.             return dataTbl.Columns.Cast().Select(col => col.ColumnName);
  79.         }
  80.         // Writes an Excel file from the datatable (using late binding)
  81.         public static void WriteXls(this System.Data.DataTable dataTbl, string filename, string sheetName, bool visible)
  82.         {
  83.             object mis = Type.Missing;
  84.             object xlApp = LateBinding.GetOrCreateInstance("Excel.Application");
  85.             xlApp.Set("DisplayAlerts", false);
  86.             object workbooks = xlApp.Get("Workbooks");
  87.             object workbook, worksheet;
  88.             if (File.Exists(filename))
  89.                 workbook = workbooks.Invoke("Open", filename);
  90.             else
  91.                 workbook = workbooks.Invoke("Add", mis);
  92.             if (string.IsNullOrEmpty(sheetName))
  93.                 worksheet = workbook.Get("Activesheet");
  94.             else
  95.             {
  96.                 object worksheets = workbook.Get("Worksheets");
  97.                 try
  98.                 {
  99.                     worksheet = worksheets.Get("Item", sheetName);
  100.                     worksheet.Get("Cells").Invoke("Clear");
  101.                 }
  102.                 catch
  103.                 {
  104.                     worksheet = worksheets.Invoke("Add", mis);
  105.                     worksheet.Set("Name", sheetName);
  106.                 }
  107.             }
  108.             object range = worksheet.Get("Cells");
  109.             dataTbl.GetColumnNames()
  110.                 .Iterate((name, i) => range.Get("Item", 1, i + 1).Set("Value2", name));
  111.             dataTbl.Rows
  112.                 .Cast()
  113.                 .Iterate((row, i) => row.ItemArray
  114.                     .Iterate((item, j) => range.Get("Item", i + 2, j + 1).Set("Value2", item)));
  115.             xlApp.Set("DisplayAlerts", true);
  116.             if (visible)
  117.             {
  118.                 xlApp.Set("Visible", true);
  119.             }
  120.             else
  121.             {
  122.                 if (File.Exists(filename))
  123.                     workbook.Invoke("Save");
  124.                 else
  125.                 {
  126.                     int fileFormat =
  127.                         string.Compare("11.0", (string)xlApp.Get("Version"))  string.Format("{0},{1}", s1, s2)));
  128.                 dataTbl.Rows
  129.                     .Cast()
  130.                     .Select(row => row.ItemArray.Aggregate((s1, s2) => string.Format("{0},{1}", s1, s2)))
  131.                     .Iterate(line => writer.WriteLine(line));
  132.             }
  133.         }
  134.         // Creates an AutoCAD Table from the datatable.
  135.         public static Table ToAcadTable(this System.Data.DataTable dataTbl, double rowHeight, double columnWidth)
  136.         {
  137.             //return dataTbl.Rows.Cast().ToAcadTable(dataTbl.TableName, dataTbl.GetColumnNames(), rowHeight, columnWidth);
  138.             Table tbl = new Table();
  139.             tbl.Rows[0].Height = rowHeight;
  140.             tbl.Columns[0].Width = columnWidth;
  141.             tbl.InsertColumns(0, columnWidth, dataTbl.Columns.Count - 1);
  142.             tbl.InsertRows(0, rowHeight, dataTbl.Rows.Count + 1);
  143.             tbl.Cells[0, 0].Value = dataTbl.TableName;
  144.             dataTbl.GetColumnNames()
  145.                 .Iterate((name, i) => tbl.Cells[1, i].Value = name);
  146.             dataTbl.Rows
  147.                 .Cast()
  148.                 .Iterate((row, i) =>
  149.                     row.ItemArray.Iterate((item, j) =>
  150.                         tbl.Cells[i + 2, j].Value = item));
  151.             return tbl;
  152.         }
  153.     }
  154. }

LateBinding类提供了帮助程序,以更友好的风格编写后期绑定指令(感谢Thorsten和Tony T)。
  1. using BF = System.Reflection.BindingFlags;
  2. namespace AttributeExtraction
  3. {
  4.     public static class LateBinding
  5.     {
  6.         public static object GetInstance(string appName)
  7.         {
  8.             return System.Runtime.InteropServices.Marshal.GetActiveObject(appName);
  9.         }
  10.         public static object CreateInstance(string appName)
  11.         {
  12.             return System.Activator.CreateInstance(System.Type.GetTypeFromProgID(appName));
  13.         }
  14.         public static object GetOrCreateInstance(string appName)
  15.         {
  16.             try { return GetInstance(appName); }
  17.             catch { return CreateInstance(appName); }
  18.         }
  19.         public static object Get(this object obj, string propName, params object[] parameter)
  20.         {
  21.             return obj.GetType().InvokeMember(propName, BF.GetProperty, null, obj, parameter);
  22.         }
  23.         public static void Set(this object obj, string propName, params object[] parameter)
  24.         {
  25.             obj.GetType().InvokeMember(propName, BF.SetProperty, null, obj, parameter);
  26.         }
  27.         public static object Invoke(this object obj, string methName, params object[] parameter)
  28.         {
  29.             return obj.GetType().InvokeMember(methName, BF.InvokeMethod, null, obj, parameter);
  30.         }
  31.         public static void ReleaseInstance(this object obj)
  32.         {
  33.             System.Runtime.InteropServices.Marshal.ReleaseComObject(obj);
  34.         }
  35.     }
  36. }

A 测试命令
  1. using System.Linq;
  2. using Autodesk.AutoCAD.ApplicationServices;
  3. using Autodesk.AutoCAD.DatabaseServices;
  4. using Autodesk.AutoCAD.EditorInput;
  5. using Autodesk.AutoCAD.Runtime;
  6. using AcAp = Autodesk.AutoCAD.ApplicationServices.Application;
  7. namespace AttributeExtraction
  8. {
  9.     public class Commands
  10.     {
  11.         [CommandMethod("Test")]
  12.         public void Test()
  13.         {
  14.             Document doc = AcAp.DocumentManager.MdiActiveDocument;
  15.             Database db = doc.Database;
  16.             Editor ed = doc.Editor;
  17.             TypedValue[] filter = { new TypedValue(0, "INSERT") };
  18.             PromptSelectionResult psr = ed.GetSelection(new SelectionFilter(filter));
  19.             if (psr.Status != PromptStatus.OK) return;
  20.             PromptPointResult ppr = ed.GetPoint("\nInsertion point: ");
  21.             if (ppr.Status != PromptStatus.OK) return;
  22.             using (Transaction tr = db.TransactionManager.StartTransaction())
  23.             {
  24.                 System.Data.DataTable dataTable = psr.Value.GetObjectIds()
  25.                     .Select(id => new BlockAttribute(id.GetObject[B]()))
  26.                     .ToDataTable("Extraction");
  27.                 Table tbl = dataTable.ToAcadTable(9.0, 40.0);
  28.                 tbl.Position = ppr.Value.TransformBy(ed.CurrentUserCoordinateSystem);
  29.                 BlockTableRecord btr = db.CurrentSpaceId.GetObject[B](OpenMode.ForWrite);
  30.                 btr.AppendEntity(tbl);
  31.                 tr.AddNewlyCreatedDBObject(tbl, true);
  32.                 try
  33.                 {
  34.                     string filename = (string)AcAp.GetSystemVariable("dwgprefix") + "Extraction.xls";
  35.                     dataTable.WriteXls(filename, null, true);
  36.                 }
  37.                 catch
  38.                 {
  39.                     AcAp.ShowAlertDialog("Failed to open Excel");
  40.                 }
  41.                 tr.Commit();
  42.             }
  43.         }
  44.     }
  45. }

回复

使用道具 举报

3

主题

28

帖子

1

银币

初来乍到

Rank: 1

铜币
40
发表于 2011-11-6 02:53:55 | 显示全部楼层
我在上面的例子中添加了一些方法:System。Data.Datatable.WriteCsv(将数据表写入Csv文件)和System。Data.DataTable.WriteXls(将数据表写入Excel表中),它使用后期绑定来避免Excel版本依赖。LateBinding类提供了使后期绑定指令更具可读性的方法。
回复

使用道具 举报

15

主题

687

帖子

169

银币

中流砥柱

Rank: 25

铜币
582
发表于 2011-11-8 09:22:25 | 显示全部楼层

棒极了,这就是你的小例子:棒极了。
这里有一个基本的F#版本做同样的事情;它从选择集中的块参照中读取属性,对不同的属性集进行计数,将此信息存储在数据表中,并最终将其转换为AutoCAD表格。
我们的目标不是在gile的原创基础上进行改进(这几乎是不可能的),而是说明实现中的典型差异。
-用绑定函数代替扩展方法
-用流水线操作(| >)和函数组合(>>)代替方法链接
-与扩展方法相比,用相反的参数顺序来支持流水线操作
-使用支持IEquatable和IStructuralEquatable的数据类型,避免了对overriden Equals和GetHashCode方法的需要
-尝试“在小范围内”更具命令性,因为
对于bar中的foo...
读起来比
bar | > seq . ITER(fun foo-->...)
代码12]
已编辑: getObjects需要一个类型批注才能成为泛型
回复

使用道具 举报

发表回复

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

  • 微信公众平台

  • 扫描访问手机版

  • 点击图片下载手机App

QQ|关于我们|小黑屋|乐筑天下 繁体中文

GMT+8, 2025-2-5 11:52 , Processed in 0.164858 second(s), 72 queries .

© 2020-2025 乐筑天下

联系客服 关注微信 帮助中心 下载APP 返回顶部 返回列表