明经CAD社区

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
查看: 6151|回复: 14

[VBA]如何实现选择集内的数据或对象按一定要求排序并生成新的选择集

  [复制链接]
发表于 2004-4-30 23:39:00 | 显示全部楼层 |阅读模式
我的图形上有10个text,选择10个text,生成一个选择集,我想按10个text的插入点(insertpoint)的Y轴坐标点大小排序并生成一个新的选择集
发表于 2004-5-1 07:07:00 | 显示全部楼层
这是排序问题,一般来说将所有的选择集中的对象及插入点坐标放到一个自定义数据类型中,然后按自定义数据类型中的某一项对整个自定义数据进行排序。
我写的对象均布程序就是这样做的。
 楼主| 发表于 2004-5-1 17:02:00 | 显示全部楼层
小生不才,能否给我一个例子,万分感谢。E-mail:fjy602@163.com
发表于 2004-5-1 19:57:00 | 显示全部楼层
本帖最后由 作者 于 2004-5-2 16:15:15 编辑
  1. Public Function Sort(Texts As Variant, TextHeight As Double) As Collection
  2. '将选择集、文本数组或文本集合按X轴和Y轴进行排序,返回一个集合的集合
  3. Dim Total As New Collection
  4. Dim pPnts As Collection
  5. Dim Judge As Boolean
  6. Dim i As AcadObject, j As Collection, k As Integer, l As Integer
  7. Dim p1, p2, p3, p4
  8. For Each i In Texts
  9.        Judge = False
  10.        For Each j In Total
  11.        p1 = j(1).InsertionPoint: p2 = i.InsertionPoint
  12.                If Abs(p1(1) - p2(1)) < TextHeight Then
  13.                        For k = 1 To j.Count
  14.                        p3 = j(k).InsertionPoint
  15.                                If p3(0) >= p2(0) Then
  16.                                        j.Add i, , k
  17.                                        Judge = True
  18.                                        Exit For
  19.                                End If
  20.                        Next k
  21.                        If Not Judge Then j.Add i: Judge = True
  22.                        Exit For
  23.                End If
  24.        Next j
  25.        If Not Judge Then
  26.                Set pPnts = New Collection
  27.                pPnts.Add i
  28.                For l = 1 To Total.Count
  29.                        p4 = Total(l)(1).InsertionPoint
  30.                        If p4(1) < p2(1) Then
  31.                                Total.Add pPnts, , l
  32.                                Judge = True
  33.                                Exit For
  34.                        End If
  35.                Next l
  36.                If Not Judge Then Total.Add pPnts
  37.        End If
  38. Next i
  39. Set Sort = Total
  40. End FunctionPublic Sub UnExplodeMText()
  41. '将选择的多个Text或MText按X轴和Y轴连接为一个MText,即炸开MText的逆过程
  42. On Error GoTo ErrClear
  43. Dim pFilterType(0) As Integer, pFilter(0) As Variant
  44. Dim pHeight As Double
  45. Dim pText As String
  46. Dim ss As AcadSelectionSet
  47. Dim i, j, k As Integer
  48. pFilterType(0) = 0: pFilter(0) = "Text,MText"
  49. Set ss = ThisDrawing.SelectionSets.Add("*MergeTexts*")
  50. ss.SelectOnScreen pFilterType, pFilter
  51. pHeight = ss(0).Height
  52. For Each i In Sort(ss, pHeight)
  53. For Each j In i
  54. pText = pText & j.TextString
  55. Next j
  56. pText = pText & "\P"
  57. Next i
  58. For k = 0 To ss.Count - 1
  59. ss(k).Delete
  60. Next k
  61. ThisDrawing.ModelSpace.AddMText(ThisDrawing.Utility.GetPoint(, "请输入插入点:"), 0, pText).Height = pHeight
  62. ErrClear:
  63. ss.Delete
  64. End Sub
发表于 2004-5-2 18:39:00 | 显示全部楼层
本帖最后由 作者 于 2004-5-6 7:43:30 编辑

这是改进版
  1. Private Function MToS(MText As Variant) As Variant
  2. '炸开MText并返回一个Text数组
  3.        Dim i As Integer
  4.        Dim ss As AcadSelectionSet
  5.        Dim pTexts() As AcadObject
  6.        ThisDrawing.ActiveSelectionSet.Clear
  7.        ThisDrawing.SendCommand "Explode" & vbCr & "(handent " & Chr(34) _
  8.                                                        & MText.Handle & Chr(34) & ")" & vbCr & vbCr       Set ss = ThisDrawing.ActiveSelectionSet
  9.        ReDim pTexts(ss.Count - 1) As AcadObject
  10.        For i = 0 To ss.Count - 1
  11.        Set pTexts(i) = ss(i)
  12.        Next i
  13.        MToS = pTexts
  14. End Function
  15. Public Function Sort(Texts As Variant, TextHeight As Double) As Collection
  16. '将选择集、Text数组或Text集合按X轴和Y轴进行排序,返回一个集合的集合
  17. Dim Total As New Collection
  18. Dim pPnts As Collection
  19. Dim Judge As Boolean
  20. Dim i As AcadObject, j As Collection, k As Integer, l As Integer
  21. Dim p1, p2, p3, p4
  22. For Each i In Texts
  23.        Judge = False
  24.        For Each j In Total
  25.        p1 = j(1).InsertionPoint: p2 = i.InsertionPoint
  26.                If Abs(p1(1) - p2(1)) < TextHeight Then
  27.                        For k = 1 To j.Count
  28.                        p3 = j(k).InsertionPoint
  29.                                If p3(0) >= p2(0) Then
  30.                                        j.Add i, , k
  31.                                        Judge = True
  32.                                        Exit For
  33.                                End If
  34.                        Next k
  35.                        If Not Judge Then j.Add i: Judge = True
  36.                        Exit For
  37.                End If
  38.        Next j
  39.        If Not Judge Then
  40.                Set pPnts = New Collection
  41.                pPnts.Add i
  42.                For l = 1 To Total.Count
  43.                        p4 = Total(l)(1).InsertionPoint
  44.                        If p4(1) < p2(1) Then
  45.                                Total.Add pPnts, , l
  46.                                Judge = True
  47.                                Exit For
  48.                        End If
  49.                Next l
  50.                If Not Judge Then Total.Add pPnts
  51.        End If
  52. Next i
  53. Set Sort = Total
  54. End Function
  55. Public Sub UnExplodeMText()
  56. '将选择的多个Text或MText按X轴和Y轴连接为一个MText,即炸开MText的逆过程
  57. On Error Resume Next
  58. Dim pFilterType(0) As Integer, pFilter(0) As Variant
  59. Dim Ents(0) As AcadObject, l As AcadObject
  60. Dim pHeight As Double
  61. Dim pText As String
  62. Dim pObjs As New Collection
  63. Dim ss As AcadSelectionSet
  64. Dim i, j, k As Integer
  65. Set ss = ThisDrawing.SelectionSets.Add("*UnExplodeMText*")
  66. If Err Then
  67. Set ss = ThisDrawing.SelectionSets("*UnExplodeMText*")
  68. Err.Clear
  69. End If
  70. ss.Clear
  71. pFilterType(0) = 0: pFilter(0) = "Text,MText"
  72. ss.SelectOnScreen pFilterType, pFilter
  73. For Each l In ss
  74. pObjs.Add l
  75. Next l
  76. ss.Delete
  77. Debug.Print pObjs.Count
  78. i = 1
  79. Do While i <= pObjs.Count
  80.        If UCase(pObjs(i).ObjectName) = "ACDBMTEXT" Then
  81.        For Each j In MToS(pObjs(i))
  82.        pObjs.Add j, , , i
  83.        Next j
  84.        pObjs.Remove i
  85.        End If
  86.        i = i + 1
  87. Loop
  88. Debug.Print pObjs.Count
  89. pHeight = pObjs(1).Height
  90. For Each i In Sort(pObjs, pHeight)
  91. For Each j In i
  92. pText = pText & j.TextString
  93. Next j
  94. pText = pText & "\P"
  95. Next i
  96. For k = 1 To pObjs.Count
  97. pObjs(k).Delete
  98. Next k
  99. ThisDrawing.ModelSpace.AddMText(ThisDrawing.Utility.GetPoint(, "请输入插入点:"), 0, pText).Height = pHeight
  100. ErrClear:
  101. End Sub
 楼主| 发表于 2004-5-3 19:44:00 | 显示全部楼层
这是我修改后的程序,由于我调试失败,我不知道我修改后是否与您程序结果是否一样? Sub sort1()
Dim Total As New Collection
Dim pPnts As Collection
Dim Judge As Boolean
Dim i As AcadText, j As Collection, k, a As Integer, l As Integer
Dim p1, p2, p3, p4
Dim textheight As Double
Dim ssetobjcount As Integer
Dim ssetobj As AcadSelectionSet
Dim va

If ThisDrawing.SelectionSets.Count <> 0 Then
For a = 0 To ThisDrawing.SelectionSets.Count - 1
Set ssetobj = ThisDrawing.SelectionSets.Item(a)
ssetobj.Delete
Next
End If
Dim gpCode(0) As Integer
Dim dataValue(0) As Variant
gpCode(0) = 0
dataValue(0) = "TEXT"
Dim FilterType As Variant, FilterData As Variant
FilterType = gpCode
FilterData = dataValue
Set ssetobj = ThisDrawing.SelectionSets.Add("texts")
ssetobj.SelectOnScreen FilterType, FilterData

ssetobjcount = ssetobj.Count
If ssetobjcount = 0 Then
Exit Sub
End If
For Each i In ssetobj
Judge = False
For Each j In Total
p1 = j(1).insertionPoint: p2 = i.insertionPoint
If Abs(p1(1) - p2(1)) < textheight Then
For k = 1 To j.Count
p3 = j(k).insertionPoint
If p3(0) >= p2(0) Then
j.Add i, , k
Judge = True
Exit For
End If
Next k
If Not Judge Then j.Add i: Judge = True
Exit For
End If
Next j
If Not Judge Then
Set pPnts = New Collection
pPnts.Add i
For l = 1 To Total.Count
p4 = Total(l)(1).insertionPoint
If p4(1) < p2(1) Then
Total.Add pPnts, , l
Judge = True
Exit For
End If
Next l
If Not Judge Then Total.Add pPnts
End If
Next i
[U]Dim entobj As AcadEntity
Dim text As AcadText
For a = 1 To Total.Count - 1
Set entobj = Total(a)
Set text = entobj
MsgBox RTrim(LTrim(text.textString))
Next a
[/U]
End sub
我还在End sub 前加了几条语句(带下划线显示),本想读出Total内的数据,但调试失败(提示类型不匹配),我不知道为什么会出错,忘告知出错原因和修正程序,谢谢!
发表于 2004-5-3 20:20:00 | 显示全部楼层
Total是一个集合的集合,要引用用


for each i in Total


for each j in i


debug.print j.textstring


next j


next i
 楼主| 发表于 2004-5-3 20:52:00 | 显示全部楼层
我按下列语句已调试成功,谢谢! 按下面语句msgbox显示的是单个Text的文本内容,假如我想用msgbox显示同一行内Text对象的全部文本,我该如何呢?为昐,谢谢! For Each j In Total
For Each i In j
MsgBox j.Count
MsgBox i.textString
Next i
Next j
发表于 2004-5-3 21:06:00 | 显示全部楼层
上面有: For Each i In Sort(ss, pHeight)
For Each j In i
pText = pText & j.TextString
Next j
pText = pText & "\P"
Next i
 楼主| 发表于 2004-5-3 21:22:00 | 显示全部楼层
我已调试成功,谢谢!!!!!
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2025-2-22 18:38 , Processed in 0.310230 second(s), 24 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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