Word Automation Issue

Hi all. I figured out the following set of codes and variables that will allow me printing a word document without opening it from Navision: Nomin.GET(“Entry No.”); IF Nomin.“Doc. Specification Source” <> ‘’ THEN BEGIN CLEAR(MSWordApp); CREATE(MSWordApp,TRUE); MSWordApp.Documents.Open(Nomin.“Doc. Specification Source”); MSWordApp.Documents.Save; MSWordApp.PrintOut; END; Name DataType Subtype Length MSWordApp Automation ‘Microsoft Word 8.0 Object Library’.Application Nomin Record Nomination Notice that I didn’t use Word.Documents and Word.Document as part of the automation as the codes. The reason is I am getting error messages that I couldn’t assign a document to a document, while some other folks are able to assign a document to a document. So far, the only problem that I am facing is I don’t know how to quit Word application. Although the word application is closed through the whole process, it isn’t true. I discovered that by pressing alt + ctrl + del buttons, and notice that winword is running. Say, I run the printing job for 10 times, you can see 10 winword on the program list. I tried using this line of code as the last line of my set of codes: MSWordApp.quit; And guess what, it will pop up sort of like an error message in the middle of the printing process that says, ‘Word is currently printing a job. Quitting word will not let you print the document. Do you want to exit word?’ Anyway, that is why I told out this line of code. I even tried to set a boolean after the close line, which marks as the ending point of the print job, but still, it didn’t work out right. Is there anyway in the world I can quit winword after the printing is completely done without seeing the above annoying message? Thanks a lot in advance.

Hi, I had a similar problem with Excel. The Navision- code doesn’t wait for the automation! Perhaps you may enforce Navision to wait a while before closing Word with:


SLEEP(10000);
App.Quit;

Andre

Sylvia, The PrintOut method has a first parameter Background that specifies if execution of the macro should continue during printing or not. As a workaround (in case the parameter doesn’t work as expected), you could use CREATE(MSWordApp, FALSE); This will reuse an existing instance of Word, which will result in at most 2 winword.exe running instead of 10.

Hi

quote:


Originally posted by xorph … CREATE(MSWordApp, FALSE); This will reuse an existing instance of Word, which will result in at most 2 winword.exe running instead of 10. …


Hmm. [xx(] On a long and ‘painful’ way of testing I had to learn, it’s mostly better to create a new instance of automation. If a instance already exits and you use it, it could be that at the end of the code all open documents are closed. I don’t know why but if I have more then one file opened before starting the automation code and I want to close my automation file (Excel) the system tries to close all the other files (with Save Yes/No - Question) except 1 file. I think this is to hard to handle for a ‘normal’ user: ‘Why the system wants to close my open files?’. This is the reason why I use allways CREATE(App,TRUE) with App.Quit at the end. Andre

Take a look at codeunit 5054: // Wait for print job to finish IF wrdApp.BackgroundPrintingStatus <> 0 THEN REPEAT Window.UPDATE(6,Text007); SLEEP(500); UNTIL wrdApp.BackgroundPrintingStatus = 0; I didn’t test it myself, but I guess this should work. Wouter

quote:


Originally posted by Andre DDB
If a instance already exists and you use it, it could be that at the end of the code all open documents are closed.


Right. Thanks for pointing this out, Andre. If you reuse a running instance and call Quit at the end, everything is closed. This is a “trial-and-error” situation, sometimes it’s better to reuse a running instance, sometimes not, sometimes it depends on your users’ preferences… [:0] We use Automation quite extensively, and boy, have we seen everything under the sun! [xx(]

Special thanks to Andre: I finally got it working! This is the final version of my code that works: Nomin.GET(“Entry No.”); IF Nomin.“Doc. Specification Source” <> ‘’ THEN BEGIN CLEAR(MSWordApp); CREATE(MSWordApp,TRUE); MSWordApp.Documents.Open(Nomin.“Doc. Specification Source”); MSWordApp.Documents.Save; MSWordApp.PrintOut; SLEEP(10000); MSWordApp.Quit; END; I surely had learned alot about automation from this project. Thank you for the input, folks.

quote:


Originally posted by Woutervn
Take a look at codeunit 5054: …


I can’t take a look at CU 5054 [:(] ! I wonder why such helpful things are not available in the basic Attain! So- I have to invent the wheel once more! Andre

I wish CU 5054 can be found in NF 2.60, since my project is currently in this version. Isn’t it available in all the Attain versions? I just looked at Attain 3.01.

quote:


Originally posted by yummi
MSWordApp.PrintOut; SLEEP(10000); MSWordApp.Quit;


Sorry if this makes me sound like a smart-a**, but what if the print process takes longer than 10 secs? [:p] The loop construct posted by Wouter or the Background parameter of the PrintOut method make for a more stable program. Generally, putting the program to sleep for arbitrary amounts of time opens the door for hard to find runtime errors and race conditions [;)]

Good point, Xorph! I just added that loop suggested by Woutervn that can be found in CU 5054. It worked out just fine after the implementation: Nomin.GET(“Entry No.”); IF Nomin.“Doc. Specification Source” <> ‘’ THEN BEGIN CLEAR(MSWordApp); CREATE(MSWordApp,TRUE); MSWordApp.Documents.Open(Nomin.“Doc. Specification Source”); MSWordApp.Documents.Save; MSWordApp.PrintOut; IF MSWordApp.BackgroundPrintingStatus <> 0 THEN REPEAT SLEEP(500); UNTIL MSWordApp.BackgroundPrintingStatus = 0; MSWordApp.Quit; END; When you said putting the program to sleep for a certain period of time is not a good idea, so what is the sleep function for?

quote:


Originally posted by yummi
When you said putting the program to sleep for a certain period of time is not a good idea, so what is the sleep function for?


[:D] Good question. In your case above, 10 secs is a completely arbitrary period - you might as well have chosen 5, 13 or 29 seconds. A choice like this is generally guided by the “gut feeling” that “this process is most likely finished after xxx secs”. Experience teaches us that sometimes the process will take longer, especially when no one expects it to and everybody has long forgotten this 10 secs sleep period. [xx(] On the other side, it might be necessary to put the program to sleep for a defined period for whatever reasons (like performing a periodic task over and over again). In this case, a SLEEP is perfectly ok. Wouter’s code piece is another example of a correct and stable application: The program waits in a loop until a certain condition is met. To minimize CPU load, it sleeps a short amount of time on each iteration. Please note the difference to your code: In your code, waiting is achieved using the SLEEP function, but in Wouter’s code, waiting is done by the loop! The SLEEP could have been omitted, but is practically necessary to prevent the program from burning itself into the CPU [:p]

Hi, I aggree with Heinz [:D]. If it is possible you should avoid my solution of your problem (sometimes it is impossible). To check the situation with a loop ( and a short sleep) is much better than a predefined sleep. As i wrote in one of my postings I didn’t knew the CU 5054 [:(] as I had to solve a similar problem. Andre