如何在Word表格中复制一行?

6
我正在尝试使用VBA在Word中复制表格行,不使用选择对象或剪贴板。也就是说,我想要一个新的行,其内容与现有行相同。
为此,我首先创建一个新的(空)行,并循环遍历源行中的每个单元格,并将其内容复制到目标行中相应的单元格中。
要复制每个单元格,我获取一个引用源单元格整个内容的Range对象,以及目标单元格的等效Range,然后执行以下操作:
oToRange.FormattedText = oFromRange.FormattedText

这在Office 2003上运行得很好,在Office 2010上大多数情况下也能运行。但是,我在一个特定的场景中遇到了一个真正的问题。我已经(大大)简化了这个场景,以展示问题的核心。
在下面的图片中,外部(灰色的)2R x 1C表中有两个单元格。第二行是要复制的行。第一行是我创建的新行,我想将第二行的内容复制到其中。
你会注意到,第二行包含一个嵌套表格。
当我在Word 2003中运行下面的代码时,它完美地工作,我得到以下结果:
但是,在Word 2010中,同样的代码产生了这个结果:
正如你所看到的,单元格内容被插入到目标表格单元格的前面(和外部)。
值得一提的是,如果我在嵌套表格后面放置一些东西,使其不再是源单元格中的最后一件事,那么这个问题就不会发生。
这是我使用的完整VBA代码:
Dim oDoc As Word.Document
Set oDoc = ThisDocument

Dim oFromRange As Range
Set oFromRange = ThisDocument.Tables(1).Cell(2, 1).Range
oFromRange.End = oFromRange.End - 1

Dim oToRange As Range
Set oToRange = ThisDocument.Tables(1).Cell(1, 1).Range
oToRange.End = oToRange.End - 1

oToRange.FormattedText = oFromRange.FormattedText
注意:需要调整源和目标范围的末尾,因为Cell.Range包括单元格结束标记,我不想复制它。 我该怎么做才能说服它将内容放在目标单元格内(就像Word 2003一样),而不是在它之前呢?

1
+1 对于一个解释得很好的问题 :) - Siddharth Rout
3个回答

9

希望我正确理解了您的问题... 这不就是您想要做的吗?这段代码将复制表格的第一行,并在其下创建该行的副本。

Sub Sample()
    Dim tbl As Table

    Set tbl = ActiveDocument.Tables(1)

    tbl.Rows(1).Range.Copy
    tbl.Rows(1).Select
    Selection.InsertRowsBelow
    tbl.Rows(2).Range.Paste
End Sub

屏幕截图

在此输入图片描述

后续(来自评论)

此代码未使用Selection对象。

Sub Sample()
    Dim tbl As Table
    Dim rowNew As Row

    Set tbl = ActiveDocument.Tables(1)
    Set rowNew = tbl.Rows.Add(BeforeRow:=tbl.Rows(1))
    tbl.Rows(2).Range.Copy
    tbl.Rows(1).Range.Paste
End Sub

更多跟进(来自评论)

Sub Sample()
    Dim tbl As Table
    Dim rowNew As Row

    Set tbl = ActiveDocument.Tables(1)
    Set rowNew = tbl.Rows.Add(BeforeRow:=tbl.Rows(1))
    tbl.Rows(1).Range.FormattedText = tbl.Rows(2).Range.FormattedText
    '~~~> This is required as the above code inserts a blank row in between
    tbl.Rows(2).Delete
End Sub

谢谢。抱歉,我在问题中应该说清楚我不想使用“Selection”对象。我有成千上万行的代码有意避免使用它,在这里我不想例外。肯定可以不用它实现相同的结果,对吧? - Gary McGill
可以的 :) 已更新上述帖子 - Siddharth Rout
啊啊啊。我很不好意思再次抱怨,但我也不想使用剪贴板。我已经把这个更新放在了问题的顶部,但是我忘记在评论中也添加它了。对不起,我在这里浪费了你的时间两次,我谨向您道歉。 - Gary McGill
@SiddharthRout:我收到以下错误信息:无法访问此集合中的单个行,因为表格具有垂直合并的单元格。有什么建议吗? - Amir
1
@rima:我建议您提出一个新问题,并附上此问题的链接。在您的问题中还应包括表格的结构。最重要的是,包括您尝试解决问题的代码。我们会从那里开始处理 :) - Siddharth Rout
显示剩余2条评论

1
Function duplicate_row(ByRef ontable, rownnumber) As Row
 Dim c
 Dim fromrow As Row
 Dim newrow As Row
 Set fromrow = ontable.Rows(rownnumber)
 Set newrow = ontable.Rows.Add
 newrow.Range.FormattedText = fromrow.Range.FormattedText
 ontable.Rows(ontable.Rows.Count).Delete
 Set duplicate_row = newrow
End Function



Sub test()
 Dim newrow As Row

 Set newrow = duplicate_row(ActiveDocument.Tables(1), 2)
 newrow.Range.Find.Execute FindText:="text_service", ReplaceWith:="aaa", Replace:=wdReplaceAll
 newrow.Range.Find.Execute FindText:="text_amount", ReplaceWith:="500", Replace:=wdReplaceAll
 newrow.Range.Find.Execute FindText:="text_price", ReplaceWith:="50", Replace:=wdReplaceAll
 newrow.Range.Find.Execute FindText:="text_comment", ReplaceWith:="bbb", Replace:=wdReplaceAll

' ActiveDocument.Tables(1).Rows(1).Delete ' after adding all rows, delete the tempalte row
End Sub

这与已接受答案中的上一个版本有何不同? - Gary McGill
不同之处在于它是一个有用的函数。它会在模板后添加行。 - Shimon Doodkin

0

我想分享一下我认为最简单的解决方案。它不使用选择对象或剪贴板,也不会创建需要删除的额外行。

Sub DuplicateRow(t As Table, r As Integer)
    t.Rows(r).Range.Next.InsertBefore vbCr
    t.Rows(r).Range.Next.FormattedText = t.Rows(r).Range.FormattedText
End Sub

只需使用表格和行索引调用宏即可复制。适用于表内的任何行(第一行、最后一行或中间的任何行)

DuplicateRow ActiveDocument.Tables(1), 2

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接