[VBA]如何实现选择集内的数据或对象按一定要求排序并生成新的选择集
我的图形上有10个text,选择10个text,生成一个选择集,我想按10个text的插入点(insertpoint)的Y轴坐标点大小排序并生成一个新的选择集 这是排序问题,一般来说将所有的选择集中的对象及插入点坐标放到一个自定义数据类型中,然后按自定义数据类型中的某一项对整个自定义数据进行排序。<BR>我写的对象均布程序就是这样做的。 小生不才,能否给我一个例子,万分感谢。E-mail:fjy602@163.com 本帖最后由 作者 于 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 本帖最后由 作者 于 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 这是我修改后的程序,由于我调试失败,我不知道我修改后是否与您程序结果是否一样?
<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 <> 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)) < textheight Then<BR> For k = 1 To j.Count<BR> p3 = j(k).insertionPoint<BR> If p3(0) >= 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) < 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内的数据,但调试失败(提示类型不匹配),我不知道为什么会出错,忘告知出错原因和修正程序,谢谢! Total是一个集合的集合,要引用用
for each i in Total
for each j in i
debug.print j.textstring
next j
next i 我按下列语句已调试成功,谢谢!
按下面语句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> 上面有:
For Each i In Sort(ss, pHeight)<BR>For Each j In i<BR>pText = pText & j.TextString<BR>Next j<BR>pText = pText & "\P"<BR>Next i<BR> 我已调试成功,谢谢!!!!!
页:
[1]
2