Checking if word file is already open vba - excel

Before opening a Word file, I want to check if this file is already open. (More word files are open at the same time)
The main sub calls this function to tell me if it's open or not.
Function FileInWdOpen(DokName As String) As Boolean
Dim wd As Word.Application
Dim wDoc As Word.Document
On Error Resume Next
Set wd = GetObject(, "Word.Application")
On Error GoTo NO_WORD_FOUND
If wd Is Nothing Then
FileInWdOpen = False
End If
For Each wDoc In wd.Documents 'should check for every open word file but doesn't do that
If wDoc.Name = DokName Then 'checks if this file is named like the one I want to check if its open or not
FileInWdOpen = True
Exit Function
End If
Next
FileInWdOpen = False
Exit Function
NO_WORD_FOUND:
FileInWdOpen = False
End Function
This code works out well when only one word file is open. If two or more files are open, the script don't work.
The problem is that the for loop only checks the first file that is open.
I don't understand why it don't check all open files.
I thought it's possible to access all Documents with:
Dim WordApp As Word.Application 'sets an var for the Word Application
Set WordApp = GetObject(, "Word.Application") 'give the var an obj, in this case the Word Application
Dim WordDoc As Word.Document 'sets an var for the singel Word Documents
For Each WordDoc In WordApp.Documents 'for each Document in Dokuments
'code
Next
So why only the first document gets attention?

this one works - finally, took me hours to find the solution. But I still miss an answer to following problem:
Users in my network are opening Word-Files from Server - how can I find out in VBA which User opened (and keeps ist open)?
Function FileInWordOpen(DokName As String) As Boolean
Dim wd As Word.Application
Dim wDoc As Word.Document
Dim i As Long, s As String
On Error Resume Next
Set wd = GetObject(, "Word.Application")
On Error GoTo NO_WORD_FOUND
If wd Is Nothing Then
FileInWordOpen = False
End If
For i = 1 To wd.Documents.Count
s = wd.Documents(i)
If InStr(DokName, s) <> 0 Then
FileInWordOpen = True
Exit Function
End If
Next
'For Each wDoc In wd.Documents 'should check for every open word file but doesn't do that
' If wDoc.Name = DokName Then 'checks if this file is named like the one I want to check if its open or not
' FileInWdOpen = True
' Exit Function
' End If
'Next
NO_WORD_FOUND:
FileInWordOpen = False
End Function
Function GetOpenWordDoc(DokName As String) As Word.Document
Dim wd As Word.Application
Dim wDoc As Word.Document
Dim i As Long, s As String
On Error Resume Next
Set wd = GetObject(, "Word.Application")
On Error GoTo NO_WORD_FOUND
If wd Is Nothing Then
Set GetOpenWordDoc = Nothing
End If
For i = 1 To wd.Documents.Count
s = wd.Documents(i)
If InStr(DokName, s) <> 0 Then
Set GetOpenWordDoc = wd.Documents(i)
Exit Function
End If
Next
NO_WORD_FOUND:
Set GetOpenWordDoc = Nothing
End Function

Related

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

VBA Closing a word document which has already been opened using another sub, bad file name error

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")

How to correctly get the position of the cursor in Word using VBA?

I am trying to write a program in VBA which writes some text to a Word document, what I want to happen is when the text gets to a certain distance from the left side of the document it prints out the remaining characters up to the next full stop and then starts a new line and a tab for every character in the string. This is an example of what should happen:
The code I have below works correctly on the first page of word but on additional pages it starts to print out randomly and the value given from objSelection.range.Information(WdInformation.wdHorizontalPositionRelativeToPage) seems to be the cause the issue.
An example of the incorrect output printed to word:
A few things I have noticed while trying to work out this issue:
If I set a break point and step through the code one line at a time everything works fine and the correct output is printed every time.
If I have the word app set to not be visible from the start it fails every time after the first page
If I have the word app set as visible it runs correctly on every page until I click somewhere on the screen outside of the word application.
This is the code I have:
Sub print_to_word()
'**** SETTING UP WORD *****
Dim wordApp As Word.Application
On Error Resume Next
Set wordApp = GetObject(, "Word.Application")
If wordApp Is Nothing Then 'if word is not open then open it
Set wordApp = CreateObject("Word.Application")
End If
On Error GoTo 0 'reset error warnings
Dim objdoc As Document
Set objdoc = wordApp.Documents.Add 'Create a new word document
Dim objSelection As Selection
Set objSelection = wordApp.Selection 'Selection used to write text
wordApp.Visible = True
Dim wirecodes As String
wirecodes = "114.114*.98.98*.99.99*.123.123*.92*.92**.92.114.114*.98.98*.99.99*.123.123*.92*.92**.92.114.114*.98.98*.99.99*.123.123*.92*.92**.92.114.114*.98.98*.99.99*.123.123*.92*.92**.92.114.114*.98.98*.99.99*.123.123*.92*.92**.92.114.114*.98.98*.99.99*.123.123*.92*.92**.92.114.114*.98.98*.99.99*.123.123*.92*.92**.92.114.114*.98.98*.99.99*.123.123*.92*.92**.92"
For x = 1 To 5 'print 5 lots of wirecodes
Dim pos As Integer
objSelection.TypeText (Chr(9)) 'tab
For i = 1 To Len(wirecodes) 'loop through each character
pos = objSelection.range.Information(WdInformation.wdHorizontalPositionRelativeToPage)
If i <> 1 And pos > 215 Then 'if the cursor is past 215 then
Do While Mid(wirecodes, i - 1, 1) <> "." And i <> Len(wirecodes) + 1 'print out the remaining wirecode before starting a new line
objSelection.TypeText (Mid(wirecodes, i, 1))
i = i + 1
Loop
If i < Len(wirecodes) Then 'if its not the last wirecode print a newline and tab
objSelection.TypeText (Chr(11) + Chr(9))
End If
End If
objSelection.TypeText (Mid(wirecodes, i, 1)) 'just print the character
Next
objSelection.TypeText (Chr(10)) 'new line
Next
'close word
objdoc.Close
Set objdoc = Nothing
wordApp.Quit 'close word
Set wordApp = Nothing
End Sub
I'm using Microsoft office 2010 on Windows 10 any help would be greatly appreciated.
If you simply input the text into the document, then use the following wildcard Find/Replace:
Find = <[0-9.\*]{1,19}[!.]#.
Replace = ^&^l
(which can be implemented in code) you'll get:
114.114*.98.98*.99.99*.
123.123*.92*.92**.92.
114.114*.98.98*.99.99*.
123.123*.92*.92**.92.
114.114*.98.98*.99.99*.
123.123*.92*.92**.92.
114.114*.98.98*.99.99*.
123.123*.92*.92**.92.
114.114*.98.98*.99.99*.
123.123*.92*.92**.92.
114.114*.98.98*.99.99*.
123.123*.92*.92**.92.
114.114*.98.98*.99.99*.
123.123*.92*.92**.92.
114.114*.98.98*.99.99*.
123.123*.92*.92**.92
Is that good enough?
It's not apparent what the tab is for, but even that can be incorporated, via:
Find = <[0-9.\*]{1,19}[!.]#.
Replace = ^&^l^t
or:
Find = <[0-9.\*]{1,19}[!.]#.
Replace = ^t^&^l
Try:
Sub Print_to_Word()
Dim wdApp As Word.Application, wdDoc As Word.Document, bNew As Boolean, wirecodes As String, i As Long
wirecodes = "114.114*.98.98*.99.99*.123.123*.92*.92**.92.114.114*.98.98*.99.99*.123.123*.92*.92**.92.114.114*.98.98*.99.99*.123.123*.92*.92**.92.114.114*.98.98*.99.99*.123.123*.92*.92**.92.114.114*.98.98*.99.99*.123.123*.92*.92**.92.114.114*.98.98*.99.99*.123.123*.92*.92**.92.114.114*.98.98*.99.99*.123.123*.92*.92**.92.114.114*.98.98*.99.99*.123.123*.92*.92**.92"
bNew = False
On Error Resume Next
Set wdApp = GetObject(, "Word.Application")
'If Word is not open then open it
If wdApp Is Nothing Then
Set wdApp = CreateObject("Word.Application")
bNew = True
End If
On Error GoTo 0 'reset error warnings
With wdApp
'Hide Word if we started it
If bNew = True Then .Visible = False
'Turn off ScreenUpdating anyway
.ScreenUpdating = False
'Create a new word document
Set wdDoc = .Documents.Add
With wdDoc
With .Range
'Parse the data
.InsertBefore vbTab
For i = 0 To UBound(Split(wirecodes, "."))
.InsertAfter Split(wirecodes, ".")(i) & "."
If .Characters.Last.Information(wdHorizontalPositionRelativeToPage) > 215 Then
.InsertAfter Chr(11) & vbTab
End If
Next
End With
'Print & close
.PrintOut Copies:=5
.Close False
End With
'Quit Word only if we started it
If bNew = True Then .Quit
End With
Set wdDoc = Nothing: Set wdApp = Nothing
End Sub

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")

Select Word Doc using Excel VBA

I want to create Excel VBA code that asks the user to open a pre-existing Word document with text form fields and input existing Excel data in these form fields.
I have code that writes the Excel data into the Word text form field.
Sub NewMacro()
Dim wdApp As Object, wd As Object, ac As Long, ws As Worksheet
Set ws = Sheets("Tables")
On Error Resume Next
Set wdApp = GetObject(, "Word.Application")
If Err.Number <> 0 Then
Set wdApp = CreateObject("Word.Application")
End If
On Error GoTo 0
Set wd = wdApp.Documents.Open("C:\Test\Test.docx")
wdApp.Visible = True
With wd
.FormFields("CustomerName").Result = ws.Range("D4").Value
End With
Set wd = Nothing
Set wdApp = Nothing
End Sub
I am lost as to converting the Set wd= wdApp.Documents.Open("FilePath") line into a dialog box.
Does a function exist where the user can select the file by clicking through Windows Explorer as opposed to typing the path?
Do you want the user to input the name of a Word file? Do you want the InputBox method?
Dim strWord As String
strWord = InputBox(prompt:="Type the file path and name of the Word file.", title:="Which file?", default:="C:\Path\File.docx")
Set wd = wdApp.Documents.Open(strWord)
Tell me if I didn't understand your question.

Resources