# NB loading code broken in MMA 10 is there a workaround?

In MMA 9 I use the following code to load multiple nb's and close them after they are evaluated. In MMA 10 this code is broken. It appears that MMA 10 takes far longer to evaluate the code than the function takes to run, and the NotebookClose closes them before they are completely evaluated in 10. Eliminating the NotebookClose lets the code load properly, but then the user has all of these nb's to close before using the GUI. The point of this code was to have only the nb with the GUI open for the user.

nbs = {"ImportFunctions.nb", "StandardData.nb","DataConditioning.nb", "Functions_1.nb", "Functions_2.nb", "Functions_3.nb", "PaperDifference.nb", "PlotFunctions.nb"};

For[i = 1, i <=  Length[nbs], i++,
Block[{nb = NotebookOpen[NotebookDirectory[] <> nbs[[i]]]},
FrontEndTokenExecute[nb, "EvaluateNotebook"];
NotebookClose[nb];
]
]


Is there a better way to accomplish this in MMA 10?

A modification of procedure1[] from the answer by Kuba that does something recognizable when evaluated in version 9, but not in version 10.4.1:

procedure0[] := Module[{nbs},
nbs = Table[With[{i = i},
NotebookPut @ Notebook[{Cell[BoxData@MakeBoxes[Speak[ToString@i]], "Input"]}]], {i, 4}];
For[i = 1, i <= Length[nbs], i++,
FrontEndTokenExecute[nbs[[i]], "EvaluateNotebook"];
NotebookClose[nbs[[i]]];];
Print["is this really finished?"];]

procedure0[]


A simpler single notebook example

With[{nb = NotebookPut @ Notebook[{Cell[BoxData@MakeBoxes[Speak["Hi"]], "Input"]}]},
FrontEndTokenExecute[nb, "EvaluateNotebook"]; NotebookClose[nb];]

• Have you looked at reference.wolfram.com/language/ref/NotebookEvaluate.html ? Jul 26 '16 at 13:20
• Also see (120936) Jul 27 '16 at 1:22
• Which MMA 10 version are you using. Does evaluating the code given in your question within a normal notebook work in version 9, or does it only work using the GUI? Jul 27 '16 at 9:16
• Does adding NotebookClose[] to the end of the individual notebooks together with removing NotebookClose[nb] from the given code work? Jul 27 '16 at 18:40
• @Karsten7. That was a very good solution! Solved the problem...Thank you! Jul 27 '16 at 19:48

FrontEndTokenExecute[nb, "EvaluateNotebook"] does not return anything, it won't wait for a nb to finish evaluating. If it worked I think it was a coincidence. Compare those examples:

The first one is analogous to your approach.

procedure1[] := Module[{nb},
nb = NotebookPut @ Notebook[
Table[
Cell[BoxData@MakeBoxes[Print[#]; Pause[1];], "Input"] & @ i,
{i, 4}
]
];
FrontEndTokenExecute[nb, "EvaluateNotebook"];
Print["is this really finished?"];
NotebookClose[nb]
]


The second works as expected:

procedure2[] := Module[{nb},
nb = NotebookPut @ Notebook[
Table[
Cell[BoxData@MakeBoxes[Print[#]; Pause[1];], "Input"] & @ i,
{i, 4}
]
];
NotebookEvaluate[nb];              (* <-- the only change*)
Print["is this really finished?"];
NotebookClose[nb]
]


Prints from nb are not evaluated because they are not fast enough and NotebookClose fires. Without NotebookClose you'd see 1,2,3,4 in a Message window.

As noted in comments you can use NotebookEvaluate or SelectionMove[nb,All, Notebook] + SelectionEvaluate[nb] instead of your FronEndTokenExecute.

For differences between those two functions take a look at Global context seems to be shared between kernels

• So to understand this code, replacing "Input" with {"ImportFunctions.nb", "StandardData.nb","DataConditioning.nb", "Functions_1.nb", "Functions_2.nb", "Functions_3.nb", "PaperDifference.nb", "PlotFunctions.nb"} should load all of these nb's? Jul 26 '16 at 13:47
• @RHall No, this code is only an example of the sequence of events. Just use NotebookEvaluate in your code instead of tokens and it should work.
– Kuba
Jul 26 '16 at 13:49
• Sorry I can't easily recognize the connection between your proposed solution and my code. Can you show a working example? Jul 26 '16 at 14:18