Bryco 发表于 2006-3-16 01:51:55

外部参照附着或覆盖

我用的是某个CallMeDave的vbassoc函数,我有Frank的Vlax类。因为我不知道lisp,所以后者有点难用。我现在正在处理一个xref类或函数,想知道xref是附加的还是叠加的。到目前为止,dxf代码70似乎是我需要的块,但我不知道如何去做。使用SCMD的函数我得到一个nil。我假设答案是一个列表,并且只需要正确处理。有什么想法吗?
这是vbassoc
'SomeCallMeDave
'http://www.vbdesign.net/expresso/showthread.php?postid=83887#post83887
'Changed pAcadObj As AcadObject to pAcadObj As Object to access imagedef as well
Public Function vbAssoc(pAcadObj, pDXFCode As Integer) As Variant
Dim VLisp As Object
Dim VLispFunc As Object
Dim varRetVal As Variant
Dim obj1 As Object
Dim obj2 As Object
Dim strHnd As String
Dim strVer As String
Dim lngCount As Long
Dim i As Long
Dim j As Long
On Error GoTo vbAssocError
strHnd = pAcadObj.handle
If Left(ThisDrawing.Application.Version, 2) = "16" Then
Set VLisp = ThisDrawing.Application.GetInterfaceObject("VL.Application.16")
Else
Set VLisp = ThisDrawing.Application.GetInterfaceObject("VL.Application.1")
End If
Set VLispFunc = VLisp.ActiveDocument.Functions
Set obj1 = VLispFunc.item("read").funcall("pDXF")
varRetVal = VLispFunc.item("set").funcall(obj1, pDXFCode)
Set obj1 = VLispFunc.item("read").funcall("pHandle")
varRetVal = VLispFunc.item("set").funcall(obj1, strHnd)
Set obj1 = VLispFunc.item("read").funcall("(vl-princ-to-string (cdr (assoc pDXF (entget (handent pHandle)))))")
varRetVal = VLispFunc.item("eval").funcall(obj1)

vbAssoc = varRetVal
'clean up the newly created LISP symbols
Set obj1 = VLispFunc.item("read").funcall("(setq pDXF nil)")
varRetVal = VLispFunc.item("eval").funcall(obj1)
Set obj1 = VLispFunc.item("read").funcall("(setq pHandle nil)")
varRetVal = VLispFunc.item("eval").funcall(obj1)

'release the objects or Autocad gets squirrely (no offense RR)
Set obj2 = Nothing
Set obj1 = Nothing
Set VLispFunc = Nothing
Set VLisp = Nothing
Exit Function
vbAssocError:
Set obj2 = Nothing
Set obj1 = Nothing
Set VLispFunc = Nothing
Set VLisp = Nothing
MsgBox "Error occurred " & Err.Description
End Function

Debug.Print"lisp",vbAssoc(oBlock,2),vbAssoc(oBlock,70)
**** Hidden Message *****

Jeff_M 发表于 2006-3-16 14:10:09

Bryco,
问题在于在 BlocksCollection 中为 Block 返回的句柄与 lisp 中从 Block 表返回的句柄不同。
我认为这是由于一个引用了块表,另一个引用了Block_Record表........Block_Record没有组 70 代码,而 Block 有。
我现在正在寻找是否有一个简单的方法来解决这个问题....

Bryco 发表于 2006-3-16 14:24:54

哎哟棘手的地面。

Jeff_M 发表于 2006-3-16 14:51:26

好吧,这对我来说很有用:
'SomeCallMeDave
'http://www.vbdesign.net/expresso/showthread.php?postid=83887#post83887
'Changed pAcadObj As AcadObject to pAcadObj As Object to access imagedef as well
'Modified by Jeff Mishler, March 2006, to get the Block table object, not Block_Record table object
Public Function vbAssoc(pAcadObj, pDXFCode As Integer) As Variant
Dim VLisp As Object
Dim VLispFunc As Object
Dim varRetVal As Variant
Dim obj1 As Object
Dim obj2 As Object
Dim strHnd As String
Dim strVer As String
Dim lngCount As Long
Dim i As Long
Dim j As Long
On Error GoTo vbAssocError
   
If Left(ThisDrawing.Application.Version, 2) = "16" Then
Set VLisp = ThisDrawing.Application.GetInterfaceObject("VL.Application.16")
Else
Set VLisp = ThisDrawing.Application.GetInterfaceObject("VL.Application.1")
End If
Set VLispFunc = VLisp.ActiveDocument.Functions
If Not TypeOf pAcadObj Is AcadBlock Then
    strHnd = pAcadObj.Handle
Else
    Dim lispStr As String
    lispStr = "(cdr (assoc 5 (entget (tblobjname " & Chr(34) & "Block" & Chr(34) & Chr(34) & pAcadObj.Name & Chr(34) & "))))"
    Set obj1 = VLispFunc.Item("read").funcall(lispStr)
    strHnd = VLispFunc.Item("eval").funcall(obj1)
End If
Set obj1 = VLispFunc.Item("read").funcall("pDXF")
varRetVal = VLispFunc.Item("set").funcall(obj1, pDXFCode)
Set obj1 = VLispFunc.Item("read").funcall("pHandle")
varRetVal = VLispFunc.Item("set").funcall(obj1, strHnd)
Set obj1 = VLispFunc.Item("read").funcall("(vl-princ-to-string (cdr (assoc pDXF (entget (handent pHandle)))))")
varRetVal = VLispFunc.Item("eval").funcall(obj1)

vbAssoc = varRetVal
'clean up the newly created LISP symbols
Set obj1 = VLispFunc.Item("read").funcall("(setq pDXF nil)")
varRetVal = VLispFunc.Item("eval").funcall(obj1)
Set obj1 = VLispFunc.Item("read").funcall("(setq pHandle nil)")
varRetVal = VLispFunc.Item("eval").funcall(obj1)

'release the objects or Autocad gets squirrely (no offense RR)
Set obj2 = Nothing
Set obj1 = Nothing
Set VLispFunc = Nothing
Set VLisp = Nothing
Exit Function
vbAssocError:
Set obj2 = Nothing
Set obj1 = Nothing
Set VLispFunc = Nothing
Set VLisp = Nothing
MsgBox "Error occurred " & Err.Description
End Function

Bryco 发表于 2006-3-16 16:21:02

杰夫你确实有渊博的知识。如果你知道关于100美元账单的老笑话,这里有99粒花生,告诉你从哪里下手。
嘿,什么是沼泽花生?
谢谢你,伙计。

Jeff_M 发表于 2006-3-16 16:39:15


别客气!即使我以前遇到过这种情况,从而让我知道问题是什么,我直到现在才寻求解决方案.....令我惊喜的是,这是一个相对简单的修复程序。

Jeff_M 发表于 2006-3-16 17:17:59

根据 MP 在 lisp 论坛上的帖子,这只有在检查当前图形中外部参照的状态时才有效。如果你想在远程/ObjectDBX绘图上使用它,它需要像MP所做的那样重写。

Jeff_M 发表于 2006-3-16 18:21:03

好吧,把这个:
If Not TypeOf pAcadObj Is AcadBlock Then
    strHnd = pAcadObj.Handle
Else
    Dim lispStr As String
    lispStr = "(cdr (assoc 5 (entget (tblobjname " & Chr(34) & "Block" & Chr(34) & Chr(34) & pAcadObj.Name & Chr(34) & "))))"
    Set obj1 = VLispFunc.Item("read").funcall(lispStr)
    strHnd = VLispFunc.Item("eval").funcall(obj1)
End If

换成这个:
    strHnd = pAcadObj.Handle
If TypeOf pAcadObj Is AcadBlock Then
    strHnd = Hex(1 + Val("&H" & strHnd))
End If

,这似乎有效,但我似乎记得T.T.说这种方法不能总是被依赖。
*Jeff_M去研究更多......

Bryco 发表于 2006-3-19 11:43:07

我尝试在vba中查找块表,但没有结果
使用十六进制(1+Val(“&H”&strHnd))给出了以下消息:
“出现错误参数类型:lentinype nil”和崩溃
这是一个137文件(88 mb)的dwg。有人给我玩的。没有覆盖层,所有连接和嵌套在阴阳上。由于某些原因,即使它们都在同一个文件夹中,它们也不会改变路径,所以我也在做(如果是这个词的话)一个重设子对象。似乎路径只能在外部参照的直接宿主中更改,所以现在它变得很耗时。Getsubentity将为您提供所有者,但这不是一个好方法。块的所有者始终是AcDbBlockTable,因此使用ownerid是不可行的。这样,就可以在每个块中循环查找是否为外部参照,并将所有内容放入嵌套深度的有序组中
更改父dwg上的路径。然后打开孩子的画,改变他们的路径等等,缓慢而痛苦
(我宁愿派几个用钳子和喷灯打硬管的家伙来用“低俗小说”的方式来创作dwg。)
想知道我是否错过了简单的方法?

Bryco 发表于 2006-3-19 22:05:49

谢谢Glenn。我要花一段时间才能明白这一点。0和1的block.counts(1是文本-xref)可能会有所帮助。
我还没有找到可靠的方法来计算xref是否已加载并且符合犹太标准。我认为block.path没有/就足够了,但出于某种原因,我有一个没有完整路径的xref,并且计数大于1,这就像dwg中的larry一样快乐。
页: [1] 2
查看完整版本: 外部参照附着或覆盖