尝试查找块引用,但没有成功
使用以下代码Private Function GetBlockReferenceFromList(ByVal thisDocument As Document, _
ByVal db As Database, _
ByVal transaction As Transaction, _
ByVal listOfBlockRefNames As List(Of String)) As List(Of BlockReference)
Dim listOfBlockRef As New List(Of BlockReference)
Dim blockTable As BlockTable
Dim blockTableRecord As BlockTableRecord
Dim objectID As ObjectId
Dim objectCollection As ObjectIdCollection
Dim i As Integer
Dim blockRef As BlockReference
Try
blockTable = transaction.GetObject(db.BlockTableId, OpenMode.ForRead)
For Each objectID In blockTable
blockTableRecord = TryCast(transaction.GetObject(objectID, OpenMode.ForRead), BlockTableRecord)
If Not IsNothing(blockTableRecord) Then
objectCollection = blockTableRecord.GetBlockReferenceIds(True, False)
If Not IsNothing(objectCollection) Then
If objectCollection.Count > 0 Then
For i = 0 To objectCollection.Count
blockRef = TryCast(transaction.GetObject(objectCollection(i), OpenMode.ForRead), BlockReference)
If Not IsNothing(blockRef) Then
If listOfBlockRefNames.Contains(blockRef.Name) Then
listOfBlockRef.Add(blockRef)
End If
End If
Next
End If
End If
End If
Next
Catch ex As Exception
MsgBox("HollowCore_RemoveBlockReference.GetBlockReferenceFromList : " & ex.Message, MsgBoxStyle.OkOnly, EasiCADException.EasiCADErrorTitle)
End Try
Return listOfBlockRef
End Function
我使用的是AutoCAD 2014, VS2010(. NET v4)。
为了正确看待这个功能,我继承了一个创建和维护块(用于表示平面图上的混凝土板)的系统,每个块应该只有一个块引用。我正在寻找具有重复块引用的图纸,其中一个或其他定制命令,例如复制、移动,正在破坏并将这些重复的东西留在周围,这些是不可见的。上述功能是删除重复块引用的更广泛功能的一部分。
**** Hidden Message ***** 检查相同的插入点和旋转。
检查可见性
检查非注释性和注释性(如果在来自同一块的块参照中发现两者,则某些块将不可见) 您可能希望更详细地说明“没有成功”的含义。您的意思是您确实知道图形中存在具有给定块名称的块引用,但代码找不到它(因此,函数返回具有Count= 0的列表)?
如果是这种情况,那么可能有 2 个原因,从你的代码中看到:
1. 代码将块引用的名称与此处的已知块名称列表进行比较:
如果 listOfBlockRefNames.Contains(blockRef.Name) 则
此代码有问题的原因是列表中的块名称,块引用的名称可能字面上相同,但大小不相同(上或下), 然后是“如果...”中的条件可能会返回 False。
2. 您没有提到,但如果感兴趣的块是动态块,则块引用的名称可能是由 AutoCAD 生成的匿名块名称。因此,如果该块可能是动态的,则需要找到其“有效”名称,而不是 BlockReference.Name。
此外,由于您只对一组给定的块名称感兴趣,因此您可以遍历块名称列表,而不是遍历整个块记录表。这将使代码逻辑更易于遵循。类似的东西:
Private Function GetBlockReferenceFromList(db as Database, tran as Trsnaction, blkNames as List(of String)) As ...
Dim listOfBlockRef As New List(of BlockReference)
Dim blockTable as BlockTable=....
对于每个 blkName As String in blkNames
If blockTable.Has(blkName) 则
Dim brefs=GetBlockRefs(tran, blockTable(blkName))
if brefs.Count>0 then
listOfBlockref.AddRange(brefs)
End If
End If
Next
Return lisOfBlockRef
End Function
Private Function GetBlockRefs(tran as Transaction, blkId as ObjectId) As List(of BlockReference)
Dim brefs as New List(of BlockReference)()
Dim blockRecord=DirectCast(tran.GetObject(blkId,OpenMode.ForRead), BlockTableRecord)
''Get direct BlockReference
Dim blks=FindBlockReferences(tran, blockRecord)
If blks.Count>0 然后是 brefs。AddRange(blks)
''If the block is dynamic
If blkRecord.IsDynamic then
Dim anonyBlkIds=blockRecord.GetAnonymousBlockIds()
If anonyBlkIds Is Not Nothing andAlso anonyBlkIds.Count>0 Then
For Each blkId As ObjectId in anonyBlkIds
Dim anonyBlkRecord=DirectCast(tran.GetObject(blkId,OpenMode.ForRead), BlockTableRecord)
blks=FindBlockReferences(tran, anonyBlkRecord)
If blks.Count>0 然后是 brefs。AddRange(blks)
end if
end if
end if end if
return brefs
end function
Private Function FindBlockreferences(tran As Transaction, blkRecord as BlockTableRecord) As List(of BlockReference)
Dim brefs as New List(of BlockReference)()
Dim idCollection=blkRecord.GetBlockReferenceIds(True, False)
if idCollection Is Not Nothing and also idCollection.Count>0 then
for each idCollection.Count>0 then for each idCollection in idCollection
bref.Add((DirectCast(tran.GetObject(id, OpenMode.ForRead), Blockreference))
Next
End If
Return brefs
End Function
代码没有经过测试,但你明白了:
1. 使用 BlockTable.Has() 查看数据库中是否存在具有特定名称的块定义。在这里,您不必自己比较块名称(消除潜在角色的CASE问题);使用BlockTable.Has()方法在循环访问您的块名称列表时,如果块名称确实是定义的BlockTableRecord,则只会更深入;
2. 如果感兴趣的区块可以是动态区块,则必须确保同时搜索到相应的匿名区块引用
非常感谢,n元。因此,缺乏成功的原因确实是我知道有命名块引用,而我的代码没有找到它们。它确实找到了块引用,但没有找到我知道存在的名称
系统的大部分使用COM风格的编程,最后我用这种方法编写了例程,只是为了让它正常工作:
Private Function GetBlockReferenceFromList(ByVal thisDrawing As AcadDocument, ByVal listOfBlockRefNames As List(Of String)) As List(Of AcadBlockReference)
Dim listOfBlockRef As New List(Of AcadBlockReference)
Dim blockRef As AcadBlockReference
Dim selectionSet As AcadSelectionSet = Nothing
Dim filterType(1) As Short
Dim filterData(1) As Object
Try
selectionSet = CreateSelSet(thisDrawing, "RemoveBlockReferences")
filterType(0) = 0
filterData(0) = "INSERT"
filterType(1) = 8
filterData(1) = "SLABOUTLINE"
selectionSet.Select(AcSelect.acSelectionSetAll, , , filterType, filterData)
If selectionSet.Count > 0 Then
For Each blockRef In selectionSet
If listOfBlockRefNames.Contains(blockRef.Name) Then
listOfBlockRef.Add(blockRef)
End If
Next
End If
Catch ex As Exception
MsgBox("HollowCore_RemoveObjects.GetBlockReferenceFromList : " & ex.Message, MsgBoxStyle.OkOnly, EasiCADException.EasiCADErrorTitle)
Finally
If Not IsNothing(selectionSet) Then
selectionSet.Clear()
End If
DelSelSet(thisDrawing, "RemoveBlockReferences")
End Try
Return listOfBlockRef
End Function
然而,我希望尽可能远离COM,所以我会在有时间的时候使用您的指针进一步研究
所讨论的块和块引用名称是数字,因此不考虑大小写敏感度……但了解这一点很有用。谢谢。我在编辑那里注意到了这一点。GetString函数。
关于块是否是动态的,我不确定。系统使用AcadDocument.Blocks。添加函数以添加块和AcadDocument.ModelSpace。用于BlockReferences的InsertBlock函数(我无法理解为什么名为InsertBlocks的例程返回BlockReference)。
页:
[1]