【问题标题】:Using vba to copy the contents of a word document into another word document使用vba将一个word文档的内容复制到另一个word文档中
【发布时间】:2019-07-09 20:51:56
【问题描述】:

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

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


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

ThisDocument.Activate

Selection.InsertFile("fileA")

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

【问题讨论】:

    标签: vba ms-word


    【解决方案1】:

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

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

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

    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
    

    然后你可以去格式化,或者用之前的原始格式复制和粘贴它们。

    【讨论】:

      【解决方案2】:

      这是一个重大改进(我认为)你会想要合并,因为它:

      1. 不使用剪贴板,因此不会使您的宏容易受到用户在宏运行时更改剪贴板内容的影响
      2. 不使用文件,因此通过消除 I/O 大大提高了速度,并消除了必须处理文件系统安全/权限等的可能性。如果您正在循环文件,请不要使用 .InsertFile()你会让自己慢下来。使用一次,最后 - 仅在必要时使用。下面的示例展示了如何在不使用 .InsertFile() 的情况下完成相同的结果

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

      完成上述(跳过代码打开文档):

      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
      

      【讨论】:

      • 感谢指向FormattedText 属性的指针! (in a Selection, in a Range)
      • 不确定这是否是一个问题,但不需要选择。只需使用 2 个范围对象及其 .FormattedText 属性就足够了。用户的选择不会被不必要地改变。如果我可以补充一下,下面来自 Andras Kovacs 的帖子正在传播关于我应该如何使用 .InsertFile() 函数的误导性信息。请完整阅读我的帖子,了解为什么要尽量减少对该功能的使用。
      【解决方案3】:

      录制宏...

      1. 从源文档开始
      2. 按 ctrl-a 选择所有内容
      3. 按 ctrl-c 将其复制到剪贴板
      4. 切换到目标文档
      5. 按 ctrl-v 粘贴到文档中
      6. 停止录制

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

      1. 从目标文档开始,关闭源文档
      2. 在功能区上单击插入 > 对象 > 文件中的文本...
      3. 导航到源文档
      4. 点击插入按钮
      5. 停止录制

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

      【讨论】:

      • 这可以集成到我的用户表单的 vba 脚本中吗?关键是我需要根据用户输入选择要转储到当前文档中的文件。我想避免复制用户表单代码以将字段填充到每个 fileA、fileB 等中。
      • 是的。您记录为宏的任何内容都以 VBA 结尾,因此可以粘贴到您的逻辑中并修改为使用变量 i8 而不是硬连线名称。在 VBA IDE 中打开 Normal > Modules > NewMacros,你会看到它。如果您在开始录制宏时命名宏,会有所帮助。
      【解决方案4】:

      我也在做同样的事情,试图选择另一个文档,复制和粘贴。但它没有用(我收到一个错误可能是因为其他一些应用程序正在使用剪贴板,但我不确定。)。所以我做了一点搜索,在微软开发中心找到了完美的解决方案。

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

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

      【讨论】:

        【解决方案5】:
        '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
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2020-03-20
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-01-06
          相关资源
          最近更新 更多