Function Repository Resource:

SpreadsheetTrace

Source Notebook

Trace dependencies among spreadsheet formulas

Contributed by: Daniele Gregori

ResourceFunction["SpreadsheetTrace"][file,cell]

trace the dependencies of a cell in a spreadsheet file.

ResourceFunction["SpreadsheetTrace"][{sheets,data,formulas},cell]

trace the dependencies of a cell given a lists of sheets, data and formulas.

Details and Options

ResourceFunction["SpreadsheetTrace"] can help analyze spreadsheets by automatically tracing all the formula dependencies of a given cell.
The output of ResourceFunction["SpreadsheetTrace"] closely mirrors that of Trace, but it is cut before the actual spreadsheet evaluations occur. This is because not all Microsoft Excel functions are directly portable to Wolfram Language functions.
ResourceFunction["SpreadsheetTrace"] accepts the following options:
"TraceDuplicates"Truekeep duplicate dependency branches

Examples

Basic Examples (3) 

Download an XLSX file:

In[1]:=
file1 = URLDownload[
   "https://www.wolframcloud.com/obj/064eb405-e9b5-4e95-941a-7898dd493f80",
   FileNameJoin[{$TemporaryDirectory, "example_01.xlsx"}]];

Trace the dependencies of the cell D1:

In[2]:=
trace = ResourceFunction["SpreadsheetTrace"][file1, "D1"]
Out[2]=

Visualize it as an ExpressionTree:

In[3]:=
ExpressionTree[trace, "Atoms"]
Out[3]=

Scope (4) 

Trace a deeper spreadsheet dependency:

In[4]:=
file2 = URLDownload[
   "https://www.wolframcloud.com/obj/67cccf43-b7be-471a-9826-378d88ce4534",
   FileNameJoin[{$TemporaryDirectory, "example_02.xlsx"}]];
In[5]:=
ResourceFunction["SpreadsheetTrace"][file2, "C5"]
Out[5]=

Trace formulas with absolute references:

In[6]:=
file3 = URLDownload[
   "https://www.wolframcloud.com/obj/0439d3b1-0a32-4ccc-a01c-c724965a2386", FileNameJoin[{$TemporaryDirectory, "example_03.xlsx"}]];
In[7]:=
ResourceFunction["SpreadsheetTrace"][file3, "F2"]
Out[7]=

Trace cross-sheet references:

In[8]:=
file4 = URLDownload[
   "https://www.wolframcloud.com/obj/cb328fb3-3a35-4601-a7cb-611e09245574",
   FileNameJoin[{$TemporaryDirectory, "example_04.xlsx"}]];
In[9]:=
ResourceFunction["SpreadsheetTrace"][file4, "Summary!B3"]
Out[9]=

Trace through a column range, expanding it across all rows:

In[10]:=
file5 = URLDownload[
   "https://www.wolframcloud.com/obj/066a6a74-e239-40f7-bf4a-851fde0da7ea",
   FileNameJoin[{$TemporaryDirectory, "example_05.xlsx"}]];
In[11]:=
trace = ResourceFunction["SpreadsheetTrace"][file5, "Orders!D2"]
Out[11]=
In[12]:=
ExpressionTree[trace, "Atoms", TreeLayout -> "BalloonEmbedding"]
Out[12]=

Options (1) 

TraceDuplicates (1) 

Delete duplicate branches and show a more compact visualization:

In[13]:=
file2 = URLDownload[
   "https://www.wolframcloud.com/obj/67cccf43-b7be-471a-9826-378d88ce4534",
   FileNameJoin[{$TemporaryDirectory, "example_02.xlsx"}]];
In[14]:=
traceND = ResourceFunction["SpreadsheetTrace"][file2, "D1", "TraceDuplicates" -> False]
Out[14]=
In[15]:=
ExpressionTree[traceND, "Atoms", ImageSize -> Full]
Out[15]=

Applications (3) 

Find all the cells a formula depends on:

In[16]:=
file3 = URLDownload[
   "https://www.wolframcloud.com/obj/0439d3b1-0a32-4ccc-a01c-c724965a2386", FileNameJoin[{$TemporaryDirectory, "example_03.xlsx"}]];
In[17]:=
trace = ResourceFunction["SpreadsheetTrace"][file3, "G2"]
Out[17]=
In[18]:=
Cases[trace, {cell_String, val_ /; ! StringQ[val]} :> cell, Infinity]
Out[18]=

Measure the total dependency depth:

In[19]:=
file1 = URLDownload[
   "https://www.wolframcloud.com/obj/064eb405-e9b5-4e95-941a-7898dd493f80",
   FileNameJoin[{$TemporaryDirectory, "example_01.xlsx"}]];
In[20]:=
trace = ResourceFunction["SpreadsheetTrace"][file1, "E1"]
Out[20]=
In[21]:=
Depth@trace
Out[21]=

Visualize the full tree of dependencies:

In[22]:=
file2 = URLDownload[
    "https://www.wolframcloud.com/obj/67cccf43-b7be-471a-9826-378d88ce4534",
    FileNameJoin[{$TemporaryDirectory, "example_02.xlsx"}]];;
In[23]:=
trace = ResourceFunction["SpreadsheetTrace"][file2, "D1", "TraceDuplicates" -> False];
In[24]:=
ExpressionTree[trace, "Atoms", ImageSize -> Full]
Out[24]=

Notice this ExpressionTree respects the ordering among dependencies, but their hierarchical structure is not captured perfectly. See proper Trace tree examples in Properties and Relations.

Properties and Relations (4) 

The output of SpreadsheetTrace[file,cell] has the same form as the output of Trace, but truncated after the elementary leafs are reached.

To truncate Trace at the leafs use replacements rules like the this:

In[25]:=
cutTrace[trace_] :=
 ReplaceRepeated[trace,
  {k : {_, HoldCompleteForm[_?StringQ]} :> k,
   {HoldCompleteForm[_?NumericQ], HoldCompleteForm[_?NumericQ]} -> Nothing,
   _[___, _?StringQ ..] -> Nothing,
   HoldCompleteForm@Nothing -> Nothing,
   _[___, Nothing .., ___] -> Nothing,
   _[_[___, __?StringQ ..] ..] -> Nothing}]

Find the full Trace of a double sum:

In[26]:=
traceDef =
 Block[{C1, B1, B2, A1 = "a1", A2 = "a2", A3 = "a3", A4 = "a4", A5 = "a5", A6 = "a6"},
  C1 := B1 + B2;
  B1 := A1 + A2 + A3;
  B2 := A4 + A5 + A6;
  Trace[C1]]
Out[26]=

Its truncated version perfectly matches the output of SpreadsheetTrace[file,cell]:

In[27]:=
file2 = URLDownload[
   "https://www.wolframcloud.com/obj/67cccf43-b7be-471a-9826-378d88ce4534",
   FileNameJoin[{$TemporaryDirectory, "example_02.xlsx"}]];
In[28]:=
replFile1Col1 = Thread[{"a1", "a2", "a3", "a4", "a5", "a6"} -> Take[First /@ First@Import[file2, "Data"], 6]];
In[29]:=
trace = ResourceFunction["SpreadsheetTrace"][file2, "C1"]
Out[29]=
In[30]:=
cutTrace@traceDef /. replFile1Col1
Out[30]=

Nevertheless, only the pure Wolfram Language Trace allows the drawing of a proper ExpressionTree, which respects all hierarchical relations:

In[31]:=
ExpressionTree[cutTrace@traceDef /. replFile1Col1, "Trace"]
Out[31]=
In[32]:=
ExpressionTree[trace, "Atoms"]
Out[32]=

See Possible Issues for other exceptions to the general analogy between SpreadsheetTrace[file,cell] and Trace.

Possible Issues (1) 

In some examples, to achieve complete analogy with Excel formulas, Wolfram built-in functions like If need to be redefined so to be cleared of Attributes like HoldRest:

In[33]:=
cutTrace[trace_] :=
 ReplaceRepeated[trace,
  {k : {_, HoldCompleteForm[_?StringQ]} :> k,
   {HoldCompleteForm[_?NumericQ], HoldCompleteForm[_?NumericQ]} -> Nothing,
   _[___, _?StringQ ..] -> Nothing,
   HoldCompleteForm@Nothing -> Nothing,
   _[___, Nothing .., ___] -> Nothing,
   _[_[___, __?StringQ ..] ..] -> Nothing}]
In[34]:=
traceDef = Block[{C5, C4, C1, C3, B1, B2, B4, A1 = "a1", A2 = "a2", A3 = "a3", A4 = "a4", A5 = "a5", A6 = "a6", if},
   if[cond_, then_, else_] := If[cond, then, else];
     B1 := A1 + A2 + A3; B2 := A4 + A5 + A6;
     B4 := (A1 + A2 + A3 + A4 + A5 + A6)/6;
     C1 := B1 + B2; C3 := B4*2; C4 := C1 - C3;
     C5 := if[C4 > 0, C4, 0];
     Trace[C5]];
In[35]:=
file2 = URLDownload[
   "https://www.wolframcloud.com/obj/67cccf43-b7be-471a-9826-378d88ce4534",
   FileNameJoin[{$TemporaryDirectory, "example_02.xlsx"}]];
In[36]:=
replFile1Col1 = Thread[{"a1", "a2", "a3", "a4", "a5", "a6"} -> Take[First /@ First@Import[file2, "Data"], 6]];
In[37]:=
cutTrace@traceDef /. replFile1Col1 /. if -> If
Out[37]=
In[38]:=
ResourceFunction["SpreadsheetTrace"][file2, "C5"]
Out[38]=

Still, in this case the analogy with Trace is not yet perfect because SpreadsheetTrace[file,cell] treats as Atom elements only spreadsheet formula cells and their values, ignoring numeric constants in relations such as C4>0 (0) and C1-C3 (-1).

Publisher

Daniele Gregori

Requirements

Wolfram Language 13.2 (December 2022) or above

Version History

  • 1.0.0 – 29 June 2026

Related Resources

License Information