fjy602 发表于 2004-4-30 23:39:00

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

我的图形上有10个text,选择10个text,生成一个选择集,我想按10个text的插入点(insertpoint)的Y轴坐标点大小排序并生成一个新的选择集

mccad 发表于 2004-5-1 07:07:00

这是排序问题,一般来说将所有的选择集中的对象及插入点坐标放到一个自定义数据类型中,然后按自定义数据类型中的某一项对整个自定义数据进行排序。<BR>我写的对象均布程序就是这样做的。

fjy602 发表于 2004-5-1 17:02:00

小生不才,能否给我一个例子,万分感谢。E-mail:fjy602@163.com

雪山飞狐_lzh 发表于 2004-5-1 19:57:00

本帖最后由 作者 于 2004-5-2 16:15:15 编辑

Public Function Sort(Texts As Variant, TextHeight As Double) As Collection
'将选择集、文本数组或文本集合按X轴和Y轴进行排序,返回一个集合的集合
Dim Total As New Collection
Dim pPnts As Collection
Dim Judge As Boolean
Dim i As AcadObject, j As Collection, k As Integer, l As Integer
Dim p1, p2, p3, p4
For Each i In Texts
       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
Set Sort = Total
End FunctionPublic Sub UnExplodeMText()
'将选择的多个Text或MText按X轴和Y轴连接为一个MText,即炸开MText的逆过程
On Error GoTo ErrClear
Dim pFilterType(0) As Integer, pFilter(0) As Variant
Dim pHeight As Double
Dim pText As String
Dim ss As AcadSelectionSet
Dim i, j, k As Integer
pFilterType(0) = 0: pFilter(0) = "Text,MText"
Set ss = ThisDrawing.SelectionSets.Add("*MergeTexts*")
ss.SelectOnScreen pFilterType, pFilter
pHeight = ss(0).Height
For Each i In Sort(ss, pHeight)
For Each j In i
pText = pText & j.TextString
Next j
pText = pText & "\P"
Next i
For k = 0 To ss.Count - 1
ss(k).Delete
Next k
ThisDrawing.ModelSpace.AddMText(ThisDrawing.Utility.GetPoint(, "请输入插入点:"), 0, pText).Height = pHeight
ErrClear:
ss.Delete
End Sub

雪山飞狐_lzh 发表于 2004-5-2 18:39:00

本帖最后由 作者 于 2004-5-6 7:43:30 编辑

这是改进版Private Function MToS(MText As Variant) As Variant
'炸开MText并返回一个Text数组
       Dim i As Integer
       Dim ss As AcadSelectionSet
       Dim pTexts() As AcadObject
       ThisDrawing.ActiveSelectionSet.Clear
       ThisDrawing.SendCommand "Explode" & vbCr & "(handent " & Chr(34) _
                                                       & MText.Handle & Chr(34) & ")" & vbCr & vbCr       Set ss = ThisDrawing.ActiveSelectionSet
       ReDim pTexts(ss.Count - 1) As AcadObject
       For i = 0 To ss.Count - 1
       Set pTexts(i) = ss(i)
       Next i
       MToS = pTexts
End Function
Public Function Sort(Texts As Variant, TextHeight As Double) As Collection
'将选择集、Text数组或Text集合按X轴和Y轴进行排序,返回一个集合的集合
Dim Total As New Collection
Dim pPnts As Collection
Dim Judge As Boolean
Dim i As AcadObject, j As Collection, k As Integer, l As Integer
Dim p1, p2, p3, p4
For Each i In Texts
       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
Set Sort = Total
End Function
Public Sub UnExplodeMText()
'将选择的多个Text或MText按X轴和Y轴连接为一个MText,即炸开MText的逆过程
On Error Resume Next
Dim pFilterType(0) As Integer, pFilter(0) As Variant
Dim Ents(0) As AcadObject, l As AcadObject
Dim pHeight As Double
Dim pText As String
Dim pObjs As New Collection
Dim ss As AcadSelectionSet
Dim i, j, k As Integer
Set ss = ThisDrawing.SelectionSets.Add("*UnExplodeMText*")
If Err Then
Set ss = ThisDrawing.SelectionSets("*UnExplodeMText*")
Err.Clear
End If
ss.Clear
pFilterType(0) = 0: pFilter(0) = "Text,MText"
ss.SelectOnScreen pFilterType, pFilter
For Each l In ss
pObjs.Add l
Next l
ss.Delete
Debug.Print pObjs.Count
i = 1
Do While i <= pObjs.Count
       If UCase(pObjs(i).ObjectName) = "ACDBMTEXT" Then
       For Each j In MToS(pObjs(i))
       pObjs.Add j, , , i
       Next j
       pObjs.Remove i
       End If
       i = i + 1
Loop
Debug.Print pObjs.Count
pHeight = pObjs(1).Height
For Each i In Sort(pObjs, pHeight)
For Each j In i
pText = pText & j.TextString
Next j
pText = pText & "\P"
Next i
For k = 1 To pObjs.Count
pObjs(k).Delete
Next k
ThisDrawing.ModelSpace.AddMText(ThisDrawing.Utility.GetPoint(, "请输入插入点:"), 0, pText).Height = pHeight
ErrClear:
End Sub

fjy602 发表于 2004-5-3 19:44:00

这是我修改后的程序,由于我调试失败,我不知道我修改后是否与您程序结果是否一样?



<FONT style="BACKGROUND-COLOR: #ffffff">Sub sort1()<BR>Dim Total As New Collection<BR>Dim pPnts As Collection<BR>Dim Judge As Boolean<BR>Dim i As AcadText, j As Collection, k, a As Integer, l As Integer<BR>Dim p1, p2, p3, p4<BR>Dim textheight As Double<BR>Dim ssetobjcount As Integer<BR>Dim ssetobj       As AcadSelectionSet<BR>Dim va<BR><BR>If ThisDrawing.SelectionSets.Count &lt;&gt; 0 Then<BR>For a = 0 To ThisDrawing.SelectionSets.Count - 1<BR>Set ssetobj = ThisDrawing.SelectionSets.Item(a)<BR>ssetobj.Delete<BR>Next<BR>End If</FONT>


<FONT style="BACKGROUND-COLOR: #ffffff">Dim gpCode(0) As Integer<BR>Dim dataValue(0) As Variant<BR>gpCode(0) = 0<BR>dataValue(0) = "TEXT"</FONT>


<FONT style="BACKGROUND-COLOR: #ffffff">Dim FilterType As Variant, FilterData As Variant<BR>FilterType = gpCode<BR>FilterData = dataValue<BR>Set ssetobj = ThisDrawing.SelectionSets.Add("texts")<BR>ssetobj.SelectOnScreen FilterType, FilterData<BR><BR>ssetobjcount = ssetobj.Count<BR>If ssetobjcount = 0 Then<BR>Exit Sub<BR>End If</FONT>


<FONT style="BACKGROUND-COLOR: #ffffff">For Each i In ssetobj<BR>                       Judge = False<BR>                                                       For Each j In Total<BR>                                                                               p1 = j(1).insertionPoint: p2 = i.insertionPoint<BR>                                                       If Abs(p1(1) - p2(1)) &lt; textheight Then<BR>                                                                                       For k = 1 To j.Count<BR>                                                                                       p3 = j(k).insertionPoint<BR>                                                                                                                       If p3(0) &gt;= p2(0) Then<BR>                                                                                                                                                       j.Add i, , k<BR>                                                                                                                                                       Judge = True<BR>                                                                                                                                                       Exit For<BR>                                                                                                                       End If<BR>                                                                                       Next k<BR>                                                                                       If Not Judge Then j.Add i: Judge = True<BR>                                                                                       Exit For<BR>                                                       End If<BR>                       Next j<BR>                       If Not Judge Then<BR>                                                       Set pPnts = New Collection<BR>                                                       pPnts.Add i<BR>                                                       For l = 1 To Total.Count<BR>                                                                                       p4 = Total(l)(1).insertionPoint<BR>                                                                                       If p4(1) &lt; p2(1) Then<BR>                                                                                                                       Total.Add pPnts, , l<BR>                                                                                                                       Judge = True<BR>                                                                                                                       Exit For<BR>                                                                                       End If<BR>                                                       Next l<BR>                                                       If Not Judge Then Total.Add pPnts<BR>                       End If<BR>Next i</FONT>


<FONT style="BACKGROUND-COLOR: #ffffff"><FONT color=#3d11ee>Dim entobj As AcadEntity<BR>Dim text As AcadText<BR>For a = 1 To Total.Count - 1<BR>Set entobj = Total(a)<BR>Set text = entobj<BR>MsgBox RTrim(LTrim(text.textString))<BR>Next a<BR></FONT>End sub</FONT>


我还在End sub 前加了几条语句(带下划线显示),本想读出Total内的数据,但调试失败(提示类型不匹配),我不知道为什么会出错,忘告知出错原因和修正程序,谢谢!

雪山飞狐_lzh 发表于 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

fjy602 发表于 2004-5-3 20:52:00

我按下列语句已调试成功,谢谢!


按下面语句msgbox显示的是单个Text的文本内容,假如我想用msgbox显示同一行内Text对象的全部文本,我该如何呢?为昐,谢谢!


For Each j In Total<BR>For Each i In j<BR>MsgBox j.Count<BR>MsgBox i.textString<BR>Next i<BR>Next j<BR>

雪山飞狐_lzh 发表于 2004-5-3 21:06:00

上面有:


For Each i In Sort(ss, pHeight)<BR>For Each j In i<BR>pText = pText &amp; j.TextString<BR>Next j<BR>pText = pText &amp; "\P"<BR>Next i<BR>

fjy602 发表于 2004-5-3 21:22:00

我已调试成功,谢谢!!!!!
页: [1] 2
查看完整版本: [VBA]如何实现选择集内的数据或对象按一定要求排序并生成新的选择集