Triple advice here:
1) You automate another process, an error or dialog happening in it doesn't trigger an error in VFP, you get a message such as "This action cannot be completed because the other program is busy.. [Switch to][Retry]" as a timeout. The first step to defend against that is to make your Excel instance visible at least while you develop and test things. You have a case to test, open a file in Excel, automate Excel and try to open the same file in a new instance with workbooks.open().
2) See descriptions of the _VFP properties OLERequestPendingTimeout, OLEServerBusyRaiseError, and OLEServerBusyTimeout. Btw. if you wonder what a server has to do with it Excel.Application is an automation server, a COM server AKA OLE class.
3) Specifically in Excel you have the property DisplayAlerts of the Excel.Application object/server, which you can set False or 0 or .F. (from VFP) - see
That's not only applicable to suppress the "Save Changes?" question when you close something. Instead of the user dialog that's unseen as you don't automate Excel while it's visible, you then will get an error triggered in VFP when you use Workbooks.Open().
The major lessons to learn from 1) is that you can't expect errors happening in another process to raise an error event in VFP and cause the catch block in a TRY...CATCH or the general ON ERROR routine. That is well known when using SQLPassthrough functions, where getting the return value 0 from SQLExec, for example, means you have to pull out what error happened with AERROR(). That's not generally that way, too. In your case, the call to Workbooks.Open opens up a dialog to the user that's putting it into a modal state and the call does not end and return, no error happens, just a call into the OLE class taking too long to return. Therefore after a timeout, you get that default "busy" message with the RETRY/SWITCH buttons, which most commonly both don't resolve the issue. You can't switch to something invisible. And retrying the same method call, you get the same modal blocking.
In 2) you get hands on how that timeout process works. It's best to try out the meanings of the properties by implementing your own COM server (an OLEPUBLIC class) that has a method which calls Messagebox(), for example, to cause a non-returning modal blocking state.
Also take a look into COMReturnerror(), while you're experimenting with your own COM server to see how this mechanism works and can raise an error from the COM server in the client that called. In a class, you would program the Error event of it and within that do a COMRETURNERROR() call, which will show up in the client as an OLE error (1427 or 1429) reported by LineNo() or AERROR() in the line calling the COM server method.
Well, and finally 3) is another resolution but only very specific to Excel, I think Word has a similar property. But don't come to think because the timeout mechanism and choosing between timeout and raising an error, this mode of not allowing dialogs or any modal states is an OLE standard, too. So you only sometimes find solutions like DisplayAlerts, where the developers of the OLE automation server actually thought about the automation that happens in the non-visible mode of the application that's automated.
If you ask yourself why things aren't the same anywhere, the answer is a bit of opinion, I guess MS didn't want to make an OLE interface a hurdle to programming automation servers that have to adhere to a set of basics before you can start with the methods you actually want to provide to the automation server user. So there is no nonvisual mode that COM server code has to take into account or not depending on a standard setting. The other simpler answer is that the Office suite consists of software MS purchased from different original sources and while they certainly did a lot of things to make the suite look like it's one suite, the details show that the single parts of the suite have different roots.
Chriss