Need some help with "Word Automation"

We have here some Navsion Word Automation Funktion wich work fine. But we ned a new funktion, wich simply closes a given (and in word opend) document. Well to do that in VB is very clear (i also got the vba documentation) But i can’t do that simple task in word through an automation. i don’ t know how to pass the whole action in Navision code. The following VB Code (example fom Microsoft) will do that what i want do in Navision Documents(“Sales.doc”).Close SaveChanges:=wdSaveChanges i tried so many code variations from navison, but with no result. I have follwing Word Automation Objects in my function: oWordApplication oWordDocuments oWordDocument maybe anyone here is able to help. PLEASE Therfore Thanks

Did you try VAR Dummy: Integer; Dummy := -1; oWordDocument.Close(Dummy); I have found that the automation functions sometimes are a bit unhappy with fixed constants as parameters… [:(]

HI Heinz! First off all thnaks for your help. The code you provided works. But can you explain me what oWordDocument.Close(Dummy); where dummy is -1 means ??? I mean is Dummy the index number for the word document, wich will be closed ?? Lets say we have word opend with documents named Doc1 Doc2 Doc3 and i want to close doc2. Ho can i find out the internal word doc index for the document doc2 ?? I thought to activate the given Word document “doc2” and to close it then. It also must be possible to close a word document through its name something like oWordDocument.Close(dokname) witch actualy does not work. or do i have to say something like this Dummy := INDEX No of word Dokument (Dokname) oWordDocument.Close(Dummy) Hope to hear from you. Therfore Thanks

Hello Heinz !! It Is me again. I found a solution AnzahlDoks := oWordDocuments.Count(); speichern := FALSE; IF AnzahlDoks = 0 THEN EXIT; FOR i := 1 TO AnzahlDoks DO BEGIN oWordDocument := oWordDocuments.Item(i); oWordDocument.Activate; dkname := oWordDocument.Name(); IF DotName = dkname THEN BEGIN oWordDocument.Close(speichern); i := AnzahlDoks; END; END; I don’t know wether this is the best solution, but it work’s maybe this will help some other people here. Well my main problem was, that i tried to use fixed values insted off using variables.

Hello Ufuk! First, the explanation: -1 is Visual Basic’s internal representation of the Boolean value TRUE and, not really by coincidence, it is also the internal representation of the Automation constant wdSaveChanges. You need to pass this value to the Close function. Since Automation constants and VB values are not available in C/AL, you need to pass the “hard value” -1. And because Automation functions seem to be a bit unstable from time to time when constants are passed (I learned this the hard way [:p]), I’ve got used to assigning this value to a dummy variable right before the function call. Regarding your question and proposed solution about closing a specific document: You can of course access each document by an index in the Documents collection. But you are also able to specify the document’s name as the index into the items collection, i.e. Documents.Item(“Doc1”). Using this technique, you can access a specific document without having to iterate through all the documents and checking each name.

Hello Heinz!

quote:


But you are also able to specify the document’s name as the index into the items collection, i.e. Documents.Item(“Doc1”)


Well i also tried this, but in fact the wrong way, but now as i saw your example, i am able to acces the given document by it’s name (puhh this automation stuff is a bit hard, but when you get some basics it works [:D]) Only one question letf: when doing Documents.Item(“Doc1”) and DOC1 is not in word opend, do i then get a feedback insted of an runtime error. Or in other words how can i check wheter DOC1 is in word opend or not ??

quote:


Originally posted by Ufuk Altinkaynak
when doing Documents.Item(“Doc1”) and DOC1 is not in word opend, do i then get a feedback insted of an runtime error. Or in other words how can i check wheter DOC1 is in word opend or not ??


A very good question! If you ever find a way to trap (VB-) Automation errors in C/AL, let me know! [:D] Joking aside, if you were doing this in VB in- or outside Word, you would do an “On Error Resume Next” before and an “If Err.Number <> 0” after accessing the Documents.Item() collection. The only way the collection object can inform you about a non-existing item is by raising a runtime error - and unfortunately, these errors can not be trapped in C/AL as is possible in VB. Your C/AL code will simply terminate with the usual error message [:(] Now depending upon what you are doing, you have a few options to circumvent this problem. Personally, I would try to keep Word under maximum control from within C/AL, i.e. I would not allow to open and work with a document whose name is unknown to C/AL. If the user must be able to interfere in the running process, I would make it clear that only the original document name (assigned by C/AL) will be recognized for further processing. On the other hand, if it is inevitable that you deal with this error, I would wrap the most important automation functions into a VB COM DLL that handles the error and returns an error code back to C/AL as an ordinary function result. It’s easier than it sounds: You just write in VB what you would liked to have done in C/AL, and then call the VB functions from C/AL. I had to do this with our Easy Archive, whose API is a bit complicated to use from C/AL, and haven’t had any problems ever since.

Hello Heinz !

quote:


On the other hand, if it is inevitable that you deal with this error, I would wrap the most important automation functions into a VB COM DLL that handles the error and returns an error code back to C/AL as an ordinary function result.


I did something similar to automate Novell Groupwise. It looks to me, like you wrote, that it is much much easier to do an automation process throug an on written VB dll, then to use C/Al code. Even you have more controll on what will (or could)happen. Maybe in the follwing Navision Products this will change. Think so, cause now after Microsoft has bought Navision, some things will change in the future. We will have to see. And again thanks for your help, to bring me throug this problem, your tips helped me lot.

quote:


I had to do this with our Easy Archive, whose API is a bit complicated to use from C/AL, and haven’t had any problems ever since.


Oh that is good to hear cause one of our next projects in the near future, is to integrate an archive into navision. I hope i can ask you some question to that point [:D]

quote:


Originally posted by Ufuk Altinkaynak
Oh that is good to hear cause one of our next projects in the near future, is to integrate an archive into navision. I hope i can ask you some question to that point [:D]


I’m sure my boss will be most happy to sell you our interface components along with a few days of customization and training [:D][:D] I agree with you that some (most? [}:)]) things are more easily done in VB than in C/AL. Fortunately, creating COM components in VB is just as easy as using them from within Navision [8D] On the other hand, with all the existing code, I don’t expect Navision to switch from C/AL to VBA in the near future… [:p]