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")
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 am writing a function in vba that will take a cell on the worksheet's value and replace any carriage returns with another character. To populate the cell on the worksheet, I am manually copying (ctrl+c, ctrl+v) a few paragraphs from a Word document and pasting them into the formula box of excel, so it all shows up in that cell on the worksheet.
When I do this and try to store the contents of this cell as as string in my vba function, I get a Type mismatch error. What is going on here and how can I store the contents of the cell in a string variable in vba without getting this error?
I do not get a type mismatch error if I simply type in the cell itself and insert carriage returns using Alt+Enter.
Thanks for the help.
This kind of thing has been addressed numerous time on various forums, including here. See, for example:
VBA code that copies tables from multiple Word files to separate worksheets in excel Excel, naming the worksheet the name of the Word doc?
https://www.excelguru.ca/forums/showthread.php?8900-Help-with-VBA-to-extract-data-from-Word-to-Excel&p=36586&viewfull=1#post36586
For a single Word document, you might use code like:
Sub GetTableData()
'Note: this code requires a reference to the Word object model.
'See under the VBE's Tools|References.
Application.ScreenUpdating = False
Dim wdApp As New Word.Application, wdDoc As Word.Document, wdTbl As Word.Table
Dim strFile As String, WkSht As Worksheet, r As Long
Set WkSht = Activesheet
'Disable any Word Alerts
wdApp.DisplayAlerts = wdAlertsNone
'Disable any auto macros in the documents being processed
wdApp.WordBasic.DisableAutoMacros
strFile = "Filename & path"
Set wdDoc = wdApp.Documents.Open(FileName:=strFile, ReadOnly:=True, AddToRecentFiles:=False, Visible:=False)
With wdDoc
WkSht.Name = Split(.Name, ".doc")(0)
For Each wdTbl In .Tables
With wdTbl.Range.Find
.ClearFormatting
.Replacement.ClearFormatting
.Text = "[^13^l]"
.Replacement.Text = "?"
.Forward = True
.Wrap = wdFindStop
.Format = False
.MatchWildcards = True
.Execute Replace:=wdReplaceAll
End With
r = WkSht.Cells(WkSht.Rows.Count, 1).End(xlUp).Row
If r > 1 Then r = r + 2
wdTbl.Range.Copy
WkSht.Paste Destination:=WkSht.Range("A" & r)
Next
WkSht.UsedRange.Replace What:="?", Replacement:=Chr(10), LookAt:=xlPart, SearchOrder:=xlByRows
.Close SaveChanges:=False
End With
wdApp.Quit
Set wdDoc = Nothing: Set wdApp = Nothing: Set WkSht = Nothing
Application.ScreenUpdating = True
End Sub
Note how whole tables are copied & pasted, without the circumlocution of your cell-by-cell approach. FWIW, Neither Word's paragraph breaks nor Word's manual line breaks can be copied & pasted directly into a single Excel cell; they're both interpreted as indication the end of a cell's contents by Excel.
Note also that, with the code above, you need to supply the document's path & name.
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
I have created the below code for exporting an embedded Word document in a Excel Sheet to the workbook's path:
Private Sub Export()
Dim sh As Shape
Dim objWord As Object 'Word.Document
Dim objOLE As OLEObject
Set sh = Sheet1.Shapes("Object 1")
sh.OLEFormat.Activate
Set objOLE = sh.OLEFormat.Object
Set objWord = objOLE.Object
objWord.SaveAs2 Filename:=ActiveWorkbook.Path & "\MyTemplate.docx", FileFormat:= _
wdFormatDocumentDefault
End Sub
The above code is working fine, but I was looking to add that the Word Applications starts as invisible and that it exits MS Word at the end of the code. I have tried using objWord.Visible = False and objWord.Quit but when I add these lines I get an "Object doesn't support this property or method" error.
Please advise.
I guess you want this
objWord.Application.Visible = False
and this
objWord.Application.Quit
I'm trying to copy the values from a named range in Excel to a bookmark in Word. I found this code on the web that does it in Excel VBA, but I'm getting an Error 13.
Set pappWord = CreateObject("Word.Application")
Set docWord = pappWord.Documents.Add(Path)
'Loop through names in the activeworkbook
For Each xlName In wb.Names
'if xlName's name is existing in document then put the value in place of the bookmark
If docWord.Bookmarks.Exists(xlName.Name) Then
docWord.Bookmarks(xlName.Name).Range.Text = Range(xlName.Value)
End If
Next xlName
'Activate word and display document
With pappWord
.Visible = True
.ActiveWindow.WindowState = 0
.Activate
End With
I know that the line that is causing the error is:
docWord.Bookmarks(xlName.Name).Range.Text = Range(xlName.Value)
What am i doing wrong? Also, how & where would I code so that I can export the doc to PDF?
Thanks in advance.
Note: I've already selected the reference to the Microsoft Word (version number 14) Object model in Excel
so I use it to accomplish this task but taking an image from formatted Excel table.
Sub FromExcelToWord()
Dim rg As Range
For Each xlName In wb.Names
If docWord.Bookmarks.Exists(xlName.Name) Then
Set rg = Range(xlName.Value)
rg.Copy
docWord.ActiveWindow.Selection.Goto what:=-1, Name:=xlName.Name
docWord.ActiveWindow.Selection.PasteSpecial link:=False, DataType:=wdPasteEnhancedMetafile, Placement:= _
0, DisplayAsIcon:=False
End If
Next xlName
End Sub
Just curious... Why are you adding a document rather than opening the relevant doc which has the bookmarks? Try this code (I usually test the code before posting but I haven't tested this particular code. Just quickly wrote it)
Also I am using Late Binding so no reference to the Word Object Library is required.
Sub Sample()
Dim wb As Workbook
Dim pappWord As Object, docWord As Object
Dim FlName As String
Dim xlName As Name
FlName = "C:\MyDoc.Doc" '<~~ Name of the file which has bookmarks
'~~> Establish an Word application object
On Error Resume Next
Set pappWord = GetObject(, "Word.Application")
If Err.Number <> 0 Then
Set pappWord = CreateObject("Word.Application")
End If
Err.Clear
On Error GoTo 0
Set docWord = pappWord.Documents.Open(FlName)
Set wb = ActiveWorkbook
For Each xlName In wb.Names
'if xlName's name is existing in document then put the value in place of the bookmark
If docWord.Bookmarks.Exists(xlName.Name) Then
docWord.Bookmarks(xlName.Name).Range.Text = Range(xlName).Value
End If
Next xlName
'Activate word and display document
With pappWord
.Visible = True
.ActiveWindow.WindowState = 0
.Activate
End With
End Sub
EDIT
Changed
Range(xlName.Value)
to
Range(xlName).Value
Now the above code is TRIED AND TESTED :)