Retain formatting when copying from word to outlook - vba

I have a code which replaces the text of certain format into a hyperlink. This code works during an incoming email.
Incoming email -> copy the email to word editor(formatting lost) -> make necessary changes -> copy from word editor to outlook mail item(again replaced hyperlinks gets lost in mail item)
My code is here for your refernce..
Sub IncomingHyperlink(MyMail As MailItem)
Dim strID As String
Dim Body As String
Dim objMail As Outlook.MailItem
Dim strtemp As String
Dim RegExpReplace As String
Dim RegX As Object
Dim myObject As Object
Dim myDoc As Word.Document
Dim mySelection As Word.Selection
strID = MyMail.EntryID
Set objMail = Application.Session.GetItemFromID(strID)
Set objWord = CreateObject("Word.Application")
objWord.Visible = True
'Set myDoc = objWord.Documents.Open("filename")
'Set objDoc = objWord.Documents.Open("C:\test.doc")
Set objDoc = objWord.Documents.Add()
Set objSelection = objWord.Selection
objSelection.TypeText "GOOD" & objMail.HTMLBody
With objSelection.Find
.ClearFormatting
.Text = "ASA[0-9][0-9][0-9][0-9][a-z][a-z]"
.Forward = True
.Wrap = wdFindAsk
.MatchWildcards = True
End With
objSelection.Find.Execute
objSelection.Hyperlinks.Add Anchor:=objSelection.Range, _
Address:="http://www.code.com/" & objSelection.Text, _
TextToDisplay:=objSelection.Text
objMail.HTMLBody = objDoc.Range(0, objDoc.Range.End)
objMail.Save
Set objMail = Nothing
End Sub
Also, this code replaces only the first occurrence of the needed text and does not replace others.
Please help solve these problems. Thank you...

In order to replace every occurrences of the regex, you can loop over the results :
With objSelection.Find
.ClearFormatting
.Text = "ASA[0-9][0-9][0-9][0-9][a-z][a-z]"
.Forward = True
.Wrap = wdFindAsk
.MatchWildcards = True
While objSelection.Find.Execute
Hyperlinks.Add Anchor:= objSelection.Range, _
Address:="http://www.code.com/" & objSelection.Text, _
TextToDisplay:=objSelection.Text
objSelection.Collapse wdCollapseEnd
Wend
End With
In order to keep your formatting, did you try (if possible) to execute your vba only in Outlook ?
Regards,
Max

Related

Find and delete all highlighted text in an email

I need to find and delete all highlighted text in an email body.
I tried to use WordEditor in Outlook VBA.
The following works in a Word document because I recorded the macro in Word:
.Find.ClearFormatting
.Find.Highlight = True
.Find.Replacement.ClearFormatting
With .Find
.Text = ""
.Replacement.Text = ""
.Forward = True
.Wrap = wdFindContinue
.Format = True
.MatchCase = False
.MatchWholeWord = False
.MatchWildcards = False
.MatchSoundsLike = False
.MatchAllWordForms = False
MsgBox "running macro"
End With
Selection.Find.Execute Replace:=wdReplaceAll
What are the necessary Outlook objects and code to include in the Outlook macro?
I know I need to dim ObjectInspector and a few other objects.
To deal with the Word editor in Outlook you need to use the Inspector.WordEditor property which returns the Microsoft Word Document Object Model of the message. You can use the following ways to get an instance of the Inspector class:
Use the ActiveInspector method to return the object representing the currently active inspector (if there is one).
Sub CloseItem()
Dim myinspector As Outlook.Inspector
Dim myItem As Outlook.MailItem
Set myinspector = Application.ActiveInspector
Set myItem = myinspector.CurrentItem
myItem.Close olSave
End Sub
Use the GetInspector property to return the Inspector object associated with an item.
Sub InsertBodyTextInWordEditor()
Dim myItem As Outlook.MailItem
Dim myInspector As Outlook.Inspector
'You must add a reference to the Microsoft Word Object Library
'before this sample will compile
Dim wdDoc As Word.Document
Dim wdRange As Word.Range
On Error Resume Next
Set myItem = Application.CreateItem(olMailItem)
myItem.Subject = "Testing..."
myItem.Display
'GetInspector property returns Inspector
Set myInspector = myItem.GetInspector
'Obtain the Word.Document for the Inspector
Set wdDoc = myInspector.WordEditor
If Not (wdDoc Is Nothing) Then
'Use the Range object to insert text
Set wdRange = wdDoc.Range(0, wdDoc.Characters.Count)
wdRange.InsertAfter ("Hello world!")
End If
End Sub

Looping through files in folder successfully but all files print corrupted error

This code is supposed to open all files in the subfolders of my target
folder and search them for specific terms, print those terms and where
they were found in a text file. If it encounters an error, print that
error so we know which documents to search manually.
It seems to be working, it's finding the search terms in the
documents, but then it prints an error message for each file in the
subfolder that it's corrupted? These files are fine to open, btw. They
don't appear to be corrupted in any way. They do have tracked changes
on, could that be why? I've included some sample output for one folder
below the code.
FINAL CODE: thanks so much everyone for your help
Option Explicit
Sub CheckCrossRef()
Dim FSO As Scripting.FileSystemObject
Dim masterFolder As folder
Dim allSubfolders As Folders
Dim currSubfolder As folder
Dim subfolderFiles As Files
Dim currFile As File
Set FSO = Nothing
Dim leftChar As String
Dim strFolder As String
Dim strDoc As String
Dim wordApp As Word.Application
Dim wordDoc As Word.Document
Dim nameArchive As Word.Document
Set wordApp = New Word.Application
wordApp.Visible = True
Set nameArchive = Documents.Add(Visible:=False)
Dim fd As FileDialog
Set fd = Application.FileDialog(msoFileDialogFolderPicker)
With fd
.Title = "Select the folder that contains the documents."
If .Show = -1 Then
strFolder = .SelectedItems(1) & "\"
Else
MsgBox "You did Not Select the folder that contains the documents."
Exit Sub
End If
End With
Set FSO = CreateObject("Scripting.FileSystemObject")
Set masterFolder = FSO.GetFolder(strFolder)
Set allSubfolders = masterFolder.subFolders
For Each currSubfolder In allSubfolders
Set subfolderFiles = currSubfolder.Files
For Each currFile In subfolderFiles
On Error GoTo errorProcess
leftChar = Left(currFile.Name, 1)
If leftChar <> "~" Then
Set wordDoc = Word.Documents.Open(currFile.Path)
With wordDoc
Dim SearchTerm As String, i As Long, fileName As String
Dim Rng As Range, Doc As Document, RngOut As Range
Dim searchTerms As Variant
fileName = currFile.Name
searchTerms = [removed]
For i = LBound(searchTerms) To UBound(searchTerms)
SearchTerm = searchTerms(i)
With ActiveDocument.Range
With .Find
.ClearFormatting
.Text = SearchTerm
.Forward = True
.Wrap = wdFindStop
.MatchWildcards = True
.Execute
End With
If .Find.Found Then
Dim valueFound As String
Do While .Find.Found
Set Rng = .Duplicate
valueFound = Rng.Text
nameArchive.Activate
ActiveDocument.Range(0, 0).Select
Selection.EndKey Unit:=wdStory
Selection.TypeText Text:=vbCrLf & valueFound & "," & fileName
wordDoc.Activate
.Collapse wdCollapseEnd
.Find.Execute
Loop
End If
End With
Next
End With
wordDoc.Close
End If
nextIteration:
Next currFile
Next
Dim newPath
newPath = FSO.BuildPath(masterFolder.Path, "SpecList.txt")
nameArchive.SaveAs2 fileName:=newPath, FileFormat:=wdFormatText
nameArchive.Close
wordApp.Quit
Set wordApp = Nothing
Set FSO = Nothing
valueFound = "null"
Set Rng = Nothing
Set masterFolder = Nothing
Set allSubfolders = Nothing
Set currSubfolder = Nothing
Set subfolderFiles = Nothing
Set currFile = Nothing
Exit Sub
errorProcess:
nameArchive.Activate
ActiveDocument.Range(0, 0).Select
Selection.EndKey Unit:=wdStory
If Err.Number <> 0 Then
If Not currFile Is Nothing Then
fileName = currFile.Name
Selection.TypeText Text:=vbCrLf & fileName & " " & Err.Number & " " & Err.Description
Else
Selection.TypeText Text:=vbCrLf & Err.Number & " " & Err.Description
End If
End If
Resume nextIteration
On Error GoTo 0
End Sub
Some greatly abbreviated output:
03100,03100 Concrete Formwork.docx
05501,03200 Concrete Reinforcement.docx
07920,03251 Concrete Joints.docx
03600,03300 Cast in Place Concrete.docx
~$100 Concrete Formwork.docx - 5792 The file appears to be corrupted.
~$200 Concrete Reinforcement.docx - 5792 The file appears to be corrupted.
~$251 Concrete Joints.docx - 5792 The file appears to be corrupted.
~$300 Cast in Place Concrete.docx - 5792 The file appears to be corrupted.
Any advice? Also if you see any other mistakes in the code feel free
to correct. Thank you!
~$100 Concrete Formwork.docx
~$200 Concrete Reinforcement.docx
These look like the "lock" file which Word generates when someone has a file open for editing. It's not an actual Word file, so you should maybe consider excluding any files which begin with a tilde.

VBA - Find string in email body or subject

I am trying to create a simple macro, which reads the active email and checks whether or not a certain string is present. Now, the string can have two possible formats, and will only contains digits.
The two formats:
xxx-xxxxxxxx or xxxxxxxxxxx
(x will always be a digit)
I am unsure on how to do this. Below I have a macro, which reads the mail - but it can only find a specific string:
Sub AutomateReplyWithSearchString()
Dim myInspector As Outlook.Inspector
Dim myObject As Object
Dim myItem As Outlook.MailItem
Dim myDoc As Word.Document
Dim mySelection As Word.Selection
Dim strItem As String
Dim strGreeting As String
Set myInspector = Application.ActiveInspector
Set myObject = myInspector.CurrentItem
'The active inspector is displaying a mail item.
If myObject.MessageClass = "IPM.Note" And myInspector.IsWordMail = True Then
Set myItem = myInspector.CurrentItem
'Grab the body of the message using a Word Document object.
Set myDoc = myInspector.WordEditor
myDoc.Range.Find.ClearFormatting
Set mySelection = myDoc.Application.Selection
With mySelection.Find
.Text = "xxx-xxxxxxxx"
.Replacement.Text = ""
.Forward = True
.Wrap = wdFindContinue
.Format = False
.MatchCase = False
.MatchWholeWord = False
.MatchAllWordForms = False
.MatchSoundsLike = False
.MatchWildcards = True
End With
If mySelection.Find.Execute = True Then
strItem = mySelection.Text
'Mail item is in compose mode in the inspector
If myItem.Sent = False Then
strGreeting = "With reference to " + strItem
myDoc.Range.InsertBefore (strGreeting)
End If
Else
MsgBox "There is no item number in this message."
End If
End If
End Sub
You can use regex pattern:
(\d{11}|\d{3}-\d{8})
Try it.
This example is copied from here. I have not tested it.
Option Explicit
Sub GetValueUsingRegEx()
' Set reference to VB Script library
' Microsoft VBScript Regular Expressions 5.5
Dim olMail As Outlook.MailItem
Dim Reg1 As RegExp
Dim M1 As MatchCollection
Dim M As Match
Set olMail = Application.ActiveExplorer().Selection(1)
' Debug.Print olMail.Body
Set Reg1 = New RegExp
With Reg1
.Pattern = "(\d{11}|\d{3}-\d{8})"
.Global = True
End With
If Reg1.test(olMail.body) Then
Set M1 = Reg1.Execute(olMail.body)
For Each M In M1
Debug.Print M.SubMatches(1)
Next
End If
End Sub

Use VB within Excel to open up a Word Doc and search and replace a string which is in a text box within the word document

When my code is executed from Excel, it will open up a Word document and can replace strings in the word doc with a given value taken from the Excel file, however it will not currently replace any text that is within a Text Box in the Word doc.
Here is my code (which I took from a previous post on here) -
For Each itm In arrNames
Dim objWord As Object
Set objWord = CreateObject("Word.Application")
objWord.Visible = True
objWord.Documents.Open "C:\Users\Test\Desktop\Test.docx"
With objWord
.Activate
With objWord.Selection.Find
.Text = "Sheep"
.Replacement.Text = itm
.Forward = True
.Wrap = 2
.Format = False
.MatchCase = False
.MatchWholeWord = False
.MatchSoundsLike = False
.MatchWildcards = True
.Execute Replace:=2
End With
End With
objWord.Application.ActiveDocument.SaveAs ("C:\Users\Test\Desktop\ReportPage\" & itm & ".doc")
Next itm
Are there additional arguments I need to pass into the With statement in order for text in a Text Box to also be replaced?
I was able to find a solution.
Here is the code -
Dim objWord2 As Object
Set objWord2 = CreateObject("Word.Application")
objWord2.Visible = True
objWord2.Documents.Open "C:\Users\kmccorma\Desktop\FRONTCOVER.doc"
'Iterate round a list of names
For Each itm In arrNames
Dim rngStory As Word.Range
'Iterate through all story types in the current document
For Each rngStory In ActiveDocument.StoryRanges
'Iterate through all linked stories
Do
Dim strText As String
' Get the text from the current TextBox
strText = rngStory.Text
'Check if the current text box contains the string you are looking for
If InStr(1, strText, "SearchText") Then
'Overwrite the text in the TextBox
rngStory.Text = itm
End If
'Get next linked story (if any)
Set rngStory = rngStory.NextStoryRange
Loop Until rngStory Is Nothing
Next
If itm & "X" <> "X" Then
ActiveDocument.SaveAs ("C:\Users\kmccorma\Desktop\FrontCover\" & itm & ".doc")
End If
Next itm

Replace specific ids in body with specific hyperlinks

After my thorough homework, I am posting this question. Please help me solve this..
I want to search for ASA1234yy in the body of a text and replace it with the embedded hyperlink [ASA1234yy][1]
There can be many ids of this type in the body and each of theri hyperlinks should be unique which follows a pattern
Code done so far
Sub ConvertToHyperlink(MyMail As MailItem)
Dim strID As String
Dim Body As String
Dim objMail As Outlook.MailItem
Dim temp As String
Dim RegExpReplace As String
Dim RegX As Object
strID = MyMail.EntryID
Set objMail = Application.Session.GetItemFromID(strID)
Body = objMail.Body
Body = Body + "Test"
objMail.Body = Body
Set RegX = CreateObject("VBScript.RegExp")
With RegX
.Pattern = "ASA[0-9][0-9][0-9][0-9][a-z][a-z]"
.Global = True
.IgnoreCase = Not MatchCase
End With
RegExpReplace = RegX.Replace(Body, "http://www.code.com/ABCD")
Set RegX = Nothing
objMail.Body = RegExpReplace
objMail.Save
Set objMail = Nothing
End Sub
This code replaces the entire id only. How do I add the id to the hyperlink.
and after adding it, I need a embedded hyperlink.
thanks
Ok my modified idea below...
Hi..
I am facing two problems in the process described below..
Convert specified text extracted from Outlook mailitem to hyperlinks in word document and save it in outlook mailitem.
i.e Incoming email -> Save it in a Word Document -> Change text to hyperlinks-> Save changed WORD document to Outlook mail item
My code finds only the first occuring text in the document , and replaces it with a hyperlink and leaves the other ocurrences
After making modifications in the word document, I want to copy the contents of the document to the outlook mailitem.
Formatting getting lost if email has tables and other stuff.
My code here for you...
Sub IncomingHyperlink(MyMail As MailItem)
Dim strID As String
Dim Body As String
Dim objMail As Outlook.MailItem
Dim temp As String
Dim RegExpReplace As String
Dim RegX As Object
Dim myObject As Object
Dim myDoc As Word.Document
Dim mySelection As Word.Selection
strID = MyMail.EntryID
Set objMail = Application.Session.GetItemFromID(strID)
Set objWord = CreateObject("Word.Application")
objWord.Visible = True
Set objDoc = objWord.Documents.Add()
Set objSelection = objWord.Selection
objSelection.TypeText "GOOD" & objMail.Body
With objSelection.Find
.ClearFormatting
.Text = "ASA[a-z][a-z][0-9][0-9][0-9][0-9][0-9]"
.Forward = True
.Wrap = wdFindAsk
.MatchWildcards = True
End With
'Find next instance of Pattern "ASA[a-z][a-z][0-9][0-9][0-9][0-9]"
objSelection.Find.Execute
'Replace it with a hyperlink
objSelection.Hyperlinks.Add Anchor:=objSelection.Range, _
Address:="http://www.code.com/" & objSelection.Text, _
TextToDisplay:=objSelection.Text
objDoc.SaveAs ("C:\Desktop\testdoc.doc")
objWord.Quit
objMail.Body = objSelection.Paste
objMail.Save
Set objMail = Nothing
End Sub
Can you please help solve these two problems?
Ok, I think I understand you now. You want to use named groups.
Start with this regex pattern:
(?<key>ASA\d{3}[a-z]{2})
Then, use this for the replacement pattern:
<a href=http://code.com${key}/example>${key}</a>
--dave
Suggestion: just use Word's built-in Find method.
'Set up search
With Selection.Find
.ClearFormatting
.Text = "ASA[0-9][0-9][0-9][0-9][a-z][a-z]"
.Forward = True
.Wrap = wdFindAsk
.MatchWildcards = True
End With
' Find next instance of Pattern "ASA[0-9][0-9][0-9][0-9][a-z][a-z]"
Selection.Find.Execute
' Replace it with a hyperlink
ActiveDocument.Hyperlinks.Add Anchor:=Selection.Range, _
Address:="http://www.code.com/" & Selection.Text, _
TextToDisplay:=Selection.Text
The above will keep the orinigal text e.g. "ASA5534yy" and insert the hyperlink http://www.code.com/ASA5534yy (adjust as you see fit).