I'm a beginner to VBA macros in Excel, and this is the first attempt in Outlook, but here's what I am trying to do:
In Outlook 2010, assign a macro to a button that, when pushed,
Gets the entire body of the active email
Copies the body including all formatting and html to the clipboard
Opens a new word document
Pastes the content of the clipboard to this word doc
Clears the clipboard
So far, all I have are steps 1 and 3 (and I wonder if I'm going about this the wrong way in step 1) below:
Sub pasteToWord()
Dim activeMailMessage As Outlook.MailItem 'variable for email that will be copied.
Dim activeBody
Dim clearIt As String 'Intended to eventually clear clipboard.
'Code to get to the body of the active email.
If TypeName(ActiveExplorer.Selection.Item(1)) = "MailItem" Then _
Set activeMailMessage = ActiveExplorer.Selection.Item(1)
activeBody = activeMailMessage.Body
'MsgBox activeBody
'^This displayed what I want in plaintext form,
'so I think im on the right track
'Code to copy selection to clipboard
'Code to open new Word doc
Set WordApp = CreateObject("Word.Application")
WordApp.Documents.Add
WordApp.Visible = True
'Code to paste contents of clipboard to active word document
'Code to clear clipboard
End Sub
Any guidance to fill in the blanks above would be much appreciated.
Edit:
Here is what has come the closest so far, thanks to David Zemens. I think I am missing some reference though, because my compiler doesn't understand "DataObject" for the ClearClipboard() function. It does copy and paste into word with formatting though, as is below (though I had to comment out the last function to avoid errors):
Sub pasteToWord()
Dim WordApp As Word.Application 'Need to link Microsoft Word Object library
Dim wdDoc As Word.Document 'for these to be understood by compiler
Dim activeMailMessage As Outlook.MailItem
Dim activeBody As String
If TypeName(ActiveExplorer.Selection.Item(1)) = "MailItem" Then
'Get a handle on the email
Set activeMailMessage = ActiveExplorer.Selection.Item(1)
'Ensure Word Application is open
Set WordApp = CreateObject("Word.Application")
'Make Word Application visible
WordApp.Visible = True
'Create a new Document and get a handle on it
Set wdDoc = WordApp.Documents.Add
'Copy the formatted text:
activeMailMessage.GetInspector().WordEditor.Range.FormattedText.Copy
'Paste to the word document
wdDoc.Range.Paste
'Clear the clipboard entirely:
Call ClearClipBoard
End If
End Sub
Public Sub ClearClipBoard()
Dim oData As New DataObject 'object to use the clipboard -- Compiler error,
'I think I'm missing a reference here.
oData.SetText Text:=Empty 'Clear
oData.PutInClipboard 'take in the clipboard to empty it
End Sub
This method will copy the formatted text from the selected mailitem, and paste it in to word document:
Dim WordApp As Word.Application
Dim wdDoc As Word.Document
Dim activeMailMessage As MailItem
If TypeName(ActiveExplorer.Selection.Item(1)) = "MailItem" Then
'Get a handle on the email
Set activeMailMessage = ActiveExplorer.Selection.Item(1)
'Ensure Word Application is open
Set WordApp = CreateObject("Word.Application")
'Make Word Application visible
WordApp.Visible = True
'Create a new Document and get a handle on it
Set wdDoc = WordApp.Documents.Add
'Copy the formatted text:
activeMailMessage.GetInspector().WordEditor.Range.FormattedText.Copy
'Paste to the word document
wdDocument.Range.Paste
'Clear the clipboard entirely:
Call ClearClipBoard
End If
NOTE Clearing the clipboard entirely can be done pretty easily with a function like the one described here:
Public Sub ClearClipBoard()
Dim oData As New DataObject 'object to use the clipboard
oData.SetText Text:=Empty 'Clear
oData.PutInClipboard 'take in the clipboard to empty it
End Sub
You can use the Word object model when dealing woth item bodies.
Word is used as an email editor in Outlook. The WordEditor property of the Inspector class returns an instance of the Document class from the Word object model which represents the Body of your email. See Chapter 17: Working with Item Bodies for more information.
As you may see, there is no need to use any extra tools or classes (Clipboard and etc.). You can copy the document using built-in mechanisms or save the document as is.
Related
I'm trying to open a Word Document and copy the whole table inside it and then paste it into another already-open document after a specific heading/bookmark (that I have bookmarked in the document). Then finally prompt the user to save the document with the newly pasted table.
Examples seen online are Excel-to-Word or Word-to-Excel; I need Word-to-Word.
I'm able to pull up the first document (I think it successfully copies it, too--I haven't tested it), but when it activates the second document, it stops and gives an error that it doesn't have an object assigned.
The debugger highlights Set WrdRng = Active.Bookmarks("AppendixA").Range.
Sub TEST()
'
' Declare Table Document Var as Object
Dim tb As Object
Dim bk As Bookmark
Dim WrdRng As Range
'
'
'Set up Word Application
Set tb = CreateObject("Word.Application")
tb.Visible = True
'Opens Pre-Saved Document & activates it to use
tb.Documents.Open "C:\ Desktop\Table.dotm"
tb.Activate
Selection.WholeStory
'ActiveDocument.Tables(1).Select
Selection.Font.Name = "Calibri"
Selection.Copy
'Activate Rolling Trend Report Document and Paste
Windows("TEST - Compatibility Mode").Activate
' where the error occurs and the debugger highlights
Set WrdRng = Active.Bookmarks("AppendixA").Range
'Paste to Bookmark
With WrdRng
Selection.InsertAfter
End With
'Save Completed Report to Desktop
ChangeFileOpenDirectory "C: \Desktop\"
ActiveDocument.SaveAs2 FileName:="TEST.docm", _
FileFormat:=wdFormatXMLDocumentMacroEnabled
'
'
'
End Sub
Your code is failing because Set WrdRng = Active.Bookmarks("AppendixA").Range should be Set WrdRng = ActiveDocument.Bookmarks("AppendixA").Range
However, your code is badly written, will also fail in other places and will create an extra instance of Word.
The code below is to run from Word
Sub TEST()
'store a pointer to the document you wnat to insert table into
'assumed to be currently active document
Dim targetDoc As Document
Set targetDoc = ActiveDocument
'Open Pre-Saved Document
Dim tblDoc As Document
Set tblDoc = Documents.Open("C:\ Desktop\Table.dotm")
Dim source As Range
Set source = tblDoc.Content
'exclude the paragraph that comes after the table
source.MoveEnd Unit:=wdCharacter, Count:=-1
source.Font.Name = "Calibri"
Dim appxA As Range
Set appxA = targetDoc.Bookmarks("AppendixA").Range
appxA.Collapse wdCollapseEnd
'transfer the text and close the source document
appxA.FormattedText = source.FormattedText
tblDoc.Close wdDoNotSaveChanges
'it is necessary to pass the full file path to the SaveAs command
ActiveDocument.SaveAs2 FileName:="C: \Desktop\TEST.docm", _
FileFormat:=wdFormatXMLDocumentMacroEnabled
End Sub
I have an excel spreadsheet that is linked to multiple Word documents (.docx), which act as templates.
I have written a macro that opens the required word template from excel (the template chosen is dependent on the value of cell M17). The links in the word template update automatically as word opens. I am then trying to break the links of the document that I opened. This is what I have so far:
Function FnOpeneWordDoc()
Dim objWord
Dim objDoc
Dim path As String
path = Range("M17")
Set objWord = CreateObject("Word.Application")
Set objDoc = objWord.Documents.Open("*file_path*" & path & ".docx")
objWord.Visible = True
Application.Wait (Now + TimeValue("0:00:30"))
objDoc.Fields.Unlink
End Function
I suspect that it isn't working because the macro is trying to break the links before the document has fully loaded (and therefore the existing links haven't had a chance to update?), which is why I added the wait. Unfortunately this doesn't seem to be the solution.
The above code would have been fine, but I didn't realise that the code had to be different if the text was in textboxes.
I struggled to break the links within textboxes, and kept getting run-time error 438. However, I found a workaround:
I wrote a sub in the word documents:
Sub Unlink
Selection.Fields.Unlink
End Sub
I then called this macro from my excel document:
Sub FnOpeneWordDoc()
Dim objWord
Dim objDoc
Set objWord = CreateObject("Word.Application")
Set objDoc = objWord.Documents.Open("filename")
objWord.Visible = True
For i = 1 To objDoc.Shapes.Count
objDoc.Shapes(i).Select
objDoc.Application.Run ("unlink")
Next
End Sub
I am currently working on a project that have one word template embedded in one excel template.
A button in excel was created for opening the embedded word template, exporting the data from excel and puting them into word by using bookmarks in word template. The issue is that word report can be generated only once, because the text will be insert into the original bookmark rather than overwrite the previous data.
I'm trying to export a named field from excel(CoverPageRCA) and copy it into an embedded word template using a bookmark (bkmtable1_1).
I get:
run-time error 13 Type mismatch
that occurs at the following line:
Set bkMark = ActiveDocument.Bookmarks(bookmarkname).Range
I searched the web and spent almost 24 hrs on it. Can anybody please suggest a solution?
Option Explicit
Dim WD As New Word.Application
Dim RCAcell1 As Range
Sub CreateRCAReports1()
Dim wordDoc As Word.Document
Dim oleObj As oleObject
Dim WordApp As Word.Application
WD.Visible = True
Set oleObj = ActiveWorkbook.Sheets("CoverPageRCA").OLEObjects(1)
oleObj.Verb xlVerbPrimary
Set WordApp = oleObj.Object.Application
With WordApp
.Visible = True
.Activate
Set wordDoc = .Documents(1)
End With
'-------------------------------------------------------
ThisWorkbook.Sheets("CoverPageRCA").Activate
ActiveSheet.Range("B2").Select
Set RCAcell1 = ActiveSheet.Range(ActiveCell, ActiveCell.End(xlDown))
'go to each bookmark and type in details
CopyCell1 "bkmtable1_1", 1
Set WD = Nothing
End Sub
'----------------------------------------------------------
Sub CopyCell1(bookmarkname As String, RowOffset As Integer)
Dim bkMark As Range
'clear content on each bookmark and add new bookmarK
Set bkMark = ActiveDocument.Bookmarks(bookmarkname).Range
bkMark.Select
bkMark.Text = "dsfsf"
ActiveDocument.Bookmarks.Add bookmarkname, bkMark
'copy each cell to relevant Word bookmark
WD.Selection.GoTo What:=wdGoToBookmark, Name:=bookmarkname
WD.Selection.TypeText RCAcell1(RowOffset, 1).Value
End Sub
Looking at the code, the issue is on declaration of bkMark:
Dim bkMark As Range
The range object exists on both Excel and Word (different objects), and as the code above runs on excel, it will declare bkMark as an Excel Range object, not a Word Range object.
But the range returned on the line below is a Word range, causing the type mismatch error.:
Set bkMark = ActiveDocument.Bookmarks(bookmarkname).Range
To fix this issue, you must declare bkMark as a Word range,:
Dim bkMark As Word.Range
I'm using Excel 2010 with an embedded Word Document. The Word document is basically a communication template with some formatting (bold / underline / hyperlinks).
Process: User opens Excel Document, provides inputs to Excel, and completes template. There is no interaction between the inputs in Excel and the contents of the template.
I'm trying to build out this process such that once they edit the embedded Word Document the user hits a button. The VBA code would then take the contents of the embedded Word document and paste (formatting and all) it as the body of the email. The file would attach itself to that email, and off it would go for approval.
I've been able to locate code to get me part of the way there, and to give props where props are due, I located the code here (see below for the code)
But this doesn't retain the Word Document's Formatting. Any recommendations? Maybe if I could extract the Word contents as HTML that would work. But not sure how to do that. All help appreciated.
Sub Test()
Dim Oo As OLEObject
Dim wDoc As Object 'Word.Document
'Search for the embedded Word document
For Each Oo In Sheet8.OLEObjects
If InStr(1, Oo.progID, "Word.Document", vbTextCompare) > 0 Then
'Open the embedded document
Oo.Verb xlVerbPrimary
'Get the document inside
Set wDoc = Oo.Object
'Copy the contents to cell A1
wDoc.Content.Copy
With Sheet8.Range("M1")
.PasteSpecial xlPasteFormats
.PasteSpecial xlPasteValues
End With
'Select any cell to close the document
Sheet8.Range("M1").Select
'Done
Exit For
End If
Next
Set wDoc = Nothing
End Sub
After reviewing comintern's code, I was getting an error I couldn't solve for. I went back to the boards and located some additional code. Merging the two seems to have fixed it.
Sub HTMLExport()
Dim objOnSheet As oleObject
Dim strFileName As String
Dim sh As Shape
Dim objWord As Object ''Word.Document
Dim objOLE As oleObject
Sheet8.Activate
Set sh = ActiveSheet.Shapes("RA_Template")
sh.OLEFormat.Activate
Set objOLE = sh.OLEFormat.Object
Set objWord = objOLE.Object
ActiveSheet.Range("M1").Activate
''Easy enough
strFileName = CreateObject("Scripting.FileSystemObject").GetSpecialFolder(2) & "\temp.html"
objWord.SaveAs2 Filename:=strFileName, FileFormat:=10 '10=wdFormatFilteredHTML
'Copy the file contents into cell M1...
Dim handle As Integer
handle = FreeFile
Open strFileName For Input As handle
Sheet8.Range("M1").Value = Input$(LOF(handle), handle)
Close handle
'Delete the Temp File (strFileName)
Kill strFileName
'Select any cell to close the document
Sheet8.Range("M1").Select
End Sub`
If getting it into HTML will work (Word makes pretty ugly HTML...), you can just save it to a temp file and then pick it back up:
Sub HTMLExport()
Dim Oo As OLEObject
'Search for the embedded Word document
For Each Oo In Sheet8.OLEObjects
If InStr(1, Oo.progID, "Word.Document", vbTextCompare) > 0 Then
Dim temp As String
'GetSpecialFolder(2) gives the user's temp folder.
temp = CreateObject("Scripting.FileSystemObject").GetSpecialFolder(2) & "\temp.html"
'10 = wdFormatFilteredHTML
Oo.Object.SaveAs2 temp, 10
'Copy the file contents into cell M1...
Dim handle As Integer
handle = FreeFile
Open temp For Input As handle
Sheet8.Range("M1").Value = Input$(LOF(handle), handle)
Close handle
'...and delete the temp file.
Kill temp
'Select any cell to close the document
Sheet8.Range("M1").Select
'Done
Exit For
End If
Next
End Sub
Note that if you're using this method, you can't open the embedded Word document after you get the OLEObject or Word won't allow you to save it.
Trying to build a macro to copy data from Excel into MS Publsiher. I have the code for MS Word but it does not seem to work when applied to Publisher. It fails at this line appPub.ActiveWindow.Bookmarks("Growth").Paste
Word VBA:
Sub SendData()
Dim WordApp As Object
Set WordApp = CreateObject("Word.Application")
Dim ws As Worksheet
' Sheet1 is the codename for the sheet with the named range you want to copy,
' this is the name of the sheet in brackets in the VBAProject explorer, not the
' friendly name given on the worksheet tab itself visible to the end user.
Set ws = Sheet4
' This is the constant string which holds the filepath to your Word document
Const WORDDOC As String = "C:\Quarterly Reports - Word Version\Growth.docx"
WordApp.Visible = True
WordApp.Documents.Open WORDDOC
' Copies the named range "OrderRange" from the Excel book
'you are running this from.
ws.Range("Growth").Copy
' Pastes it to the bookmark "OrderBookmark" in your Word doc template.
WordApp.ActiveDocument.Bookmarks("Growth").Range.PasteAppendTable
' Sets your printer in Word to Adobe PDF and then prints the whole doc.
' WordApp.ActivePrinter = "Adobe PDF"
' WordApp.ActiveDocument.PrintOut
Set WordApp = Nothing
End Sub
Publisher VBA:
Sub SendDataPB()
Dim appPub As Object
Set appPub = CreateObject("Publisher.Application")
Dim ws As Worksheet
' Sheet1 is the codename for the sheet with the named range you want to copy,
' this is the name of the sheet in brackets in the VBAProject explorer, not the
' friendly name given on the worksheet tab itself visible to the end user.
Set ws = Sheet4
' This is the constant string which holds the filepath to your Publisher document
Const PublisherDOC As String = "C:\Quarterly Reports - Publisher Version\Growth.pub"
appPub.ActiveWindow.Visible = True
appPub.Open PublisherDOC
' Copies the named range "OrderRange" from the Excel book
' you are running this from.
ws.Range("Growth").Copy
' Pastes it to the bookmark "OrderBookmark" in your Publisher doc template.
appPub.ActiveWindow.Bookmarks("Growth").Paste
' Sets your printer in Publisher to Adobe PDF and then prints the whole doc.
' PublisherApp.ActivePrinter = "Adobe PDF"
' PublisherApp.ActiveDocument.PrintOut
Set appPub = Nothing
End Sub
ActiveWindow doesn't seem to contain any .Bookmarks collection: https://msdn.microsoft.com/EN-US/library/office/ff939707.aspx
Try ActiveDocument.Pages(YourPage).Shapes.Paste perhaps... With some luck that pastes your copied table as a new shape. From then on you'd just need to think of a clever way to place and find placeholders, unless you manage to find a usable Bookmarks collection somewhere else in the object model... Good luck!