I'm trying to edit a .docx file from excel(vba).
My code so far:
Dim wApp As Word.Application
Dim wDoc As Word.Document
Set wApp = CreateObject("word.Application")
wApp.Visible = True
Set wDoc = wApp.Documents.Open(Filename:=ThisWorkbook.Path & "\file.docx", ReadOnly:=False)
The thing is that the word file opens correctly, but it opens as read only file and i need to edit its text.
What am I missing?
Related
I've set up code that opens a word document and closes excel, from the word document there is code to reopen excel and copy user data to a new sheet which I pull from for a form. This whole process works perfectly, the issue is trying to close the word document once I've finished my tasks.
I want to close the word document once I'm back in excel however everything I'm trying returns bad file name error when I try to reference the doc. I know for a fact that the file path is correct. I also know that you cant reference the open doc the normal way you would. I've substituted the variable filePath for privacy reasons.
Here is the code from word which is executed first
Sub sendTableToExcel()
Dim xlApp As Excel.Application
Dim xlWb As Excel.Workbook
Dim ws As Worksheet
Dim doc As Document
Dim tbl As Table
Set doc = ThisDocument
Set xlApp = CreateObject("Excel.Application")
xlApp.Visible = True
Set xlWb = xlApp.Workbooks.Open(filePath)
Set ws = Sheets.Add
ws.Name = "temp"
Set tbl = doc.Tables(1)
tbl.Range.Copy
xlWb.Worksheets(ws.Name).PasteSpecial wdPasteText
ws.Visible = False
xlWb.Application.Run "pasteCopiedValuesFromRequestDocs"
xlWb.Application.Run "openRequestLanding", "Casual" //this is the where I'm trying to close the doc
Set xlWb = Nothing
Set xlApp = Nothing
Set tblRange = Nothing
Set tbl = Nothing
Set doc = Nothing
End Sub
and the sub from excel which is called from word
Public Sub openRequestLanding(requestType As String)
Dim wdApp As Word.Application
Dim doc As Word.Document
Set wdApp = CreateObject("Word.Application")
wdApp.Visible = True
Set doc = wdApp.Documents(filePath)
doc.Close SaveChanges:=wdDoNotSaveChanges
Set wdApp = Nothing
Set doc = Nothing
RequestLanding.RequestTypeBox.Value = requestType
RequestLanding.Show
End Sub
You will have no success in closing the document as it is not open in the instance of Word that your code references. Your code in Excel needs to get the currently open instance of Word, not create a new one.
Change
Set wdApp = CreateObject("Word.Application")
to
Set wdApp = GetObject(, "Word.Application")
Recently I manage to make an automation in VBA where the external word file in the same folder as the excel file is been opened and add new content from excel then save as the word file different name. Below the code:
Dim wordapp As Word.Application
Dim wordfile As Word.Document
Set wordapp = New Word.Application
Set wordfile = wordapp.Documents.Open(Application.ActiveWorkbook.Path & "<word file name>")
wordapp.Visible = False
<code to manipulate the word.document to insert value and graph from excel>
wordfile.SaveAs Filename:=Application.ActiveWorkbook.Path & "<new word file name>"
wordapp.Quit
Set wordapp = Nothing
Set wordfile = Nothing
The original external word file is behaving like a template with header and footer and some paragraph.
Because the nature of my project, I need to embedded the external word file into the excel thus turning the external word file into OLEObject in excel file. Even though I manage to open the OLEObject and manipulate the word.document to insert value and graph from excel and save as external word file, the closed OLEObject will also retain the insert value and graph making it not good for use as template.
I come up with this code. Basically to open the OLEObject and copy the content, then create a new word file and paste the content in it so that the OLEObject will not retain any changes:
Dim objSampleReport As OLEObject
Dim wordApp As Word.Application
Dim wordFileEmbed As Word.Document
Dim wordFileNew As Word.Document
Set objSampleReport = pgReport.OLEObjects("objSampleReport")
objSampleReport.Verb xlVerbPrimary
Set wordFileEmbed = objSampleReport.Object
Set wordApp = New Word.Application
Set wordFileNew = wordApp.Documents.Add
wordFileEmbed.Content.Copy
wordFileNew.Content.PasteAndFormat
wordFileEmbed.Application.Quit False
<code to manipulate the word.document to insert value and graph from excel using wordApp.selection>
Eventhough I manage to copy the OLEObject and retain the embedded as original intended, the new created word file dont have header footer and the format is wrong.
So I try to record the copypaste behaviour using Word Macro and this is come up:
Selection.WholeStory
Selection.Copy
Windows("Document1").Activate
Selection.PasteAndFormat (wdUseDestinationStylesRecovery)
With this new knowlegde I try to come up something similar as above. This is the code:
Dim objSampleReport As OLEObject
Dim wordAppEmbed As Word.Application
Dim wordAppNew As Word.Application
Dim wordFileEmbed As Word.Document
Dim wordFileNew As Word.Document
Set objSampleReport = pgReport.OLEObjects("objSampleReport")
objSampleReport.Verb xlVerbPrimary
Set wordAppEmbed = objSampleReport.Object.Application
Set wordAppNew = New Word.Application
Set wordFileNew = wordAppNew.Documents.Add
wordAppEmbed.Activate
wordAppEmbed.Selection.WholeStory
wordAppEmbed.Selection.Copy
wordAppNew.Activate
wordAppNew.Selection.PasteAndFormat
wordAppEmbed.Quit False
<code to manipulate the word.document to insert value and graph from excel using wordApp.selection>
But this still result in header footer not been copy paste and the format still wrong. I try to play around with .PasteAndFormat type parameter but the result are still the same.
Can someone help me with this problem? My other option is to use the template as external word file and using the first code but that require me to send excel file and word file at the same time, and human error can occur if the user only copying the excel file.
May try Something in line with following code
Sub NewTest()
Dim objSampleReport As OLEObject
Dim wordAppEmbed As Word.Application
'Dim wordAppNew As Word.Application
Dim wordFileEmbed As Word.Document
Dim wordFileNew As Word.Document
Dim pgReport As Worksheet
Set pgReport = ThisWorkbook.Sheets("Sheet1") 'Used for test purpose. May Use your choice
Set objSampleReport = pgReport.OLEObjects("Object 2") 'Used for test purpose. Use use choice
objSampleReport.Verb xlOpen
Set wordAppEmbed = objSampleReport.Object.Application
Set wordFileEmbed = wordAppEmbed.ActiveDocument
Set wordFileNew = wordAppEmbed.Documents.Add
wordFileEmbed.Content.Copy
wordFileNew.Range.Paste
wordFileEmbed.Close
' Now may Work with wordFileNew for further processing New file
End Sub
Edit As suggested by #Cindy Meister's expert opinion and valuable comment, I also feel first saving the embedded document as a new file, then open that document is far more prudent option. My last code is just an attempt to make your code work and tested on simple template only. (It may fail with complex documents). Therefore, I am posting modified code in line with #Cindy Meister's comment
Sub NewTest2()
Dim objSampleReport As OLEObject
Dim wordAppEmbed As Word.Application
Dim wordFileEmbed As Word.Document
Dim wordFileNew As Word.Document
Dim pgReport As Worksheet, Fname As String
Set pgReport = ThisWorkbook.Sheets("Sheet1") 'Modify to your choice
Fname = "C:\users\user\Desktop\Test2.docx" 'Modify to your choice
Set objSampleReport = pgReport.OLEObjects("Object 2") 'Used for test purpose. May modify to your choice
objSampleReport.Verb xlOpen
Set wordAppEmbed = objSampleReport.Object.Application
Set wordFileEmbed = wordAppEmbed.ActiveDocument
wordFileEmbed.SaveAs Fname
wordFileEmbed.Close
Set wordFileNew = wordAppEmbed.Documents.Open(Fname)
' Now may Work with wordFileNew for further processing New file
End Sub
.
I have code that opens a Word document and goes through the charts, updating the data.
The problem is that I call this macro multiple times in a row. Even though I close the Word application, the chartdata window remains open.
Excel is crashing without telling me why but E think the problem is with the chartdata windows not being closed. Because if I run the macro only one time, it works.
But, how do I close the chartdata window if the chart doesn't support this property?
Dim wdApp As Word.Application
Dim wdDoc As Word.Document
Dim wdShape As InlineShape
Dim wdChart As Word.Chart
Set wdApp = CreateObject("Word.Application")
wdApp.Visible = True
'Opening the document
Set wdDoc = wdApp.Documents.Open("path_here")
'Opening the chartdata window
Set wdShape = wdDoc.InlineShapes(1)
Set wdChart = wdShape.Chart
wdChart.ChartData.Activate
'Changing the data
Range("B2").Value = 120
Range("B3").Value = 155
'Closing the app
wdApp.Quit SaveChanges:=wdSaveChanges
Set wdShape = Nothing
Set wdChart = Nothing
Set wdApp = Nothing
Set wdDoc = Nothing
This code will change the values in the data without activating the chartdata window. For some reason the wdChart variable was throwing a constant assignment error, so I changed it to wdCh.
Set wdShape = wdDoc.InlineShapes(1)
Set wdCh = wdShape.Chart
With wdCh.ChartData.Workbook.Sheets(1)
.Range("B2").Value = 120
.Range("B3").Value = 155
End With
May I assign the objDoc as a document of the ObjWord (after Set objDoc = oDoc.Object)?
My code looks like this:
'Declaration
Dim oDoc As OLEObject
Dim objWord As Word.Application
Dim objDoc As Word.Document
Dim WS as Worksheet
Dim strOdoc as String
'Initialization
Set WS = Whorksheets("Sheet1")
strOdoc = "WordDoc"
Set objWord = New Word.Application
'Set objWord = GetObject(, "Word.Application")
'I need using GetObject to be able to made the activated OLEDocument, invisible.
'And Need Set objWord = New Word.Application to be able
'to EndTask the WINWORD.EXE with objWord.Quit.
objWord.Visible = False
Set oDoc = WS.OLEObjects(strOdoc)
oDoc.Activate
Set objDoc = oDoc.Object
'I need here Add the objDoc to the objWord
I need objDoc to have been a document of the objWord object, which has been hidden with objWord.Visible = False (I can't use Dim objDoc As objWord.Document variable declaration).
I need the objWord to have been isolated because when using
objWord.Quit, it must not try to close other Word Documents. (Here I used Set objWord = New Word.Application)
I need using the GetObject statement to be able to made the activated OLEDocument invisible.
And Need Set objWord = New Word.Application to be able to EndTask the
WINWORD.EXE with objWord.Quit.
But how can integrate two above advantages: 1) Working Invisible with the OLEObjectDocument and 2) Perform EndTask the WINWORD.EXE if no other word documents are opened?
Please take a more logical, step-by-step approach. Bear in mind that you need the Microsoft Word Object Library to be referenced (VBE > Tools > References).
Now you can create an instance of the Word application. It is invisible by default. You can use it and quit it without affecting any other instances of the Word that might be running concurrently. That part of your code is logically correct but the recommended code is Set objWord = CreateObject("Word.Application"). This creates a new instance. I'm not sure if Set objWord = New Word.Application perhaps does the same thing but you shouldn't need both.
Now you can open a document. Use the Documents.Open method to do that. The document will be of Word.Document data type, not an OLEObject. This document will open in a window and it is that window which you can make invisible. Address it as objWord.Windows(1) or objWord.ActiveWindow. Perhaps there will be a flicker on the screen which you might combat with objWord.ScreenUpdating = False.
After these steps you would have a normal Word document, invisible in its own Window, open in an instance of Word which has no other document open in it. You can manipulate that document, close it and then quit objWord.
I am trying to open word document from the excel but stuck at the first line when I am using the below code. I have added reference still get the compile error user- defined type not defined.
Dim oApp As Word.Application
Dim oSec As Word.Section
Dim oDoc As Word.Document
Set AppWord = CreateObject("Word.Application")
Set oApp = New Word.Application
Set oDoc = oApp.Documents.Add
You need to add a reference in the VBA context by opening VBA (Developer Tab, Click: Visual Basic), Select your Workbook and Click from the menu: Tools, References.
In the references list find the Word Object Library and make sure it is checked before clicking OK
Now try again, and don't forget to make oApp visible! :
Sub Test()
Dim oApp As Word.Application
Dim oSec As Word.Section
Dim oDoc As Word.Document
Set AppWord = CreateObject("Word.Application")
Set oApp = New Word.Application
Set oDoc = oApp.Documents.Add
oApp.Visible = True
End Sub