乐筑天下

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

外部参照-在VBA区分“已卸载”和“未找到”

[复制链接]

1

主题

3

帖子

1

银币

初来乍到

Rank: 1

铜币
7
发表于 2006-6-28 08:14:50 | 显示全部楼层 |阅读模式
你好,这是我在这里的第一篇帖子,所以大家好-很高兴见到你
现在进入正题:
我正在尝试编写一个宏,它将修复我继承的一堆非常混乱的绘图。在很大程度上,这个宏运行得很好,节省了我大量的时间和压力,但是我有一个症结。由于我从另一个位置继承了这些图形,因此我的所有外部参照路径都已断开。当然,这可以通过使用“PROJECTNAME”变量更改缺失外部参照的搜索路径并重新加载所有外部参照来轻松解决,但是有些外部参照已被引用但未被加载,需要保持这种状态。我一直在寻找一种方法来区分未加载的外部参照和路径断开的外部参照(即“未找到”),但我在任何地方都找不到方法。我的大部分编程经验都来自VBA,所以用这种语言的解决方案是最好的——但是如果需要的话,我有足够的LISP经验来理解它。
预先感谢任何帮助

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

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

使用道具 举报

3

主题

88

帖子

4

银币

初露锋芒

Rank: 3Rank: 3Rank: 3

铜币
100
发表于 2006-6-28 08:41:11 | 显示全部楼层
这是我几年前写的东西(从那以后就再也没看过)。所以我不记得它当时的效果如何,也不知道它现在是否还会有效,但它可能会让你开始。
  1. Option Explicit
  2. Public Enum XRefStatus
  3.   xrloaded = 1
  4.   xrdetached = 2
  5.   xrNotFound = 3
  6. End Enum
  7. Public Sub test()
  8.   Dim colBlocks As AcadObject
  9.   Dim objBlock As AcadBlock
  10.   Dim objXRefDbase1 As AcadDatabase
  11.   Dim objXRefDbase2 As AcadDatabase
  12.   Dim objXref As AcadExternalReference
  13.   Dim varXref() As Variant
  14.   Dim intCount As Integer
  15.   
  16.   
  17.   Set colBlocks = Me.Blocks
  18.     For Each objBlock In colBlocks
  19.       If objBlock.IsXRef Then
  20.         Select Case GetXRefStatus(objBlock)
  21.           Case 1 'xrloaded
  22.             MsgBox "Xref " & objBlock.Name & " is Loaded"
  23.           Case 2 'xrdetached
  24.             MsgBox "Xref " & objBlock.Name & " is Detached"
  25.           Case 3 'xrnotfound
  26.             MsgBox "Xref " & objBlock.Name & " was not found"
  27.           Case Else
  28.             MsgBox "Xref " & objBlock.Name & " has me confused"
  29.         End Select
  30.       End If
  31.     Next objBlock
  32.    
  33.   
  34.   
  35.   
  36. End Sub
  37. Public Function GetXRefStatus(pXRef As AcadBlock) As XRefStatus
  38.   Dim xStatus As XRefStatus
  39.   Dim objTestObj As Object
  40.   
  41.   On Error GoTo XRefStatus_Error
  42.    
  43.   If pXRef.Count > 1 Then
  44.     GetXRefStatus = xrloaded
  45.     Exit Function
  46.   End If
  47.   
  48.   If pXRef.Count = 1 Then
  49.     If pXRef(0).ObjectName = "AcDbText" Then
  50.       If pXRef(0).TextString Like "*" & pXRef.Name & "*" Then
  51.         GetXRefStatus = xrNotFound
  52.         Exit Function
  53.       Else ' it only has one item, and that item is text
  54.         GetXRefStatus = xrloaded
  55.         Exit Function
  56.       End If
  57.     Else ' it only has one object in it, but that item isnt text
  58.       GetXRefStatus = xrloaded
  59.       Exit Function
  60.     End If
  61.   End If
  62.   
  63.   If pXRef.Count = 0 Then 'either unloaded or empty xref
  64.     'unloaded xrefs have no database so this will raise an error
  65.     Set objTestObj = pXRef.XRefDatabase
  66.     GetXRefStatus = xrloaded ' if it gets to here, then the xref is attached but
  67.     Exit Function            ' contains no objects
  68.   End If
  69.   
  70. XRefStatus_Error:
  71.   Select Case Err.Number
  72.     Case -2145386390 ' no database error
  73.       GetXRefStatus = xrdetached
  74.       Err.Clear
  75.       Exit Function
  76.     Case Else
  77.       MsgBox Err.Number
  78.       Debug.Print "Error " & Err.Number
  79.       Err.Clear
  80.       Exit Function
  81.   End Select
  82. End Function

回复

使用道具 举报

1

主题

3

帖子

1

银币

初来乍到

Rank: 1

铜币
7
发表于 2006-6-28 09:19:16 | 显示全部楼层
我必须将第15行中的“我”改为“this drawing ”( Set col blocks = Me。Blocks)来让它为我工作,但是我的朋友很可能就是我正在寻找的代码!
非常感谢
回复

使用道具 举报

3

主题

88

帖子

4

银币

初露锋芒

Rank: 3Rank: 3Rank: 3

铜币
100
发表于 2006-6-28 09:22:14 | 显示全部楼层
不客气希望能帮上忙
回复

使用道具 举报

1

主题

3

帖子

1

银币

初来乍到

Rank: 1

铜币
7
发表于 2006-6-28 09:27:40 | 显示全部楼层
请参见此主题中的此帖子。最好的运气编码一个纯vb[a]等效利用dxf组码71。
PS:欢迎来到沼泽。
回复

使用道具 举报

3

主题

88

帖子

4

银币

初露锋芒

Rank: 3Rank: 3Rank: 3

铜币
100
发表于 2006-6-28 10:59:26 | 显示全部楼层
我记得那个戴夫。你在一个类似的问题上为我做了那件事。
回复

使用道具 举报

3

主题

88

帖子

4

银币

初露锋芒

Rank: 3Rank: 3Rank: 3

铜币
100
发表于 2006-6-28 11:21:33 | 显示全部楼层

我不得不说,那个线程正好在我的脑海中。谢天谢地,Dave的代码完全符合要求,所以我现在不会试图理解它而给自己一个疝气。在这种情况下使用LISP有明显的优势吗?
回复

使用道具 举报

3

主题

88

帖子

4

银币

初露锋芒

Rank: 3Rank: 3Rank: 3

铜币
100
发表于 2006-6-28 11:28:43 | 显示全部楼层

它更漂亮?开玩笑。
正如我所读到的:在vb中,它是演绎的,在lisp中它是确定的。最后,这可能只是学术性的,对你的解决方案没有任何影响。
回复

使用道具 举报

3

主题

88

帖子

4

银币

初露锋芒

Rank: 3Rank: 3Rank: 3

铜币
100
发表于 2006-6-28 11:55:07 | 显示全部楼层
我同意MP的观点。我发布的代码是基于当时有效的一些未记录的条件,可能会改变,也可能不是对所有情况都有效。这只是一个快速的似乎奏效了。
我猜,位代码的值也可能改变。但是人们希望AutoDesk能够记录它们。
回复

使用道具 举报

3

主题

88

帖子

4

银币

初露锋芒

Rank: 3Rank: 3Rank: 3

铜币
100
发表于 2006-6-28 13:41:33 | 显示全部楼层
真是度过几个雨天的好方法!!当然比工作好。
这是一个VBA例程,它使用70和71代码进行xref状态。它需要在AutoCAD安装文件夹中重新引用VLisp ActiveX模块(vl16.tlb2004、2005、2006版本。无论如何,在我的计算机上。您可能必须搜索它)
我还没有完全测试它,但它似乎在我所做的测试中起作用。
  1. Public Sub XRefTest2()
  2.   Dim colBlocks As AcadObject
  3.   Dim objBlock As AcadBlock
  4.   Dim testBlock As AcadObject
  5.   Dim Flag70 As Variant
  6.   Dim Flag71 As Variant
  7.   Dim sHandle1 As String
  8.   Dim sHandle2 As String
  9.   Dim sBlockName As String
  10.   Set colBlocks = Me.Blocks
  11.     For Each objBlock In colBlocks
  12.       If objBlock.IsXRef Then
  13.         sHandle1 = "&H" + objBlock.Handle
  14.         sBlockName = objBlock.Name
  15.         sHandle2 = Hex(sHandle1 + 1)
  16.         Set testBlock = ThisDrawing.HandleToObject(sHandle2)
  17.         Flag70 = vbAssoc(testBlock, 70)
  18.         Flag71 = vbAssoc(testBlock, 71)
  19.         If Flag71 = "1" Then
  20.             MsgBox sBlockName & " appears to be UNLOADED "
  21.         ElseIf (Val(Flag70) And 32) = 32 Then MsgBox sBlockName & " appears to be LOADED and RESOLVED "
  22.         ElseIf (Val(Flag70) And 4) = 4 Then MsgBox sBlockName & " appears to be NOT FOUND "
  23.         End If
  24.       End If
  25.     Next objBlock
  26. End Sub
  27. Public Function vbAssoc(pAcadObj As AcadObject, pDXFCode As Integer) As Variant
  28. Dim VLisp As Object
  29. Dim VLispFunc As Object
  30. Dim varRetVal As Variant
  31. Dim obj1 As Object
  32. Dim obj2 As Object
  33. Dim strHnd As String
  34. Dim strVer As String
  35. Dim lngCount As Long
  36. Dim i As Long
  37. Dim j As Long
  38. On Error GoTo vbAssocError
  39. strHnd = pAcadObj.Handle
  40. If Me.Application.Version = "16.0" Then
  41.   Set VLisp = ThisDrawing.Application.GetInterfaceObject("VL.Application.16")
  42. Else
  43.   Set VLisp = ThisDrawing.Application.GetInterfaceObject("VL.Application.1")
  44. End If
  45. Set VLispFunc = VLisp.ActiveDocument.Functions
  46. Set obj1 = VLispFunc.Item("read").funcall("pDXF")
  47.   varRetVal = VLispFunc.Item("set").funcall(obj1, pDXFCode)
  48. Set obj1 = VLispFunc.Item("read").funcall("pHandle")
  49.   varRetVal = VLispFunc.Item("set").funcall(obj1, strHnd)
  50. Set obj1 = VLispFunc.Item("read").funcall("(vl-princ-to-string (cdr (assoc pDXF (entget (handent pHandle)))))")
  51.   varRetVal = VLispFunc.Item("eval").funcall(obj1)
  52.   
  53. vbAssoc = varRetVal
  54. 'clean up the newly created LISP symbols
  55. Set obj1 = VLispFunc.Item("read").funcall("(setq pDXF nil)")
  56.   varRetVal = VLispFunc.Item("eval").funcall(obj1)
  57. Set obj1 = VLispFunc.Item("read").funcall("(setq pHandle nil)")
  58.   varRetVal = VLispFunc.Item("eval").funcall(obj1)
  59.   
  60. 'release the objects or Autocad gets squirrely
  61. Set obj2 = Nothing
  62. Set obj1 = Nothing
  63. Set VLispFunc = Nothing
  64. Set VLisp = Nothing
  65. Exit Function
  66. vbAssocError:
  67.   Set obj2 = Nothing
  68.   Set obj1 = Nothing
  69.   Set VLispFunc = Nothing
  70.   Set VLisp = Nothing
  71.   MsgBox "Error occurred " & Err.Description
  72. End Function

这可能有点过分,但玩它确实很有趣
回复

使用道具 举报

发表回复

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

本版积分规则

  • 微信公众平台

  • 扫描访问手机版

  • 点击图片下载手机App

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

GMT+8, 2025-7-5 22:45 , Processed in 0.609391 second(s), 83 queries .

© 2020-2025 乐筑天下

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