Excel VBA Run Time error the second times - excel

Can anyone say me why the second time I run the macro I receive a runtime error?
Dim wApp as Object
Dim wDoc as Object
Set wApp = CreateObject("word.Application")
Set wDoc = wApp.Documents.Add(Template:="Test.dotm", Visible:=True)
On Microsoft support:
"Visual Basic has established a reference to Word due to a line of code that calls a Word object, method, or property without qualifying it with a Word object variable. Visual Basic does not release this reference until you end the program. This errant reference interferes with automation code when the code is run more than once."
I don't see any unqualified object or method or property in my code.

I think it's likely that MS Word is already running. So here are a couple of routines from my library to check if MS Word is already running or not, and to make a connection to the process.
Option Explicit
Public Function MSWordIsRunning() As Boolean
'--- quick check to see if an instance of MS Word is running
Dim msApp As Object
On Error Resume Next
Set msApp = GetObject(, "Word.Application")
If Err > 0 Then
'--- not running
MSWordIsRunning = False
Else
'--- running
MSWordIsRunning = True
End If
End Function
Public Function AttachToMSWordApplication() As Word.Application
'--- finds an existing and running instance of MS Word, or starts
' the application if one is not already running
Dim msApp As Word.Application
On Error Resume Next
Set msApp = GetObject(, "Word.Application")
If Err > 0 Then
'--- we have to start one
' an exception will be raised if the application is not installed
Set msApp = CreateObject("Word.Application")
End If
Set AttachToMSWordApplication = msApp
End Function

Related

open excel file without creating new instance

i've looked up all topics regarding this and still can't find solution.
My main issue is that any time I'm opening excel file from my application it gets opened in new instance. What i want - detect if there's running excel, if there is - use this instance, if not - create new one.
This is not working:
Dim xlsApp As Object
Dim AllExcelProcess() As Process = System.Diagnostics.Process.GetProcessesByName("Excel")
If AllExcelProcess.Length = 0 Then xlsApp = New Excel.Application Else xlsApp = GetObject(, "Excel.Application")
AllExcelProcess works correctly returning that there's running excel application, yet the GetObject always returns nothing. What am I doing wrong?
This works for me from within Word and an excel instance already open. Microsoft 365.
Sub main()
On Error Resume Next
Set excelapp = GetObject(class:="Excel.Application")
'Clear the error between errors
Err.Clear
If excelapp Is Nothing Then Set excelapp = CreateObject(class:="Excel.Application")
If Err.Number = 429 Then
MsgBox "Excel could not be found, aborting."
Exit Sub
End If
On Error GoTo 0
excelapp.Workbooks("Book2").sheets("Sheet1").Range("j2").Value = 2
End Sub
Easier way to do what I wanted:
On Error Resume Next
Dim xlsApp As Object = GetObject(, "Excel.Application")
On Error GoTo 0
If xlsApp Is Nothing Then xlsApp = New Excel.Application
I had 2 issues you might want to check out:
You have Microsoft Excel library loaded under References. If you can't find it, add existing EXCEL.EXE to it
If still not working, try GetObject on other objects, can VS detect their classes or not. In my case it was not working at all
Solution:
I added MS Excel library, created new solution. GetObject started working there, everything further was easy using above code.

How to check if a Word file is open from Excel VBA?

I searched for the exact term in Google, it spits out multiple results.
I tried al least 4-5 of them.
None works. It is either all TRUE or all FALSE depending on the function, but it is never correct.
In addition to not understanding how those functions are supposed to work (which would be a secondary endpoint) I would be really grateful if someone could lead me to primary endpoint (which is checking if a Word document is open from Excel VBA)?
Thanks
Is Word File Open?
A Word file cannot be open (in Word) if the Word application is not open.
So first check if Word is open, then check if the file is open.
Is Word open?
Function IsWordOpen() As Boolean
Dim wdApp As Object
' Attempt to reference the word application.
On Error Resume Next
Set wdApp = GetObject(, "Word.Application")
On Error GoTo 0
IsWordOpen = Not wdApp Is Nothing
End Function
Sub IsWordOpenTEST()
Debug.Print IsWordOpen
End Sub
Reference Word
Function RefWord() As Object
Dim wdApp As Object
' Attempt to reference the word application.
On Error Resume Next
Set wdApp = GetObject(, "Word.Application")
On Error GoTo 0
If Not wdApp Is Nothing Then Set RefWord = wdApp
End Function
Sub RefWordTEST()
' Reference the word application.
Dim wdApp As Object: Set wdApp = RefWord
If wdApp Is Nothing Then
MsgBox "Word is not open", vbExclamation
Exit Sub
End If
' Print the names of open files.
Dim wdDoc As Object
For Each wdDoc In wdApp.Documents
Debug.Print wdDoc.Name
Next wdDoc
End Sub
Is Word file open?
' Uses the RefWord function.
Function IsWordFileOpen( _
ByVal WordFileName As String) _
As Boolean
Dim wdApp As Object: Set wdApp = RefWord
If wdApp Is Nothing Then Exit Function
Dim wdDoc As Object
On Error Resume Next
' Attempt to reference the word document.
Set wdDoc = wdApp.Documents(WordFileName)
On Error GoTo 0
IsWordFileOpen = Not wdDoc Is Nothing
End Function
Sub IsWordFileOpenTEST()
Debug.Print IsWordFileOpen("Test.docx")
End Sub
Is Word file open (stand-alone)?
Why did I post all those procedures above?
When you run the following, if the result is True then you know the following:
Word is open,
a file named Test.docx is open.
What you don't know is whether it is the correct file or another with the same name.
If the result is False, it gets even worse i.e. then you don't know the following:
whether Word is open, or not
whether there is another instance of Word where the file is open, or not
whether another application has locked the file, or not...
To conclude, depending on what you plan to do with this information, you will have to decide what to check i.e. be careful, this is just a basic approach.
' Stand-Alone
Function IsWordFileOpenCompact( _
ByVal WordFileName As String) _
As Boolean
Dim wdApp As Object
' Attempt to reference the word application.
On Error Resume Next
Set wdApp = GetObject(, "Word.Application")
On Error GoTo 0
If wdApp Is Nothing Then Exit Function
Dim wdDoc As Object
On Error Resume Next
' Attempt to reference the word document.
Set wdDoc = wdApp.Documents(WordFileName)
On Error GoTo 0
IsWordFileOpenCompact = Not wdDoc Is Nothing
End Function
Sub IsWordFileOpenCompactTEST()
Debug.Print IsWordFileOpenCompact("Test.docx")
End Sub

Delete all comments of Wordfile

so I'm trying to delete all comments in a Wordfile per VBA-Code of an Excelfile.
I've tried using
'Dim ObjWord as Word.Application
ObjWord.ActiveDocument.DeleteAllComments
and calling
Sub RemoveAllComments(Doc As Document)
Dim n As Long
Dim oComments As Comments
Set oComments = Doc.Comments
For n = oComments.Count To 1 Step -1
oComments(n).Delete
Next
Set oComments = Nothing
End Sub
but the first gave me the run-time 'error 4605 command not available' and the second code segment throws an 'error 438 object doesn't support this property or method'.
Is there any other way I could do it?
Edit 1:
Dim ObjWord As Word.Application
Set ObjWord = LoadWord()
ObjWord.Visible = True
is in the Function and it calls LoadWord():
Function LoadWord() As Word.Application
Set LoadWord = GetObject(, "Word.Application")
If MsgBox("Word's already in use klick ok to dismiss all changes", vbOKCancel) = vbCancel Then
Set LoadWord = Nothing
End If
Exit Function
End Function
Error 4605 with:
ObjWord.ActiveDocument.DeleteAllComments
indicates the ActiveDocument (if there is one) contains no comments. Since you haven't posted any code relating to how the ActiveDocument (or Doc, in your second sub) is instantiated, or whether you've established that the document concerned even contains any comments, it is impossible to give further advice in that regard.
Furthermore, this:
Sub RemoveAllComments(Doc As Document)
would be invalid. At the very least it would need to be:
Sub RemoveAllComments(Doc As ObjWord.Document)
For the first example, the situation can be remedied with nothing more complicated than:
On Error Resume Next
ObjWord.ActiveDocument.DeleteAllComments
On Error Goto 0

Writing from Excel, to Word Activex Text box

I have an Excel application which collects information via a form based interface. This is used to;
Fill values in the workbook
A procedure opens a Word document (template essentially) and names the file according to rules, based
on some of the input data. (Okay to this point)
The idea then, is to transfer collected information (from the Excel app driving this process) to
the same Word document opened and named.
Specifically, I intend to populate a number of uniquely named ActiveX textboxes with document.
*** This is where I fail miserably.
I have enabled the "Microsoft Word 16.0 Object Library" under references in the MSExcel VBA environment.
Given that I know the name/title of the content control (ActiveX textbox is a 'content control' isn't it?). The code below is a simplified example, if it works for the example I should be able to sort out the broader document:
Sub trial()
Dim Word As Word.Application
Dim wdDoc As Word.Document
On error resume next
Set Word = New Word.Application
Set wdDoc = Word.Documents.Open("G:\CAPS Management Tool\Customer.docm")
Word.Application.Visible = True
Dim cc As Object
Set cc = ActiveDocument.SelectContentControlsByTitle(txt_PersonName) 'txt_PersonName is the control name
cc.Range.Text = "SUCCESS" 'Run-time error 438
'Object does not support property or method
Set cc = ActiveDocument.SelectContentControlsByTitle(txt_Address) 'txt_Address is the control name
cc.Range.Text = "SUCCESS" 'Run-time error 438
'Object does not support property or method
End Sub
Anybody able to assist? There are a lot of text boxes in the Word document I wish to plug in to.
Thanks in advance.
OK, so I kept digging (I don't like accepting defeat) and found that my entire premise was wrong! ActiveX controls in Word are considered "InlineShapes" not "ContentControls". But the results I was reading in the internet searches had me confused (didn't claim to be the sharpest tool in the shed).
Once I realised this, some more digging provided the answer (see below).
So, first to list the 3 controls in my document (and their index) with the following Sub
Sub ListActiveXControls()
Dim i As Integer
i = 1
Do Until i > ActiveDocument.InlineShapes.Count
Debug.Print ActiveDocument.InlineShapes(i).OLEFormat.Object.Name & " Control Index = " & i
i = i + 1
Loop
End Sub
Now moving to EXCEL, I used the following:
Sub trial()
Dim Word As Word.Application
Dim wdDoc As Word.Document
Set Word = New Word.Application
Set wdDoc = Word.Documents.Open("G:\CAPS Management Tool\Customer.docm")
Word.Application.Visible = True
debug.print "ActiveDocument Name is : " & ActiveDocument.Name
' Result = Nothing
' Allowing the code to continue without the pause caused the operation to fail
Application.Wait (Now + TimeValue("0:00:10")) ' See text below, would not work without pause
wdDoc.Activate
' Begin set ActiveX control values. In this instance,
' The first line corresponds to 'Textbox1'
ActiveDocument.InlineShapes(1).OLEFormat.Object.Text = "Success"
' The second line corresponds to 'Textbox2'
ActiveDocument.InlineShapes(2).OLEFormat.Object.Text = "Success"
' The third line corresponds to 'ChkBox1'
ActiveDocument.InlineShapes(3).OLEFormat.Object.Value = True
End Sub
For some reason, without the 'Wait' command, the operation fails. Stepping through, if there is no pause, the ActiveDocument seems to be null, no idea why. It occurs with a document with 2 ActiveX controls or 165 ActiveX controls and the wait required seems to
be 10 secs on my PC. Incidentally, setting almost 150 control values was only seconds, once the wait period was completed.
If anyone knows why the 'Wait' is seemingly required, I'd be interested to know!
Here are a few tips to help you work this out.
Don't use On Error Resume Next unless you really need it. And then when you do use it, re-enable error catching with On Error Goto 0 as quickly as possible. Otherwise you'll miss many errors in your code and it will be hard to tell what's happening.
Don't use the name Word as a variable name. It is reserved for the Word.Application and will only confuse the compiler (and you).
The control titles are text strings, so you must enclose them in double-quotes.
I've thrown in a bonus Sub that gives you a quick method to either open a new Word application instance or attach to an existing application instance. You'll find that (especially during debugging) there will be dozens of Word exe's opened and running.
The example code below also breaks the assignment of your "SUCCESS" value to the control into a separate Sub. It's in this short Sub that using On Error Resume Next is appropriate -- and isolated from the rest of the logic -- limiting its scope.
Option Explicit
Sub trial()
Dim wdApp As Word.Application
Dim wdDoc As Word.Document
Set wdApp = AttachToMSWordApplication
Set wdDoc = wdApp.Documents.Open("C:\Temp\Customer.docm")
wdApp.Application.Visible = True
TextToControl wdDoc, "txt_PersonName", "SUCCESS"
TextToControl wdDoc, "txt_Address", "SUCCESS"
End Sub
Private Sub TextToControl(ByRef doc As Word.Document, _
ByVal title As String, _
ByVal value As String)
Dim cc As ContentControl
On Error Resume Next
Set cc = doc.SelectContentControlsByTitle(title).Item(1)
If Not cc Is Nothing Then
cc.Range.Text = value
Else
Debug.Print "ERROR: could not find control titled '" & title & "'"
'--- you could also raise an error here to be handled by the caller
End If
End Sub
Public Function AttachToMSWordApplication() As Word.Application
'--- finds an existing and running instance of MS Word, or starts
' the application if one is not already running
Dim msApp As Word.Application
On Error Resume Next
Set msApp = GetObject(, "Word.Application")
If Err > 0 Then
'--- we have to start one
' an exception will be raised if the application is not installed
Set msApp = CreateObject("Word.Application")
End If
Set AttachToMSWordApplication = msApp
End Function

Can't get reference to the existing instance of Word object from excel; runtime error 429

I have a script in excel which opens a certain MS Word file. Both Word and Excel object libraries are included. Here is the code of initializing an instance of Word:
Sub InitializeWord()
'Path for the upper-level folder
Dim RootPath As String
'Path for the destination of my document
Dim WordDocPath As String
RootPath = Left(ActiveWorkbook.Path, InStrRev(ActiveWorkbook.Path, "\"))
WordDocPath = RootPath & "Templates\" & "ÎÌÄ.docm"
'Try to get a reference to existing Word instance
On Error Resume Next
Set WordApp = GetObject(, Word.Application)
'If WordApp still references nothing - create a new instance of WordApp and open the document.
If WordApp Is Nothing Then
Set WordApp = CreateObject("Word.Application")
'word will be closed while running
WordApp.Visible = True
Set WordDoc = WordApp.Documents.Open(WordDocPath)
'Else search open documents for the file you need and reference it, if there's none - open it.
Else
Dim OpenedDoc As Object
For Each OpenedDoc In Word.Documents
If StrComp(OpenedDoc.FullName, WordDocPath, vbTextCompare) = 0 Then
Set WordDoc = OpenedDoc
Exit For
End If
Next OpenedDoc
If WordDoc Is Nothing Then
Set WordDoc = Word.Documents.Open(WordDocPath)
End If
End If
Set Headers = WordDoc.SelectContentControlsByTitle("DocHeader")(1)
WordApp.Visible = True
End Sub
The script correctly creates the instance of word when there is none, but when there is word app already opened during the runtime, the script fails to get the Word.Application Object and tries to open the document the second time. Disabling On Error Resume Next string gets Runtime Error "ActiveX component can't create object".
GetObject() expects a string value, not a reference, so add quotes to it:
Set WordApp = GetObject(, "Word.Application")

Resources