[英]copy Word document contents without using clipboard (VBA)
I was wondering how to avoid using Windows clipboard, when you want to "replicate" multiple sections of a Word document (using VBA in macros) 我想知道如何避免使用Windows剪贴板,当你想“复制”Word文档的多个部分时(在宏中使用VBA)
Why to avoid? 为什么要避免? Because we're using Word on a server, in a multiuser environment (I know that it is officially frowned upon) 因为我们在服务器上使用Word,在多用户环境中(我知道它是正式的不赞成)
Otherwise, this would be easily accomplished with Selection.Copy and Selection.Paste methods. 否则,使用Selection.Copy和Selection.Paste方法可以轻松完成。
Thanks. 谢谢。
I finally resolved to copy word by word. 我终于决定一字一句地复制。 FormattedText seemed to work fairly well, until the last word (some special (evidently) characters), where suddenly the cell that I just filled with copied content would go blank. FormattedText似乎工作得相当好,直到最后一个字(一些特殊的(显然)字符),突然我刚刚填充复制内容的单元格将变为空白。 When I increased the number of cells, other run-time errors would pop up, like Your table got corrupted, and other ambiguous ones. 当我增加单元格数量时,会弹出其他运行时错误,例如你的表被破坏,以及其他模糊的错误。 Somehow, the source cell that I was copying from always seemed to have these peculiar chars in the end with ASCII codes 13 and 7. I know what 13 means, but 7? 不知何故,我复制的源单元似乎总是有这些特殊的字符,最后用ASCII码13和7.我知道13的意思是什么,但7? Anyway, I decided to copy everything apart from this last character with code 7. It seems to work alright. 无论如何,我决定用代码7复制除最后一个字符之外的所有内容。它似乎工作正常。 Both formatting and fields are copied too. 格式和字段也都被复制了。 In any case, the whole story proved to me for one more time that programming in VBA is mostly trial-and-error occupation. 无论如何,整个故事再次向我证明了VBA中的编程主要是反复试验。 You are never sure when something might break.. unless I am missing update on some crucial concepts.. 你永远不确定什么时候可能会破坏......除非我错过了一些关键概念的更新。
Here's the chunks of the code I used. 这是我使用的代码块。 The idea is that first we have a document with a single 1x1 cell table, with some rich text content. 我们的想法是,首先我们有一个带有单个1x1单元格表的文档,其中包含一些富文本内容。 In the first piece of the code (inside a macro) I multiply the cells: 在第一段代码中(在宏内)我将单元格相乘:
Dim cur_width As Integer, i As Integer, max_cells As Integer, cur_row As Integer
Dim origin_width As Integer
If ActiveDocument.Tables.Count = 1 _
And ActiveDocument.Tables(1).Rows.Count = 1 _
And ActiveDocument.Tables(1).Columns.Count = 1 _
Then
max_cells = 7 ' how many times we are going to "clone" the original content
i = 2 ' current cell count - starting from 2 since the cell with the original content is cell number 1
cur_width = -1 ' current width
cur_row = 1 ' current row count
origin_width = ActiveDocument.Tables(1).Rows(1).Cells(1).Width
' loop for each row
While i <= max_cells
' adjust current width
If cur_row = 1 Then
cur_width = origin_width
Else
cur_width = 0
End If
' loop for each cell - as long as we have space, add cells horizontally
While i <= max_cells And cur_width + origin_width < ActiveDocument.PageSetup.PageWidth
Dim col As Integer
' \ returns floor() of the result
col = i \ ActiveDocument.Tables(1).Rows.Count
// 'add cell, if it is not already created (which happens when we add rows)
If ActiveDocument.Tables(1).Rows(cur_row).Cells.Count < col Then
ActiveDocument.Tables(1).Rows(cur_row).Cells.Add
End If
// 'adjust new cell width (probably unnecessary
With ActiveDocument.Tables(1).Rows(cur_row).Cells(col)
.Width = origin_width
End With
// 'keep track of the current width
cur_width = cur_width + origin_width
i = i + 1
Wend
' when we don't have any horizontal space left, add row
If i <= max_cells Then
ActiveDocument.Tables(1).Rows.Add
cur_row = cur_row + 1
End If
Wend
End If
In the second part of the macro I populate each empty cell with the contents of the first cell: 在宏的第二部分中,我用第一个单元格的内容填充每个空单元格:
' duplicate the contents of the first cell to other cells
Dim r As Row
Dim c As Cell
Dim b As Boolean
Dim w As Range
Dim rn As Range
b = False
i = 1
For Each r In ActiveDocument.Tables(1).Rows
For Each c In r.Cells
If i <= max_cells Then
// ' don't copy first cell to itself
If b = True Then
' copy everything word by word
For Each w In ActiveDocument.Tables(1).Rows(1).Cells(1).Range.Words
' get the last bit of formatted text in the destination cell, as range
' do it first by getting the whole range of the cell, then collapsing it
' so that it is now the very end of the cell, and moving it one character
' before (because collapsing moves the range actually beyond the last character of the range)
Set rn = c.Range
rn.Collapse Direction:=wdCollapseEnd
rn.MoveEnd Unit:=wdCharacter, Count:=-1
' somehow the last word of the contents of the cell is always Chr(13) & Chr(7)
' and especially Chr(7) causes some very strange and murky problems
' I end up avoiding them by not copying the last character, and by setting as a rule
' that the contents of the first cell should always contain an empty line in the end
If c.Range.Words.Count <> ActiveDocument.Tables(1).Rows(1).Cells(1).Range.Words.Count Then
rn.FormattedText = w
Else
'MsgBox "The strange text is: " & w.Text
'the two byte values of this text (which obviously contains special characters with special
'meaning to Word can be found (and watched) with
'AscB(Mid(w.Text, 1, 1)) and AscB(Mid(w.Text, 2, 1))
w.MoveEnd Unit:=WdUnits.wdCharacter, Count:=-1
rn.FormattedText = w
End If
Next w
End If
b = True
End If
i = i + 1
Next c
Next r
Here are the images of the Word document in question. 以下是相关Word文档的图像。 First image is before running the macro, second is between the first chunk of code and the last, while the third image is the resulting document. 第一个图像在运行宏之前,第二个图像在第一个代码块和最后一个之间,而第三个图像是结果文档。
Image 1 Image 2 Image 3 图像1 图像2 图像3
That's it. 而已。
This doesn't always work, with text fields, diagramms, for example, or if you need to copy it to another document, but it's good for copying simple formatted text inside one document. 这并不总是有效,例如文本字段,图表,或者如果您需要将其复制到另一个文档,但它有利于在一个文档中复制简单的格式化文本。
'First select something, then do
Word.WordBasic.CopyText
'Then move somewhere
Word.WordBasic.OK;
To copy the whole document to a new document use this: 要将整个文档复制到新文档,请使用以下命令:
Word.Application.Documents.Add Word.ActiveDocument.FullName
I ran into a similar issue. 我遇到了类似的问题。 I wanted to copy a table from one word doc to another using Powershell without using the clipboard. 我想使用Powershell将表格从一个单词doc复制到另一个单词doc而不使用剪贴板。 Since a user using the computer while the script ran could break the script by using the clipboard. 由于在脚本运行时使用计算机的用户可能会使用剪贴板破坏脚本。 The solution I came up with was: 我想出的解决方案是:
range.InsertFile
with the first parameter of the source file with my bookmark and the second parameter of my bookmark name. 使用range.InsertFile
,带有我的书签的源文件的第一个参数和我的书签名称的第二个参数。 This single operation pulled the entire table plus source formatting directly into the destination document. 此单个操作将整个表格和源格式直接拉入目标文档。 I then added code based on where the insertion was being done and how much longer the story was to select the inserted table to allow further operations on it. 然后,我根据插入的位置添加代码,以及选择插入表以允许对其进行进一步操作的故事。
I tried many any other methods to move the table and this was by far the best. 我尝试了许多其他方法来移动表格,这是迄今为止最好的方法。 Sorry I can't provide VBA code for this solution. 抱歉,我无法为此解决方案提供VBA代码。
In Office 2007+ VSTO, you can export the block with Range.ExportFragment and then go to your new document and import it with Range.ImportFragment . 在Office 2007+ VSTO中,您可以使用Range.ExportFragment导出块,然后转到新文档并使用Range.ImportFragment导入它。 I haven't used this in production, but experimented with it and it seems to work OK. 我没有在生产中使用过这个,但是对它进行了实验,似乎工作正常。
One caveat, I got errors when trying to export as a .docx, but RTF seemed to work ok. 有一点需要注意,我在尝试导出为.docx时出错,但RTF似乎工作正常。
Both methods exist in VBA as well, but I only tested the VSTO methods. 这两种方法也存在于VBA中,但我只测试了VSTO方法。
Use the Text property of the Selection object to put the data into a string variable rather than onto the clipboard: 使用Selection对象的Text属性将数据放入字符串变量而不是放在剪贴板上:
Dim strTemp as String 将strTemp作为字符串调暗
strTemp = Selection.Text strTemp = Selection.Text
You can then insert the text stored in the variable elsewhere as needed. 然后,您可以根据需要将存储在变量中的文本插入其他位置。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.