How to use Words selection methods through Excel VBA - vba

In Word VBA you are able to set and move the cursor position by using the Selection.MoveLeft, Selection.MovRight etc...
However while trying to use this same method in Excel VBA I get an error saying "Object doesnt support this property or method."
I have imported the Word Object Library reference.
How am I able to move the cursor position on the Word document using VBA on the Excel application. Any help will be greatly appreciated.
Code:
Set Doc = ActiveDocument.Content
With Doc.Find
.Execute FindText:="*", ReplaceWith:="NEW*"
End With
Selection.HomeKey Unit:=wdStory
Selection.MoveDown Unit:=wdParagraph, Count:=11
Selection.MoveRight Unit:=wdWord, Count:=4
Selection.MoveRight Unit:=wdWord, Count:=2, Extend:=wdExtend
Selection.Font.Bold = False
Selection.Font.Name = "Arial"
Selection.Font.Size = 9

Your problem will go away if you would rephrase your question, "move the cursor position on the Word document using VBA on the Excel application". You can't move the cursor in a Word document using the Excel application.
When you open an Excel workbook you load an instance of the Excel application. You can use this same instance to open several workbooks. It also contains Excel VBA with all objects, methods and functions of the Excel application. This instance has no name.
But you could create another instance of the Excel application with code like
Dim XlApp as Excel.Application
Set XlApp = New Excel.Application
The new instance you have thus created has all the facilities of the first instance but is completely separate form it. You can open workbooks in it with code like
Dim Wb as workbook
Set Wb = XlApp.Workbooks.Add([Template])
Now, if you have set a reference to the MS Word Object Library you can create a Word application using similar code, for example,
Dim WdApp as Word.Application
Set WdApp = New Word.Application
This could be the only instance of MS Word running on your computer or it could be a new instance created in addition to other instances already running. This instance knows all the objects and methods of MS Word.
You can control both instances, XlApp and WdApp, in the same VBA project, but you should be careful to differentiate the objects. Both Excel and Word have a Range object for example. They are very different animals. You can specify, for example,
Dim xlRng As Excel.Range
Dim wdRng As Word.Range
Dim MyRng As Range
In this example, MyRng will be an Excel range if your VBA project is an Excel project. While you have both applications running this kind of defaulting will cause hair loss.
Dim Wb As Workbook
Dim Doc As Document
don't cause similar confusion because there is no Workbook object in MS Word and no Document object in MS Excel. VBA will use the correct application automatically, provided it is available.
When manipulating the WdRng you will have access to all the methods of the Word Range object, including Move, but there is no Address property, for example, which is a property of the XlRng.
Dealing with the two Selection objects is problematic. You will have to activate a window or document or workbook, and VBA will know which Selection object you mean by looking at the application running in the selected window. You won't have that problem if you specify the document/workbook object and use the WdRng or XlRng objects to manipulate your data.

As your code stands the keyword "selection" refers to the currently selected cell in excel, not the cursor position in your Word document. And the Excel Selection object does not have move methods. You might have more success using Range rather than selection: You example code translates as
With ActiveDocument
With .Content.Find
.Execute FindText:="*", ReplaceWith:="NEW*"
End With
with .Paragraphs(4).Range.Words(5).Font
.Bold = false
.name = "Arial"
.size = 9
end with
With .Paragraphs(4).Range.Words(6)
.Bold = false
.name = "Arial"
.size = 9
end with
end with

'Something Basic
'Session of word
'Existing document
Sub fromaWordDoc0()
Dim wdApp As Word.Application
Dim wdDoc As Word.Document
Set wdApp = CreateObject("word.application")
wdApp.Visible = True
Set wdDoc = wdApp.Documents.Add("C:\Documents\words.docx")
With wdApp.Selection
wdApp.Selection.MoveRight Unit:=wdWord, Count:=4
End With
Set wdApp = Nothing: Set wdDoc = Nothing
End Sub

Related

Opening and then breaking links to a Word document from Excel

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

Run-Time Error 1004 'Worksheet' of Object _Global

I have been using a Macro within a word document to input data from an Excel workbook into that MS Word document.
The routine prompts you to find the excel workbook where the data is stored, then copies fields from the workbook, finds an item in the word document text then replaces it in the word document text.
The following code was working, but would occasionally get a run-time error. Now I am getting the following error with every execution.
Run-time error '1004' Method 'Worksheets' of object'_Global' failed
It is trigger by this line:
.Replacement.Text = Worksheets("1- Organization Service Area").Range("B3").Value 'Insert Organization Name
The code is much longer, but here is the idea. The error is triggered on the first sub that is shown below.
Sub InputContractData()
'
' You must pick Microsoft Excel Object Library from Tools>References
' in the Visual Basic editor to execute Excel commands.
' InputContractData Macro
'
'
'Define Excel and Workbook Information
Dim objExcelApp As Excel.Application
Dim objCDCDataWorkbook As Workbook
Dim CDCDataFile
Dim CDCDataFilePath
Dim CDCDataFileName
'Define Word and Document Information
Dim objWordApp As Word.Application
Dim objWordDoc As Word.Document
'Open Excel Program
Set objExcelApp = New Excel.Application
Set objWordApp = Word.Application
Set objWordDoc = objWordApp.ActiveDocument
objExcelApp.Visible = True
objWordApp.Visible = True
CDCDataFile = objExcelApp.GetOpenFilename("Excel Files (*.xlsx), *xlsx")
Set objCDCDataWorkbook = objExcelApp.Workbooks.Open(CDCDataFile)
CDCDataFilePath = Left(CDCDataFile, InStrRev(CDCDataFile, "\"))
CDCDataFileName = Dir(CDCDataFile)
Call Sheet001
'Save Document in same folder as CDC Workbook
objWordDoc.SaveAs CDCDataFilePath & "\DraftContract.docx"
' Close the new Word document.
objWordApp.ActiveDocument.Close
' Close the Word application.
objWordApp.Quit
End Sub
Sub Sheet001()
'Sheet 1- Organization Service Area -----------------------------
With Selection.Find
.ClearFormatting
.Text = "[[ORGANIZATION]]"
.Replacement.ClearFormatting
.Replacement.Text = Worksheets("1- Organization Service Area").Range("B3").Value 'Insert Organization Name
.Execute Replace:=wdReplaceAll, Forward:=True, _
Wrap:=wdFindContinue
End With
End Sub
The problem in the line:
.Replacement.Text = Worksheets("1- Organization Service Area").Range("B3").Value 'Insert Organization Name
is that MS Word has no idea what a Worksheet is since it's not a native object in the Word Object Model.
If you explicitly assign the object to it's proper parent it will work all the time. Since a Worksheet is an object in Excel, fully qualify it to the Excel object. I have shown this below and have chose to pass the Excel Workbook into the sub since you declar the variables locally in the InputContractData procedure.
Sub Sheet001(ws as Excel.Worksheet)
'Sheet 1- Organization Service Area -----------------------------
With Selection.Find
.ClearFormatting
.Text = "[[ORGANIZATION]]"
.Replacement.ClearFormatting
.Replacement.Text = ws.Range("B3").Value 'Insert Organization Name
.Execute Replace:=wdReplaceAll, Forward:=True, _
Wrap:=wdFindContinue
End With
End Sub
Then call like this:
Sheet001 objExcelApp.Workbooks(CDCDataFileName).Worksheets("1- Organization Service Area")

Inserting text in a embedded Word template, at a bookmark, from excel. "error 13 Type mismatch" error

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

Pasting a table into open Word document at a bookmark

I have searched a fair bit on this and other forums but I can't get code to work. I know this is user error - I am learning/self-taught at this.
What I want is to copy a (admittedly large) table in a specific Excel worksheet into an already-open Word document, at a specific point. I have seen this done using a keyword search but I would prefer to use a bookmark (and I've made the bookmark thing work!) purely because it's not visible to the end user. I'm trying to automate the creation of a document as much as possible.
The below code works, but I can only get it to work when the Word document in question is closed. If I try to run this sub when the word doc is open, it just tries to re-open it and of course can't. I can't find a neat bit of code that allows me to paste data into an already-open document.
Also, I can make this work for one value, but not for a range (i.e. the table I want to paste).
Sub ExcelRangeToWord()
Dim objWord As Object
Dim ws As Worksheet
Set ws = ThisWorkbook.Sheets("Summary")
Set objWord = CreateObject("Word.Application")
objWord.Visible = True
'Optimize Code
Application.ScreenUpdating = False
Application.EnableEvents = False
'open the word doc
objWord.Documents.Open "K:\Exeter Office\Quotebuilder project\testbed\test.docx" 'change as required
'pastes the value of cell I19 at the "heatlosses" bookmark
With objWord.ActiveDocument
.Bookmarks("heatlosses").Range.Text = ws.Range("I19").Value
End With
'Optimize Code
Set objWord = Nothing
Application.ScreenUpdating = True
Application.EnableEvents = True
'Clear The Clipboard
Application.CutCopyMode = False
End Sub
I'm trying to tackle this one step at a time, cos then I have half a chance of understanding things a bit better...
If I try and copy/paste a range, instead of just one value, I was using Currentregion to select all used cells surrounding B19:
With objWord.ActiveDocument
.Bookmarks("heatlosses").Range.Text = Range("B19").CurrentRegion
End With
All this does is paste the word "True" into Word.
I am baffled. Please, can anyone offer assistance?
Use the code below to achieve what you require:
Sub CopyToWord()
Dim wApp, wDoc
'Get the running word application
Set wApp = GetObject(, "Word.Application")
'select the open document you want to paste into
Set wDoc = wApp.documents("test.docx")
'copy what you want to paste from excel
Sheet1.Range("A1").copy
'select the word range you want to paste into
wDoc.bookmarks("heatlosses").Select
'and paste the clipboard contents
wApp.Selection.Paste
End Sub

Selecting and copying Outlook email body with a VBA macro

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.