Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

ms-word

vba

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.

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.

like image 846
user3229306 Avatar asked Jan 23 '14 19:01

user3229306


2 Answers

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()

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.

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
like image 132
Fr4nc01s Avatar answered Nov 16 '22 04:11

Fr4nc01s


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

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.

like image 34
Alex D Avatar answered Nov 16 '22 02:11

Alex D