Setting range in Word with VBA in Excel - excel

How do I set a range in Word while opening that file with VBA in Excel?
Dim wordApp As Word.Application
Dim wordObject As Word.Document
Dim wordRange As Word.Range
Dim filePath As String
Dim fileName As String
filePath = "C:\Users\"
fileName = "somename.docx"
Set wordApp = CreateObject("Word.Application")
With wordApp
.Visible = True
.Activate
.WindowState = wdWindowStateNormal
End With
Set wordObject = wordApp.Documents.Open(filePath & fileName)
Set wordRange = Documents(fileName).Sections(1).Range
With wordRange
'code
End With
The line causing trouble:
Set wordRange = Documents(fileName).Sections(1).Range
Regardless of the string I put in this returns
4160 runtime error "Bad File Name"
If I use ActiveDocument instead of Documents(), I get
4248 runtime error: "This command is not available because no document is open".
The error persists even after opening multiple unsaved and saved Word docs whilst running the code, only to have the same error message show up.

Set wordRange = Documents(fileName).Sections(1).Range errors because Excel doesn't know what Documents is (or it resolves it to something other than Word.Documents)
To fix that, you'd use (just as you did in the previous line)
Set wordRange = wordApp.Documents(fileName).Sections(1).Range
That said, you've already Set the Document(filepath & filename) to wordObject, so use it:
Set wordRange = wordObject.Sections(1).Range
Also, Excel doesn't know wdWindowStateNormal, so a new Variant variable is created (unless you have Option Explicit, which you should, always) and assigned the default value 0. Which just happens to be the value of Word.wdWindowStateNormal so no harm done, but the code is misleading.
To fix, use
.WindowState = 0 'wdWindowStateNormal
I'm curious about the way you've created the object. Using early binding but instead of creating New Word.Application you use CreateObject
Was this an intentional decision?
What is the benefit?

Related

Open two existing word files from excel

Hi I'm trying to write code to use excel to work with two existing word documents but I keep getting OLE errors. This is just the start but it keeps crashing. What am I doing wrong?
Sub BoQtoWord()
Dim Word As Object
Dim WordDoc As Object
Dim WordDoc1 As Object
Dim StdSpec As String
Dim NewSpec As String
StdSpec = Application.GetOpenFilename()
Set Word = CreateObject("Word.Application")
Set WordDoc = Word.Documents.Open(StdSpec)
Sheet1.Range ("A1").Value = StdSpec
NewSpec = Application.GetOpenFilename()
Set WordDoc1 = Word.Documents.Open(NewSpec)
Sheet1.Range("A2").Value = NewSpec
End Sub
It seems to works fine on my end, albeit a bit slow, at least as far as writing the file paths to cells A1 and A2 is concerned. Beyond that we'd need to see more of your code.
Depending on what you're trying to accomplish with the Word objects the OLE problems might stem from conflicts in your references, make sure you check what libraries you are referencing (Tools/References...) for any possible conflict.
Another possible conflict might be the use of the word "Word" as your variable name for the object. Word is also a key name when using the Microsoft Word library, try using a different name see if that helps at all.
Speaking of which, by adding the Microsoft Word library to your references you can skip the step to create the word object, you can directly create a word.document object instead, like this:
Sub BoQtoWord()
Dim WordDoc As Word.Document
Dim WordDoc1 As Word.Document
Dim StdSpec As String
Dim NewSpec As String
'Get first doc
StdSpec = Application.GetOpenFilename()
Set WordDoc = Documents.Open(StdSpec)
Sheet1.Range("A1").Value = StdSpec
'Get second doc
NewSpec = Application.GetOpenFilename()
Set WordDoc1 = Documents.Open(NewSpec)
Sheet1.Range("A2").Value = NewSpec
'Do something with the documents opened
End Sub
Maybe that would solve your OLE problems.
Hope this points you in the right direction, if anything, a bit more information might help narrow down the issue!

Write to Word template from Excel crushes on the second run

When I open Workbook and run this code everything is fine. Also if I close Workbook and open it again and run this code everything if functioning. However if I open Workbook and try to run this code for the second time then all Word operations are crushing. Word template is opened by code and even is saved to needed destination but it is not able to close Word document and gives an error:
Is there some variable or something in Windows memory still present after code has been executed because after closing and reopening Workbook everything works fine. Any ideas how to fix this?
Sub opentemplateWordOL()
Dim sh As Shape
Dim objWord As Object, objNewDoc As Object ''Word.Document
Dim objOL As OLEObject
Dim wSystem As Worksheet
'Application.ScreenUpdating = False
Set wSystem = ThisWorkbook.Sheets("Templates")
''The shape holding the object from 'Create from file'
''Object 2 is the name of the shape
Set sh = wSystem.Shapes("OfferLetterTemplate")
''The OLE Object contained
Set objOL = sh.OLEFormat.Object
'Instead of activating in-place, open in Word
objOL.Verb xlOpen
'Set objWord = objOL.Object 'The Word document
Set objNewDoc = objOL.Object
Set objWord = objNewDoc.Application
Dim objUndo As Object 'Word.UndoRecord
'Be able to undo all editing performed by the macro in one step
Set objUndo = objWord.UndoRecord
objUndo.StartCustomRecord "Edit In Word"
With objNewDoc
'Cover page
.Bookmarks("CoverPageTitle").Range.Text = ThisWorkbook.Sheets("Sheet1").Range("B2").Value
objNewDoc.SaveAs2 Environ$("Temp") & "\" & _
"MyFile" & ".docx"
objUndo.EndCustomRecord
objNewDoc.Undo
.Application.Quit False
End With
Set objWord = Nothing
Set objUndo = Nothing
Set sh = Nothing
Set wSystem = Nothing
Set objNewDoc = Nothing
'Application.ScreenUpdating = True
End Sub
You can check how this behaves on my computer here: https://streamable.com/2xd8k
You can see (by time of creation of file) that it is getting overwritten every time even when there is an error.

Macro using Documents.Open doesn't return a Document, but a String.

I want to open and read paragraphs of a Word document from an Excel macro. Here's the sample code that confuses me:
Sub example()
Dim docPath
docPath = "C:\temp\test.docx"
Dim wordApp
Set wordApp = CreateObject("Word.Application")
Dim doc
doc = wordApp.Documents.Open(docPath)
MsgBox (TypeName(doc)) 'This line displays String. According to the documentation it should be a Document.
End Sub
According to the documentation the Documents.Open method should return a Document that you can operate on. But when I check the type it says it has returned a String. Obviously I can't loop through the paragraphs of a string:
https://msdn.microsoft.com/en-us/vba/word-vba/articles/documents-open-method-word
Is the documentation wrong? Am I doing something wrong? More importantly, how do I loop through the paragraphs of a Word document from an Excel macro?
I'm using Office 365 if that matters and I have created a small Word document at C:\temp\test.docx.
try:
Set doc = wordApp.Documents.Open(docPath)
The String you are getting is some property of the Object you have created; might be the Name of the Object.................insert MsgBox doc to see what it is.
Although basically what is missing is a 'Set Doc = ...' you are guaranteed to get into trouble with a code like that. To prevent that some suggestions and a starter code (your code really, a little bit modified):
Add Word object reference from Tools\References and "type" your objects. Typing them would make it much easier to write code with intellisense support.
Never ever let the word object hang out there. Get rid of it when you are done.
Sample:
Dim docPath
docPath = "C:\temp\test.docx"
Dim wordApp As Word.Application
Set wordApp = CreateObject("Word.Application")
Dim doc As Word.Document
Set doc = wordApp.Documents.Open(docPath)
For i = 1 To doc.Paragraphs.Count
Cells(i, 1) = doc.Paragraphs(i).Range.Words.Count
Cells(i, 2) = doc.Paragraphs(i)
Next
wordApp.Quit
Set doc = Nothing
Set wordApp = Nothing

Access VBA: working with an existing excel workbook (Run-Time error 9, if file is already open)

I'm writing a macro in Access that (hopefully) will:
create an Excel worksheet
set up and format it based on information in the Access database
after user input, will feed entered data into an existing Excel master file
Opening the blank sheet etc. is working absolutely fine, but I'm stuck trying to set the existing master file up as a variable:
Sub XLData_EnterSurvey()
Dim appXL As Excel.Application
Dim wbXLnew, wbXLcore As Excel.Workbook
Dim wsXL As Excel.Worksheet
Dim wbXLname As String
Set appXL = CreateObject("Excel.Application")
appXL.Visible = True
wbXLname = "G:\[*full reference to file*].xlsm"
IsWBOpen = fnIsWBOpen(wbXLname)
'separate function (Boolean), using 'attempt to open file and lock it' method
'from Microsoft site.
If IsWBOpen = False Then
Set wbXLcore = appXL.Workbooks.Open(wbXLname, True, False)
'open file and set as variable.
ElseIf IsWBOpen = True Then
wbXLcore = appXL.Workbooks("ResultsOverall.xlsm") 'ERROR HERE.
'file is already open, so just set as variable.
End If
Debug.Print wbXLcore.Name
Debug.Print IsWBOpen
Set appXL = Nothing
End Sub
When the file is closed, this works perfectly. However, when it's open I get:
Run-Time error '9':
Subscript out of range
I'm only just starting to teach myself VBA (very trial and error!) and nothing else I've seen in answers here / Google quite seems to fit the problem, so I'm a bit lost...
Considering that it works fine when the file is closed, I suspect I've just made some silly error in referring to the file - perhaps something to do with the 'createobject' bit and different excel instances??
Any suggestions would be much appreciated! Thanks
Thank you #StevenWalker
Here's the working code:
Sub XLData_EnterSurvey()
Dim appXL As Excel.Application
Dim wbXLnew As Excel.Workbook, wbXLcore As Excel.Workbook
Dim wsXL As Excel.Worksheet
On Error GoTo Handler
Set appXL = GetObject(, "Excel.Application")
appXL.Visible = True
Dim wbXLname As String
wbXLname = "G:\ [...] .xlsm"
IsWBOpen = fnIsWBOpen(wbXLname)
If IsWBOpen = False Then
Set wbXLcore = appXL.Workbooks.Open(wbXLname, True, False)
ElseIf IsWBOpen = True Then
Set wbXLcore = appXL.Workbooks("ResultsOverall.xlsm")
End If
Set appXL = Nothing
'-------------------Error handling------------------
Exit Sub
' For if excel is not yet open.
Handler:
Set appXL = CreateObject("Excel.Application")
Err.Clear
Resume Next
End Sub
Sorry I'm on my phone so I can't go in to too much detail or do much with the code but at a glance I think you might need to add an error handler so that if the file is already open, a different line of code is executed.
Add 'On error go to handler' (before creating the excel object) and at the bottom
Of your code add 'handler:'. In the error handler, use get object rather than create object.
You will have to ensure you use exit sub before the error handler or it will run the handler every time you run the code.
You can see an example of what I mean here: How to insert chart or graph into body of Outlook mail
Although please note in this example it's the other way round (if error 'getting' outlook, then create it).
Example in link:
Set myOutlook = GetObject(, "Outlook.Application")
Set myMessage = myOutlook.CreateItem(olMailItem)
rest of code here
Exit Sub
'If Outlook is not open, open it
Handler:
Set myOutlook = CreateObject("Outlook.Application")
Err.Clear
Resume Next
End sub
If you move the appXL.Workbooks statement to the debugging window, you will find that the names of the items in that collection are without extension.
So in your case, I'm guessing the line should read:
wbXLcore = appXL.Workbooks("ResultsOverall")

I can't close the Excel application

I have this code I wrote in VBScript for wincc, and after running it the Excel application is still running, and the project is not working properly after this script. What can I do to close the Excel app?
Here is the script:
Dim fso
Dim rowcount
Dim ExcelObject
Dim WorkbookObject
Dim file
Dim i
Dim tg
Dim objSheet1
Dim objSheet2
'Set Object
Set fso = CreateObject("Scripting.FileSystemObject")
Set ExcelObject = CreateObject("Excel.Application")
file="C:\Parametri\Codificari.xls"
Set WorkbookObject = ExcelObject.Workbooks.Open(file)
'Set objSheet1 = WorkbookObject.Worksheets(1)
Set objSheet2 = WorkbookObject.Worksheets(2)
objSheet2.Cells(1,1)=SmartTags("locatie_defect")
If (fso.FileExists(file)) Then
'Raw numbering in Excel
rowcount = objSheet2.UsedRange.Rows.count
For i=3 To rowcount
tg="defect_"&i-2
SmartTags(tg)=objSheet2.Cells(i,2)
Next
End If
On Error Resume Next
'Save and close excel
ExcelObject.DisplayAlerts = False
ExcelObject.Workbooks.Close False
ExcelObject.Workbooks.Save
ExcelObject.Quit
On Error Resume Next
The standard way to close (sans error handling)
WorkbookObject.Save
WorkbookObject.Close False
ExcelObject.Quit
Set WorkbookObject= Nothing
Set ExcelObject = Nothing
Ensure all references are fully qualified, see here. On a quick look-over this doesnt jump out from your code.
For some reason Excel doesn't follow COM rules when used as an app object. No doubt for some compatibility reason.
It does follow COM rules as a doc object.
So Set WorkbookObject = GetObject("C:\Parametri\Codificari.xls") and now when it goes out of scope it will close as long as it's not visible. So just save it and it will close when your script ends. You probably only need half the lines you have.

Resources