How can I run a notebook from another notebook multiple times?

I have not used this code in quite a while but I think it still works. The calling notebook could be

Dynamic[{loop, linked`vdtdz}]
distab = {}; Dynamic[distab // TableForm]
Dynamic[return]

Do[linked`vdtdz = 0.1 loop; linked`$callingNotebook = EvaluationNotebook[];
return = NotebookEvaluate[$UserDocumentsDirectory<>"/Mathematica/PSTD_Solve.nb"];
distab = Append[distab, linked`maxai], {loop, 8, 10}]

It passes a variable

linked`vdtdz

and saves the returned variable

linked`maxai

It also temporarily displays a pair of plots produced by the called notebook.

The called notebook begins with

linked = ValueQ[linked`$callingNotebook]; Clear[linked`$callingNotebook]

which determines whether the called notebook actually has been called by another notebook, as opposed to being run on its own. Later, the called notebook uses the passed variable

vdtdz = If[linked, linked`vdtdz, 1.0]; \[CapitalDelta]t0 = vdtdz \[CapitalDelta]z0/vz0

Still later, the called notebook saves plots to disk, depending on whether it actually has been called by another notebook.

If[linked, saveplot = True, (*other code*)]

On its last line of code, the called notebook stores the answer to be returned to the calling notebook and also creates a final pair of plots which automatically are returned.

If[linked, linked`maxai = kout[[1, 4]]; Grid[{{grow3D, growContour}}]]

This may be more than you want. If so, delete what is unnecessary (the plots and the use of Dynamic, for instance).


Starting with your intended code...

Table[
        FolderNumber= i; (*  this is the variable inside NoteBookToRun *)
        nb = NotebookOpen[FileNameJoin[{Directory[], NoteBookToRun}]];
        SelectionMove[nb,All,Notebook];
        SelectionEvaluate[nb];

            {ResultsFromNoteBookToRun},
        {i, 1, NumberOfFolders}
     ]

...as you know, SelectionEvaluate is a poor choice for this because all it does it to queue the evaluation, not perform the evaluation and wait for a response. What you probably don't realize is that the similarly-named NotebookEvaluate function (available since v8) is much more powerful and does something very different. It evaluates the notebook synchronously, not returning until the notebook is fully evaluated -- not unlike evaluating a package.

NotebookEvaluate can insert the results or not depending upon the InsertResults option. And you don't even have to visibly open and close notebook windows. NotebookEvaluate, if given a filename for a notebook which is currently unopened, will invisibly open, evaluate, and close the window (saving if needed to insert results).

Changing your proposed code to use NotebookEvaluate is pretty straightforward:

Table[
        FolderNumber= i; (*  this is the variable inside NoteBookToRun *)
        NotebookEvaluate[FileNameJoin[{Directory[], NoteBookToRun}]];
            {ResultsFromNoteBookToRun},
        {i, 1, NumberOfFolders}
     ]

This version follows the default behavior to not insert the results into the notebooks, but if you wish to change that, simply add InsertResults->True.

Tags:

Notebooks