我想将所有表移到文档的末尾,只是为了在单独的会话中首先处理所有其他非表(普通)段落。这是我(最终)提出的代码:
Dim iCounter As Integer
For iCounter = 1 To ThisDocument.Tables.Count
ThisDocument.Tables(1).Range.Select
Selection.Cut
Selection.EndKey (wdStory)
Selection.TypeParagraph
Selection.Paste
Next iCounter
它已经奏效了。但是,我想知道:为什么我总是要操作第一张桌子,而不是第一张,第二张......等等到最后一张?这种“不断变化的指数”或“不变 - 应该在哪里变化”现象的一般术语或一般概念是什么?为什么像下面这样的普通循环不起作用?
for each oTable in ThisDocument.Tables
oTable.Range.Cut
Selection.EndKey (wdStory)
Selection.TypeParagraph
Selection.Paste
DoEvents
next oTable
上述解决方案,一个看似正常的循环,结果是不合适的,并最终不间断运行。我不得不强行关闭Word窗口。和
Dim iCounter as Integer
For iCounter = 1 To ThisDocument.Tables.Count
ThisDocument.Tables(iCounter).Range.Cut
Selection.EndKey (wdStory)
Selection.TypeParagraph
Selection.Paste
Next iCounter
上述解决方案,另一个看似正常的循环,在试运行时输出一个“半成品”产品,即它移动了一些而不是全部的表。
答案 0 :(得分:1)
根据您的第一个工作示例提出的原始问题 - 为什么总是选择Table(1)
?当您将表格剪切并将其放在文档的末尾时,Table(1)
成为Table(n)
,Table(2)
现在成为Table(1)
。但是它有效,因为你没有改变表的总数,所以循环完全迭代n
次。
在第二个示例中,您将在迭代集合时从集合中删除对象。因为您将该对象放在集合的末尾,所以迭代永远不会到达终点。 基本规则:永远不要在For-Each
循环中删除或重新排序任何内容!。
你的第三个例子是类似的:你正在从选择中删除某些东西然后将它放在选择的结尾 - 这是一种奇怪的行为。在这种情况下,您还要递增表号。因此,如果Table(1)
移到最后,Table(2)
变为Table(1)
,那么当您将icounter
增加到2
时,您实际上正在处理最初的内容Table(3)
[现在Table(2)
]和新Table(1)
[Table(2)
]未受影响。
当您知道从集合或列表中删除某些内容时,避免这种混淆的最简单方法是向后工作。然后,您可以避免(1)
而不是(iCounter)
的微妙编码细微差别。
Dim iCounter as Integer
Dim NumLoops as Long
NumLoops = ThisDocument.Tables.Count
' NumLoops is not important in this example, but
' when you delete (not move) a table you also change the overall count.
For iCounter = NumLoops To 1 Step -1
ThisDocument.Tables(iCounter).Range.Cut
Selection.EndKey (wdStory)
Selection.TypeParagraph
Selection.Paste
Next iCounter