[{"data":1,"prerenderedAt":2391},["ShallowReactive",2],{"doc:\u002Fautomating-reporting-workflows\u002Fbuilding-multi-sheet-excel-dashboards\u002Flink-dashboard-cells-to-data-sheets-with-formulas":3,"surround:\u002Fautomating-reporting-workflows\u002Fbuilding-multi-sheet-excel-dashboards\u002Flink-dashboard-cells-to-data-sheets-with-formulas":2355,"ancestors:\u002Fautomating-reporting-workflows\u002Fbuilding-multi-sheet-excel-dashboards\u002Flink-dashboard-cells-to-data-sheets-with-formulas":2364,"children:\u002Fautomating-reporting-workflows\u002Fbuilding-multi-sheet-excel-dashboards\u002Flink-dashboard-cells-to-data-sheets-with-formulas":2369,"related:\u002Fautomating-reporting-workflows\u002Fbuilding-multi-sheet-excel-dashboards\u002Flink-dashboard-cells-to-data-sheets-with-formulas":2370},{"id":4,"title":5,"body":6,"dateModified":2319,"datePublished":2319,"description":2320,"extension":2321,"faq":2322,"keyword":2332,"kind":2333,"meta":2334,"navigation":252,"path":2343,"seo":2344,"slug":2347,"stem":2348,"topics":2349,"type":2353,"__hash__":2354},"docs\u002Fautomating-reporting-workflows\u002Fbuilding-multi-sheet-excel-dashboards\u002Flink-dashboard-cells-to-data-sheets-with-formulas\u002Findex.md","Link Dashboard Cells to Data Sheets with Formulas",{"type":7,"value":8,"toc":2306},"minimark",[9,19,187,192,221,224,696,700,711,819,832,836,851,1051,1077,1081,1084,1179,1190,1397,1401,1404,1579,1582,1741,1752,1882,1886,1889,2033,2036,2040,2047,2163,2173,2177,2219,2223,2234,2238,2244,2250,2256,2269,2273,2302],[10,11,12,13,18],"p",{},"A dashboard sheet computed in pandas and written as values is a snapshot: correct the day it was produced, wrong as soon as someone adds a row to the data sheet or wants to see last month instead. A dashboard made of formulas that point at the data sheets stays consistent with the data it sits next to, and lets readers change inputs — the report month, a region — and see every figure update. This guide, part of ",[14,15,17],"a",{"href":16},"\u002Fautomating-reporting-workflows\u002Fbuilding-multi-sheet-excel-dashboards\u002F","Building Multi-Sheet Excel Dashboards",", writes such a dashboard with openpyxl, using table references and a named input cell, and verifies the numbers without opening Excel.",[20,21,29,30,29,34,29,38,29,46,29,56,29,67,29,74,29,79,29,87,29,94,29,100,29,105,29,108,29,113,29,116,29,122,29,126,29,130,29,133,29,135,29,140,29,147,29,152,29,156,29,159,29,161,29,166,29,173,29,178,29,182,29,185],"svg",{"viewBox":22,"role":23,"ariaLabelledBy":24,"xmlns":27,"style":28},"4 0 752 436","img",[25,26],"ld-fan-t","ld-fan-d","http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg","width:100%;max-width:752px;height:auto;display:block;margin:1.5rem auto;font-family:Inter,ui-sans-serif,system-ui,sans-serif","\n  ",[31,32,33],"title",{"id":25},"Dashboard figures computed from the data sheet",[35,36,37],"desc",{"id":26},"The dashboard's revenue, order count, average order and North revenue cells are formulas. Each reads the Sales table on the Sales Data sheet and the ReportMonth input cell on the dashboard itself, so changing the month or adding rows updates every figure.",[39,40],"rect",{"x":41,"y":42,"width":43,"height":44,"fill":45},"4","0","752","436","#ffffff",[39,47],{"x":48,"y":49,"width":50,"height":51,"rx":52,"fill":53,"stroke":54,"style":55},"520.0","171.5","220.0","93.0","12","#d9f4f1","var(--teal,#0f9488)","stroke-width:2px",[57,58,60],"g",{"transform":59},"translate(618.0,184.5) scale(1.000)",[61,62],"path",{"d":63,"fill":64,"stroke":65,"style":66},"M3 5h18v14H3z M3 10h18 M3 15h18 M9 5v14","none","var(--teal-ink,#0b6157)","stroke-width:1.80px;stroke-linecap:round;stroke-linejoin:round",[68,69,73],"text",{"x":70,"y":71,"style":72},"630.0","231.0","font-size:13.5px;font-weight:700;fill:var(--teal-ink,#0b6157);text-anchor:middle","Sales table",[68,75,78],{"x":70,"y":76,"style":77},"250.5","font-size:11.5px;font-weight:400;fill:var(--text,#172033);text-anchor:middle","'Sales Data'!A1:E7",[39,80],{"x":81,"y":82,"width":83,"height":84,"rx":52,"fill":85,"stroke":86,"style":55},"20.0","16.0","250.0","92.0","#f0f4ff","var(--brand,#5b5cf0)",[57,88,90],{"transform":89},"translate(133.0,29.0) scale(1.000)",[61,91],{"d":92,"fill":64,"stroke":93,"style":66},"M4 20h16 M7 17v-5 M12 17V7 M17 17v-8","var(--brand-strong,#4338ca)",[68,95,99],{"x":96,"y":97,"style":98},"145.0","75.0","font-size:13px;font-weight:700;fill:var(--brand-strong,#4338ca);text-anchor:middle","Revenue this month",[68,101,104],{"x":96,"y":102,"style":103},"94.0","font-size:11px;font-weight:400;fill:var(--text,#172033);text-anchor:middle","SUMIFS(Sales[Revenue], …)",[61,106],{"d":107,"fill":64,"stroke":86,"style":55},"M274.0,62.0 C394.0,62.0 394.0,218.0 510.0,218.0",[109,110],"polygon",{"points":111,"fill":112},"514.0,218.0 505.0,223.0 505.0,213.0","#5b5cf0",[39,114],{"x":81,"y":115,"width":83,"height":84,"rx":52,"fill":85,"stroke":86,"style":55},"120.0",[57,117,119],{"transform":118},"translate(133.0,133.0) scale(1.000)",[61,120],{"d":121,"fill":64,"stroke":93,"style":66},"M5 9h14 M4 15h14 M10 4l-2 16 M16 4l-2 16",[68,123,125],{"x":96,"y":124,"style":98},"179.0","Orders this month",[68,127,129],{"x":96,"y":128,"style":103},"198.0","COUNTIFS(Sales[Date], …)",[61,131],{"d":132,"fill":64,"stroke":86,"style":55},"M274.0,166.0 C394.0,166.0 394.0,218.0 510.0,218.0",[109,134],{"points":111,"fill":112},[39,136],{"x":81,"y":137,"width":83,"height":84,"rx":52,"fill":138,"stroke":139,"style":55},"224.0","#fdefd8","var(--gold,#b4740a)",[57,141,143],{"transform":142},"translate(133.0,237.0) scale(1.000)",[61,144],{"d":145,"fill":64,"stroke":146,"style":66},"M13 2L4 14h7l-1 8 9-12h-7z","var(--gold-ink,#7a4e06)",[68,148,151],{"x":96,"y":149,"style":150},"283.0","font-size:13px;font-weight:700;fill:var(--gold-ink,#7a4e06);text-anchor:middle","Average order",[68,153,155],{"x":96,"y":154,"style":103},"302.0","IFERROR(B3\u002FB4, 0)",[61,157],{"d":158,"fill":64,"stroke":86,"style":55},"M274.0,270.0 C394.0,270.0 394.0,218.0 510.0,218.0",[109,160],{"points":111,"fill":112},[39,162],{"x":81,"y":163,"width":83,"height":84,"rx":52,"fill":164,"stroke":165,"style":55},"328.0","#fee8f2","var(--accent,#f43f8f)",[57,167,169],{"transform":168},"translate(133.0,341.0) scale(1.000)",[61,170],{"d":171,"fill":64,"stroke":172,"style":66},"M9 11a3.5 3.5 0 1 0 0-7 3.5 3.5 0 0 0 0 7z M2.5 20c0-3.6 2.9-6 6.5-6s6.5 2.4 6.5 6 M16 4.5a3.3 3.3 0 0 1 0 6.3 M18 14.3c2.2.7 3.5 2.8 3.5 5.7","var(--accent-ink,#be185d)",[68,174,177],{"x":96,"y":175,"style":176},"387.0","font-size:13px;font-weight:700;fill:var(--accent-ink,#be185d);text-anchor:middle","North revenue",[68,179,181],{"x":96,"y":180,"style":103},"406.0","SUMIFS(… \"North\" …)",[61,183],{"d":184,"fill":64,"stroke":86,"style":55},"M274.0,374.0 C394.0,374.0 394.0,218.0 510.0,218.0",[109,186],{"points":111,"fill":112},[188,189,191],"h2",{"id":190},"prerequisites","Prerequisites",[193,194,199],"pre",{"className":195,"code":196,"language":197,"meta":198,"style":198},"language-bash shiki shiki-themes github-light github-dark-high-contrast","pip install openpyxl pandas\n","bash","",[200,201,202],"code",{"__ignoreMap":198},[203,204,207,211,215,218],"span",{"class":205,"line":206},"line",1,[203,208,210],{"class":209},"sMTad","pip",[203,212,214],{"class":213},"srMev"," install",[203,216,217],{"class":213}," openpyxl",[203,219,220],{"class":213}," pandas\n",[10,222,223],{},"A data sheet with a named table — the dashboard's formulas will refer to it by name:",[193,225,229],{"className":226,"code":227,"language":228,"meta":198,"style":198},"language-python shiki shiki-themes github-light github-dark-high-contrast","import datetime as dt\n\nfrom openpyxl import Workbook\nfrom openpyxl.workbook.defined_name import DefinedName\nfrom openpyxl.worksheet.table import Table, TableStyleInfo\n\nwb = Workbook()\ndash = wb.active\ndash.title = \"Dashboard\"\ndata = wb.create_sheet(\"Sales Data\")\ndata.append([\"Date\", \"Region\", \"Product\", \"Revenue\", \"Units\"])\nfor row in [(dt.date(2026, 8, 3), \"North\", \"Tea\", 1200, 40), (dt.date(2026, 8, 9), \"South\", \"Coffee\", 950, 25),\n            (dt.date(2026, 9, 2), \"North\", \"Coffee\", 1400, 35), (dt.date(2026, 9, 5), \"East\", \"Tea\", 600, 20),\n            (dt.date(2026, 9, 12), \"North\", \"Tea\", 800, 30), (dt.date(2026, 9, 20), \"South\", \"Tea\", 700, 28)]:\n    data.append(row)\nsales = Table(displayName=\"Sales\", ref=f\"A1:E{data.max_row}\")\nsales.tableStyleInfo = TableStyleInfo(name=\"TableStyleLight9\", showRowStripes=True)\ndata.add_table(sales)\n","python",[200,230,231,247,254,268,281,294,299,311,322,333,350,383,470,539,605,611,659,690],{"__ignoreMap":198},[203,232,233,237,241,244],{"class":205,"line":206},[203,234,236],{"class":235},"s-kum","import",[203,238,240],{"class":239},"skGVy"," datetime ",[203,242,243],{"class":235},"as",[203,245,246],{"class":239}," dt\n",[203,248,250],{"class":205,"line":249},2,[203,251,253],{"emptyLinePlaceholder":252},true,"\n",[203,255,257,260,263,265],{"class":205,"line":256},3,[203,258,259],{"class":235},"from",[203,261,262],{"class":239}," openpyxl ",[203,264,236],{"class":235},[203,266,267],{"class":239}," Workbook\n",[203,269,271,273,276,278],{"class":205,"line":270},4,[203,272,259],{"class":235},[203,274,275],{"class":239}," openpyxl.workbook.defined_name ",[203,277,236],{"class":235},[203,279,280],{"class":239}," DefinedName\n",[203,282,284,286,289,291],{"class":205,"line":283},5,[203,285,259],{"class":235},[203,287,288],{"class":239}," openpyxl.worksheet.table ",[203,290,236],{"class":235},[203,292,293],{"class":239}," Table, TableStyleInfo\n",[203,295,297],{"class":205,"line":296},6,[203,298,253],{"emptyLinePlaceholder":252},[203,300,302,305,308],{"class":205,"line":301},7,[203,303,304],{"class":239},"wb ",[203,306,307],{"class":235},"=",[203,309,310],{"class":239}," Workbook()\n",[203,312,314,317,319],{"class":205,"line":313},8,[203,315,316],{"class":239},"dash ",[203,318,307],{"class":235},[203,320,321],{"class":239}," wb.active\n",[203,323,325,328,330],{"class":205,"line":324},9,[203,326,327],{"class":239},"dash.title ",[203,329,307],{"class":235},[203,331,332],{"class":213}," \"Dashboard\"\n",[203,334,336,339,341,344,347],{"class":205,"line":335},10,[203,337,338],{"class":239},"data ",[203,340,307],{"class":235},[203,342,343],{"class":239}," wb.create_sheet(",[203,345,346],{"class":213},"\"Sales Data\"",[203,348,349],{"class":239},")\n",[203,351,353,356,359,362,365,367,370,372,375,377,380],{"class":205,"line":352},11,[203,354,355],{"class":239},"data.append([",[203,357,358],{"class":213},"\"Date\"",[203,360,361],{"class":239},", ",[203,363,364],{"class":213},"\"Region\"",[203,366,361],{"class":239},[203,368,369],{"class":213},"\"Product\"",[203,371,361],{"class":239},[203,373,374],{"class":213},"\"Revenue\"",[203,376,361],{"class":239},[203,378,379],{"class":213},"\"Units\"",[203,381,382],{"class":239},"])\n",[203,384,386,389,392,395,398,402,404,407,409,412,415,418,420,423,425,428,430,433,436,438,440,442,444,447,449,452,454,457,459,462,464,467],{"class":205,"line":385},12,[203,387,388],{"class":235},"for",[203,390,391],{"class":239}," row ",[203,393,394],{"class":235},"in",[203,396,397],{"class":239}," [(dt.date(",[203,399,401],{"class":400},"sP0c6","2026",[203,403,361],{"class":239},[203,405,406],{"class":400},"8",[203,408,361],{"class":239},[203,410,411],{"class":400},"3",[203,413,414],{"class":239},"), ",[203,416,417],{"class":213},"\"North\"",[203,419,361],{"class":239},[203,421,422],{"class":213},"\"Tea\"",[203,424,361],{"class":239},[203,426,427],{"class":400},"1200",[203,429,361],{"class":239},[203,431,432],{"class":400},"40",[203,434,435],{"class":239},"), (dt.date(",[203,437,401],{"class":400},[203,439,361],{"class":239},[203,441,406],{"class":400},[203,443,361],{"class":239},[203,445,446],{"class":400},"9",[203,448,414],{"class":239},[203,450,451],{"class":213},"\"South\"",[203,453,361],{"class":239},[203,455,456],{"class":213},"\"Coffee\"",[203,458,361],{"class":239},[203,460,461],{"class":400},"950",[203,463,361],{"class":239},[203,465,466],{"class":400},"25",[203,468,469],{"class":239},"),\n",[203,471,473,476,478,480,482,484,487,489,491,493,495,497,500,502,505,507,509,511,513,515,518,520,523,525,527,529,532,534,537],{"class":205,"line":472},13,[203,474,475],{"class":239},"            (dt.date(",[203,477,401],{"class":400},[203,479,361],{"class":239},[203,481,446],{"class":400},[203,483,361],{"class":239},[203,485,486],{"class":400},"2",[203,488,414],{"class":239},[203,490,417],{"class":213},[203,492,361],{"class":239},[203,494,456],{"class":213},[203,496,361],{"class":239},[203,498,499],{"class":400},"1400",[203,501,361],{"class":239},[203,503,504],{"class":400},"35",[203,506,435],{"class":239},[203,508,401],{"class":400},[203,510,361],{"class":239},[203,512,446],{"class":400},[203,514,361],{"class":239},[203,516,517],{"class":400},"5",[203,519,414],{"class":239},[203,521,522],{"class":213},"\"East\"",[203,524,361],{"class":239},[203,526,422],{"class":213},[203,528,361],{"class":239},[203,530,531],{"class":400},"600",[203,533,361],{"class":239},[203,535,536],{"class":400},"20",[203,538,469],{"class":239},[203,540,542,544,546,548,550,552,554,556,558,560,562,564,567,569,572,574,576,578,580,582,584,586,588,590,592,594,597,599,602],{"class":205,"line":541},14,[203,543,475],{"class":239},[203,545,401],{"class":400},[203,547,361],{"class":239},[203,549,446],{"class":400},[203,551,361],{"class":239},[203,553,52],{"class":400},[203,555,414],{"class":239},[203,557,417],{"class":213},[203,559,361],{"class":239},[203,561,422],{"class":213},[203,563,361],{"class":239},[203,565,566],{"class":400},"800",[203,568,361],{"class":239},[203,570,571],{"class":400},"30",[203,573,435],{"class":239},[203,575,401],{"class":400},[203,577,361],{"class":239},[203,579,446],{"class":400},[203,581,361],{"class":239},[203,583,536],{"class":400},[203,585,414],{"class":239},[203,587,451],{"class":213},[203,589,361],{"class":239},[203,591,422],{"class":213},[203,593,361],{"class":239},[203,595,596],{"class":400},"700",[203,598,361],{"class":239},[203,600,601],{"class":400},"28",[203,603,604],{"class":239},")]:\n",[203,606,608],{"class":205,"line":607},15,[203,609,610],{"class":239},"    data.append(row)\n",[203,612,614,617,619,622,626,628,631,633,636,638,641,644,648,651,654,657],{"class":205,"line":613},16,[203,615,616],{"class":239},"sales ",[203,618,307],{"class":235},[203,620,621],{"class":239}," Table(",[203,623,625],{"class":624},"sa561","displayName",[203,627,307],{"class":235},[203,629,630],{"class":213},"\"Sales\"",[203,632,361],{"class":239},[203,634,635],{"class":624},"ref",[203,637,307],{"class":235},[203,639,640],{"class":235},"f",[203,642,643],{"class":213},"\"A1:E",[203,645,647],{"class":646},"sSjpA","{",[203,649,650],{"class":239},"data.max_row",[203,652,653],{"class":646},"}",[203,655,656],{"class":213},"\"",[203,658,349],{"class":239},[203,660,662,665,667,670,673,675,678,680,683,685,688],{"class":205,"line":661},17,[203,663,664],{"class":239},"sales.tableStyleInfo ",[203,666,307],{"class":235},[203,668,669],{"class":239}," TableStyleInfo(",[203,671,672],{"class":624},"name",[203,674,307],{"class":235},[203,676,677],{"class":213},"\"TableStyleLight9\"",[203,679,361],{"class":239},[203,681,682],{"class":624},"showRowStripes",[203,684,307],{"class":235},[203,686,687],{"class":400},"True",[203,689,349],{"class":239},[203,691,693],{"class":205,"line":692},18,[203,694,695],{"class":239},"data.add_table(sales)\n",[188,697,699],{"id":698},"step-1-a-named-input-cell","Step 1 — A named input cell",[10,701,702,703,706,707,710],{},"The report month is an input: readers should be able to change it. Put it in one cell on the dashboard and give that cell a name, so formulas read ",[200,704,705],{},"ReportMonth"," rather than ",[200,708,709],{},"Dashboard!$B$1",":",[193,712,714],{"className":226,"code":713,"language":228,"meta":198,"style":198},"dash[\"A1\"] = \"Report month\"\ndash[\"B1\"] = dt.date(2026, 9, 1)\ndash[\"B1\"].number_format = \"mmm yyyy\"\nwb.defined_names[\"ReportMonth\"] = DefinedName(\"ReportMonth\", attr_text=\"Dashboard!$B$1\")\nprint(wb.defined_names[\"ReportMonth\"].attr_text)       # Dashboard!$B$1\n",[200,715,716,732,759,773,802],{"__ignoreMap":198},[203,717,718,721,724,727,729],{"class":205,"line":206},[203,719,720],{"class":239},"dash[",[203,722,723],{"class":213},"\"A1\"",[203,725,726],{"class":239},"] ",[203,728,307],{"class":235},[203,730,731],{"class":213}," \"Report month\"\n",[203,733,734,736,739,741,743,746,748,750,752,754,757],{"class":205,"line":249},[203,735,720],{"class":239},[203,737,738],{"class":213},"\"B1\"",[203,740,726],{"class":239},[203,742,307],{"class":235},[203,744,745],{"class":239}," dt.date(",[203,747,401],{"class":400},[203,749,361],{"class":239},[203,751,446],{"class":400},[203,753,361],{"class":239},[203,755,756],{"class":400},"1",[203,758,349],{"class":239},[203,760,761,763,765,768,770],{"class":205,"line":256},[203,762,720],{"class":239},[203,764,738],{"class":213},[203,766,767],{"class":239},"].number_format ",[203,769,307],{"class":235},[203,771,772],{"class":213}," \"mmm yyyy\"\n",[203,774,775,778,781,783,785,788,790,792,795,797,800],{"class":205,"line":270},[203,776,777],{"class":239},"wb.defined_names[",[203,779,780],{"class":213},"\"ReportMonth\"",[203,782,726],{"class":239},[203,784,307],{"class":235},[203,786,787],{"class":239}," DefinedName(",[203,789,780],{"class":213},[203,791,361],{"class":239},[203,793,794],{"class":624},"attr_text",[203,796,307],{"class":235},[203,798,799],{"class":213},"\"Dashboard!$B$1\"",[203,801,349],{"class":239},[203,803,804,807,810,812,815],{"class":205,"line":283},[203,805,806],{"class":400},"print",[203,808,809],{"class":239},"(wb.defined_names[",[203,811,780],{"class":213},[203,813,814],{"class":239},"].attr_text)       ",[203,816,818],{"class":817},"s-wDw","# Dashboard!$B$1\n",[10,820,821,822,826,827,831],{},"Named inputs make formulas self-explanatory and keep working if the cell moves when someone inserts a row above it. A data validation list on the input cell restricts it to valid months; filters of that kind are covered in ",[14,823,825],{"href":824},"\u002Fautomating-reporting-workflows\u002Fbuilding-multi-sheet-excel-dashboards\u002Fadd-slicer-style-filters-to-an-excel-dashboard\u002F","Add a Dropdown Filter That Drives an Excel Dashboard",". Named ranges in general are covered in ",[14,828,830],{"href":829},"\u002Fgetting-started-with-python-excel-automation\u002Fworking-with-excel-formulas-in-python\u002Fcreate-named-range-in-excel-with-openpyxl\u002F","Create a Named Range in Excel with openpyxl",".",[188,833,835],{"id":834},"step-2-figures-as-formulas-over-the-table","Step 2 — Figures as formulas over the table",[10,837,838,839,842,843,846,847,850],{},"Each figure is a conditional aggregate over table columns. ",[200,840,841],{},"SUMIFS"," and ",[200,844,845],{},"COUNTIFS"," with date bounds pick the report month; ",[200,848,849],{},"EOMONTH"," finds its last day:",[193,852,854],{"className":226,"code":853,"language":228,"meta":198,"style":198},"MONTH = '\">=\"&ReportMonth, Sales[Date], \"\u003C=\"&EOMONTH(ReportMonth,0)'\nfigures = [\n    (\"Revenue this month\", f\"=SUMIFS(Sales[Revenue], Sales[Date], {MONTH})\", \"#,##0\"),\n    (\"Orders this month\", f\"=COUNTIFS(Sales[Date], {MONTH})\", \"0\"),\n    (\"Average order\", \"=IFERROR(B3\u002FB4, 0)\", \"#,##0\"),\n    (\"Last order date\", \"=MAX(Sales[Date])\", \"yyyy-mm-dd\"),\n]\nfor row, (label, formula, fmt) in enumerate(figures, start=3):\n    dash.cell(row, 1, label)\n    dash.cell(row, 2, formula).number_format = fmt\nwb.save(\"dashboard.xlsx\")\nprint(dash[\"B3\"].value)\n",[200,855,856,867,877,908,937,955,974,979,1004,1014,1028,1038],{"__ignoreMap":198},[203,857,858,861,864],{"class":205,"line":206},[203,859,860],{"class":400},"MONTH",[203,862,863],{"class":235}," =",[203,865,866],{"class":213}," '\">=\"&ReportMonth, Sales[Date], \"\u003C=\"&EOMONTH(ReportMonth,0)'\n",[203,868,869,872,874],{"class":205,"line":249},[203,870,871],{"class":239},"figures ",[203,873,307],{"class":235},[203,875,876],{"class":239}," [\n",[203,878,879,882,885,887,889,892,894,896,898,901,903,906],{"class":205,"line":256},[203,880,881],{"class":239},"    (",[203,883,884],{"class":213},"\"Revenue this month\"",[203,886,361],{"class":239},[203,888,640],{"class":235},[203,890,891],{"class":213},"\"=SUMIFS(Sales[Revenue], Sales[Date], ",[203,893,647],{"class":646},[203,895,860],{"class":400},[203,897,653],{"class":646},[203,899,900],{"class":213},")\"",[203,902,361],{"class":239},[203,904,905],{"class":213},"\"#,##0\"",[203,907,469],{"class":239},[203,909,910,912,915,917,919,922,924,926,928,930,932,935],{"class":205,"line":270},[203,911,881],{"class":239},[203,913,914],{"class":213},"\"Orders this month\"",[203,916,361],{"class":239},[203,918,640],{"class":235},[203,920,921],{"class":213},"\"=COUNTIFS(Sales[Date], ",[203,923,647],{"class":646},[203,925,860],{"class":400},[203,927,653],{"class":646},[203,929,900],{"class":213},[203,931,361],{"class":239},[203,933,934],{"class":213},"\"0\"",[203,936,469],{"class":239},[203,938,939,941,944,946,949,951,953],{"class":205,"line":283},[203,940,881],{"class":239},[203,942,943],{"class":213},"\"Average order\"",[203,945,361],{"class":239},[203,947,948],{"class":213},"\"=IFERROR(B3\u002FB4, 0)\"",[203,950,361],{"class":239},[203,952,905],{"class":213},[203,954,469],{"class":239},[203,956,957,959,962,964,967,969,972],{"class":205,"line":296},[203,958,881],{"class":239},[203,960,961],{"class":213},"\"Last order date\"",[203,963,361],{"class":239},[203,965,966],{"class":213},"\"=MAX(Sales[Date])\"",[203,968,361],{"class":239},[203,970,971],{"class":213},"\"yyyy-mm-dd\"",[203,973,469],{"class":239},[203,975,976],{"class":205,"line":301},[203,977,978],{"class":239},"]\n",[203,980,981,983,986,988,991,994,997,999,1001],{"class":205,"line":313},[203,982,388],{"class":235},[203,984,985],{"class":239}," row, (label, formula, fmt) ",[203,987,394],{"class":235},[203,989,990],{"class":400}," enumerate",[203,992,993],{"class":239},"(figures, ",[203,995,996],{"class":624},"start",[203,998,307],{"class":235},[203,1000,411],{"class":400},[203,1002,1003],{"class":239},"):\n",[203,1005,1006,1009,1011],{"class":205,"line":324},[203,1007,1008],{"class":239},"    dash.cell(row, ",[203,1010,756],{"class":400},[203,1012,1013],{"class":239},", label)\n",[203,1015,1016,1018,1020,1023,1025],{"class":205,"line":335},[203,1017,1008],{"class":239},[203,1019,486],{"class":400},[203,1021,1022],{"class":239},", formula).number_format ",[203,1024,307],{"class":235},[203,1026,1027],{"class":239}," fmt\n",[203,1029,1030,1033,1036],{"class":205,"line":352},[203,1031,1032],{"class":239},"wb.save(",[203,1034,1035],{"class":213},"\"dashboard.xlsx\"",[203,1037,349],{"class":239},[203,1039,1040,1042,1045,1048],{"class":205,"line":385},[203,1041,806],{"class":400},[203,1043,1044],{"class":239},"(dash[",[203,1046,1047],{"class":213},"\"B3\"",[203,1049,1050],{"class":239},"].value)\n",[10,1052,1053,1054,706,1057,1060,1061,1064,1065,1068,1069,842,1073,831],{},"Structured references — ",[200,1055,1056],{},"Sales[Revenue]",[200,1058,1059],{},"'Sales Data'!D2:D7"," — name the column, follow the table as it grows and survive inserted columns. ",[200,1062,1063],{},"IFERROR"," keeps the average from showing ",[200,1066,1067],{},"#DIV\u002F0!"," for a month with no orders. The pandas equivalents of these functions are covered in ",[14,1070,1072],{"href":1071},"\u002Fadvanced-data-transformation-and-cleaning\u002Fexcel-formula-equivalents-in-pandas\u002Fsumif-and-sumifs-equivalent-in-pandas\u002F","SUMIF and SUMIFS Equivalent in pandas",[14,1074,1076],{"href":1075},"\u002Fadvanced-data-transformation-and-cleaning\u002Fexcel-formula-equivalents-in-pandas\u002Faverageifs-maxifs-minifs-in-pandas\u002F","AVERAGEIFS, MAXIFS and MINIFS Equivalents in pandas",[188,1078,1080],{"id":1079},"step-3-plain-references-to-other-sheets","Step 3 — Plain references to other sheets",[10,1082,1083],{},"Not everything is a table. When a formula refers to an ordinary range on another sheet, the sheet name needs single quotes if it contains spaces or punctuation — and those quotes sit happily inside a Python string built with double quotes:",[193,1085,1087],{"className":226,"code":1086,"language":228,"meta":198,"style":198},"dash[\"A8\"] = \"North revenue this month\"\ndash[\"B8\"] = (\"=SUMIFS('Sales Data'!$D:$D, 'Sales Data'!$B:$B, \\\"North\\\", \"\n              \"'Sales Data'!$A:$A, \\\">=\\\"&ReportMonth, 'Sales Data'!$A:$A, \\\"\u003C=\\\"&EOMONTH(ReportMonth,0))\")\ndash[\"B8\"].number_format = \"#,##0\"\nwb.save(\"dashboard.xlsx\")\n",[200,1088,1089,1103,1131,1158,1171],{"__ignoreMap":198},[203,1090,1091,1093,1096,1098,1100],{"class":205,"line":206},[203,1092,720],{"class":239},[203,1094,1095],{"class":213},"\"A8\"",[203,1097,726],{"class":239},[203,1099,307],{"class":235},[203,1101,1102],{"class":213}," \"North revenue this month\"\n",[203,1104,1105,1107,1110,1112,1114,1117,1120,1123,1126,1128],{"class":205,"line":249},[203,1106,720],{"class":239},[203,1108,1109],{"class":213},"\"B8\"",[203,1111,726],{"class":239},[203,1113,307],{"class":235},[203,1115,1116],{"class":239}," (",[203,1118,1119],{"class":213},"\"=SUMIFS('Sales Data'!$D:$D, 'Sales Data'!$B:$B, ",[203,1121,1122],{"class":646},"\\\"",[203,1124,1125],{"class":213},"North",[203,1127,1122],{"class":646},[203,1129,1130],{"class":213},", \"\n",[203,1132,1133,1136,1138,1141,1143,1146,1148,1151,1153,1156],{"class":205,"line":256},[203,1134,1135],{"class":213},"              \"'Sales Data'!$A:$A, ",[203,1137,1122],{"class":646},[203,1139,1140],{"class":213},">=",[203,1142,1122],{"class":646},[203,1144,1145],{"class":213},"&ReportMonth, 'Sales Data'!$A:$A, ",[203,1147,1122],{"class":646},[203,1149,1150],{"class":213},"\u003C=",[203,1152,1122],{"class":646},[203,1154,1155],{"class":213},"&EOMONTH(ReportMonth,0))\"",[203,1157,349],{"class":239},[203,1159,1160,1162,1164,1166,1168],{"class":205,"line":270},[203,1161,720],{"class":239},[203,1163,1109],{"class":213},[203,1165,767],{"class":239},[203,1167,307],{"class":235},[203,1169,1170],{"class":213}," \"#,##0\"\n",[203,1172,1173,1175,1177],{"class":205,"line":283},[203,1174,1032],{"class":239},[203,1176,1035],{"class":213},[203,1178,349],{"class":239},[10,1180,1181,1182,1185,1186,1189],{},"Whole-column references such as ",[200,1183,1184],{},"$D:$D"," pick up new rows automatically and ignore the text header for sums. Quote every sheet name in generated formulas, even ones without spaces — ",[200,1187,1188],{},"'Summary'!A1"," is valid — so the code keeps working when a sheet is later given a name like \"Summary 2026\".",[20,1191,29,1197,29,1200,29,1203,29,1208,29,1215,29,1219,29,1225,29,1230,29,1235,29,1239,29,1245,29,1249,29,1253,29,1256,29,1260,29,1262,29,1266,29,1269,29,1273,29,1276,29,1279,29,1281,29,1283,29,1286,29,1289,29,1291,29,1294,29,1296,29,1300,29,1303,29,1306,29,1308,29,1310,29,1312,29,1314,29,1317,29,1320,29,1322,29,1324,29,1326,29,1329,29,1332,29,1336,29,1338,29,1341,29,1343,29,1346,29,1349,29,1353,29,1355,29,1357,29,1360,29,1362,29,1364,29,1367,29,1369,29,1372,29,1377,29,1383,29,1387,29,1391],{"viewBox":1192,"role":23,"ariaLabelledBy":1193,"xmlns":27,"style":1196},"187 0 386 358",[1194,1195],"ld-result-t","ld-result-d","width:100%;max-width:386px;height:auto;display:block;margin:1.5rem auto;font-family:Inter,ui-sans-serif,system-ui,sans-serif",[31,1198,1199],{"id":1194},"The dashboard after calculation",[35,1201,1202],{"id":1195},"With the report month set to September 2026, the dashboard shows revenue of 3,500, four orders, an average order of 875, a last order date of 20 September 2026 and North revenue of 2,200, all calculated by formulas from the Sales table.",[39,1204],{"x":1205,"y":42,"width":1206,"height":1207,"fill":45},"187","386","358",[39,1209],{"x":1210,"y":82,"width":1211,"height":1212,"rx":42,"fill":45,"stroke":1213,"style":1214},"207.7","344.7","28.0","var(--line,#cdd5e6)","stroke-width:1px",[39,1216],{"x":1210,"y":82,"width":1217,"height":1212,"rx":42,"fill":1218,"stroke":1213,"style":1214},"40.0","#e7ebef",[68,1220,1224],{"x":1221,"y":1222,"style":1223},"227.7","35.0","font-size:12px;font-weight:700;fill:var(--muted,#5b6780);text-anchor:middle","fx",[68,1226,1229],{"x":1227,"y":1222,"style":1228},"257.7","font-size:12px;font-weight:400;fill:var(--text,#172033);text-anchor:start;font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace","=SUMIFS(Sales[Revenue],…,ReportMonth)",[39,1231],{"x":1210,"y":1232,"width":1233,"height":1234,"rx":42,"fill":1218,"stroke":1213,"style":1214},"44.0","32.0","24.0",[39,1236],{"x":1237,"y":1232,"width":1238,"height":1234,"rx":42,"fill":1218,"stroke":1213,"style":1214},"239.7","181.3",[68,1240,1244],{"x":1241,"y":1242,"style":1243},"330.3","61.0","font-size:11px;font-weight:600;fill:var(--muted,#5b6780);text-anchor:middle","A",[39,1246],{"x":1247,"y":1232,"width":1248,"height":1234,"rx":42,"fill":1218,"stroke":1213,"style":1214},"420.9","131.4",[68,1250,1252],{"x":1251,"y":1242,"style":1243},"486.6","B",[39,1254],{"x":1210,"y":1255,"width":1233,"height":1212,"rx":42,"fill":1218,"stroke":1213,"style":1214},"68.0",[68,1257,756],{"x":1258,"y":1259,"style":1243},"223.7","87.0",[39,1261],{"x":1237,"y":1255,"width":1238,"height":1212,"rx":42,"fill":45,"stroke":1213,"style":1214},[68,1263,1265],{"x":1241,"y":1259,"style":1264},"font-size:12px;font-weight:700;fill:var(--text,#172033);text-anchor:middle","Report month",[39,1267],{"x":1247,"y":1255,"width":1248,"height":1212,"rx":42,"fill":138,"stroke":139,"style":1268},"stroke-width:1.5px",[68,1270,1272],{"x":1251,"y":1259,"style":1271},"font-size:12px;font-weight:700;fill:var(--gold-ink,#7a4e06);text-anchor:middle","Sep 2026",[39,1274],{"x":1210,"y":1275,"width":1233,"height":1212,"rx":42,"fill":1218,"stroke":1213,"style":1214},"96.0",[68,1277,486],{"x":1258,"y":1278,"style":1243},"115.0",[39,1280],{"x":1237,"y":1275,"width":1238,"height":1212,"rx":42,"fill":45,"stroke":1213,"style":1214},[39,1282],{"x":1247,"y":1275,"width":1248,"height":1212,"rx":42,"fill":45,"stroke":1213,"style":1214},[39,1284],{"x":1210,"y":1285,"width":1233,"height":1212,"rx":42,"fill":1218,"stroke":1213,"style":1214},"124.0",[68,1287,411],{"x":1258,"y":1288,"style":1243},"143.0",[39,1290],{"x":1237,"y":1285,"width":1238,"height":1212,"rx":42,"fill":45,"stroke":1213,"style":1214},[68,1292,99],{"x":1241,"y":1288,"style":1293},"font-size:12px;font-weight:400;fill:var(--text,#172033);text-anchor:middle",[39,1295],{"x":1247,"y":1285,"width":1248,"height":1212,"rx":42,"fill":85,"stroke":86,"style":1268},[68,1297,1299],{"x":1251,"y":1288,"style":1298},"font-size:12px;font-weight:700;fill:var(--brand-strong,#4338ca);text-anchor:middle","3,500",[39,1301],{"x":1210,"y":1302,"width":1233,"height":1212,"rx":42,"fill":1218,"stroke":1213,"style":1214},"152.0",[68,1304,41],{"x":1258,"y":1305,"style":1243},"171.0",[39,1307],{"x":1237,"y":1302,"width":1238,"height":1212,"rx":42,"fill":45,"stroke":1213,"style":1214},[68,1309,125],{"x":1241,"y":1305,"style":1293},[39,1311],{"x":1247,"y":1302,"width":1248,"height":1212,"rx":42,"fill":85,"stroke":86,"style":1268},[68,1313,41],{"x":1251,"y":1305,"style":1298},[39,1315],{"x":1210,"y":1316,"width":1233,"height":1212,"rx":42,"fill":1218,"stroke":1213,"style":1214},"180.0",[68,1318,517],{"x":1258,"y":1319,"style":1243},"199.0",[39,1321],{"x":1237,"y":1316,"width":1238,"height":1212,"rx":42,"fill":45,"stroke":1213,"style":1214},[68,1323,151],{"x":1241,"y":1319,"style":1293},[39,1325],{"x":1247,"y":1316,"width":1248,"height":1212,"rx":42,"fill":85,"stroke":86,"style":1268},[68,1327,1328],{"x":1251,"y":1319,"style":1298},"875",[39,1330],{"x":1210,"y":1331,"width":1233,"height":1212,"rx":42,"fill":1218,"stroke":1213,"style":1214},"208.0",[68,1333,1335],{"x":1258,"y":1334,"style":1243},"227.0","6",[39,1337],{"x":1237,"y":1331,"width":1238,"height":1212,"rx":42,"fill":45,"stroke":1213,"style":1214},[68,1339,1340],{"x":1241,"y":1334,"style":1293},"Last order date",[39,1342],{"x":1247,"y":1331,"width":1248,"height":1212,"rx":42,"fill":45,"stroke":1213,"style":1214},[68,1344,1345],{"x":1251,"y":1334,"style":1293},"2026-09-20",[39,1347],{"x":1210,"y":1348,"width":1233,"height":1212,"rx":42,"fill":1218,"stroke":1213,"style":1214},"236.0",[68,1350,1352],{"x":1258,"y":1351,"style":1243},"255.0","7",[39,1354],{"x":1237,"y":1348,"width":1238,"height":1212,"rx":42,"fill":45,"stroke":1213,"style":1214},[39,1356],{"x":1247,"y":1348,"width":1248,"height":1212,"rx":42,"fill":45,"stroke":1213,"style":1214},[39,1358],{"x":1210,"y":1359,"width":1233,"height":1212,"rx":42,"fill":1218,"stroke":1213,"style":1214},"264.0",[68,1361,406],{"x":1258,"y":149,"style":1243},[39,1363],{"x":1237,"y":1359,"width":1238,"height":1212,"rx":42,"fill":45,"stroke":1213,"style":1214},[68,1365,1366],{"x":1241,"y":149,"style":1293},"North revenue this month",[39,1368],{"x":1247,"y":1359,"width":1248,"height":1212,"rx":42,"fill":85,"stroke":86,"style":1268},[68,1370,1371],{"x":1251,"y":149,"style":1298},"2,200",[39,1373],{"x":1374,"y":1375,"width":1376,"height":1234,"rx":42,"fill":1218,"stroke":1213,"style":1214},"215.7","292.0","86.4",[68,1378,1382],{"x":1379,"y":1380,"style":1381},"258.9","308.5","font-size:11.5px;font-weight:400;fill:var(--muted,#5b6780);text-anchor:middle","Dashboard",[39,1384],{"x":1385,"y":1375,"width":1386,"height":1234,"rx":42,"fill":1218,"stroke":1213,"style":1214},"304.0","84.5",[68,1388,1390],{"x":1389,"y":1380,"style":1381},"346.3","Sales Data",[68,1392,1396],{"x":1393,"y":1394,"style":1395},"380.0","338.0","font-size:12.5px;font-weight:400;fill:var(--muted,#5b6780);text-anchor:middle","the gold cell is the input; the blue cells recalculate from it",[188,1398,1400],{"id":1399},"step-4-check-the-figures-without-excel","Step 4 — Check the figures without Excel",[10,1402,1403],{},"openpyxl writes formulas but no results, so reading the saved file back with pandas shows empty dashboard cells. Recalculate with headless LibreOffice to check the numbers, and compare them with the same figures computed in pandas:",[193,1405,1407],{"className":226,"code":1406,"language":228,"meta":198,"style":198},"import subprocess\n\nimport pandas as pd\n\nsubprocess.run([\"soffice\", \"--headless\", \"--convert-to\",\n                \"csv:Text - txt - csv (StarCalc):44,34,76,1,,0,false,true,true\", \"dashboard.xlsx\"],\n               check=True, capture_output=True, timeout=120)\nshown = dict(line.split(\",\", 1) for line in open(\"dashboard.csv\").read().splitlines() if \",\" in line)\nprint(shown[\"Revenue this month\"], shown[\"Orders this month\"], shown[\"North revenue this month\"])\n# \"3,500\" 4 \"2,200\"\n",[200,1408,1409,1416,1420,1432,1436,1457,1469,1499,1553,1574],{"__ignoreMap":198},[203,1410,1411,1413],{"class":205,"line":206},[203,1412,236],{"class":235},[203,1414,1415],{"class":239}," subprocess\n",[203,1417,1418],{"class":205,"line":249},[203,1419,253],{"emptyLinePlaceholder":252},[203,1421,1422,1424,1427,1429],{"class":205,"line":256},[203,1423,236],{"class":235},[203,1425,1426],{"class":239}," pandas ",[203,1428,243],{"class":235},[203,1430,1431],{"class":239}," pd\n",[203,1433,1434],{"class":205,"line":270},[203,1435,253],{"emptyLinePlaceholder":252},[203,1437,1438,1441,1444,1446,1449,1451,1454],{"class":205,"line":283},[203,1439,1440],{"class":239},"subprocess.run([",[203,1442,1443],{"class":213},"\"soffice\"",[203,1445,361],{"class":239},[203,1447,1448],{"class":213},"\"--headless\"",[203,1450,361],{"class":239},[203,1452,1453],{"class":213},"\"--convert-to\"",[203,1455,1456],{"class":239},",\n",[203,1458,1459,1462,1464,1466],{"class":205,"line":296},[203,1460,1461],{"class":213},"                \"csv:Text - txt - csv (StarCalc):44,34,76,1,,0,false,true,true\"",[203,1463,361],{"class":239},[203,1465,1035],{"class":213},[203,1467,1468],{"class":239},"],\n",[203,1470,1471,1474,1476,1478,1480,1483,1485,1487,1489,1492,1494,1497],{"class":205,"line":301},[203,1472,1473],{"class":624},"               check",[203,1475,307],{"class":235},[203,1477,687],{"class":400},[203,1479,361],{"class":239},[203,1481,1482],{"class":624},"capture_output",[203,1484,307],{"class":235},[203,1486,687],{"class":400},[203,1488,361],{"class":239},[203,1490,1491],{"class":624},"timeout",[203,1493,307],{"class":235},[203,1495,1496],{"class":400},"120",[203,1498,349],{"class":239},[203,1500,1501,1504,1506,1509,1512,1515,1517,1519,1522,1524,1527,1529,1532,1535,1538,1541,1544,1547,1550],{"class":205,"line":313},[203,1502,1503],{"class":239},"shown ",[203,1505,307],{"class":235},[203,1507,1508],{"class":400}," dict",[203,1510,1511],{"class":239},"(line.split(",[203,1513,1514],{"class":213},"\",\"",[203,1516,361],{"class":239},[203,1518,756],{"class":400},[203,1520,1521],{"class":239},") ",[203,1523,388],{"class":235},[203,1525,1526],{"class":239}," line ",[203,1528,394],{"class":235},[203,1530,1531],{"class":400}," open",[203,1533,1534],{"class":239},"(",[203,1536,1537],{"class":213},"\"dashboard.csv\"",[203,1539,1540],{"class":239},").read().splitlines() ",[203,1542,1543],{"class":235},"if",[203,1545,1546],{"class":213}," \",\"",[203,1548,1549],{"class":235}," in",[203,1551,1552],{"class":239}," line)\n",[203,1554,1555,1557,1560,1562,1565,1567,1569,1572],{"class":205,"line":324},[203,1556,806],{"class":400},[203,1558,1559],{"class":239},"(shown[",[203,1561,884],{"class":213},[203,1563,1564],{"class":239},"], shown[",[203,1566,914],{"class":213},[203,1568,1564],{"class":239},[203,1570,1571],{"class":213},"\"North revenue this month\"",[203,1573,382],{"class":239},[203,1575,1576],{"class":205,"line":335},[203,1577,1578],{"class":817},"# \"3,500\" 4 \"2,200\"\n",[10,1580,1581],{},"Recalculated, September shows revenue of 3,500 from four orders — an average of 875 — and North revenue of 2,200. Compute the same figures independently in pandas from the data sheet, and the two must agree:",[193,1583,1585],{"className":226,"code":1584,"language":228,"meta":198,"style":198},"import pandas as pd\n\nframe = pd.read_excel(\"dashboard.xlsx\", sheet_name=\"Sales Data\")\nmonth = frame[(frame[\"Date\"] >= \"2026-09-01\") & (frame[\"Date\"] \u003C= \"2026-09-30\")]\nexpected = {\n    \"Revenue this month\": month[\"Revenue\"].sum(),\n    \"Orders this month\": len(month),\n    \"North revenue this month\": month.loc[month[\"Region\"] == \"North\", \"Revenue\"].sum(),\n}\nprint(expected)\n# {'Revenue this month': np.int64(3500), 'Orders this month': 4, 'North revenue this month': np.int64(2200)}\n",[200,1586,1587,1597,1601,1624,1663,1673,1686,1700,1724,1729,1736],{"__ignoreMap":198},[203,1588,1589,1591,1593,1595],{"class":205,"line":206},[203,1590,236],{"class":235},[203,1592,1426],{"class":239},[203,1594,243],{"class":235},[203,1596,1431],{"class":239},[203,1598,1599],{"class":205,"line":249},[203,1600,253],{"emptyLinePlaceholder":252},[203,1602,1603,1606,1608,1611,1613,1615,1618,1620,1622],{"class":205,"line":256},[203,1604,1605],{"class":239},"frame ",[203,1607,307],{"class":235},[203,1609,1610],{"class":239}," pd.read_excel(",[203,1612,1035],{"class":213},[203,1614,361],{"class":239},[203,1616,1617],{"class":624},"sheet_name",[203,1619,307],{"class":235},[203,1621,346],{"class":213},[203,1623,349],{"class":239},[203,1625,1626,1629,1631,1634,1636,1638,1640,1643,1645,1648,1651,1653,1655,1657,1660],{"class":205,"line":270},[203,1627,1628],{"class":239},"month ",[203,1630,307],{"class":235},[203,1632,1633],{"class":239}," frame[(frame[",[203,1635,358],{"class":213},[203,1637,726],{"class":239},[203,1639,1140],{"class":235},[203,1641,1642],{"class":213}," \"2026-09-01\"",[203,1644,1521],{"class":239},[203,1646,1647],{"class":235},"&",[203,1649,1650],{"class":239}," (frame[",[203,1652,358],{"class":213},[203,1654,726],{"class":239},[203,1656,1150],{"class":235},[203,1658,1659],{"class":213}," \"2026-09-30\"",[203,1661,1662],{"class":239},")]\n",[203,1664,1665,1668,1670],{"class":205,"line":283},[203,1666,1667],{"class":239},"expected ",[203,1669,307],{"class":235},[203,1671,1672],{"class":239}," {\n",[203,1674,1675,1678,1681,1683],{"class":205,"line":296},[203,1676,1677],{"class":213},"    \"Revenue this month\"",[203,1679,1680],{"class":239},": month[",[203,1682,374],{"class":213},[203,1684,1685],{"class":239},"].sum(),\n",[203,1687,1688,1691,1694,1697],{"class":205,"line":301},[203,1689,1690],{"class":213},"    \"Orders this month\"",[203,1692,1693],{"class":239},": ",[203,1695,1696],{"class":400},"len",[203,1698,1699],{"class":239},"(month),\n",[203,1701,1702,1705,1708,1710,1712,1715,1718,1720,1722],{"class":205,"line":313},[203,1703,1704],{"class":213},"    \"North revenue this month\"",[203,1706,1707],{"class":239},": month.loc[month[",[203,1709,364],{"class":213},[203,1711,726],{"class":239},[203,1713,1714],{"class":235},"==",[203,1716,1717],{"class":213}," \"North\"",[203,1719,361],{"class":239},[203,1721,374],{"class":213},[203,1723,1685],{"class":239},[203,1725,1726],{"class":205,"line":324},[203,1727,1728],{"class":239},"}\n",[203,1730,1731,1733],{"class":205,"line":335},[203,1732,806],{"class":400},[203,1734,1735],{"class":239},"(expected)\n",[203,1737,1738],{"class":205,"line":352},[203,1739,1740],{"class":817},"# {'Revenue this month': np.int64(3500), 'Orders this month': 4, 'North revenue this month': np.int64(2200)}\n",[10,1742,1743,1744,1747,1748,831],{},"Wrapped in a test that compares ",[200,1745,1746],{},"expected"," with the recalculated values, this check runs every time the dashboard layout changes. A mismatch points at a formula with a wrong column, date bound or sheet reference. Other ways to recalculate are covered in ",[14,1749,1751],{"href":1750},"\u002Fgetting-started-with-python-excel-automation\u002Fworking-with-excel-formulas-in-python\u002Frecalculate-excel-formulas-without-excel-in-python\u002F","Recalculate Excel Formulas Without Excel in Python",[20,1753,29,1758,29,1761,29,1764,29,1767,29,1772,29,1779,29,1785,29,1790,29,1796,29,1803,29,1807,29,1812,29,1816,29,1822,29,1826,29,1832,29,1835,29,1840,29,1845,29,1849,29,1853,29,1858,29,1861,29,1866,29,1869,29,1874,29,1877],{"viewBox":1754,"role":23,"ariaLabelledBy":1755,"xmlns":27,"style":28},"4 0 752 233",[1756,1757],"ld-choice-t","ld-choice-d",[31,1759,1760],{"id":1756},"A dashboard of formulas or a dashboard of values",[35,1762,1763],{"id":1757},"A formula dashboard updates when the data or the report month changes and stays consistent with the data sheet, but other programs see empty cells unless the file is recalculated. A value dashboard is a fixed snapshot that any program can read, but goes stale when data is added or readers want another period.",[39,1765],{"x":41,"y":42,"width":43,"height":1766,"fill":45},"233",[39,1768],{"x":81,"y":82,"width":1769,"height":1770,"rx":1771,"fill":53,"stroke":54,"style":55},"351.0","201.0","14",[57,1773,1775],{"transform":1774},"translate(182.5,29.0) scale(1.083)",[61,1776],{"d":1777,"fill":64,"stroke":65,"style":1778},"M20 11a8 8 0 1 0-2.3 5.7 M20 4v7h-7","stroke-width:1.66px;stroke-linecap:round;stroke-linejoin:round",[68,1780,1784],{"x":1781,"y":1782,"style":1783},"195.5","78.0","font-size:14px;font-weight:700;fill:var(--teal-ink,#0b6157);text-anchor:middle","Formulas",[205,1786],{"x1":1787,"y1":1788,"x2":1789,"y2":1788,"stroke":54,"style":1214},"36.0","91.0","355.0",[68,1791,1795],{"x":1792,"y":1793,"style":1794},"60.0","111.0","font-size:12px;font-weight:400;fill:var(--text,#172033);text-anchor:start","updates with the data",[57,1797,1799],{"transform":1798},"translate(38.5,99.5) scale(0.625)",[61,1800],{"d":1801,"fill":64,"stroke":54,"style":1802},"M5 12.5l4.5 4.5L19 7","stroke-width:2.88px;stroke-linecap:round;stroke-linejoin:round",[68,1804,1806],{"x":1792,"y":1805,"style":1794},"137.0","readers change inputs",[57,1808,1810],{"transform":1809},"translate(38.5,125.5) scale(0.625)",[61,1811],{"d":1801,"fill":64,"stroke":54,"style":1802},[68,1813,1815],{"x":1792,"y":1814,"style":1794},"163.0","empty for non-calculating readers",[57,1817,1819],{"transform":1818},"translate(38.5,151.5) scale(0.625)",[61,1820],{"d":1821,"fill":64,"stroke":165,"style":1802},"M6 6l12 12 M18 6L6 18",[68,1823,1825],{"x":1792,"y":1824,"style":1794},"189.0","extend tables as data grows",[57,1827,1829],{"transform":1828},"translate(38.5,177.5) scale(0.625)",[61,1830],{"d":1831,"fill":64,"stroke":139,"style":1802},"M12 3.5l9.5 17h-19z M12 10v5 M12 17.8v.4",[39,1833],{"x":1834,"y":82,"width":1769,"height":1770,"rx":1771,"fill":138,"stroke":139,"style":55},"389.0",[57,1836,1838],{"transform":1837},"translate(551.5,29.0) scale(1.083)",[61,1839],{"d":63,"fill":64,"stroke":146,"style":1778},[68,1841,1844],{"x":1842,"y":1782,"style":1843},"564.5","font-size:14px;font-weight:700;fill:var(--gold-ink,#7a4e06);text-anchor:middle","Values from pandas",[205,1846],{"x1":1847,"y1":1788,"x2":1848,"y2":1788,"stroke":139,"style":1214},"405.0","724.0",[68,1850,1852],{"x":1851,"y":1793,"style":1794},"429.0","readable by any program",[57,1854,1856],{"transform":1855},"translate(407.5,99.5) scale(0.625)",[61,1857],{"d":1801,"fill":64,"stroke":54,"style":1802},[68,1859,1860],{"x":1851,"y":1805,"style":1794},"exactly what was computed",[57,1862,1864],{"transform":1863},"translate(407.5,125.5) scale(0.625)",[61,1865],{"d":1801,"fill":64,"stroke":54,"style":1802},[68,1867,1868],{"x":1851,"y":1814,"style":1794},"stale after edits",[57,1870,1872],{"transform":1871},"translate(407.5,151.5) scale(0.625)",[61,1873],{"d":1821,"fill":64,"stroke":165,"style":1802},[68,1875,1876],{"x":1851,"y":1824,"style":1794},"one period per file",[57,1878,1880],{"transform":1879},"translate(407.5,177.5) scale(0.625)",[61,1881],{"d":1821,"fill":64,"stroke":165,"style":1802},[188,1883,1885],{"id":1884},"step-5-keep-the-table-in-step-with-new-data","Step 5 — Keep the table in step with new data",[10,1887,1888],{},"Structured references follow the table — but the table itself only grows when Excel adds rows to it. When a script appends rows to the data sheet with openpyxl, extend the table's range as well, or the new rows fall outside every formula:",[193,1890,1892],{"className":226,"code":1891,"language":228,"meta":198,"style":198},"from openpyxl import load_workbook\n\nwb = load_workbook(\"dashboard.xlsx\")\ndata = wb[\"Sales Data\"]\ndata.append([dt.date(2026, 9, 28), \"East\", \"Coffee\", 1100, 22])\ntable = data.tables[\"Sales\"]\ntable.ref = f\"A1:E{data.max_row}\"\ntable.autoFilter.ref = table.ref\nwb.save(\"dashboard.xlsx\")\nprint(table.ref)                                       # A1:E8\n",[200,1893,1894,1905,1909,1922,1935,1970,1984,2005,2015,2023],{"__ignoreMap":198},[203,1895,1896,1898,1900,1902],{"class":205,"line":206},[203,1897,259],{"class":235},[203,1899,262],{"class":239},[203,1901,236],{"class":235},[203,1903,1904],{"class":239}," load_workbook\n",[203,1906,1907],{"class":205,"line":249},[203,1908,253],{"emptyLinePlaceholder":252},[203,1910,1911,1913,1915,1918,1920],{"class":205,"line":256},[203,1912,304],{"class":239},[203,1914,307],{"class":235},[203,1916,1917],{"class":239}," load_workbook(",[203,1919,1035],{"class":213},[203,1921,349],{"class":239},[203,1923,1924,1926,1928,1931,1933],{"class":205,"line":270},[203,1925,338],{"class":239},[203,1927,307],{"class":235},[203,1929,1930],{"class":239}," wb[",[203,1932,346],{"class":213},[203,1934,978],{"class":239},[203,1936,1937,1940,1942,1944,1946,1948,1950,1952,1954,1956,1958,1960,1963,1965,1968],{"class":205,"line":283},[203,1938,1939],{"class":239},"data.append([dt.date(",[203,1941,401],{"class":400},[203,1943,361],{"class":239},[203,1945,446],{"class":400},[203,1947,361],{"class":239},[203,1949,601],{"class":400},[203,1951,414],{"class":239},[203,1953,522],{"class":213},[203,1955,361],{"class":239},[203,1957,456],{"class":213},[203,1959,361],{"class":239},[203,1961,1962],{"class":400},"1100",[203,1964,361],{"class":239},[203,1966,1967],{"class":400},"22",[203,1969,382],{"class":239},[203,1971,1972,1975,1977,1980,1982],{"class":205,"line":296},[203,1973,1974],{"class":239},"table ",[203,1976,307],{"class":235},[203,1978,1979],{"class":239}," data.tables[",[203,1981,630],{"class":213},[203,1983,978],{"class":239},[203,1985,1986,1989,1991,1994,1996,1998,2000,2002],{"class":205,"line":301},[203,1987,1988],{"class":239},"table.ref ",[203,1990,307],{"class":235},[203,1992,1993],{"class":235}," f",[203,1995,643],{"class":213},[203,1997,647],{"class":646},[203,1999,650],{"class":239},[203,2001,653],{"class":646},[203,2003,2004],{"class":213},"\"\n",[203,2006,2007,2010,2012],{"class":205,"line":313},[203,2008,2009],{"class":239},"table.autoFilter.ref ",[203,2011,307],{"class":235},[203,2013,2014],{"class":239}," table.ref\n",[203,2016,2017,2019,2021],{"class":205,"line":324},[203,2018,1032],{"class":239},[203,2020,1035],{"class":213},[203,2022,349],{"class":239},[203,2024,2025,2027,2030],{"class":205,"line":335},[203,2026,806],{"class":400},[203,2028,2029],{"class":239},"(table.ref)                                       ",[203,2031,2032],{"class":817},"# A1:E8\n",[10,2034,2035],{},"After this, recalculating shows September revenue of 4,600 from five orders. Forgetting the range update is the most common reason a formula-driven dashboard \"stops counting\" new data.",[188,2037,2039],{"id":2038},"step-6-compare-with-the-previous-month","Step 6 — Compare with the previous month",[10,2041,2042,2043,2046],{},"Once the month is an input, comparisons come almost free. ",[200,2044,2045],{},"EDATE(ReportMonth,-1)"," is the first day of the previous month, so last month's revenue and the change are two more formulas:",[193,2048,2050],{"className":226,"code":2049,"language":228,"meta":198,"style":198},"dash = wb[\"Dashboard\"]\ndash[\"A10\"] = \"Revenue last month\"\ndash[\"B10\"] = ('=SUMIFS(Sales[Revenue], Sales[Date], \">=\"&EDATE(ReportMonth,-1), '\n               'Sales[Date], \"\u003C\"&ReportMonth)')\ndash[\"A11\"] = \"Change vs last month\"\ndash[\"B11\"] = '=IFERROR(B3\u002FB10-1, \"\")'\ndash[\"B10\"].number_format = \"#,##0\"\ndash[\"B11\"].number_format = \"+0.0%;-0.0%;0.0%\"\nwb.save(\"dashboard.xlsx\")\n",[200,2051,2052,2065,2079,2095,2102,2116,2130,2142,2155],{"__ignoreMap":198},[203,2053,2054,2056,2058,2060,2063],{"class":205,"line":206},[203,2055,316],{"class":239},[203,2057,307],{"class":235},[203,2059,1930],{"class":239},[203,2061,2062],{"class":213},"\"Dashboard\"",[203,2064,978],{"class":239},[203,2066,2067,2069,2072,2074,2076],{"class":205,"line":249},[203,2068,720],{"class":239},[203,2070,2071],{"class":213},"\"A10\"",[203,2073,726],{"class":239},[203,2075,307],{"class":235},[203,2077,2078],{"class":213}," \"Revenue last month\"\n",[203,2080,2081,2083,2086,2088,2090,2092],{"class":205,"line":256},[203,2082,720],{"class":239},[203,2084,2085],{"class":213},"\"B10\"",[203,2087,726],{"class":239},[203,2089,307],{"class":235},[203,2091,1116],{"class":239},[203,2093,2094],{"class":213},"'=SUMIFS(Sales[Revenue], Sales[Date], \">=\"&EDATE(ReportMonth,-1), '\n",[203,2096,2097,2100],{"class":205,"line":270},[203,2098,2099],{"class":213},"               'Sales[Date], \"\u003C\"&ReportMonth)'",[203,2101,349],{"class":239},[203,2103,2104,2106,2109,2111,2113],{"class":205,"line":283},[203,2105,720],{"class":239},[203,2107,2108],{"class":213},"\"A11\"",[203,2110,726],{"class":239},[203,2112,307],{"class":235},[203,2114,2115],{"class":213}," \"Change vs last month\"\n",[203,2117,2118,2120,2123,2125,2127],{"class":205,"line":296},[203,2119,720],{"class":239},[203,2121,2122],{"class":213},"\"B11\"",[203,2124,726],{"class":239},[203,2126,307],{"class":235},[203,2128,2129],{"class":213}," '=IFERROR(B3\u002FB10-1, \"\")'\n",[203,2131,2132,2134,2136,2138,2140],{"class":205,"line":301},[203,2133,720],{"class":239},[203,2135,2085],{"class":213},[203,2137,767],{"class":239},[203,2139,307],{"class":235},[203,2141,1170],{"class":213},[203,2143,2144,2146,2148,2150,2152],{"class":205,"line":313},[203,2145,720],{"class":239},[203,2147,2122],{"class":213},[203,2149,767],{"class":239},[203,2151,307],{"class":235},[203,2153,2154],{"class":213}," \"+0.0%;-0.0%;0.0%\"\n",[203,2156,2157,2159,2161],{"class":205,"line":324},[203,2158,1032],{"class":239},[203,2160,1035],{"class":213},[203,2162,349],{"class":239},[10,2164,2165,2166,2168,2169,831],{},"Recalculated with the extra September row from Step 5, August revenue is 2,150 and the change shows +114.0%. Change the report month to August and every figure — including the comparison, which now looks at July — follows. The ",[200,2167,1063],{}," returns an empty string when there is no previous month to compare with, rather than a division error. Growth calculations in pandas are covered in ",[14,2170,2172],{"href":2171},"\u002Fadvanced-data-transformation-and-cleaning\u002Fexcel-formula-equivalents-in-pandas\u002Frunning-totals-and-year-over-year-growth-in-pandas\u002F","Running Totals and Year-over-Year Growth in pandas",[188,2174,2176],{"id":2175},"common-pitfalls","Common pitfalls",[2178,2179,2180,2192,2201,2213],"ul",{},[2181,2182,2183,2187,2188,2191],"li",{},[2184,2185,2186],"strong",{},"Unquoted sheet names."," ",[200,2189,2190],{},"=SUM(Sales Data!D:D)"," is a syntax error; quote names with spaces, and preferably all names.",[2181,2193,2194,2187,2197,2200],{},[2184,2195,2196],{},"Hard-coded months in formulas.",[200,2198,2199],{},"\">=2026-09-01\""," in every formula means editing every formula next month. Reference one input cell.",[2181,2202,2203,2187,2206,842,2209,2212],{},[2184,2204,2205],{},"Volatile helpers.",[200,2207,2208],{},"INDIRECT",[200,2210,2211],{},"OFFSET"," recalculate on every change and break silently when sheets are renamed. Table references and named cells do the same jobs more robustly.",[2181,2214,2215,2218],{},[2184,2216,2217],{},"Readers of the file that do not calculate."," If another program reads the dashboard, recalculate the file or store the values too.",[188,2220,2222],{"id":2221},"conclusion","Conclusion",[10,2224,2225,2226,361,2228,2230,2231,2233],{},"A formula-driven dashboard stays consistent with its data and lets readers change inputs. Put inputs such as the report month in named cells, compute figures with ",[200,2227,841],{},[200,2229,845],{}," and friends over structured table references, quote sheet names in plain references, guard divisions with ",[200,2232,1063],{},", extend the table's range whenever a script adds data, and check the results by recalculating the file with LibreOffice.",[188,2235,2237],{"id":2236},"frequently-asked-questions","Frequently asked questions",[10,2239,2240,2243],{},[2184,2241,2242],{},"Should dashboard figures be formulas or values?","\nFormulas when readers will change inputs such as the report month, or when data is added to the workbook after it is generated. Values when the dashboard is a fixed snapshot. Formulas keep the dashboard and data consistent; values are simpler for other programs to read.",[10,2245,2246,2249],{},[2184,2247,2248],{},"How do I reference a sheet name with spaces in a formula?","\nWrap it in single quotes, as in ='Sales Data'!D2. Inside a Python string that contains double quotes, keep the single quotes as they are.",[10,2251,2252,2255],{},[2184,2253,2254],{},"Why are my dashboard cells empty when pandas reads the file?","\nopenpyxl writes formulas without calculated results. Excel calculates them when the file is opened, but pandas and other readers see nothing. Recalculate the file, for example with LibreOffice, or also store the values if other programs must read them.",[10,2257,2258,2265,2266,2268],{},[2184,2259,2260,2261,2264],{},"What is the advantage of table references like Sales",[203,2262,2263],{},"Revenue","?","\nThey follow the table as it grows, name the column instead of a letter and survive columns being inserted. A formula over Sales",[203,2267,2263],{}," keeps working when rows are added inside the table.",[188,2270,2272],{"id":2271},"related","Related",[2178,2274,2275,2281,2288,2295],{},[2181,2276,2277,2278,2280],{},"Up one level: ",[14,2279,17],{"href":16}," — dashboards across sheets.",[2181,2282,2283,2287],{},[14,2284,2286],{"href":2285},"\u002Fautomating-reporting-workflows\u002Fbuilding-multi-sheet-excel-dashboards\u002Fadd-a-kpi-summary-block-to-an-excel-dashboard\u002F","Add a KPI Summary Block to an Excel Dashboard"," — the same figures presented as tiles.",[2181,2289,2290,2294],{},[14,2291,2293],{"href":2292},"\u002Fgetting-started-with-python-excel-automation\u002Fworking-with-excel-formulas-in-python\u002Fuse-structured-table-references-in-formulas-from-python\u002F","Use Structured Table References in Formulas from Python"," — table references in depth.",[2181,2296,2297,2301],{},[14,2298,2300],{"href":2299},"\u002Fautomating-reporting-workflows\u002Fbuilding-multi-sheet-excel-dashboards\u002Fbuild-a-dashboard-sheet-with-charts-from-multiple-tabs\u002F","Build a Dashboard Sheet with Charts from Multiple Tabs"," — charts alongside the figures.",[2303,2304,2305],"style",{},"html pre.shiki code .sMTad, html code.shiki .sMTad{--shiki-default:#6F42C1;--shiki-dark:#FFB757}html pre.shiki code .srMev, html code.shiki .srMev{--shiki-default:#032F62;--shiki-dark:#ADDCFF}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .s-kum, html code.shiki .s-kum{--shiki-default:#D73A49;--shiki-dark:#FF9492}html pre.shiki code .skGVy, html code.shiki .skGVy{--shiki-default:#24292E;--shiki-dark:#F0F3F6}html pre.shiki code .sP0c6, html code.shiki .sP0c6{--shiki-default:#005CC5;--shiki-dark:#91CBFF}html pre.shiki code .sa561, html code.shiki .sa561{--shiki-default:#E36209;--shiki-dark:#FFB757}html pre.shiki code .sSjpA, html code.shiki .sSjpA{--shiki-default:#005CC5;--shiki-dark:#FF9492}html pre.shiki code .s-wDw, html code.shiki .s-wDw{--shiki-default:#6A737D;--shiki-dark:#BDC4CC}",{"title":198,"searchDepth":249,"depth":249,"links":2307},[2308,2309,2310,2311,2312,2313,2314,2315,2316,2317,2318],{"id":190,"depth":249,"text":191},{"id":698,"depth":249,"text":699},{"id":834,"depth":249,"text":835},{"id":1079,"depth":249,"text":1080},{"id":1399,"depth":249,"text":1400},{"id":1884,"depth":249,"text":1885},{"id":2038,"depth":249,"text":2039},{"id":2175,"depth":249,"text":2176},{"id":2221,"depth":249,"text":2222},{"id":2236,"depth":249,"text":2237},{"id":2271,"depth":249,"text":2272},"2026-09-23","Build an Excel dashboard whose figures are live formulas pointing at the data sheets — SUMIFS and COUNTIFS over a table, a named report-month cell readers can change, quoted sheet names, errors handled with IFERROR — so the dashboard updates when the data does, and check the results without Excel.","md",[2323,2325,2327,2329],{"q":2242,"a":2324},"Formulas when readers will change inputs such as the report month, or when data is added to the workbook after it is generated. Values when the dashboard is a fixed snapshot. Formulas keep the dashboard and data consistent; values are simpler for other programs to read.",{"q":2248,"a":2326},"Wrap it in single quotes, as in ='Sales Data'!D2. Inside a Python string that contains double quotes, keep the single quotes as they are.",{"q":2254,"a":2328},"openpyxl writes formulas without calculated results. Excel calculates them when the file is opened, but pandas and other readers see nothing. Recalculate the file, for example with LibreOffice, or also store the values if other programs must read them.",{"q":2330,"a":2331},"What is the advantage of table references like Sales[Revenue]?","They follow the table as it grows, name the column instead of a letter and survive columns being inserted. A formula over Sales[Revenue] keeps working when rows are added inside the table.","link dashboard cells to data sheets with formulas",null,{"breadcrumb":2335},[2336,2339,2342],{"name":2337,"item":2338},"Home","\u002F",{"name":2340,"item":2341},"Automating Reporting Workflows with Python and Excel","\u002Fautomating-reporting-workflows\u002F",{"name":17,"item":16},"\u002Fautomating-reporting-workflows\u002Fbuilding-multi-sheet-excel-dashboards\u002Flink-dashboard-cells-to-data-sheets-with-formulas",{"title":2345,"description":2346},"Link Excel Dashboard Cells to Data Sheets with Formulas (Python)","Write live dashboard formulas with openpyxl — SUMIFS and COUNTIFS over structured table references, a defined name for the report month, quoted sheet names, IFERROR, extending the table as data grows, and verifying the figures with LibreOffice.","link-dashboard-cells-to-data-sheets-with-formulas","automating-reporting-workflows\u002Fbuilding-multi-sheet-excel-dashboards\u002Flink-dashboard-cells-to-data-sheets-with-formulas\u002Findex",[2350,2351,2352],"report-layouts","excel-formulas","openpyxl","how-to","wH3DeXNQx28EzHjJCGLO_nmopHVKt83wnr6q0nW8lKU",[2356,2360],{"title":2357,"path":2358,"stem":2359,"children":-1},"Lay Out a Dashboard Sheet on a Grid","\u002Fautomating-reporting-workflows\u002Fbuilding-multi-sheet-excel-dashboards\u002Flay-out-a-dashboard-sheet-on-a-grid","automating-reporting-workflows\u002Fbuilding-multi-sheet-excel-dashboards\u002Flay-out-a-dashboard-sheet-on-a-grid\u002Findex",{"title":2361,"path":2362,"stem":2363,"children":-1},"Write Multiple DataFrames to One Excel File","\u002Fautomating-reporting-workflows\u002Fbuilding-multi-sheet-excel-dashboards\u002Fwrite-multiple-dataframes-to-one-excel-file","automating-reporting-workflows\u002Fbuilding-multi-sheet-excel-dashboards\u002Fwrite-multiple-dataframes-to-one-excel-file\u002Findex",[2365,2367],{"path":2366,"title":17},"\u002Fautomating-reporting-workflows\u002Fbuilding-multi-sheet-excel-dashboards",{"path":2368,"title":2340},"\u002Fautomating-reporting-workflows",[],[2371,2375,2378,2381,2384,2387],{"path":2372,"title":2373,"kind":2374},"\u002Fautomating-reporting-workflows\u002Fbuilding-finance-and-operations-reports","Building Finance and Operations Reports in Excel with Python","guide",{"path":2376,"title":2377,"kind":2353},"\u002Fautomating-reporting-workflows\u002Fbuilding-finance-and-operations-reports\u002Fallocate-shared-costs-across-departments","Allocate Shared Costs Across Departments with Python",{"path":2379,"title":2380,"kind":2353},"\u002Fautomating-reporting-workflows\u002Fbuilding-finance-and-operations-reports\u002Fbuild-a-bank-reconciliation-report","Build a Bank Reconciliation Report with Python and Excel",{"path":2382,"title":2383,"kind":2353},"\u002Fautomating-reporting-workflows\u002Fbuilding-finance-and-operations-reports\u002Fbuild-a-bill-of-materials-cost-rollup","Build a Bill of Materials Cost Rollup",{"path":2385,"title":2386,"kind":2353},"\u002Fautomating-reporting-workflows\u002Fbuilding-finance-and-operations-reports\u002Fbuild-a-break-even-analysis-in-excel-with-python","Build a Break-Even Analysis in Excel with Python",{"path":2388,"title":2389,"kind":2390},"\u002Fautomating-reporting-workflows\u002Fbuilding-finance-and-operations-reports\u002Fbuild-a-budget-vs-actual-variance-report","Build a Budget vs Actual Variance Report in Excel with Python","compare",1790972129496]