# How to find the last output cell of the group to which a certain cell belongs?

Simple question, but I cannot find an answer in the documentation.

I have a CellObject handle of some cell in some notebook. This cell has "Subsubsection" style, so it starts a new cell group. Inside this cell group there are one or more input, output and text cell with different styles. I want to get the CellObject handle of the last output cell in this group. With this handle I can get the content of the cell and do whatever I need.

I don't want to change the selection on the notebook or change and restore the selection or give any visual interference from what I'm doing.

The notebook is long and complex with a lot of graphics; the access to the group and last cell should be resonably fast.

It is possible?

To make things clear I want to implement a function with this signature:

lastOutputOfGroup[cellObject_CellObject] := ...


that, given a notebook, for example

nb = CreateDocument[{
TextCell["Section", "Section"],
TextCell["Subsection", "Subsection"],
TextCell["Subsubsection 1", "Subsubsection"],
TextCell["1+1", "Input"],
TextCell["Plot[Sin[x],{x,0,2\[Pi]}]", "Input"],
TextCell["Subsubsection 2", "Subsubsection"],
TextCell["Expand[(1+x)^5]", "Input"],
TextCell["Plot[Cos[x],{x,0,2\[Pi]}]", "Input"]
}];
NotebookEvaluate[nb, InsertResults -> True];


and and handle to some heading cell, for example

cellObject = First@Cells[nb, CellStyle -> "Subsubsection"]


returns the CellObject of the cell containing the Sin[x] plot so that I can acquire its Graphics expression.

To make things even clear I added, as temporary answer, a slow method I found after posting the question. An efficient version of my implementation is what I'm searching for.

Sorry, I don't know how to rephrase this question to make it less vague.

• SelectionMove is a generic approach, could you explain why it is not acceptable? You can always use AutoScroll->False option. – Kuba Mar 4 '16 at 9:24
• @Kuba I'm not 100% sure that SelectionMove will cause any real problem to me, but, because I go to use this routine in some kind of "background" processing of my notebook, maybe "long", I don't find "clean" to act on UI during this process. These repeating SelectionMove maybe can interfere with what I'm doing interactively? – unlikely Mar 4 '16 at 9:41
• If you are not using the notebook that is being searched then I don't think it will cause any problems. – Kuba Mar 4 '16 at 9:44
• @MikeHoneychurch Why do you state my requirements are changing? I still want to get the CellObject handle of the last output cell of CellGroup started by a given CellObject handle, without changing the UI... – unlikely Mar 4 '16 at 23:04
• okay I'll reverse my close vote (if that is possible) but I find the question too vague to attempt to answer – Mike Honeychurch Mar 4 '16 at 23:07

I found this method.

lastOutputOfGroup[cellObject_CellObject] :=
With[{groupCells = Cases[NotebookGet@Notebooks[cellObject],
CellGroupData[cells : {NotebookRead@cellObject, ___}, ___] :>
cells, \[Infinity]]},
ToExpression@First@Last@Cases[groupCells, Cell[_, "Output", ___], \[Infinity]]
]


that apparently works:

lastOutputOfGroup[cellObject]


Is it a good way? Are there drawbacks? For example, what I need to put in my pattern? CellGroup or CellGroupData? I don't understand the difference.

One problem is that my method in the real case is very slow: the slowest part are the NotebookGet and the first Cases (i.e. acquiring the notebook expression and to find the cell in the large notebook).

• So you have to evaluate that from within a cell group?? – Mike Honeychurch Mar 4 '16 at 10:48
• And where do you want the output of that function to appear. It seems like it will have to appear in the target cell group – Mike Honeychurch Mar 4 '16 at 10:50
• So you want to export the last output cell of a section grouping? If that is correct you really should be saying that in the question and not leave it to guesswork. So how do you select which section grouping you want to apply this to? – Mike Honeychurch Mar 4 '16 at 22:06