PDA

View Full Version : Solved: to close one particular word doc, between many open, using vba inside access



silvkhan
09-23-2012, 03:01 PM
by vba, inside access, my program generates automatically some doc words and save them with a pathname. Each time I generate a particular word doc,which must get a name, i want to close the like doc if it is opened owing a previous generation. The clerkman using this software could have also other word doc open, so it is important choosing the right doc to close. I tried word.documents(pathname), but without success. so i tried
If FileLocked(strDocName) Then

' If the function returns true i close the doc
Set docdachiudere = Word.Application.Documents(1)
docdachiudere.Close SaveChanges:=wdDoNotSaveChanges
Word.Application.Quit
Set docdachiudere = Nothing
End If
First time ok, second time the usual error runtime 462. But i don't understand which object reference i missed on the bold instruction.
Thanks very much for your help.
Bye Silvano

fumei
09-23-2012, 03:29 PM
Not sure what you mean by inside access, but there are two ways to identify a document in the documents collection (i.e. the documents that are open).

By index number in the documents collection - Documents(1), Documents(4) etc.

By name.

silvkhan
09-24-2012, 03:28 AM
Thank you very much. My project is an application written in vba language in ms access 2010. the main form is open in access and there are some command buttons which execute vba instructions. The objective is to generate some word docs by operations of copy and paste starting from other word docs. It is all Ok. But when i save these new generated docs, i leave them open to allow the reading and editing by the clerks using them. I must control by software If they, without closing these docs, again execute the button commands of generations. That is the question. When the instructions:---> set docdachiudere=Word.application.Documents(1)
is executed the second time, i get the runtime error 462. I don't understand how i must change this instruction to kill the error.
Thanks very much
Silvano

Frosty
09-24-2012, 09:33 AM
Silvano,

The snippet of code you show is quitting the word application as well as closing the document. Are you launching the Word application at some other spot?

If you are going to make the *large* assumption that the first document ("Documents(1)") open in Word is the one you want, then it makes sense that you launch the application, open the document, do stuff with the document, then close the document, then quit the application.
But if you aren't doing all of that every single time, then you need to refer to your document in another way (you can use Documents("MyDocumentName") or you might be able to try using ActiveDocument.

But you're not defining your problem well enough, yet.

fumei
09-24-2012, 11:17 AM
Documents(1) refers to the first document in the Collection.

If I understand correctly (and I may not), your question is this:

The userform creates documents (via clicking a commandbutton). Once the button is clicked, and the document created, you want to prevent the SAME document being created if the user clicks the button a second time.

One solution is to close the userform. No userform, no click is is possible.

Regarding the 462 error, perhaps look at this:

http://anictteacher.files.wordpress.com/2011/11/vba-error-462-explained-and-resolved.pdf

silvkhan
09-24-2012, 12:41 PM
Thank you. Yes, you understand correctly, but the question is more complex. The user can exit the form leqaving the word doc open, she can open an other form to update some detail on the generation of the document and again coming back to the previous form to generate the doc with the same name. This scenario can happen, It is correct. If this happens, my procedure must close the old open document, delete the old file on the folder, open the update document and saveas with name the new version; the first time is Ok; the second time i get the error 462. Now im studying the material of the link.
Thank you very much.
Bye Silvano

this is part of the code
Dim docdachiudere As Word.Document



' per sapere la cartella dalla quale è stato aperto microsoft access, ossia il programma che gira
' in questo momento uso CurrentProject.Path
radice = CurrentProject.Path

'preparo il pathname relativo per salvare il menù.
strDocName = radice & "\menucircolari\" & "menu" & rst![numero] & ".doc"
nome = "menu" & rst![numero] & ".doc"
'controllo se il documento è aperto, in questo caso lo chiudo.
If FileLocked(strDocName) Then
' Debug.Print Word.Documents.Count
' If the function returns true chiudo il documento
Set docdachiudere = Word.Application.Documents(1)
'Debug.Print Word.Application.Documents(1)
'Debug.Print Word.Application.Documents.Count




docdachiudere.Close SaveChanges:=wdDoNotSaveChanges
Word.Application.Quit


Set docdachiudere = Nothing



End If
'controllo se il documento esiste nella cartella e in questo caso lo elimino e salvo il documento generato
If File_Exists(strDocName) = True Then
'elimino il file doc
Kill strDocName
End If
'lo salvo
doc1.ActiveDocument.SaveAs2 FileName:=strDocName, FileFormat:=wdFormatDocument

'------ fine del salvataggio del documento -------------------------------------------------------

fumei
09-24-2012, 01:41 PM
So let's see if I understand a possible scenario:

1. the userform generates a new document.
2. the userforms is closed.
3. the users decides, oh, I need something different.
4. the userform is opened again.
5. the userform generates a new document...BUT

6. you want to close and delete the existing generated document FIRST,
7. and then generate a new one with the same name.

In other words, before the userform does anything, it must check to see if its result has already happened.

Yes?

silvkhan
09-25-2012, 06:25 AM
Yes this is the scenario.
thank you very much
bye Silvano

silvkhan
09-26-2012, 06:59 AM
hi,
First of all My application from which i code vba is "ms access 2010".
I don't succeed to solve my problem.
And there are some basic things i don't understand.
For example:
1) I have 5 word documents all open and all generated by vba
2) in debug mode : Debug.Print Word.Application.Documents.Count
return 1. not five ! Why ?
3) which is the vba instruction to list all word documents open ?
4) Word.Application.Documents is not the collection of all open word documents ?

Thank you very much
bye Silvano

Frosty
09-26-2012, 07:06 AM
Check your task manager. You probably have 5 winword.exe processes.

You may need to look into GetObject. I suspect you are creating a new instance of word each time you create a new document. Word.Application is just going to find any available word process.

I already asked this-- but how are you launching word from your access VBA?

silvkhan
09-26-2012, 08:13 AM
Hi Frosty,
I do what you suspect. I launch word at this way:
Dim doc1 As Word.Application
Dim doc As Word.Document
Set doc1 = CreateObject("Word.Application")
Set doc = doc1.Documents.Add
-That code is executed each time the user enter the form and press the command button.
-In my task manager i see 5 instances of word in execution, when i have the five documents open, generated by my code.
- when the user exit the form i don't close the document for she must edit that doc. But must i do some cleaning operations with the local variables doc, doc1? I don't set them to nothing when exit the sub procedure.
- I get more instances of the word application for the following reason: the user, after editing the doc, could not close it (doing a mistake) (but i must control by program the user error). So i choose to close the previous open doc if it were not closed, before generating the new one. When my procedure will be Ok, it must be one and only one doc open each time with the same name.
- which way can i list the different instances of word application open ?

Thank you very much
bye Silvano

Frosty
09-26-2012, 09:05 AM
Well, first off-- don't create multiple instances of Word. This is unnecessary. Instead, use GetObject to get the instance that is already open. Something like...


Sub DemoGet2DocumentsAndAnApplicationObject
Dim oWord As Word.Application
Dim oDoc1 As Word.Document
Dim oDoc2 As Word.Document

'attempt to get an existing process
On Error Resume Next
Set oWord = GetObject(, "Word.Application")
If Err.Number <> 0 Then
Set oWord = CreateObject("Word.Application")
End If
On Error GoTo 0

Set oDoc1 = oWord.Documents.Add
Set oDoc2 = oWord.Documents.Add
End Sub

Can you incorporate that methodology somehow?

silvkhan
09-26-2012, 10:04 AM
Solved, solved, thank you thank you very much
Hi Frosty, I have incorporated this metodology. Good idea.
- Now I see in my task manager only one process with two documents opened and the method Word.Application.Documents.Count make his job well giving two. Ok.
- When i go to close the old document with the code:
Word.Application.Documents(nome).Close SaveChanges:=wdDoNotSaveChanges
I got again the runtime error 462. But this time my brain with the light of your lesson let me change that code into doc1.Application.Documents(nome).Close SaveChanges:=wdDoNotSaveChanges
- and now it is perfect. It functions !!! The users can forget to close the doc each time she wants but the program always close the old doc . Good You are an angel.
:hi::beerchug::beerchug:

Frosty
09-26-2012, 10:46 AM
I think oDoc1.Close should work instead of oDoc1.Application.Documents(oDoc1.Name).Close.

You don't need to use a document object to access the parent .Application property to access the .Documents collection just to close the document.

silvkhan
10-03-2012, 01:01 PM
Hi
please can you help me on my new question i asked on the post:
http://www.vbaexpress.com/forum/showthread.php?t=43837
bye Silvano

Frosty
10-03-2012, 01:14 PM
I'm not sure why you posted your question in the VBAX Issues section, which is related to problems with the forum. I'm not an administrator, but I think you need to get that post moved so others will also get a look at it.

Once it is moved (or reposted to the right section), I (or someone else) can take a look at it. But I don't want to post to that thread until it is moved, or I am encouraging "bad" posting behavior.