Zzllvb 发表于 2017-9-1 23:36:53

关于选择集RemoveItems的问题

SSet选择集中是一些多段线,现在想移除掉其中面积为0的。
...
For Each ent In SSet
      If ent.area < 0.001 Then
            Call RemoveEntFromSSet(ent, SSet)
      End If
Next
...

其中RemoveEntFromSSet过程如下:
Public Sub RemoveEntFromSSet(ByVal ent As Object, ByRef SSet As Object)
    Dim objCollection(0) As Object ' AcadEntity
    Set objCollection(0) = ent
    SSet.RemoveItems objCollection
End Sub

结果:有一些面积为0的多段线移除掉了,有一些总是移除不掉。具体说来,测试的图中有5条多段线,其中4条面积为0。可是程序只能移除掉2条面积为0的,最终SSet.count为3,但理论上最终SSet.count应该为1啊!

vbcad 发表于 2017-9-1 23:36:54

本帖最后由 vbcad 于 2017-9-2 08:07 编辑

当你删除后总数会变化,后面的没有执行,外面再套一个循环
如:
DO
for 选择集循环如果 为0 删除
NEXT
LOOP 删除结束退出


只能写一个框架你借鉴一下

DO
FLAG=True
For Each ent In SSet
      If ent.area < 0.001 Then
            Call RemoveEntFromSSet(ent, SSet)
'如果删除,则说明还有,退出再循环
FLAG=FALSE
EXIT FOR
      End If
Next
LOOP UNTIL FLAG'直到没有需要删除的退出
队列删除常碰到,一定要有删除动作。

Zzllvb 发表于 2017-9-1 23:40:01

于是我:
For Each ent In SSet
   
      If ent.area < 0.001 Then
            MsgBox "进入"
            Call RemoveEntFromSSet(ent, SSet)
            MsgBox SSet.count
      End If
    Next

我发现只MsgBox了两次"进入"。

于是我直接:
For Each ent In SSet
   
      If ent.area < 0.001 Then
            MsgBox "进入"
      End If
    Next
这样就正常了,MsgBox了4次"进入"。好奇怪,很费解

xinxirong 发表于 2017-9-2 09:03:08

很奇怪,vlisp的foreach和vb的foreach不同吗?同样的代码vlisp就没有问题。

Zzllvb 发表于 2017-9-2 11:09:49

本帖最后由 Zzllvb 于 2017-9-2 11:24 编辑

vbcad 发表于 2017-9-1 23:36
当你删除后总数会变化,后面的没有执行,外面再套一个循环
如:
DO


非常感谢您的回答!明经币奉上。
也就是说,对于集合,如果遍历的时候有删除集合元素的操作,那么就很有可能不能再正常依次遍历下去了。需要退出,对新的集合重新开始遍历。

但是小弟还有一点不太明白:
模型空间 也是一个集合,我貌似常常有遍历ThisDrawing.ModelSpace,删除特定元素的操作,但是好像并没有什么问题啊?
对于这个例子,我:
For Each ent In ThisDrawing.ModelSpace
            If ent.area < 0.001 Then
                  ent.Delete
            End If
   Next

面积为0的也都正确删除了。

还是有点不解。难道ThisDrawing.ModelSpace和SelectionSet这两个集合有何不同啊??
还望前辈进一步指点。

vbcad 发表于 2017-9-2 13:26:52

为什么遍历ThisDrawing.ModelSpace删除没有问题我也不知道,估计应该是与删除动作后数据刷新有关。

以前碰到过类似的问题,我要删除LISTBOX控件中选中的行,如果只选择一行,没有问题,如果选择多行,删除就会出错,后来经过调试代码发现队列中的总数在被删除后就会发生改变,比如有10个,当你删除一个后就会变成9个,从而刷新了队列数据,就又要从头开始。如果行数太多比如一万行以上,要删除多个的时候,每删除一个都从头开始效率是非常低下的,用For Each ...IN就不合适了,就要用FOR i=开始行 到结束行,删除后记下行位置,下次从记录的行开始,而不是从头开始,就可以解决效率低下的问题。

nslove44202489 发表于 2017-9-7 21:55:45

for each不可以删除,for循环可以

Zzllvb 发表于 2017-9-12 14:14:25

nslove44202489 发表于 2017-9-7 21:55
for each不可以删除,for循环可以

你好。for循环也不可以。最好的办法是把需要删除的加入一个新选择集,然后删除。

pengfei2010 发表于 2017-10-7 19:23:08

回帖是一种美德!感谢楼主的无私分享 谢谢

Zzllvb 发表于 2017-10-7 23:01:43

pengfei2010 发表于 2017-10-7 19:23
回帖是一种美德!感谢楼主的无私分享 谢谢

共同进步:lol
页: [1] 2
查看完整版本: 关于选择集RemoveItems的问题