Hi Phil. I used your example to create an example.
If you need more clarification, please reply with any questions.
In summary, Controller.xls creates a hidden Excel instance, opens FileProcessor.xls within, and initiates several routines.
Controller.xls runs a procedure named "Setup_Init" within FileProcessor.xls. This procedure creates 50 new workbooks and calls back Public Sub ProgressUpdate in Controller.xls after each workbook is created. The progress is reported in the statusbar of Controller.xls parent application.
When Setup_Init has completed, FileProcessor.xls notifies Controller.xls by calling back Public Sub InitComplete() within Controller.xls.
Controller.xls, from within this callback, runs another procedure in FileProcessor.xls named "Test".
Just a note to add. The use of the statusbar will cause you problems. If you need a visual progress cue, use a modeless userform.
The "Test" procedure open, writes to, saves, and then deletes each of the 50 new workbooks and calls back Public Sub ProgressUpdate in Controller.xls after each workbook is processed. The progress is reported in the statusbar of Controller.xls' parent application.
I created an error condition by deleting a file in the loop. The error handling logic is there for you to build upon. It can get quite complex. Basically, you pass back a return value to instruct FileProcessor.xls from the callback, "Public Sub OOPSError", as to the steps it should take for any given error. In the example, we just tell FileProcessor.xls to go on to the next workbook.
After test has completed, Public Sub Complete is called back in Controller.xls. We clean up in this procedure by closing FileProcessor.xls and the hidden instance of Excel.
Download the example and open Controller.xls. Click on the run button and watch the statusbar to see the flow logic. You will recieve several msgboxes along the way. Just click 'Ok' to continue. You will need to edit the path to FileProcessor.xls before running.
Example Download
To create this project...
Create a folder and and a new workbook within named, for the sake of clarity in this example, FileProcessor.xls. This is the workbook that will do the processing of your many files. Place this code in a standard module. Add a reference to MS Scripting.
Outside of this folder that contains FileProcessor.xls, create the workbook that will be visible and control, so to speak, FileProcessor.xls. Name it Controller.xls. Place this code into the workbook class.
Edit the path to FileProcessor.xls in this line:
Set OOPSWb = OOPSApp.Workbooks.Open("path of OOPWB.xls")
BTW. OOPS is there for Out Of Process Server. I do expect this to work as I have used this method for years to asynchronously update various workbooks or to just run lengthy procedures in another process. If you have access to a development environment such as VB, you can create an ActiveX.exe for better stability though I have not had any problems thus far using the method prescribed here.
The ontime hack simply releases the client. In this example, Controller.xls. Without the several ontime calls, Controller.xls would have to wait upon FileProcessor.xls for each procedure called. Using this method allows you to go about your business while FileProcessor.xls does the work in the background and notifies Controller.xls at various intervals along the way. It is not neccesary to callback to the extent that I did in this example. Normally, the client is only called back once. At the completion of some lenghty task. Such as, DataAvailable or QueryComplete.
Anyway, I hope that I was able to spell this out clearly without too much confusion...
Just a note to add. The use of the statusbar can cause you problems. If you require a visual cue of progress for some lengthy task, use a modeless userform...
Bookmarks