vba 使用vba将一个word文档的内容复制到另一个word文档中

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/21317885/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-08 17:36:51  来源:igfitidea点击:

Using vba to copy the contents of a word document into another word document

vbaword-vba

提问by user3229306

I haven't used VB for years, so please forgive me if this turns out to be obvious. I'm trying to write a word vba macro for use in a template which will display a userform and then import the contents of fileA.docx, fileB.docx, or fileC.docx depending on the userform. (After that I'm going to use bookmarks to fill in some form data, I don't know if that's relevant). Files A, B, and C will contain text with some basic formatting such as lists, but nothing fancy.

我已经多年没有使用 VB,所以如果这很明显,请原谅我。我正在尝试编写一个 word vba 宏,以便在显示用户表单的模板中使用,然后根据用户表单导入 fileA.docx、fileB.docx 或 fileC.docx 的内容。(之后我将使用书签来填写一些表单数据,我不知道这是否相关)。文件 A、B 和 C 将包含具有一些基本格式(例如列表)的文本,但没有什么特别之处。

The solutions I've seen online can copy the contents of file to a new file, but ideally I would like to import the entirety of one of those files into the new, currently unnamed file that I'm getting from the template. I think where I'm running into problems is with switching the selection to one of those files, and then back to the new unnamed document, though I could use a hand to make sure I'm copying correctly as well.

我在网上看到的解决方案可以将文件的内容复制到一个新文件,但理想情况下,我想将其中一个文件的全部导入到我从模板中获取的当前未命名的新文件中。我认为我遇到问题的地方是将选择切换到这些文件之一,然后返回到新的未命名文档,尽管我可以用手确保我也正确复制。



Update: I was making things too hard, though the answers here got me pointed in the right direction (thanks!). In the end I just did

更新:我让事情变得太难了,尽管这里的答案让我指出了正确的方向(谢谢!)。最后我只是做了

ThisDocument.Activate

Selection.InsertFile("fileA")

which gives me the raw dump of everything that I wanted.

这给了我想要的一切的原始转储。

回答by Alex D

Using commands such as these you can switch between which Document you're using and copy and paste elements:

使用诸如此类的命令,您可以在您使用的 Document 以及复制和粘贴元素之间切换:

ThisDocument.Activate 'Sets the main document active
Documents("Name.doc").Activate 'Activates another document

You can insert, copy and paste things in and out of documents using copy commands.

您可以使用复制命令在文档中插入、复制和粘贴内容。

ThisDocument.Range.InsertAfter("String") 'Insert text

Selection.WholeStory 'Select whole document
Selection.Expand wdParagraph 'Expands your selection to current paragraph
Selection.Copy 'Copy your selection
Documents("name.doc").Activate 'Activate the other document
Selection.EndKey wdStory 'Move to end of document
Selection.PasteAndFormat wdPasteDefault 'Pastes in the content

You can then go and format such, or copy and paste them with original formatting from before.

然后,您可以对其进行格式化,或者使用之前的原始格式复制并粘贴它们。

回答by Fr4nc01s

Here is a significant improvement (I think) you will want to incorporate because it:

这是您想要合并的重大改进(我认为),因为它:

  1. does not use the clipboard and thus does not make your macro vulnerable to the user changing the contents of the clipboard while your macro is running
  2. does not use a file and thus greatly improve the speed by eliminating I/O and eliminates the potential of having to deal with file system security/permissions, etc. Please do not use .InsertFile() if you are looping through documents you will slow yourself down. Use it once, at the end -only if you have to. The example below shows how to accomplish the same result without using .InsertFile()
  1. 不使用剪贴板,因此不会使您的宏容易受到用户在宏运行时更改剪贴板内容的影响
  2. 不使用文件,因此通过消除 I/O 极大地提高了速度,并消除了必须处理文件系统安全/权限等的可能性。请不要使用 .InsertFile() 如果您正在循环浏览文档,您会减慢速度自己倒。在最后使用它一次 - 仅在您必须时使用。下面的示例显示了如何在不使用 .InsertFile() 的情况下完成相同的结果

The idea is to transfer some portion of text found in 1 source document, to a destination document that is different than the source, and keep the source formatting.

这个想法是将在 1 个源文档中找到的部分文本传输到与源不同的目标文档,并保持源格式。

To accomplish the above (skipping the code to open documents):

要完成上述操作(跳过打开文档的代码):

For Each oTable In oDoc_Source  
'the above could have been anything that returns a Range object
'such as: ActiveDocument.Content.Find.Execute ....

'...
'logic here to identify the table, or text, you are looking for
'...

'I can't believe the MS Dev Center folks could only think
'of .InsertFile(), which is the last resort I would go for, 
'especially if your code runs on a web server [concurrent web requests]!

'SAFEST
'(no user interference on clipboard possible, no need to deal with file i/o and permissions)
'you need a reference to Document.Content, 
'as the act of obtaining a reference "un-collapses" the range, so the below 3 lines must be in that order.
Set oRange =  oDoc_DestinationDoc.Content
oRange.Collapse Direction:=wdCollapseEnd
oRange.FormattedText = oTable.Range

'BRUTE, AND PRONE TO RANDOM ERRORS AND HANGS DUE TO USER INTERFERENCE WITH CLIPBOARD 
'find a way to implement WIHTOUT using the CLIPBOARD altogether to copy the below range object
'it will be easier for PC users to use the clipboard while the macro runs
'and it will probably be safer for the output of this macro to remain uncorrupted

'oTable.Range.Copy
'Set oRange =  oDoc_DestinationDoc.Content
'oRange.Collapse Direction:=wdCollapseEnd
'oRange.Paste


'THE BELOW DOES NOT WORK
' '1) - cannot add a range from another document
' 'adds only text, not the formats and not the table layout
' oTable.Range.TextRetrievalMode.IncludeFieldCodes = True
' oTable.Range.TextRetrievalMode.IncludeHiddenText = True
'  oDoc_DestinationDoc.Content.InsertAfter oTable.Range
'
' '2) - cannot add a range from another document
'  oDoc_DestinationDoc.Content.Tables.Add oTable.Range, iRowMax, iColMax
' 
' '3) - only puts in plain text, and it replaces the range without the .Collapse call
'  oDoc_DestinationDoc.Content.Text = oTable.Range

回答by casgage

Record a macro...

录制宏...

  1. start in the source document
  2. press ctrl-a to select everything
  3. press ctrl-c to copy it to the clipboard
  4. switch to the target document
  5. press ctrl-v to paste into the document
  6. stop recording
  1. 从源文件开始
  2. 按 ctrl-a 选择所有内容
  3. 按 ctrl-c 将其复制到剪贴板
  4. 切换到目标文档
  5. 按 ctrl-v 粘贴到文档中
  6. 停止录音

or (assuming word 2007 or later)

或(假设 word 2007 或更高版本)

  1. start in the target document with the source document closed
  2. on the ribbon click insert > object > Text from file...
  3. navigate to the source document
  4. click the insert button
  5. stop recording
  1. 在源文档关闭的情况下从目标文档开始
  2. 在功能区上单击插入 > 对象 > 文件中的文本...
  3. 导航到源文档
  4. 单击插入按钮
  5. 停止录音

I prefer the second version so I should have put it first

我更喜欢第二个版本,所以我应该把它放在第一位

回答by András Kovács

I was doing the same thing, tried to select the other document, copy and paste. But it didn't worked (I received an error probably because some other application was using the clipboard, but I am not sure.). So I did a little search and found the perfect solution on Microsoft Dev Center.

我也在做同样的事情,试图选择另一个文档,复制和粘贴。但它没有用(我收到一个错误,可能是因为其他应用程序正在使用剪贴板,但我不确定。)。因此,我进行了一些搜索,并在 Microsoft Dev Center 上找到了完美的解决方案。

https://msdn.microsoft.com/en-us/vba/word-vba/articles/selection-insertfile-method-word

https://msdn.microsoft.com/en-us/vba/word-vba/articles/selection-insertfile-method-word

Selection.Collapse Direction:=wdCollapseEnd 
Selection.InsertFile FileName:="C:\TEST.DOC"

回答by wser

'set current doc name and path
    Dim docName As String: docName = ActiveDocument.name
    Dim filepath As String: filepath = ActiveDocument.Path
'create a new file
    Documents.Add
'get the path of a current file
    ChangeFileOpenDirectory filepath
'insert content of current file to newly created doc
    Selection.InsertFile _
        FileName:=docName, _
        Range:="", _
        ConfirmConversions:=False, _
        Link:=False, _
        Attachment:=False
'open prompt to save a new file
    With Dialogs(wdDialogFileSaveAs)
        .name = docName & "-copy"
        .Show
    End With