Find And Replace Text, retain Formatting - excel

I have an excel file that I need to do a find and replace and the cells have formatting already. I need to retain the formatting. When I do an ordinary find and replace in excel, this removes the formatting. I need help to retain the formatting. I searched online and found the below link but this code is not working for me.
When I try the below code, this line is red in the code.
Call CharactersReplace(xRg, "<span style="background-color: #ffff00;">KK</span>", "<span style="background-color: #ffff00;">Kutools</span>", True)
I need help to correct this code and get this to work. Or if there is an easier way to do this, please let me know.
https://www.extendoffice.com/documents/excel/3760-excel-find-and-replace-preserve-formatting.html
Sub CharactersReplace(Rng As Range, FindText As String, ReplaceText As String, Optional MatchCase As Boolean = False)
'UpdatebyExtendoffice20160711
Dim I As Long
Dim xLenFind As Long
Dim xLenRep As Long
Dim K As Long
Dim xValue As String
Dim M As Long
Dim xCell As Range
xLenFind = Len(FindText)
xLenRep = Len(ReplaceText)
If Not MatchCase Then M = 1
For Each xCell In Rng
If VarType(xCell) = vbString Then
xValue = xCell.Value
K = 0
For I = 1 To Len(xValue)
If StrComp(Mid$(xValue, I, xLenFind), FindText, M) = 0 Then
xCell.Characters(I + K, xLenFind).Insert ReplaceText
K = K + xLenRep - xLenFind
End If
Next
End If
Next
End Sub
Sub Test_CharactersReplace()
Dim xRg As Range
Dim xTxt As String
Dim xCell As Range
On Error Resume Next
If ActiveWindow.RangeSelection.Count > 1 Then
xTxt = ActiveWindow.RangeSelection.AddressLocal
Else
xTxt = ActiveSheet.UsedRange.AddressLocal
End If
Set xRg = Application.InputBox("Select a range:", "Kutools for Excel", xTxt, , , , , 8)
If xRg Is Nothing Then Exit Sub
Call CharactersReplace(xRg, "<span style="background-color: #ffff00;">KK</span>", "<span style="background-color: #ffff00;">Kutools</span>", True)
End Sub

I appreciate what I learned from the comment by #Marc but after trying to edit the xml, I found it was just too complicated. Any little mistake I made rendered the xml file unopenable by Excel.
So my solution was to copy the sheet into Word (it comes in as a Word table), using Word's Advanced Find and Replace features, and then pasting the table back into the Excel sheet. It worked for me.
Because I had lot of sheets I wanted to do this with, I made this VBA routine. After copying my data (in the first 2 columns) into Word, it removes all superscripted characters, plus does some formatting I needed. Not pretty but it worked to do 72 sheets for me, saving a lot of tedious work.
Sub ExcelSheetsEditedViaWord()
' note: must add a reference to the Word-library (Microsoft Word 16.0 Object Lilbrary)
Dim wrdApp As Word.Application
Dim wrdDoc As Word.Document
Dim s As String, i As Integer, sh As Worksheet, r As Range
Application.DisplayStatusBar = True
Application.StatusBar = "Opening Word ..."
Set wrdApp = CreateObject("Word.Application")
wrdApp.Visible = True
Set wrdDoc = wrdApp.Documents.Add
With ActiveDocument.PageSetup
.PageWidth = InchesToPoints(11)
.PageHeight = InchesToPoints(22)
End With
wrdApp.ActiveWindow.ActivePane.View.Zoom.Percentage = 40
i = 0
For Each sh In ThisWorkbook.Worksheets
Set r = sh.Range("A1:B1")
Set r = sh.Range(r, r.End(xlDown))
r.Copy
'wait to avoid error that sometimes stops code.
Application.Wait (Now + TimeValue("0:00:01"))
wrdDoc.Range.PasteExcelTable False, False, False
sh.Activate
sh.Range("A1").Select
With wrdApp.Selection
.Find.ClearFormatting
With .Find.Font
.Superscript = True
.Subscript = False
End With
.Find.Replacement.ClearFormatting
With .Find
.Text = ""
.Replacement.Text = ""
.Forward = True
.Wrap = wdFindContinue
End With
.Find.Execute Replace:=wdReplaceAll
.WholeStory
.Cut
'wait some second to try to avoid error that stops code. However,
'even when code stops, hitting debug allows it to continue
Application.Wait (Now + TimeValue("0:00:06"))
sh.Paste
With sh.Columns("A:B")
.VerticalAlignment = xlTop
.WrapText = True
.Font.Name = "Times New Roman"
.Font.Size = 16
End With
i = i + 1
End With
Application.StatusBar = i & " sheets done"
Next sh
wrdApp.Quit False ' close the Word application
Set wrdDoc = Nothing
Set wrdApp = Nothing
MsgBox i & " sheets of the workbook processed"
End Sub
I have some Application.Wait() statements where the code would fail occasionally -- something I've seen a lot with code that copy/pastes between Excel and Word. But when it fails, clicking debug and continuing works every time. As I said, not pretty but gets the job done.

Related

Delete paragraph in Microsoft Word if Excel cell is a specified value

This is my first post here and I'm very, very new to vba.
I have an Excel worksheet that I am using to assist in drafting several Word documents. I would like to program a command in Excel that if a specific cell has a specific value, it will delete a particular paragraph in a Word document. Specifically, I want to do something like the following:
if activesheet.range("I99")="1" then
'code to delete specific paragraph in Word document
elseif activesheet.range("I99")="2" then
'code to delete different paragraph in Word document
elseif activesheet.range("I99")="3" then
'code to delete different paragraph in Word document
end if
The following generic code (which I found on this site) in Word does what I want it to do in Word, but I can't get it to work in Excel:
Sub SomeSub()
Dim StartWord As String, EndWord As String
Dim Find1stRange As Range, FindEndRange As Range
Dim DelRange As Range, DelStartRange As Range, DelEndRange As Range
Application.ScreenUpdating = False
Application.DisplayAlerts = False
'Setting up the Ranges
Set Find1stRange = ActiveDocument.Range
Set FindEndRange = ActiveDocument.Range
Set DelRange = ActiveDocument.Range
'Set your Start and End Find words here to cleanup the script
StartWord = "From: Research.TA#traditionanalytics.com|Tradition Analytics Commentary| | |"
EndWord = "This message has been scanned for malware by Websense. www.websense.com"
'Starting the Find First Word
With Find1stRange.Find
.Text = StartWord
.Replacement.Text = ""
.Forward = True
.Wrap = wdFindAsk
.Format = False
.MatchCase = False
.MatchWholeWord = False
.MatchWildcards = False
.MatchSoundsLike = False
.MatchAllWordForms = False
'Execute the Find
Do While .Execute
'If Found then do extra script
If .Found = True Then
'Setting the Found range to the DelStartRange
Set DelStartRange = Find1stRange
'Having these Selections during testing is benificial to test your script
DelStartRange.Select
'Setting the FindEndRange up for the remainder of the document form the end of the StartWord
FindEndRange.Start = DelStartRange.End
FindEndRange.End = ActiveDocument.Content.End
'Having these Selections during testing is benificial to test your script
FindEndRange.Select
'Setting the Find to look for the End Word
With FindEndRange.Find
.Text = EndWord
.Execute
'If Found then do extra script
If .Found = True Then
'Setting the Found range to the DelEndRange
Set DelEndRange = FindEndRange
'Having these Selections during testing is benificial to test your script
DelEndRange.Select
End If
End With
'Selecting the delete range
DelRange.Start = DelStartRange.Start
DelRange.End = DelEndRange.End
'Having these Selections during testing is benificial to test your script
DelRange.Select
'Remove comment to actually delete
DelRange.Delete
End If 'Ending the If Find1stRange .Found = True
Loop 'Ending the Do While .Execute Loop
End With 'Ending the Find1stRange.Find With Statement
End Sub
I want to do it this way so that I can edit my Word document without having to edit the vba code. Any help would be greatly appreciated!
Mark
Set a reference to Word (early binding) (check this article)
Read the code's comments and adjust it to fit your needs
' Set a reference to Word Library
Public Sub DeleteInWord()
' Set reference to worksheet
Dim sourceSheet As Worksheet
Set sourceSheet = ThisWorkbook.Worksheets("MySheetName")
' Define word document path
Dim wordDocPath As String
wordDocPath = "C:\Temp"
' Define word document name (include extension)
Dim wordDocName As String
wordDocName = "test.docx"
' Define start word to find in word document
Dim startWord As String
' Define end word to find in word document
Dim endWord As String
' Select the case when value in range I99 is X
Select Case sourceSheet.Range("I99").Value
Case 1
'code to delete specific paragraph in Word document
startWord = "StartWordValue1"
endWord = "EndWordValue1"
Case 2
'code to delete different paragraph in Word document
startWord = "StartWordValue2"
endWord = "EndWordValue2"
Case 3
'code to delete different paragraph in Word document
startWord = "StartWordValue3"
endWord = "EndWordValue3"
End Select
' Call delete paragraph procedure
delParagrInWordByStartEndWord wordDocPath, wordDocName, startWord, endWord
End Sub
Private Sub delParagrInWordByStartEndWord(ByVal wordDocPath As String, ByVal wordDocName As String, ByVal startWord As String, ByVal endWord As String)
' Turn off stuff
Application.ScreenUpdating = False
Application.DisplayAlerts = False
' Set a reference to word
Dim wordApp As Word.Application
Set wordApp = createWordObject(True)
' Fix document path if missing last \
If Right(wordDocPath, 1) <> "\" Then wordDocPath = wordDocPath & "\"
' Build document full path
Dim wordDocFullPath As String
wordDocFullPath = wordDocPath & wordDocName
' Open word document
Dim wordDoc As Word.Document
If Not wordFileIsOpen(wordDocFullPath) Then
Set wordDoc = wordApp.Documents.Open(wordDocFullPath)
Else
Set wordDoc = wordApp.Documents(wordDocName)
End If
'Setting up the Ranges
Dim find1stRange As Word.Range
Set find1stRange = wordDoc.Range
Dim findEndRange As Word.Range
Set findEndRange = wordDoc.Range
Dim delRange As Word.Range
Set delRange = wordDoc.Range
'Starting the Find First Word
With find1stRange.find
.Text = startWord
.Replacement.Text = ""
.Forward = True
.Wrap = wdFindAsk
.Format = False
.MatchCase = False
.MatchWholeWord = False
.MatchWildcards = False
.MatchSoundsLike = False
.MatchAllWordForms = False
'Execute the Find
Do While .Execute
'If Found then do extra script
If .Found = True Then
'Setting the Found range to the DelStartRange
Dim delStartRange As Word.Range
Set delStartRange = find1stRange
'Having these Selections during testing is benificial to test your script
delStartRange.Select
'Setting the FindEndRange up for the remainder of the document form the end of the StartWord
findEndRange.Start = delStartRange.End
findEndRange.End = wordDoc.Content.End
'Having these Selections during testing is benificial to test your script
findEndRange.Select
'Setting the Find to look for the End Word
With findEndRange.find
.Text = endWord
.Execute
'If Found then do extra script
If .Found = True Then
'Setting the Found range to the DelEndRange
Dim delEndRange As Word.Range
Set delEndRange = findEndRange
'Having these Selections during testing is benificial to test your script
delEndRange.Select
End If
End With
'Selecting the delete range
delRange.Start = delStartRange.Start
delRange.End = delEndRange.End
'Having these Selections during testing is benificial to test your script
delRange.Select
'Remove comment to actually delete
delRange.Delete
End If 'Ending the If Find1stRange .Found = True
Loop 'Ending the Do While .Execute Loop
End With 'Ending the Find1stRange.Find With Statement
End Sub
' Credits: https://stackoverflow.com/a/47162311/1521579
Private Function createWordObject(Optional bVisible As Boolean = True) As Object
Dim tempWordObject As Object
On Error Resume Next
Set tempWordObject = GetObject(, "Word.Application")
If Err.Number <> 0 Then
Err.Clear
On Error GoTo CleanFail
Set tempWordObject = CreateObject("Word.Application")
End If
tempWordObject.Visible = bVisible
Set createWordObject = tempWordObject
On Error GoTo 0
Exit Function
CleanFail:
Select Case Err.Number
Case Else
MsgBox "Error " & Err.Number & vbCr & _
" (" & Err.Description & ") in procedure CreateWord."
Err.Clear
End Select
End Function
' Credits: https://stackoverflow.com/a/54040283/1521579
Private Function wordFileIsOpen(wordDocFullPath As String) As Boolean
Dim ff As Long
On Error Resume Next
ff = FreeFile()
Open wordDocFullPath For Input Lock Read As #ff
Close ff
wordFileIsOpen = (Err.Number <> 0)
On Error GoTo 0
End Function

VBA Word Expand Range with one line

First of all this is the first time I am creating a macro using VBA code. With some bits and pieces i found on the internet I tried to create the following. I am not a developer at all, I just have some basic knowledge from school. So my apologies if this is poor coding.
I am creating a macro in word which highlights text from a paragraph heading until the next heading with the same style. This is done based on a list of headings I import from Excel. You can find the code I have created below. The result with few input is perfect, so that's a good thing! The execution is very slow though (3 to 4h), which is probably related to the many selects I use. (I read only this is very often the cause of slow macros)
I tried to expand my Range with one line at the time using " Range.Expand Unit:=wdLine " but it's giving me errors every time. Therefore I use the moveDown selection method now which is doing the trick. Does anyone know a way I could use ranges here to speed up the process?
Many thanks in advance.
Sub Highlight_WordN()
Dim par As Paragraph
Dim par2 As Paragraph
Dim doc As Document
Dim oRng As Range
Dim Sty As Style
Dim intCurrentLine As Integer
Dim strFindArray() As String
Dim strIn As String
Dim strWorkBookName As String
Dim strNumberCells As String
Dim MessageFound As String
Dim MessageNotFound As String
Dim Flag As Boolean
Dim IsHeading As Boolean
Dim IsNothing As Boolean
'*****Set parameters for performance*****
Word.Application.ScreenUpdating = False
Word.Application.Options.CheckGrammarAsYouType = False
Word.Application.Options.CheckGrammarWithSpelling = False
Word.Application.Options.CheckSpellingAsYouType = False
Word.Application.Options.AnimateScreenMovements = False
Word.Application.Options.BackgroundSave = False
Word.Application.Options.CheckHangulEndings = False
Word.Application.Options.DisableFeaturesbyDefault = True
'*****Load data from excel*****
'List of headers to delete
Dim xlApp As Object
Dim xlBook As Object
strWorkBookName = "C:\Users\driesenn\OneDrive\OMAR\UPDATE\ToDelete.xlsx"
On Error Resume Next
Set xlApp = GetObject(, "Excel.Application")
If Err Then
Set xlApp = CreateObject("Excel.Application")
End If
On Error GoTo 0
Set xlBook = xlApp.Workbooks.Open(FileName:=strWorkBookName)
xlApp.Visible = False
ArrayLen = 0
ArrayLen = xlApp.ActiveSheet.Range("B1")
strNumberCells = "A1:A" & ArrayLen
strArray = xlApp.Transpose(xlApp.ActiveSheet.Range(strNumberCells))
ArrayLen = 0
ArrayLen = UBound(strArray) - LBound(strArray) + 1
Set xlBook = Nothing
xlApp.Quit
Set xlApp = Nothing
'*****Start evaluation process for headers*****
ArrayLen = UBound(strArray) - LBound(strArray) + 1
'Loop over all headers in the array
For i = 1 To ArrayLen
strFind = strArray(i)
'Evaluate every paragraph heading
For Each par In ActiveDocument.Paragraphs
If par.Style Like "Heading*" Then
Set Sty = par.Style
'Search for the header number in the heading
If InStr(par.Range.Text, strFind) = 1 Then
Set oRng = par.Range
oRng.Select
intCurrentLine = oRng.Information(wdFirstCharacterLineNumber)
Set oRng = Selection.Next(Unit:=wdLine, Count:=1)
'If the next line is not a header --> go on
IsHeading = False
If oRng.Style Like "Heading*" Then
IsHeading = True
End If
'Keep looping until the next heading of this type is found
Do While oRng.Style > Sty Or IsHeading = False
Selection.MoveDown Unit:=wdLine, Count:=1, Extend:=wdExtend
Set oRng = Selection.Next(Unit:=wdLine, Count:=1)
If oRng Is Nothing Then
Exit Do
End If
'If the next line is not a header --> go on
IsHeading = False
If oRng.Style Like "Heading*" Then
IsHeading = True
End If
Loop
Selection.Start = par.Range.Start
'If we are not at the end of the document selection ends with last line of current range.
If oRng Is Nothing Then
Else
Selection.End = oRng.Start
End If
'Set highlight
Selection.Range.HighlightColorIndex = wdYellow
End If
End If
Next
Next
End Sub
Firstly, it will assist you to become familiar with using help. Place your cursor in the keyword that you need help with and press F1. Had you done so for the Expand method you would have landed here. You will find the valid parameters for Unit are listed.
Secondly, paragraph styles are applied to paragraphs not lines. So you need to check the style of each paragraph and expand the range by one paragraph at a time. This will enable you to avoid selecting anything.
The following code shows a much easier way of highlighting the ranges associated with different heading levels, using Word's built-in '\HeadingLevel' bookmark:
Sub Demo()
Dim h As Long, c As Long, Rng As Range
For h = 1 To 9
With ActiveDocument.Range
With .Find
.ClearFormatting
.Replacement.ClearFormatting
.Text = ""
.Style = "Heading " & h
.Replacement.Text = ""
.Format = True
.Forward = True
.Execute
End With
Do While .Find.Found
Set Rng = .Paragraphs(1).Range
Set Rng = Rng.GoTo(What:=wdGoToBookmark, Name:="\HeadingLevel")
Select Case h
Case 1 To 4: c = h + 1
Case 5: c = h + 2
Case 6 To 8: c = h + 4
Case 9: c = h + 5
Case Else: c = 0
End Select
Rng.HighlightColorIndex = c
.Collapse wdCollapseEnd
If .Information(wdWithInTable) = True Then
If .End = .Cells(1).Range.End - 1 Then
.End = .Cells(1).Range.End
.Collapse wdCollapseEnd
If .Information(wdAtEndOfRowMarker) = True Then .End = .End + 1
End If
End If
If .End = ActiveDocument.Range.End Then Exit Do
.Collapse wdCollapseEnd
.Find.Execute
Loop
End With
Next
End Sub
Of course, as the above code loops through all 9 heading levels, what ends up with a given highlight depends on how many other lower-level headings (higher numbers) are nested within a given higher-level heading (lower numbers).

Copy text from Word to Excel based on a list of search words

Hello dear forum members,
in the context of a research work at my university I have to transfer text passages from Word documents into an Excel file based on keywords.
This is a list of keywords (all listed below each other in an Excel column) and several Word documents (about 80-100 with 400 pages each).
The program should search the Word document for the keywords and if a word is found, the corresponding word + 350 characters before and after the word should be copied to an Excel line. Additionally, the name of the document and the number of pages should be copied. Each found word should be copied into a new line.
Based on first researches at Google I have received the following code. Most of it already works with this code.
I need your help with the following two points:
1.) How can I extend the text to be copied? If a search word is found in the word document, the word + 350 characters before and after the word should be copied.
2.) How should a loop look like, so that all Word documents in a folder are processed one after the other?
Since I did not find a solution after trying for a long time, I am happy about every tip or solution.
Sub LocateSearchItem_Test22()
Dim shtSearchItem As Worksheet
Dim shtExtract As Worksheet
Dim oWord As Word.Application
Dim WordNotOpen As Boolean
Dim oDoc As Word.Document
Dim oRange As Word.Range
Dim LastRow As Long
Dim CurrRowShtSearchItem As Long
Dim CurrRowShtExtract As Long
Dim myPara As Long
Dim myLine As Long
Dim myPage As Long
Dim oDocName As Variant
On Error Resume Next
Application.ScreenUpdating = False
Set oWord = GetObject(, "Word.Application")
If Err Then
Set oWord = New Word.Application
WordNotOpen = True
End If
On Error GoTo Err_Handler
oWord.Visible = True
oWord.Activate
Set oDoc = oWord.Documents.Open("C:\Users\Lenovo\Downloads\Data fronm Word to Excel\Testdatei.docx")
oDocName = ActiveDocument.Name
Set shtSearchItem = ThisWorkbook.Worksheets(1)
If ThisWorkbook.Worksheets.Count < 2 Then
ThisWorkbook.Worksheets.Add After:=shtSearchItem
End If
Set shtExtract = ThisWorkbook.Worksheets(2)
LastRow = shtSearchItem.UsedRange.Rows(shtSearchItem.UsedRange.Rows.Count).Row
For CurrRowShtSearchItem = 2 To LastRow
Set oRange = oDoc.Range
With oRange.Find
.Text = shtSearchItem.Cells(CurrRowShtSearchItem, 1).Text
.MatchCase = False
'.MatchWholeWord = False
.MatchWildcards = True
While oRange.Find.Execute = True
oRange.Select
myPara = oDoc.Range(0, oWord.Selection.Paragraphs(1).Range.End).Paragraphs.Count
myPage = oWord.Selection.Information(wdActiveEndAdjustedPageNumber)
myLine = oWord.Selection.Information(wdFirstCharacterLineNumber)
CurrRowShtExtract = CurrRowShtExtract + 1
shtExtract.Cells(CurrRowShtExtract, 1).Value = .Text
shtExtract.Cells(CurrRowShtExtract, 2).Value = myPara
shtExtract.Cells(CurrRowShtExtract, 3).Value = myPage
shtExtract.Cells(CurrRowShtExtract, 4).Value = myLine
shtExtract.Cells(CurrRowShtExtract, 5).Value = oDocName
shtExtract.Cells(CurrRowShtExtract, 6) = oDoc.Paragraphs(myPara).Range
oRange.Collapse wdCollapseEnd
Wend
End With
Next CurrRowShtSearchItem
If WordNotOpen Then
oWord.Quit
End If
'Release object references
Set oWord = Nothing
Set oDoc = Nothing
Exit Sub
Err_Handler:
MsgBox "Word caused a problem. " & Err.Description, vbCritical, "Error: " & Err.Number
If WordNotOpen Then
oWord.Quit
End If
End Sub
I'm going to specifically focus on the Word part, because that is my expertise. It looks like you know a fair bit about VBA, so I'm just going to answer with snippets.
Here's your find:
With oRange.Find
.Text = shtSearchItem.Cells(CurrRowShtSearchItem, 1).Text
.MatchCase = False
'.MatchWholeWord = False
.MatchWildcards = True 'do you really want wildcards?
.Wrap = wdFindStop
While .Execute = True
myPara = oDoc.Range(0, oRange.End).Paragraphs.Count
myPage = oRange.Information(wdActiveEndAdjustedPageNumber)
myLine = oRange.Information(wdFirstCharacterLineNumber)
'Expand range size begins here
oRange.MoveStart wdCharacter, -350 'not sure if you want the info of just the word or the word +/- 350 characters
oRange.MoveEnd wdCharacter, 350
CurrRowShtExtract = CurrRowShtExtract + 1
shtExtract.Cells(CurrRowShtExtract, 1).Value = .Text
shtExtract.Cells(CurrRowShtExtract, 2).Value = myPara
shtExtract.Cells(CurrRowShtExtract, 3).Value = myPage
shtExtract.Cells(CurrRowShtExtract, 4).Value = myLine
shtExtract.Cells(CurrRowShtExtract, 5).Value = oDocName
shtExtract.Cells(CurrRowShtExtract, 6) = oRange.Text
oRange.Collapse wdCollapseEnd
Wend
End With
Don't select anything, ever, if you can help it. Almost everything in Word can be done without ever ever ever using selection. Declare the range and manipulate the range. There's no need to select it.
As far as looping through each document in the folder, take a look at FileSystemObject. The documentation is horrendous but Google results are generally pretty good.

Loop: Copy paragraph based on excel list from one document to another using bookmark

Please refer below screenshot for more details.
Excel Sheet
Source Document
Below my code output in Destination Document
Macropod output in Destination Document
The excel file Sheets("List1"), containing two columns with text/string.
Column A having starting word of paragraph or table and Column B having ending word of paragraph or table.
Based on column A and B text, the macro find the starting and ending word in source document.
If found then, copy all text or table including starting and ending word from source document with formatting and past it at bookmarks (Text1, Text2 and so on) in destination document with source formatting.
The paragraph I am trying to copy contains text and tables (either in between two text or at end)
How to loop column A and B text/string with loop of bookmark.
Below macro what I have try is find text based on column A and B in source document, copy with formatting and paste it at bookmark in destination document.
But it selecting range (text or table) of last entry in each loop.
I have try to edit below code but not succeeded. I do not have good knowledge of coding.
Kindly look wonderful answer received from Macropod and my comments.
Sub CopyPasteParagraphsNew()
Dim wdApp As New Word.Application
Dim DocSrc As Word.Document, DocTgt As Word.Document, wdRng As Word.Range
Dim WS As Worksheet, r As Long
Dim i As Long
Dim j As Long
Dim M As Long
Dim N As Long
Set WS = Sheets("List1")
Set MsWord = CreateObject("Word.Application")
On Error Resume Next
Set wrdApp = GetObject(, "Word.Application")
On Error GoTo 0
If wrdApp Is Nothing Then
Set wrdApp = CreateObject("Word.Application")
bWeStartedWord = True
End If
With DocSrc
With MsWord
.Visible = True
.Documents.Open (ActiveWorkbook.Path & "\Source Document.doc")
.Activate
MsWord.Selection.HomeKey Unit:=wdStory
With MsWord.Selection.Find
M = Cells(Rows.Count, "A").End(xlUp).Row 'selecting last string of column A and pasting at each bookmark
For i = 1 To M
.ClearFormatting
.Wrap = wdFindStop
.MatchCase = True
.Text = Cells(i, "A").Value
.Execute
MsWord.Selection.Collapse
Next i
N = Cells(Rows.Count, "B").End(xlUp).Row 'selecting last string of column B and pasting at each bookmark
For j = 1 To N
lngStart = MsWord.Selection.End
.Text = Cells(j, "B").Value
.Execute
Next j
lngEnd = MsWord.Selection.End
MsWord.ActiveDocument.Range(lngStart, lngEnd).Copy
Set DocTgt = Documents.Open(ActiveWorkbook.Path & "\Destination Document.doc")
With DocTgt
For t = 1 To DocTgt.Bookmarks.Count
If DocTgt.Bookmarks.Exists("Text" & t) Then
MsWord.Selection.GoTo What:=wdGoToBookmark, Name:=("Text" & t)
MsWord.Selection.PasteAndFormat wdFormatOriginalFormatting
End If
Next
End With
End With
End With
End With
End Sub
Your description is unclear. Perhaps:
Sub CopyPasteParagraphs()
Dim wdApp As New Word.Application
Dim DocSrc As Word.Document, DocTgt As Word.Document, wdRng As Word.Range
Dim WS As Worksheet, r As Long
Set WS = Sheets("List1")
With wdApp
.Visible = True
Set DocSrc = .Documents.Open(ActiveWorkbook.Path & "\Source Document.doc") 'SourceDocument
Set DocTgt = Documents.Open(ActiveDocument.Path & "\Destination Document.doc")
With DocSrc
For r = 1 To WS.UsedRange.SpecialCells(xlCellTypeLastCell).Row
With .Range
With .Find
.Text = WS.Range("A" & r) & "*" & WS.Range("B" & r)
.MatchWildcards = True
.Execute
End With
If .Find.Found = True Then Set wdRng = .Duplicate
With DocTgt
If .Bookmarks.Exists("Text" & r) Then
.Bookmarks("Text" & r).Range.FormattedText = wdRng.FormattedText
End If
End If
End If
End With
.Close False
End With
End With
End Sub
Instead of:
If .Bookmarks.Exists("Text" & r) Then
.Bookmarks("Text" & r).Range.FormattedText = wdRng.FormattedText
End If
you might use:
If .Bookmarks.Exists("Text" & r) Then
wdRng.Copy
.Bookmarks("Text" & r).Range.PasteAndFormat wdFormatOriginalFormatting
End If

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