|
发表于 2022-7-6 19:31:15
|
显示全部楼层
欢迎来到CADTutor。
您还没有发布完整的代码或示例图,因此我(或其他人)很难准确指出您面临的问题。
也就是说,这可能会有所帮助:
- using Autodesk.AutoCAD.ApplicationServices;
- using Autodesk.AutoCAD.DatabaseServices;
- using Autodesk.AutoCAD.EditorInput;
- using acApp = Autodesk.AutoCAD.ApplicationServices.Application;
- namespace BlackBox.AutoCAD.Samples
- {
- class FOO
- {
- private DocumentCollection acDocs = acApp.DocumentManager;
- void UpdateBlockAttributes(string blockName, string tagString, string textString)
- {
- Document doc = acDocs.MdiActiveDocument;
- Database db = doc.Database;
- Editor ed = doc.Editor;
- tagString = tagString.ToUpper();
- // set clayer to "0" layer
- acApp.SetSystemVariable("clayer", "0");
-
- using (Transaction tr = db.TransactionManager.StartOpenCloseTransaction())
- {
- // get the blocktable
- BlockTable bt =
- (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead);
- // instead of iterating the entire blocktable, check to see if
- // the target block exists within this database's blocktable
- if (!bt.Has(blockName))
- {
- // if not, then notify user, and exit
- // uncomment the notification, if you feel it useful - I tend
- // to not call writemessage() within non-commandmethod methods
- //ed.WriteMessage("\nerror; Block "{0}" does not exist ", blockName);
- return;
- }
- // otherwise, open the blocktablerecord
- BlockTableRecord btr =
- (BlockTableRecord)tr.GetObject(bt[blockName], OpenMode.ForRead);
-
- // and instead, simply iterate all inserts of the target blocktablerecord
- foreach (ObjectId id in btr.GetBlockReferenceIds(true, false))
- {
- BlockReference br =
- (BlockReference)tr.GetObject(id, OpenMode.ForRead);
- // <-- check for locked layer here?
- // check for attributes
- foreach (ObjectId attId in br.AttributeCollection)
- {
- AttributeReference ar =
- tr.GetObject(attId, OpenMode.ForRead) as AttributeReference;
- if (ar != null && ar.Tag.ToUpper() == tagString)
- {
- ar.UpgradeOpen();
- ar.TextString = textString;
- ar.DowngradeOpen();
- }
- }
- }
- tr.Commit();
- }
- }
- }
- }
然后我调用sub来更新属性。(描述(CONT)是属性。)
- acBlkRef = InsertBlockReference("TBClean", False, New Point3d(-0.5, 0.5, 0), True, "TITLE", Colors.Color.FromColorIndex(Colors.ColorMethod.ByAci, 0)) 'black
下面是函数和子函数的代码
- UpdateBlockAttribute(acBlkRef, "DESCRIPTION(CONT)", strDesc)
- Private Function InsertBlockReference(blockName As String, modelSpace As Boolean, insPt As Point3d, updateExisting As Boolean, Optional layerName As String = "", Optional layerColor As Colors.Color = Nothing) As BlockReference
- Dim acBlkTable As BlockTable
- Dim acLyrTbl As LayerTable
- Dim acCurLyrID As ObjectId
- Dim acBlkRef As BlockReference = Nothing
- Dim acSpaceID As ObjectId
- Dim acBlkTableRecord As BlockTableRecord
- Dim acBlkTableRecordID As ObjectId
- Dim acNewLyr As New LayerTableRecord
- Try
- acBlkTable = acTrans.GetObject(acdb.BlockTableId, OpenMode.ForRead)
- If IsNothing(acBlkTable) Then
- 'InsertBlockReference = Nothing
- Return Nothing
- End If
- 'store current layer to make it current again after function
- acLyrTbl = acTrans.GetObject(acdb.LayerTableId, OpenMode.ForRead)
- acCurLyrID = acdb.Clayer
- 'if a layer is specified, set it to the current layer
- If layerName <> "" Then
- If acLyrTbl.Has(layerName) Then
- acdb.Clayer = acLyrTbl(layerName)
- Else
- acNewLyr.Name = layerName
- acNewLyr.Color = layerColor
- acLyrTbl.UpgradeOpen()
- acLyrTbl.Add(acNewLyr)
- acLyrTbl.DowngradeOpen()
- acTrans.AddNewlyCreatedDBObject(acNewLyr, True)
- acdb.Clayer = acLyrTbl(layerName)
- End If
- End If
- 'check to see if the block is already in the CAD file
- If acBlkTable.Has(blockName) And updateExisting Then
- 'get the BlockReference for the block
- acBlkTableRecord = DirectCast(acTrans.GetObject(acBlkTable.Item(blockName), OpenMode.ForRead), BlockTableRecord)
- Dim acObjIdColl As ObjectIdCollection = acBlkTableRecord.GetBlockReferenceIds(True, True)
- Dim acEntId As ObjectId
- For Each acEntId In acObjIdColl
- 'acBlkRef = acEntId.GetObject(OpenMode.ForRead)
- acBlkRef = TryCast(acEntId.GetObject(OpenMode.ForWrite), BlockReference)
- Next
- Else
- 'if the block is NOT in the CAD file, insert it from the dwg file
- If IO.File.Exists(Me.txtCADBlocksPath.Text & "" & blockName & ".dwg") Then
- Dim acBlkSourceDb As Database
- acBlkSourceDb = New Database(False, True)
- acBlkSourceDb.ReadDwgFile(Me.txtCADBlocksPath.Text & "" & blockName & ".dwg", FileOpenMode.OpenForReadAndAllShare, True, Nothing)
- acBlkTableRecordID = acdb.Insert(blockName, acBlkSourceDb, True)
- 'insert the new block
- acBlkRef = New BlockReference(insPt, acBlkTableRecordID)
- 'select the correct block table record to insert the new block into... ModelSpace or PaperSpace
- If modelSpace = True Then
- acSpaceID = acBlkTable(BlockTableRecord.ModelSpace)
- Else
- acSpaceID = acBlkTable(BlockTableRecord.PaperSpace)
- End If
- acBlkTableRecord = DirectCast(acTrans.GetObject(acSpaceID, OpenMode.ForWrite), BlockTableRecord)
- acBlkTableRecord.AppendEntity(acBlkRef)
- acTrans.AddNewlyCreatedDBObject(acBlkRef, True)
- Else
- MsgBox("InsertBlock: Block """ & blockName & """ DWG not found")
- Return Nothing
- End If
- End If
- Catch ex As Exception
- MsgBox("InsertBlock: " & ex.Message)
- Finally
- acdb.Clayer = acCurLyrID
- End Try
- Return acBlkRef
- End Function
我希望这一切都有意义。
我必须在图纸上清除一些机密数据后才能发布,但如果你仍然需要的话,我可以这样做。 |
|