Finding multiple instances of multiple words in Word using VBA - excel

I am writing a VBA code to enter a user form and then transfer that data from the Excel sheet to an already existing Word document.
My Excel part is ok.
My document contains various words like Batch No, Manufacturing date, etc. each many times. I will have to find these words and insert Batch No and Manufacturing date from the user form every time they are found in the whole document.
Initially, I tried to find a single word in the whole document, but my sub routine can find only the first instance and is not finding similar words in rest of the document.
Please help
Sub Copy_data2()
Dim my_filename As Variant
Dim my_filenameword As Variant
Dim objselection As Object
'Word Variables
Dim mres As String
Dim oword As Object
Dim wdApp As Word.Application
Dim wdDoc As Word.Document
Dim bfound As Boolean
Dim rngDoc As Word.Range
Dim rngSearch As Word.Range
'Excel Variables
Dim wkbk As Workbook
Dim irow As Long
Dim txtSl As String
Dim txtBNo As String
Dim txtPr As String
Dim txtBS As String
Dim txtMfD As String
Dim txtExD As String
Dim workinglocation As String
Dim workingfilename As String
Dim workingdir As String
Dim ret As Boolean
Dim VbRes As String
Application.ScreenUpdating = False
Application.EnableEvents = False
Application.DisplayAlerts = False
'--------------------------------------------------------------------------------------------
'Excel extract values
'------------------------------------------------------------------------------------------
VbRes = MsgBox("Please select the Requisition sheet", vbOKOnly + vbInformation, "Select the requisition file")
my_filename = Application.GetOpenFilename(FileFilter:="Excel Files,*.xls*")
Set wkbk = Workbooks.Open(my_filename)
txtPr = FrmMaster.CmbProduct.Text
txtBNo = FrmMaster.txtBatchNo
txtBS = FrmMaster.txtBatchSize
txtMfD = FrmMaster.txtMfgDate
txtExD = FrmMaster.txtExpDate
wkbk.Sheets("Requisition").Range("C9") = txtBNo
wkbk.Sheets("Requisition").Range("G9") = txtBS
wkbk.Sheets("Requisition").Range("C10") = txtMfD
wkbk.Sheets("Requisition").Range("G10") = txtExD
irow = [Counta(Database!A:A)]
ThisWorkbook.Sheets("Database").Cells(irow, 1) = txtSl
Debug.Print txtSl
'-------------------------------------------------------------------------------------------------
'VB Word
'----------------------------------------------------------------------------------------------
mres = MsgBox("Select the Word BMR", vbOKOnly + vbInformation, "Select BMR")
my_filenameword = Application.GetOpenFilename(FileFilter:="Word Files,*.doc*")
Set wdApp = CreateObject("Word.Application")
wdApp.Visible = True
wdApp.Activate
Set wdDoc = wdApp.Documents.Open(my_filenameword)
wdDoc.Activate
With wdApp.Selection.Range.Find
.ClearFormatting
.Text = "BATCH SIZE"
bfound = .Execute(Forward:=True)
Do While bfound = True
'.Move Unit:=wdCharacter, Count:=4
.Text = "BATCH SIZE"
.Replacement.Text = "Size"
Loop
End With
my_filenameword.Close True
wkbk.Close True
Application.ScreenUpdating = True
Application.EnableEvents = True
Application.DisplayAlerts = True
End Sub

You really should spend a few moments studying Find/Replace in Word. Even the macro recorder there would give you most of the code you need. Try:
Set wdDoc = wdApp.Documents.Open(my_filenameword, , False, False, , , , , , , , False)
With wdDoc
With .Range.Find
.Forward = True
.Wrap = wdFindContinue
.Text = "BATCH SIZE"
.Replacement.Text = "Size"
.Execute Replace:=wdReplaceAll
End With
.Close True
End With
As you can see, no looping is required - just a proper application of Find/Replace.

Related

How to open a Word document with a path stored in variable?

I have a Word document with template contents where I will use VBA code to replace a textbox in the Word document with my user name to generate a pdf report for each user.
In my Excel VBA code, where I open the Word document, I need the path of the Word document.
If I hard code the Word document path, everything works.
When I store the path in a cell and assign it to a variable, it causes an error 13 type mismatch.
I declared the variable coverLocation as Variant.
I checked that the path is correct.
When I declare the variable as String it gives the error
"Object Required"
at Set coverLocation.
My simplified code to show the error.
Sub Test()
'Create and assign variables
Dim wb As Workbook
Dim ws1 As Worksheet
Dim saveLocation2 As String
Dim userName As Variant
Dim coverLocation As Variant
Set wb = ThisWorkbook
Set ws1 = wb.Worksheets("Sheet1")
Set userName = ws1.Range("B4")
Set coverLocation = ws1.Range("B2")
MsgBox coverLocation, vbOKOnly 'MsgBox showing correct path location
'Word variables
Dim wd As Word.Application
Dim doc As Word.Document
Set wd = New Word.Application
wd.Visible = True
saveLocation2 = wb.Path & Application.PathSeparator & userName & "cover.pdf"
'Word to PDF code
Set doc = wd.Documents.Open(coverLocation) ' "error 13 Type Mismatch" at this line
With doc.Shapes("Text Box Name").TextFrame.TextRange.Find
.Text = "<<name>>"
.Replacement.Text = userName
.Execute Replace:=wdReplaceAll
End With
doc.ExportAsFixedFormat OutputFileName:=saveLocation2, _
ExportFormat:=wdExportFormatPDF
Application.DisplayAlerts = False
doc.Close SaveChanges:=False
Application.DisplayAlerts = True
'Ending
wd.Quit
End Sub
I'm posting my comment as answer to make it more readable. The problem is, that in your code coverLocation is a Range object, not a string, and the same goes for userName.
The best way to fix this, is to replace this line:
Set coverLocation = ws1.Range("B2")`
with this:
coverLocation = ws1.Range("B2").Value
and additionally replace
Dim coverLocation As Variant
with
Dim coverLocation As String
Also, you should replace
Set userName = ws1.Range("B4")
with
userName = ws1.Range("B4").Value
In that case, replacing
Dim userName As Variant
with
Dim userName As String
is also advisable.
The final code could look like this:
Sub Test()
'Create and assign variables
Dim wb As Workbook
Dim ws1 As Worksheet
Dim saveLocation2 As String
Dim userName As String
Dim coverLocation As String
Set wb = ThisWorkbook
Set ws1 = wb.Worksheets("Sheet1")
userName = ws1.Range("B4").Value
coverLocation = ws1.Range("B2").Value
MsgBox coverLocation, vbOKOnly 'MsgBox showing correct path location
'Word variables
Dim wd As Word.Application
Dim doc As Word.Document
Set wd = New Word.Application
wd.Visible = True
saveLocation2 = wb.Path & Application.PathSeparator & userName & "cover.pdf"
'Word to PDF code
Set doc = wd.Documents.Open(coverLocation) ' "error 13 Type Mismatch" at this line
With doc.Shapes("Text Box Name").TextFrame.TextRange.Find
.Text = "<<name>>"
.Replacement.Text = userName
.Execute Replace:=wdReplaceAll
End With
doc.ExportAsFixedFormat OutputFileName:=saveLocation2, _
ExportFormat:=wdExportFormatPDF
Application.DisplayAlerts = False
doc.Close SaveChanges:=False
Application.DisplayAlerts = True
'Ending
wd.Quit
End Sub

Script to Copy all text from multiple Word Documents into seperate cells in a single Excel Document

I am trying to copy all the text, with formatting intact, from each of multiple Word Documents, and paste the text of each into a new cell in a single Excel Spreadsheet, placing the name of the Word Doc in an adjacent cell.
So the file name of "Document 1" goes in cell A1, and the entire contents of "Document 1" goes in cell A2.
We have several hundred Documents that need to be imported onto pages on our new corporate Intranet, and the migration tool provided only works off data in an Excel workbook.
I've checked out a number of threads, videos, and searches and tried to cobble together a couple of different attempts but neither is working. The first, if it did work, may not handle the File Name copy and it seems to run into issues with selecting the destination cell for the copy.
The second seems to be exactly what I want, but I can;t get the Paste into Excel bit working.
The first runs into an issue when it hits the "Range("LastRow").PasteSpecial xlPasteValues" line, saying the range is invalid (I have defined "LastRow" in the Excel Workbook but it doesn't help) :
Sub Copy_Data_From_Multiple_WordFiles()
Dim FolderName As String
Dim FileName As String
Dim NewWordFile As New Word.Application
Dim NewDoc As New Word.Document
Application.DisplayAlerts = False
'Application.ScreenUpdating = False
FolderName = "C:\Test\"
FileName = Dir(FolderName)
'Loop start
Do While FileName ⋖⋗ ""
Set NewDoc = NewWordFile.documents.Open(FolderName & FileName)
NewDoc.Range(0, NewDoc.Range.End).Copy
Range("LastRow").PasteSpecial xlPasteValues
NewDoc.Close SaveChanges:=wdDoNotSaveChanges
NewWordFile.Quit
FileName = Dir()
Loop
End Sub
NB: LastRow is defined in Excel Name Manager as:=OFFSET(CopyDataFromWord!$A$1,COUNTA(CopyDataFromWord!$A:$A),0,1,1)
I have tried a second set of code I got from a post on here, which should be closer to what I'm seeking, but again, won't quite get there. This one fails with a "Run-Time error '424': Object Required" at the line where it should paste into Excel. It doesn't seem to be recognising the Object "objDoc"?
Sub Excel_Word()
Dim WordApp As Object 'New Word.Application
Dim objDoc As Object ' New Word.Document
Dim Range As Object 'Word.Range
Dim WordDoc As String
Dim sPath As String
Dim i As Long
Set WordApp = CreateObject("Word.Application")
WordApp.Visible = True
sPath = "C:\Users\jdodd\Documents\Cleaned\"
WordDoc = Dir(sPath & "*.docx")
Do While WordDoc <> ""
Set objDoc = WordApp.Documents.Open(sPath & WordDoc)
objDoc.Range.Copy
i = i + 1
ImportPolicyfromWord.Cells(i, 1).Value = objDoc
ImportPolicyfromWord.Cells(i, 2).Value = objDoc.Range.PasteSpecial
WordDoc = Dir()
Loop
WordApp.Quit
'elimina variabili
'Set WordApp = Nothing
'Set objDoc = Nothing
End Sub
Appreciate any advice or help
Try:
Sub GetDocData()
'Note: this code requires a reference to the Word object model.
'See under the VBE's Tools|References.
Application.ScreenUpdating = False
Dim strFolder As String: strFolder = GetFolder: If strFolder = "" Then GoTo ErrExit
Dim wdApp As New Word.Application, wdDoc As Word.Document
Dim strFile As String, WkSht As Worksheet, r As Long
Set WkSht = ActiveSheet
'Disable any auto macros in the documents being processed
wdApp.WordBasic.DisableAutoMacros
'Disable any alerts in the documents being processed
wdApp.DisplayAlerts = wdAlertsNone
strFile = Dir(strFolder & "\*.doc", vbNormal)
While strFile <> ""
Set wdDoc = wdApp.Documents.Open(Filename:=strFolder & "\" & strFile, AddToRecentFiles:=False, Visible:=False)
With wdDoc
.ConvertNumbersToText (wdNumberAllNumbers)
With .Range.Find
.ClearFormatting
.Replacement.ClearFormatting
.Forward = True
.Wrap = wdFindContinue
.Format = False
.MatchWildcards = True
.Text = "[^12^13^l]{1,}"
.Replacement.Text = "¶"
.Execute Replace:=wdReplaceAll
.Text = "[^t]"
.Replacement.Text = " "
.Execute Replace:=wdReplaceAll
End With
r = WkSht.UsedRange.Cells.SpecialCells(xlCellTypeLastCell).Row
If r > 1 Then r = r + 2
WkSht.Range("A" & r).Value = .Name
.Range.Copy
r = r + 1
WkSht.Paste Destination:=WkSht.Range("A" & r)
.Close SaveChanges:=False
End With
strFile = Dir()
Wend
ErrExit:
wdApp.Quit
WkSht.UsedRange.Replace What:="¶", Replacement:=Chr(10), LookAt:=xlPart, SearchOrder:=xlByRows
Set wdDoc = Nothing: Set wdApp = Nothing: Set WkSht = Nothing
Application.ScreenUpdating = True
End Sub
Function GetFolder() As String
Dim oFolder As Object
GetFolder = ""
Set oFolder = CreateObject("Shell.Application").BrowseForFolder(0, "Choose a folder", 0)
If (Not oFolder Is Nothing) Then GetFolder = oFolder.Items.Item.Path
Set oFolder = Nothing
End Function
Simply select the folder to process. As coded, the macro places the document name above the contents, which are all pasted into one cell. If you want the document name on the same row, but beside the contents, change:
r = r + 1
WkSht.Paste Destination:=WkSht.Range("A" & r)
to:
WkSht.Paste Destination:=WkSht.Range("B" & r)

Finding rest of sentence after finding an specific word

I have created a code that searches different words in a column in a word document.
After finding the word, the code returns the value "yes" to the excel.
I want the code to extract the rest of the sentence after finding the word that I´m looking for.
The rest of the sentences are always something like:
Update system format.
Search for other inputs.
Havent found the sentence that it needs to do.
In conclusion, they are always a small sentence and a new paragraph after.
The code that I have developed is the following:
Sub findSubprocesos()
Dim wrdApp As New Word.Application
Dim wrdDoc As Word.Document
Set wrdApp = CreateObject("Word.Application")
Dim FindWord As String
Dim List As String
Dim Dict As Object
Dim NextFormula As Range
Dim RefElem As Range
Dim Key
Dim Wbk As Workbook: Set Wbk = ThisWorkbook
Set Dict = CreateObject("Scripting.Dictionary")
Set NextFormula = Worksheets("Datos2").Range("V2:V5")
With Dict
For Each RefElem In NextFormula
If Not .Exists(RefElem) And Not IsEmpty(RefElem) Then
Sheets("Datos2").Range("R3").Value = RefElem.Value
Debug.Print RefElem
FindSubs
On Error GoTo Skip
End If
Next RefElem
Skip:
End With
End Sub
Private Sub FindSubs()
Dim wrdApp As New Word.Application
Dim wrdDoc As Word.Document
Set wrdApp = CreateObject("Word.Application")
Dim FindWord As String
Dim List As String
Dim Dict As Object
Dim NextFormula As Range
Dim RefElem As Range
Dim Key
Dim Wbk As Workbook: Set Wbk = ThisWorkbook
Range("U3:U50").ClearContents
wrdApp.Visible = True
Set wrdDoc = wrdApp.Documents.Open("C:\Users\rriveragarrido\Desktop\Proyectos\Proyecto solaris (endesa) (PROPIO)\prueba macros\ZZZ\Narrativas antiguas\1059\1059_NAR_OTC.RC.03.01_CC.END.GEN_ENG_31.12.20.docx", OpenAndRepair:=True)
Dim cell As Range
Dim bIsEmpty As Boolean
bIsEmpty = False
For n = 3 To 20
For Each cell In Worksheets("Datos").Range("S" & n)
If IsEmpty(cell) = False Then
FindWord = Wbk.Sheets("Datos2").Range("S" & n).Value 'Modify as necessary.
wrdApp.Selection.WholeStory
wrdApp.Selection.FIND.ClearFormatting
With wrdApp.Selection.FIND
.ClearFormatting
.Text = FindWord
.Forward = True
.Wrap = wdFindContinue
.Format = False
.MatchCase = False
.MatchWholeWord = True
.MatchWildcards = False
.MatchSoundsLike = False
.MatchAllWordForms = False
If .Execute Then
Sheets("Datos2").Range("U" & n).Value = "Yes"
Else
'Sheets("Datos2").Range("T" & n).Value = "No"
wrdApp.Quit SaveChanges:=0
Sheets("Datos2").Range("U3:U50").Copy Sheets("Subprocesos").Range("A3:A50").End(xlToRight).Offset(0, 1)
GoTo Skip2
End If
End With
End If
Next cell
Next
Skip2:
End Sub
This is the part were I need to extract the rest of the sentence:
If .Execute Then
Sheets("Datos2").Range("U" & n).Value = "Yes"
Else
'Sheets("Datos2").Range("T" & n).Value = "No"
wrdApp.Quit SaveChanges:=0
Sheets("Datos2").Range("U3:U50").Copy Sheets("Subprocesos").Range("A3:A50").End(xlToRight).Offset(0, 1)
Currently is only writing "yes" when the sentence is found and pasting the information in a column and going to the next word if it is not found.
What you want to do is possible by using the Sentences collection of the document. Hopefully you can adapt the sample code below to your needs:
Option Explicit
Sub test()
Dim foundSentences As Collection
Set foundSentences = FindTheSentencesContaining(ThisWord:="access", _
FromThisDoc:="C:\Temp\test.docx")
If foundSentences Is Nothing Then
Debug.Print "The word doc was not found!"
Else
Debug.Print "found " & foundSentences.Count & " sentences"
Dim sentence As Variant
For Each sentence In foundSentences
Debug.Print sentence
Next sentence
End If
End Sub
Function FindTheSentencesContaining(ByVal ThisWord As String, _
ByVal FromThisDoc As String) As Collection
Dim wordWasRunning As Boolean
wordWasRunning = IsMSWordRunning
Dim wordApp As Word.Application
Set wordApp = AttachToMSWordApplication
On Error Resume Next
Dim wordDoc As Word.Document
Set wordDoc = wordApp.Documents.Open(Filename:=FromThisDoc, ReadOnly:=True)
On Error GoTo 0
If wordDoc Is Nothing Then Exit Function
Dim allSentences As Collection
Set allSentences = New Collection
Dim sentence As Variant
For Each sentence In wordDoc.Sentences
sentence.Select
With wordApp.Selection
.Find.Text = ThisWord
.Find.Forward = True
.Find.Wrap = wdFindStop
.Find.MatchCase = False
If .Find.Execute Then
'--- extend the selection to include the whole sentence
.Expand Unit:=wdSentence
allSentences.Add wordApp.Selection.Text
'--- move the cursor to the end of the sentence to continue looking
.Collapse Direction:=wdCollapseEnd
.MoveEnd Unit:=wdSentence
Else
'--- didn't find it, move to the next sentence
End If
End With
Next sentence
wordDoc.Close SaveChanges:=False
If Not wordWasRunning Then
wordApp.Quit
End If
Set FindTheSentencesContaining = allSentences
End Function
In a separate module, I have the following code (pulled from my library of code to reuse):
Option Explicit
Public Function IsMSWordRunning() As Boolean
'--- quick check to see if an instance of MS Word is running
Dim msApp As Object
On Error Resume Next
Set msApp = GetObject(, "Word.Application")
If Err > 0 Then
'--- not running
IsMSWordRunning = False
Else
'--- running
IsMSWordRunning = True
End If
End Function
Public Function AttachToMSWordApplication() As Word.Application
'--- finds an existing and running instance of MS Word, or starts
' the application if one is not already running
Dim msApp As Word.Application
On Error Resume Next
Set msApp = GetObject(, "Word.Application")
If Err > 0 Then
'--- we have to start one
' an exception will be raised if the application is not installed
Set msApp = CreateObject("Word.Application")
End If
Set AttachToMSWordApplication = msApp
End Function
A simple demo outputting the content to a message box, for all found instances:
Sub Demo()
With ActiveDocument.Range
With .Find
.ClearFormatting
.Replacement.ClearFormatting
.Text = InputBox("What is the Text to Find")
.Replacement.Text = ""
.Forward = True
.Wrap = wdFindStop
.Format = False
.MatchCase = False
.MatchWholeWord = False
.MatchWildcards = False
.MatchSoundsLike = False
.MatchAllWordForms = False
End With
Do While .Find.Execute
With .Duplicate
.End = .Sentences.First.End
MsgBox .Text
End With
.Collapse wdCollapseEnd
Loop
End With
End Sub
Do be aware, though, that VBA has no idea what a grammatical sentence is. For example, consider the following:
Mr. Smith spent $1,234.56 at Dr. John's Grocery Store, to buy:
10.25kg of potatoes; 10kg of avocados; and 15.1kg of Mrs. Green's Mt. Pleasant macadamia nuts.
For you and me, that would count as one sentence; for VBA it counts as 5 sentences.

Trying to insert a table from Excel into Word but getting the error "file is locked for editing.." by myself?

I'm trying to create a code that reads a dynamic Excel table into an existing Word document and changes some variables in the document (for example %Username%)
The code below gives me an "Locked for editing" error by myself, but that isn't the case.
Can someone see what I have to change in the code?
The code is:
Sub Export_Table_Word()
'Word objects.
Dim wdApp As Word.Application
Dim wdDoc As Word.Document
Dim wdbmRange As Word.Range
'Excel objects.
Dim wbBook As Workbook
Dim wsSheet As Worksheet
Dim rnReport As Range
'Path of Word Template
Dim stPathTemplate As String
Dim stPathSave As String
'Dynamic Replace variables
Dim UserName As String
Dim StrFind
Dim StrRepl As String
'Loop variable
Dim i As Long
Dim msWord As Object
Set msWord = CreateObject("Word.Application")
'Define replacement variables
UserName = Application.UserName
sFirst = Split(UserName, " ")(0) 'Firstname 'sFirst = Split(UserName, ",")(1) 'Firstname
sLast = Split(UserName, " ")(1) 'Lastname
sUserName = Left(sFirst, 1) & sLast 'First letter of firstname and lastname
sFullName = sFirst & " " & sLast 'Full name
StrFind = "%User_Name%,%Full_name%, %Date%" 'Strings to be replaced in the word document
StrRepl = sUserName & "*" & sFullName & "*" & " " & Date 'Replaced by
'Initialize Path word template
stPathTemplate = "C:\Users\xxx\Desktop\VBA_TEST\VBA_Automation.docx"
stPathSave = "C:\Users\xxx\Desktop\VBA_TEST\Finished.docx"
'Initialize the Excel objects.
Set wbBook = ThisWorkbook
Set wsSheet = wbBook.Worksheets(1)
Set rnReport = wsSheet.Range("D2:D7")
'Initialize the Word objets.
Set wdApp = New Word.Application
Set wdDoc = wdApp.Documents.Open(stPathTemplate)
Set wdbmRange = wdDoc.Bookmarks("Report").Range
'If the macro has been run before, clean up any artifacts before trying to paste the table in again.
On Error Resume Next
With wdDoc.InlineShapes(1)
.Select
.Delete
End With
On Error GoTo 0
'Turn off screen updating.
Application.ScreenUpdating = True
With wdDoc
.Visible = True
.Documents.Open (stPathTemplate)
.Activate
With .ActiveDocument.Content.Find
.ClearFormatting
.Replacement.ClearFormatting
For i = 0 To UBound(Split(StrFind, ",")) 'Loop to replace all the defined dynamic strings
.Text = Split(StrFind, ",")(i)
.Replacement.Text = Split(StrRepl, "*")(i)
.Execute Replace:=wdReplaceAll
Next i
.Forward = True
.Wrap = 1 'FindContinue
.Format = False
.MatchCase = False
.MatchWholeWord = False
.MatchWildcards = False
.MatchSoundsLike = False
.MatchAllWordForms = False
.Execute Replace:=2 'wdReplaceAll (WdReplace Enumeration)
End With
End With
'Copy the report to the clipboard.
rnReport.Copy
'Select the range defined by the "Report" bookmark and paste in the report from clipboard.
With wdbmRange
.Select
.Paste
End With
'Save and close the Word doc.
With wdDoc
'.Save
.SaveAs2 Filename:=stPathSave, _
FileFormat:=wdFormatXMLDocument, AddToRecentFiles:=False
.Close
End With
'Quit Word.
wdApp.Quit
'Null out your variables.
Set wdbmRange = Nothing
Set wdDoc = Nothing
Set wdApp = Nothing
'Clear out the clipboard, and turn screen updating back on.
With Application
.CutCopyMode = False
.ScreenUpdating = True
End With
MsgBox ("Done")
End Sub

Copy formatted text from excel to word

I have an excel sheet with two columns of strings. I track the changes of these two columns using ms-word and copy the result back to a third column. Then I copy the third column to a new word document.
The formating in Excel in Cell C3 is what I would like to transfer to word.
This is what I get at the moment. Notice the complete strike-through.
Why does it work twice but not in the third case?
I guess the root of the problem is that I remove the CR/Linefeed in the word to excel step and destroy the boundary of the strike-through-format. My goal is to get each string in one word-paragraph. If I don't remove the CR/Linefeed i get four paragraphs.
Background: In the final application the strings are going to be paragraphs of text.
Sourcecode of the excel-vba-macro (Excel 2010):
Technical remark: You may need to activate the ms-word-objects in excel-vba. (Microsoft Word 14.0 Object Library )
The macro assumes, that there a strings in the Range(A1:B3):
for example
a string a string, too
a string a new string
a string there is no try
The results will be put in the Range(C1:C3).
Option Explicit
Dim numberOfBlocks As Long
Sub main()
Dim i As Long
Dim tSht As Worksheet
Dim wordapp As Word.Application
Dim wdoc As Word.Document
Set tSht = ThisWorkbook.ActiveSheet
numberOfBlocks = 3
Application.ScreenUpdating = False
Set wordapp = CreateObject("Word.Application")
For i = 1 To numberOfBlocks
Call trackChanges(i, wordapp, tSht)
Next i
Set wdoc = wordapp.Documents.Add
Call copyChanges(tSht, wdoc)
End Sub
Sub trackChanges(i As Long, wordapp As Word.Application, tSht As Worksheet)
Dim diffDoc As Word.Document
Dim textString() As Variant
Dim j As Long
ReDim doc(2)
ReDim textString(2)
Set textString(1) = tSht.Range("A" & i)
Set textString(2) = tSht.Range("B" & i)
For j = 1 To 2
With wordapp
Set doc(j) = .Documents.Add
textString(j).Copy
doc(j).Paragraphs(1).Range.PasteSpecial
End With
Next j
wordapp.CompareDocuments OriginalDocument:=doc(1), RevisedDocument:=doc(2), _
Destination:=wdCompareDestinationNew, Granularity:=wdGranularityCharLevel
For j = 1 To 2
doc(j).Close SaveChanges:=False
Next j
Set diffDoc = wordapp.ActiveDocument
wordapp.Visible = True
'if the answer has two paragraphs, get both in one paragraph
With diffDoc.Content.Find
.Forward = True
.Wrap = wdFindStop
.Format = False
.MatchAllWordForms = False
.MatchSoundsLike = False
.MatchWildcards = True
.Text = vbCrLf
.Replacement.Text = " "
.Execute Replace:=wdReplaceAll
End With
diffDoc.Range.Copy
tSht.Range("C" & i).Select
tSht.PasteSpecial Format:="HTML"
With tSht.Range("C" & i)
.WrapText = True
.Font.Name = textString(2).Font.Name
.Font.Bold = textString(2).Font.Bold
.Font.Size = textString(2).Font.Size
.Rows.AutoFit
.Interior.Color = textString(2).Interior.Color
End With
diffDoc.Close SaveChanges:=False
Application.CutCopyMode = False
Set diffDoc = Nothing
End Sub
Sub copyChanges(tSht As Worksheet, wdoc As Word.Document)
tSht.Range("C1:C" & numberOfBlocks).Copy
wdoc.Range(wdoc.Range.End - 1, wdoc.Range.End).PasteSpecial Placement:=wdInLine, DataType:=wdPasteHTML
wdoc.Tables(1).ConvertToText Separator:=wdSeparateByParagraphs
End Sub

Resources