Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations gkittelson on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

FoxPro Automation Problem

Status
Not open for further replies.

RodBurns

Programmer
Jul 11, 2016
7
US
Hello,

First post here, but I've been searching the archives and don't see a solution to a problem I'm having.

We have a VFP 9 application that filters a table for all records that have a "selected" field set. It then scans through that filtered table, takes a bookmark name from another field and searches a Word for that bookmark. If it finds that bookmark in the word document, it selects the text, and appends it to a different word document.

We just switched from Office 2010 to Office 2016 and now this program fails. Here is the portion of code that is failing:

Code:
SELECT program_options
REINDEX 

fi = "DocumentParts.docx"
 
COUNT TO NumSelected FOR selected = .T.

oWord = CREATEOBJECT("Word.Application")
oWord.Visible = .T. 
oWdDestDoc = oWord.Documents.Add()
oWdSourceDoc = oWord.Documents.Open(fi)

SCAN
	IF selected AND LEN(ALLTRIM(WdBookMark)) > 0
		mWdBookMark = ALLTRIM(wdBookmark)
		
		oWdSourceDoc.activate
		IF oWord.ActiveDocument.Bookmarks.Exists(mWdBookMark)

			*** Copy Body ********************
			oWdSourceDoc.Bookmarks(mWdBookMark).select
			oWord.Selection.Copy

		 	oWdDestDoc.activate

At this point, the program dies with an OLE error saying "the object invoked has disconnected".

While watching the program run, it appears that the line "oWdDestDoc = oWord.Documents.Add()" is not actually creating a new word document to allow the program to paste into it (at least one doesn't show up on the task bar as it previously did).

Is there a different way we have to do this in Office 2016?

Thanks to anyone who can help :)
 
I haven't worked with Word 2016, but in general, you shouldn't need to activate a document or refer to oWord.ActiveDocument to do automation tasks. You should be able to simply refer to each document using the variable you're already created for it.

Tamar
 
But like I said, the problem appears to be that the other document is never created.

Is this incorrect?: oWdDestDoc = oWord.Documents.Add()

It has worked in Word 2003 and 2010. In those earlier versions, you would see the new document show up on the taskbar. In 2016, either it's not showing up, or it's not being created.
 
Try to pass some parameters, like:

odoc = owrd.Documents.Add(,,,.t.)
or
odoc = owrd.Documents.Add(,,0,.t.)
or
odoc = owrd.Documents.Add(,.f.,0,.t.)
or
odoc = owrd.Documents.Add('',.f.,0,.t.)
or
odoc = owrd.Documents.Add('Normal',.f.,0,.t.)


Respectfully,
Vilhelm-Ion Praisach
Resita, Romania

 
Since Office 2007 I observed something like lazy load, eg CREATEOBJECT("Word.Application") returning an object reference to a not yet fully loaded and ready Word Application ole automation server instance. What helped for me was adding a DOEVENTS FORCE after generating Word.Application or any other new objects. Setting oWord.Visible = .t. may have saved you in taking enough time to get this object instance ready to work with and now the new Word version works different again.

Give this a shot:
Code:
oWord = CREATEOBJECT("Word.Application")
DOEVENTS FORCE
oWord.Visible = .T. 
oWdDestDoc = oWord.Documents.Add()
DOEVENTS FORCE
oWdSourceDoc = oWord.Documents.Open(fi)
DOEVENTS FORCE
...

Bye, Olaf.
 
I don't know the answer to this problem, but I doubt it has anything to do with the [tt]oWord.Documents.Add()[/tt] call. That function should work correctly regardless of any parameters that are or are not passed.

Rod, can you actually see the new document open within Word at the time the error occurs? If so, that would tend to confirm what I just said.

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
The question I have is, does this also happen if you run the code in the debugger single stepping through it? If not it means waiting is of the essence and DOEVENTS FORCE is the simplest way to wait for essential things to happen, all currently queued windows events waiting for execution, eg to create the oWord.Documents collection or the new Word doc so you really can use it.

Bye, Olaf.
 
OK, some new information.

I put in the DOEVENT FORCE command everywhere that Olaf showed, and then stepped through in the debugger.

A new document is created (there is a "Document1" open in Word). Then when I load the file I want to copy pieces from, "Document1" goes away. So it's being created, but apparently not staying created? So, now I'm attempting to save the file after it's created, hoping that will make it stick around:

Code:
oWord = CREATEOBJECT("Word.Application")
DOEVENTS FORCE
oWord.Visible = .T. 
oWdDestDoc = oWord.Documents.Add()
DOEVENTS FORCE
oWdDestDoc.activate
DOEVENTS FORCE
oWord.ActiveDocument.SaveAs("c:\test.doc")

The last line gives an error that the file cannot be saved and says to check whether the disk is full or write protected (neither is the case)

Thanks everyone for the help so far. What do I look at next? :)

*edited to add* This code runs from a form - does that make a difference?
 
Well, after some messing around, I got it to work.

I just made a blank document and stored it on disk. Then I have FoxPro load that document and use it, rather than creating a new one. Works just fine.

Thanks for all the help everyone :)
 
Well, Documents.Open() is an alternative to Documents.Add(), but if you do Documents.Add() you already have a new document, no need to save it first and load it, you can wait with Saving to the end. If you first Add a document and then Open one, you don't have two open documents, Open replaces the current document, I think. Might try it out later, but it doesn't make sense to both add and open documents, either you just want a new blank doc or you open an existing (as template, doesn't need to be dot or dotx for that matter). If you open a document and don't want to change or overwrite it, a first step could be to saveas new name.

The problem you had with saving at "C:\test.doc" most probably is not having permission to write to the drive root, save to C:\dcouments\test.doc.

So either do
Code:
oMyDoc = oWord.Documents.Add()
...
oMyDoc.SaveAs(some new name)
... create/process it's components ...
or
Code:
oMyDoc = oWord.Documents.Open(..)
oMyDoc.SaveAs(some new name)
... create/process it's components ...

Besides all that - when single stepping through code the problems you might have without DOEVENTS FORCE don't show, as the debugger halts at every single line, that causes wait states in which events can occur. You typically only will have problems without DOEVENTS FORCE when also not debugging the code. What DOEVENTS does is mainly waiting for already queued events, it's mainly a wait state, but a clever one, eg not waiting, if there is no event waiting for execution, like finishing the full creation of OLE objects of the Word process.

Bye, Olaf.
 
I tried saving it in C:\documents as well, still no go.

My code is not creating, saving and loading the same file. I manually created a blank file and saved that to disk. Then my code just loads that one to paste the text into, rather than creating a new one to paste into as I had done in the past. I don't save the file when I'm done anyway, so this works.

It's just strange. Probably some quirk with Office 2016 and VFP working together.
 
C:\Documents is another bad place, it contains your documents folder, but itself is a system folder.

Bye, Olaf.

PS: Either you go the route of determining a folder to write in with system functions, the simpler eligible way to store any files is outside of the realm of Windows folders, even the Windows folders foreseen as eg the documents library of all users. Use a totally new and independent folder on drive C, perhaps even something on drive D,E,..., than that problem is fully out of your way.
 
@RodBurns, are you using Windows 10? And 32 or 64 bits? I had a similar error with automation, but only on some Win10 computers. Most Win10 worked fine. Is your Windows completely up to date?

I just tried in Win7 with Office2016 and got no error on oWord.Documents.Add, with or without ().
The new document was created, but after opening the fi document it was overwritten, leaving only the fi document open, just as you experienced.
When using oWord.Documents.Add twice(!) I got two documents: the empty one and the fi document.
 
>When using oWord.Documents.Add twice(!) I got two documents: the empty one and the fi document.

That confirms what I thought, if you have a doc open Documents.Open() compares to USE, it does not only open a doc, it also closes the current one, the same Document item of the Documents collection is used.

Documents.Open() only adds a decument to a fresh new Word instance with no open/active documents.

Bye, Olaf.
 
@JackTheC: yes, it's Windows 10 64 bit. I figured it was more of an Office problem than a Windows problem. Strange...
 
B.t.w. switching the order of the two command Add and Open command correct the Open problem:

oWdSourceDoc = oWord.Documents.Open(fi)
oWdDestDoc = oWord.Documents.Add

instead of

oWdDestDoc = oWord.Documents.Add
oWdSourceDoc = oWord.Documents.Open(fi)


And, big chance that the error "the object invoked has disconnected" does not occur on another Win10 computer. That was so in my case with IE automation.
 
Simple reasoning, in a fresh opened Word instance open opens a doc, then Add adds a secondary. First Add, then Open the opened doc replaces the new doc. It may hvae been different in earlier Word version, but that's explaining it.

Bye, Olaf.
 
Finally I made this experiment. Indeed it's the same in Word 2013. Open() closes a current document, or you could say it reuses the active item of the Documents collection for the document you specified to open. Quite like USE does with a workarea. So to open a document in a new Documents item you use Add(), you can also specify a file name here, or you Add() without file name and then Open(fi).

Bye, Olaf.
 
Thanks, Olaf.

Skipping from 2010 to 2016, I didn't realize that change :)
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top