明经CAD社区

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
查看: 1862|回复: 6

请教vba编程中的一个问题

[复制链接]
发表于 2003-10-10 11:46:00 | 显示全部楼层 |阅读模式
各位大虾:
      我有一个程序将图形内的所有相交实体打断,用vba开发过程中是调用break实现的,但打断后新增加的实体(原有一个实体变成两个实体)在程序运行过程中无法加入到原有的选择集合中,也就是无法进行递归处理,用thisdrawing.modespace.count得出的实体数目与打断前一样,同样思路用LISP可以实现,请各位指教!
发表于 2003-10-10 12:16:00 | 显示全部楼层
你的程序是怎样的,我试过了,正常,没出现你说的现象。
  1. ' 主程序
  2. Sub DispBreakMun()
  3.     Debug.Print "打断前的图元数目:" & ThisDrawing.ModelSpace.Count
  4.     Call Break
  5.     Debug.Print "打断后的图元数目:" & ThisDrawing.ModelSpace.Count
  6. End Sub

  7. '示例Break

  8. Sub Break()
  9.     Dim Pnt As Variant
  10.     Dim entObj As AcadEntity
  11.     ThisDrawing.Utility.GetEntity entObj, Pnt, "选择图元:"
  12.     Dim Pnt2 As Variant
  13.     Pnt2 = ThisDrawing.Utility.GetPoint(, "选择点:")

  14.     Dim det As String
  15.     det = GetDoubleEntTable(entObj, Pnt)

  16.     Dim lspPnt As String
  17.     lspPnt = axPoint2lspPoint(Pnt2)
  18.     ThisDrawing.SendCommand "_break" & vbCr & det & vbCr & lspPnt & vbCr

  19. End Sub

  20. '示例Trim

  21. Sub Trim()

  22.     Dim Pnt1 As Variant
  23.     Dim entObj1 As AcadEntity
  24.     ThisDrawing.Utility.GetEntity entObj1, Pnt1, "选择图元:"
  25.     Dim det1 As String
  26.     det1 = axEnt2lspEnt(entObj1)

  27.     Dim Pnt2 As Variant
  28.     Dim entObj2 As AcadEntity
  29.     ThisDrawing.Utility.GetEntity entObj2, Pnt2, "选择被剪图元:"
  30.     Dim det2 As String
  31.     det2 = GetDoubleEntTable(entObj2, Pnt2)

  32.     ThisDrawing.SendCommand "_trim" & vbCr & det1 & vbCr & vbCr & det2 & vbCr & vbCr

  33. End Sub

  34. '转换双元表的函数

  35. Public Function GetDoubleEntTable(entObj As AcadEntity, Pnt As Variant) As String
  36.     Dim entHandle As String
  37.     entHandle = entObj.Handle
  38.     GetDoubleEntTable = "(list(handent " & Chr(34) & entHandle & Chr(34) & _
  39.                      ")(list " & Str(Pnt(0)) & Str(Pnt(1)) & Str(Pnt(2)) & "))"
  40. End Function

  41. '转换点的函数

  42. Public Function axPoint2lspPoint(Pnt As Variant) As String
  43.     axPoint2lspPoint = Pnt(0) & "," & Pnt(1) & "," & Pnt(2)
  44. End Function

  45. '转换图元函数

  46. Public Function axEnt2lspEnt(entObj As AcadEntity) As String
  47.     Dim entHandle As String
  48.     entHandle = entObj.Handle
  49.     axEnt2lspEnt = "(handent " & Chr(34) & entHandle & Chr(34) & ")"
  50. End Function

 楼主| 发表于 2003-10-11 10:34:00 | 显示全部楼层
请mccad在cad2000下随意绘制几条稍微复杂的互相相交的多义线
程序代码如下:
Private Sub CommandButton3_Click()
  Dim GpCode(0 To 1) As Integer      '选择集过滤
  Dim DataValue(0 To 1) As Variant   '选择集过滤
  Dim n As Integer, m As Integer     '选择集中实体的个数
  Dim i As Integer, j As Integer, k As Integer, l As Integer  '四层循环控制
  Dim Startime As Date                   '起始运行时间
  Startime = Time()
  Dim En As Variant                      '第一层循环实体名
  Dim En1 As Variant                     '第二层循环实体名
  Dim Minext As Variant                  '实体的外界多边形左下角点(二维点)
  Dim Maxext As Variant                  '实体的外界多边形右上角点(二维点)
  Dim Vert1(0 To 2) As Double            '实体的外界多边形左下角点(三维点)
  Dim Vert2(0 To 2) As Double            '实体的外界多边形右上角点(三维点)
  Dim Intpoints As Variant               '返回的交点集
  Dim Cir As AcadCircle                  '增加的标志,圆
  Dim Pt(0 To 2) As Double               '交点坐标
  Dim Pts As Variant                     '实体的端点坐标集
  Dim Pts1 As Variant                    '实体的端点坐标集
  Dim isxj As Boolean                    '是否端点的标志
  Dim Myss As AcadSelectionSet           '定义第一层循环选择集"myss"
  Dim Myss1 As AcadSelectionSet          '定义第二层循环选择集"myss1"
  Dim Myss2 As AcadSelectionSet          '定义第三层循环选择集"myss2"
  Dim ThisCoord() As coord
  Dim lspPnt As String
  Dim det As String
  Dim LastArray(0) As Variant
  Dim inti As Integer
  Dim intj As Integer

  
  '得到多义线过滤代码
  GpCode(0) = 8
  GpCode(1) = 0
  DataValue(0) = "0"
  DataValue(1) = "lwpolyline"
  
  For Each Myss In ThisDrawing.SelectionSets    '如选择集"myss"存在则删除
    If Myss.Name = "sset" Then
       Myss.Delete
       Exit For
    End If
  Next
  For Each Myss1 In ThisDrawing.SelectionSets   '如选择集"myss1"存在则删除
    If Myss1.Name = "sset1" Then
       Myss1.Delete
       Exit For
    End If
  Next
  
  Set Myss = ThisDrawing.SelectionSets.Add("sset")       '添加选择集myss
  Set Myss1 = ThisDrawing.SelectionSets.Add("sset1")     '添加选择集myss1

  ThisDrawing.SetVariable "clayer", ComboBox5.Text       '设置当前的图层
  
  Myss.Select acSelectionSetAll, , , GpCode, DataValue   '选择所有的特定线
  
   
  '相交线打断

   For i = 0 To Myss.Count - 1                                   '外循环,控制图形中所有的界址线
    Set En = Myss.Item(i)
    Call En.GetBoundingBox(Minext, Maxext)                       '选择包含多义线外框内的所有实体
    Vert1(0) = Minext(0): Vert1(1) = Minext(1): Vert1(2) = 0#
    Vert2(0) = Maxext(0): Vert2(1) = Maxext(1): Vert2(2) = 0#
   '选择与宗地相交的所有的界址线
    Myss1.Select acSelectionSetCrossing, Vert1, Vert2, GpCode, DataValue
     For j = 0 To Myss1.Count - 1                                      '控制所有与外循环中实体相交的实体
      Set En1 = Myss1.Item(j)
      If ComboBox2.Text = "OLYLINE" Or ComboBox4.Text = "OLYLINE" Then
          setn = 3
        ElseIf ComboBox2.Text = "LWPOLYLINE" Or ComboBox4.Text = "LWPOLYLINE" Then
          setn = 2
      End If
        If En1.Handle <> En.Handle Then                        '如为自身,则跳过
         Intpoints = En.IntersectWith(En1, acExtendNone)
         If VarType(Intpoints) <> vbEmpty Then                 '如存在交点则依次取得交点的坐标
             For k = LBound(Intpoints) To UBound(Intpoints) Step 3
                 Pt(0) = Intpoints(k): Pt(1) = Intpoints(k + 1): Pt(2) = Intpoints(k + 2)
                          det = "(list(handent " & Chr(34) & En.Handle & Chr(34) & ")(list " & str(Pt(0)) & str(Pt(1)) & str(Pt(2)) & "))"
        lspPnt = axPoint2lspPoint(Pt)
        ThisDrawing.SendCommand "_break" & vbCr & det & vbCr & "f" & vbCr & lspPnt & vbCr & lspPnt & vbCr
        '程序运行到下面这行代码总提示错误
        Myss.AddItems ThisDrawing.ModelSpace.Item(ThisDrawing.ModelSpace.Count - 1)  '将打断后新增加的实体加入到原选择集进行递归处理
        Exit For
             Next k
          End If
      End If
     Next j
    Next i
End Sub
 楼主| 发表于 2003-10-11 10:36:00 | 显示全部楼层
急切盼望大虾的指点,不胜感激
 楼主| 发表于 2003-10-11 16:34:00 | 显示全部楼层
明总:
这是你曾经的回贴
这个问题可能没这么简单,因为:
断开后对象会变成两个对象,而程序的继操作只是对断开后的一个对象进行操作,而新生成的对象不做操作。但如果考虑新生成的对象,则这种操作就会变成很多的循环。这也是难点。
我想能不能先不要断开,而只取得每个对象上的断开点,再根据对象的属性重新生成对象,这样可能工作量会大点,而且对于某些对象可能不太适合,如样条曲线。
如果能够从末端开始进行断开操作,则下一个断开点还可以保留在源对象上,这可能可行,但这些点怎样排序,又是一个问题。


我现在需要处理的正是这样的问题,我上面的程序就是将新生的对象加入到原选择集中进行处理,但总是无法取得新生的对象
发表于 2003-10-11 18:40:00 | 显示全部楼层
这个问题要好好考虑考虑,其实后来想到的一种更好的方法是先求得每条线的交点列表,再求交点到线起点的距离,按距离排序所取得的交点,然后从最大的距离开始一个一个打断线,因为这样做原始的线是不会变的,也就是新生成的线不会再有交点了。
这是个思路,算法关键是排序的方法。
 楼主| 发表于 2003-10-11 20:34:00 | 显示全部楼层
谢谢明总,我那程序开始怎么也不行,但后来好像没有改什么竟然又可以了。莫名其妙!
您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋|手机版|CAD论坛|CAD教程|CAD下载|联系我们|关于明经|明经通道 ( 粤ICP备05003914号 )  
©2000-2023 明经通道 版权所有 本站代码,在未取得本站及作者授权的情况下,不得用于商业用途

GMT+8, 2024-11-28 12:42 , Processed in 0.179206 second(s), 24 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表