[{"data":1,"prerenderedAt":1419},["ShallowReactive",2],{"doc:\u002Fgetting-started-with-python-excel-automation\u002Fusing-python-in-excel\u002Freference-cells-ranges-and-tables-with-xl-in-python-in-excel":3,"surround:\u002Fgetting-started-with-python-excel-automation\u002Fusing-python-in-excel\u002Freference-cells-ranges-and-tables-with-xl-in-python-in-excel":1387,"ancestors:\u002Fgetting-started-with-python-excel-automation\u002Fusing-python-in-excel\u002Freference-cells-ranges-and-tables-with-xl-in-python-in-excel":1395,"children:\u002Fgetting-started-with-python-excel-automation\u002Fusing-python-in-excel\u002Freference-cells-ranges-and-tables-with-xl-in-python-in-excel":1400,"related:\u002Fgetting-started-with-python-excel-automation\u002Fusing-python-in-excel\u002Freference-cells-ranges-and-tables-with-xl-in-python-in-excel":1401},{"id":4,"title":5,"body":6,"dateModified":1354,"datePublished":1354,"description":1355,"extension":1356,"faq":1357,"keyword":1368,"kind":1369,"meta":1370,"navigation":695,"path":1378,"seo":1379,"slug":1381,"stem":1382,"topics":1383,"type":1385,"__hash__":1386},"docs\u002Fgetting-started-with-python-excel-automation\u002Fusing-python-in-excel\u002Freference-cells-ranges-and-tables-with-xl-in-python-in-excel\u002Findex.md","Reference Cells, Ranges and Tables with xl() in Python in Excel",{"type":7,"value":8,"toc":1340},"minimark",[9,32,160,165,201,221,225,244,335,341,345,352,421,428,500,504,525,628,638,642,651,770,780,859,863,874,970,981,985,996,1084,1096,1100,1212,1223,1227,1233,1240,1244,1255,1259,1265,1275,1284,1290,1296,1300,1336],[10,11,12,13,17,18,21,22,25,26,31],"p",{},"Python in Excel runs your code in a Microsoft cloud container that cannot see your disk, cannot reach the\nnetwork and has never heard of ",[14,15,16],"code",{},"pd.read_excel(\"sales.xlsx\")",". The workbook it lives in is the one data\nsource it has, and the only door into that workbook is a single function: ",[14,19,20],{},"xl()",". Every cell, range,\ntable, name and Power Query result a ",[14,23,24],{},"=PY"," formula uses comes through it. This guide, part of\n",[27,28,30],"a",{"href":29},"\u002Fgetting-started-with-python-excel-automation\u002Fusing-python-in-excel\u002F","Using Python in Excel",", covers\neach kind of reference, what Python receives back, and the choices that keep a formula working when the\ndata grows.",[33,34,42,43,42,47,42,51,42,58,42,67,42,74,42,79,42,83,42,90,42,95,42,99,42,104,42,108,42,111,42,115,42,118,42,121,42,125,42,128,42,131,42,135,42,138,42,143,42,148,42,151,42,154],"svg",{"viewBox":35,"role":36,"ariaLabelledBy":37,"xmlns":40,"style":41},"0 0 760 156","img",[38,39],"xlr-door-t","xlr-door-d","http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg","width:100%;max-width:760px;height:auto;display:block;margin:1.5rem auto;font-family:Inter,ui-sans-serif,system-ui,sans-serif","\n  ",[44,45,46],"title",{"id":38},"The only path from workbook data to Python code",[48,49,50],"desc",{"id":39},"Workbook cells, tables, names and Power Query results pass through the xl function into the cloud Python runtime, which returns a result to the cell that holds the formula.",[52,53],"rect",{"x":54,"y":54,"width":55,"height":56,"fill":57},"0","760","156","#ffffff",[52,59],{"x":60,"y":60,"width":61,"height":62,"rx":63,"fill":64,"stroke":65,"style":66},"20","150","86","12","#e7ebef","var(--line,#cdd5e6)","stroke-width:2px",[68,69,73],"text",{"x":70,"y":71,"style":72},"95","50","font-size:14px;font-weight:700;fill:var(--muted,#5b6780);text-anchor:middle","workbook",[68,75,78],{"x":70,"y":76,"style":77},"72","font-size:11.5px;font-weight:400;fill:var(--muted,#5b6780);text-anchor:middle","cells, tables,",[68,80,82],{"x":70,"y":81,"style":77},"92","names, queries",[84,85],"line",{"x1":86,"y1":87,"x2":88,"y2":87,"stroke":89,"style":66},"175","63","204","var(--brand,#5b5cf0)",[91,92],"polygon",{"points":93,"fill":94},"207,63 198,58 198,68","#5b5cf0",[52,96],{"x":97,"y":60,"width":61,"height":62,"rx":63,"fill":98,"stroke":89,"style":66},"210","#f0f4ff",[68,100,103],{"x":101,"y":71,"style":102},"285","font-size:14px;font-weight:700;fill:var(--brand-strong,#4338ca);text-anchor:middle","xl(\"…\")",[68,105,107],{"x":101,"y":76,"style":106},"font-size:11.5px;font-weight:400;fill:var(--text,#172033);text-anchor:middle","the one door",[68,109,110],{"x":101,"y":81,"style":106},"into Python",[84,112],{"x1":113,"y1":87,"x2":114,"y2":87,"stroke":89,"style":66},"365","394",[91,116],{"points":117,"fill":94},"397,63 388,58 388,68",[52,119],{"x":120,"y":60,"width":61,"height":62,"rx":63,"fill":98,"stroke":89,"style":66},"400",[68,122,124],{"x":123,"y":71,"style":102},"475","cloud runtime",[68,126,127],{"x":123,"y":76,"style":106},"pandas, numpy,",[68,129,130],{"x":123,"y":81,"style":106},"matplotlib",[84,132],{"x1":133,"y1":87,"x2":134,"y2":87,"stroke":89,"style":66},"555","584",[91,136],{"points":137,"fill":94},"587,63 578,58 578,68",[52,139],{"x":140,"y":60,"width":61,"height":62,"rx":63,"fill":141,"stroke":142,"style":66},"590","#d9f4f1","var(--teal,#0f9488)",[68,144,147],{"x":145,"y":71,"style":146},"665","font-size:14px;font-weight:700;fill:var(--teal-ink,#0b6157);text-anchor:middle","=PY cell",[68,149,150],{"x":145,"y":76,"style":106},"object or",[68,152,153],{"x":145,"y":81,"style":106},"Excel values",[68,155,159],{"x":156,"y":157,"style":158},"380","140","font-size:12.5px;font-weight:400;fill:var(--muted,#5b6780);text-anchor:middle","no files, no network: if it is not in the workbook, xl() cannot reach it",[161,162,164],"h2",{"id":163},"prerequisites","Prerequisites",[166,167,168,172],"ul",{},[169,170,171],"li",{},"A Microsoft 365 subscription and Excel build where Python in Excel is available. It needs an internet\nconnection, and it is not offered on device-based licences, shared computer activation, or the iPad,\niPhone and Android apps.",[169,173,174,175,178,179,182,183,182,186,182,189,192,193,196,197,200],{},"A workbook containing some data. The examples assume a sheet with an Excel table named ",[14,176,177],{},"Sales","\n(columns ",[14,180,181],{},"Date",", ",[14,184,185],{},"Region",[14,187,188],{},"Rep",[14,190,191],{},"Amount","), a single-cell named range ",[14,194,195],{},"TaxRate",", and a second sheet\ncalled ",[14,198,199],{},"Raw data",".",[10,202,203,204,208,209,212,213,216,217,220],{},"To start a Python formula, select a cell and either choose ",[205,206,207],"strong",{},"Formulas → Insert Python",", or type ",[14,210,211],{},"=PY(","\nand pick the Python entry from AutoComplete. The cell switches into Python editing mode: ",[205,214,215],{},"Enter"," adds a\nnew line and ",[205,218,219],{},"Ctrl+Enter"," commits the formula.",[161,222,224],{"id":223},"step-1-reference-a-single-cell","Step 1 — Reference a single cell",[10,226,227,228,231,232,235,236,239,240,243],{},"A one-cell reference returns a plain Python value: a number becomes an ",[14,229,230],{},"int"," or ",[14,233,234],{},"float",", text a ",[14,237,238],{},"str",", a\nlogical a ",[14,241,242],{},"bool",", and a date arrives as a datetime rather than as Excel's serial number.",[245,246,251],"pre",{"className":247,"code":248,"language":249,"meta":250,"style":250},"language-python shiki shiki-themes github-light github-dark-high-contrast","rate = xl(\"B1\")          # 0.2 from cell B1\nlabel = xl(\"A1\")         # \"Tax rate\"\nf\"{label}: {rate:.0%}\"   # returned to the cell as text\n","python","",[14,252,253,279,298],{"__ignoreMap":250},[254,255,257,261,265,268,272,275],"span",{"class":84,"line":256},1,[254,258,260],{"class":259},"skGVy","rate ",[254,262,264],{"class":263},"s-kum","=",[254,266,267],{"class":259}," xl(",[254,269,271],{"class":270},"srMev","\"B1\"",[254,273,274],{"class":259},")          ",[254,276,278],{"class":277},"s-wDw","# 0.2 from cell B1\n",[254,280,282,285,287,289,292,295],{"class":84,"line":281},2,[254,283,284],{"class":259},"label ",[254,286,264],{"class":263},[254,288,267],{"class":259},[254,290,291],{"class":270},"\"A1\"",[254,293,294],{"class":259},")         ",[254,296,297],{"class":277},"# \"Tax rate\"\n",[254,299,301,304,307,311,314,317,320,322,325,328,330,332],{"class":84,"line":300},3,[254,302,303],{"class":263},"f",[254,305,306],{"class":270},"\"",[254,308,310],{"class":309},"sSjpA","{",[254,312,313],{"class":259},"label",[254,315,316],{"class":309},"}",[254,318,319],{"class":270},": ",[254,321,310],{"class":309},[254,323,324],{"class":259},"rate",[254,326,327],{"class":263},":.0%",[254,329,316],{"class":309},[254,331,306],{"class":270},[254,333,334],{"class":277},"   # returned to the cell as text\n",[10,336,337,338,340],{},"While you are editing a Python formula you do not have to type these references. Selecting cells with the\nmouse inserts the matching ",[14,339,103],{}," call at the cursor, which avoids typos in sheet names that contain\nspaces.",[161,342,344],{"id":343},"step-2-reference-a-range-with-or-without-headers","Step 2 — Reference a range, with or without headers",[10,346,347,348,351],{},"A multi-cell reference returns a pandas DataFrame. Without further arguments, every row is data and the\ncolumns are numbered from zero. Pass ",[14,349,350],{},"headers=True"," and the first row of the range becomes the column\nnames — which is nearly always what you want for a block of records.",[245,353,355],{"className":247,"code":354,"language":249,"meta":250,"style":250},"raw = xl(\"A3:D8\")                      # columns 0, 1, 2, 3; row 3 is data\nsales = xl(\"A3:D8\", headers=True)      # columns Date, Region, Rep, Amount\nsales.groupby(\"Region\")[\"Amount\"].sum()\n",[14,356,357,375,404],{"__ignoreMap":250},[254,358,359,362,364,366,369,372],{"class":84,"line":256},[254,360,361],{"class":259},"raw ",[254,363,264],{"class":263},[254,365,267],{"class":259},[254,367,368],{"class":270},"\"A3:D8\"",[254,370,371],{"class":259},")                      ",[254,373,374],{"class":277},"# columns 0, 1, 2, 3; row 3 is data\n",[254,376,377,380,382,384,386,388,392,394,398,401],{"class":84,"line":281},[254,378,379],{"class":259},"sales ",[254,381,264],{"class":263},[254,383,267],{"class":259},[254,385,368],{"class":270},[254,387,182],{"class":259},[254,389,391],{"class":390},"sa561","headers",[254,393,264],{"class":263},[254,395,397],{"class":396},"sP0c6","True",[254,399,400],{"class":259},")      ",[254,402,403],{"class":277},"# columns Date, Region, Rep, Amount\n",[254,405,406,409,412,415,418],{"class":84,"line":300},[254,407,408],{"class":259},"sales.groupby(",[254,410,411],{"class":270},"\"Region\"",[254,413,414],{"class":259},")[",[254,416,417],{"class":270},"\"Amount\"",[254,419,420],{"class":259},"].sum()\n",[10,422,423,424,427],{},"A fixed range has one serious weakness: it does not grow. Add a ninth row of sales under ",[14,425,426],{},"A3:D8"," and this\nformula silently ignores it. That is the main reason to prefer tables, covered next.",[33,429,42,434,42,437,42,440,42,443,42,450,42,456,42,462,42,467,42,471,42,475,42,478,42,483,42,487,42,490,42,493,42,496],{"viewBox":430,"role":36,"ariaLabelledBy":431,"xmlns":40,"style":41},"0 0 760 191",[432,433],"xlr-headers-t","xlr-headers-d",[44,435,436],{"id":432},"The same range with and without headers=True",[48,438,439],{"id":433},"Without headers the DataFrame columns are numbered and the header row is treated as data. With headers equal to True the first row supplies the column names and only the rows below are data.",[52,441],{"x":54,"y":54,"width":55,"height":442,"fill":57},"191",[52,444],{"x":60,"y":60,"width":445,"height":446,"rx":447,"fill":448,"stroke":449,"style":66},"350","127","14","#fee8f2","var(--accent,#f43f8f)",[68,451,455],{"x":452,"y":453,"style":454},"195","46","font-size:13px;font-weight:700;fill:var(--accent-ink,#be185d);text-anchor:middle","xl(\"A3:D8\")",[84,457],{"x1":458,"y1":459,"x2":460,"y2":459,"stroke":449,"style":461},"36","56","354","stroke-width:1px",[68,463,466],{"x":452,"y":464,"style":465},"78","font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:11.5px;font-weight:400;fill:var(--text,#172033);text-anchor:middle","columns: 0, 1, 2, 3",[68,468,470],{"x":452,"y":469,"style":465},"101","row 3 read as data",[68,472,474],{"x":452,"y":473,"style":465},"124","6 rows returned",[52,476],{"x":477,"y":60,"width":445,"height":446,"rx":447,"fill":141,"stroke":142,"style":66},"390",[68,479,482],{"x":480,"y":453,"style":481},"565","font-size:13px;font-weight:700;fill:var(--teal-ink,#0b6157);text-anchor:middle","xl(\"A3:D8\", headers=True)",[84,484],{"x1":485,"y1":459,"x2":486,"y2":459,"stroke":142,"style":461},"406","724",[68,488,489],{"x":480,"y":464,"style":465},"columns: Date … Amount",[68,491,492],{"x":480,"y":469,"style":465},"row 3 becomes names",[68,494,495],{"x":480,"y":473,"style":465},"5 rows returned",[68,497,499],{"x":156,"y":498,"style":158},"177","forgetting headers=True puts the header text into your numbers",[161,501,503],{"id":502},"step-3-reference-an-excel-table","Step 3 — Reference an Excel table",[10,505,506,507,510,511,514,515,518,519,521,522,524],{},"Convert the data to a table (",[205,508,509],{},"Insert → Table",", or Ctrl+T), give it a name on the ",[205,512,513],{},"Table Design"," tab, and\nreference the whole thing with the ",[14,516,517],{},"[#All]"," specifier. ",[14,520,517],{}," includes the header row, and\n",[14,523,350],{}," turns it into column names.",[245,526,528],{"className":247,"code":527,"language":249,"meta":250,"style":250},"sales = xl(\"Sales[#All]\", headers=True)\nby_rep = (\n    sales.groupby([\"Region\", \"Rep\"], as_index=False)[\"Amount\"]\n         .sum()\n         .sort_values(\"Amount\", ascending=False)\n)\nby_rep\n",[14,529,530,552,562,592,598,617,622],{"__ignoreMap":250},[254,531,532,534,536,538,541,543,545,547,549],{"class":84,"line":256},[254,533,379],{"class":259},[254,535,264],{"class":263},[254,537,267],{"class":259},[254,539,540],{"class":270},"\"Sales[#All]\"",[254,542,182],{"class":259},[254,544,391],{"class":390},[254,546,264],{"class":263},[254,548,397],{"class":396},[254,550,551],{"class":259},")\n",[254,553,554,557,559],{"class":84,"line":281},[254,555,556],{"class":259},"by_rep ",[254,558,264],{"class":263},[254,560,561],{"class":259}," (\n",[254,563,564,567,569,571,574,577,580,582,585,587,589],{"class":84,"line":300},[254,565,566],{"class":259},"    sales.groupby([",[254,568,411],{"class":270},[254,570,182],{"class":259},[254,572,573],{"class":270},"\"Rep\"",[254,575,576],{"class":259},"], ",[254,578,579],{"class":390},"as_index",[254,581,264],{"class":263},[254,583,584],{"class":396},"False",[254,586,414],{"class":259},[254,588,417],{"class":270},[254,590,591],{"class":259},"]\n",[254,593,595],{"class":84,"line":594},4,[254,596,597],{"class":259},"         .sum()\n",[254,599,601,604,606,608,611,613,615],{"class":84,"line":600},5,[254,602,603],{"class":259},"         .sort_values(",[254,605,417],{"class":270},[254,607,182],{"class":259},[254,609,610],{"class":390},"ascending",[254,612,264],{"class":263},[254,614,584],{"class":396},[254,616,551],{"class":259},[254,618,620],{"class":84,"line":619},6,[254,621,551],{"class":259},[254,623,625],{"class":84,"line":624},7,[254,626,627],{"class":259},"by_rep\n",[10,629,630,631,633,634,200],{},"Table references are the right default for three reasons. They expand automatically when rows are added,\nso the formula never misses new data. They survive rows and columns being inserted elsewhere on the sheet,\nbecause they point at the table rather than at coordinates. And the table name documents what the data is,\nwhich a reference like ",[14,632,426],{}," does not. If you already build tables from Python, the same object is covered\nfrom the file side in ",[27,635,637],{"href":636},"\u002Fformatting-and-charting-excel-reports-with-python\u002Fcreating-excel-tables-and-autofilters-with-python\u002Fcreate-an-excel-table-with-python\u002F","Create an Excel Table with Python",[161,639,641],{"id":640},"step-4-reference-other-sheets-and-named-ranges","Step 4 — Reference other sheets and named ranges",[10,643,644,646,647,650],{},[14,645,20],{}," takes the same reference text you would type in an Excel formula, so a range on another sheet uses the\nusual ",[14,648,649],{},"Sheet!Range"," syntax, with single quotes around a sheet name that contains spaces. A defined name is\nreferenced by its name alone.",[245,652,654],{"className":247,"code":653,"language":249,"meta":250,"style":250},"raw = xl(\"'Raw data'!A1:C200\", headers=True)\ntax_rate = xl(\"TaxRate\")\n\nsales = xl(\"Sales[#All]\", headers=True)\nsales[\"Net\"] = sales[\"Amount\"] \u002F (1 + tax_rate)\nsales[[\"Region\", \"Amount\", \"Net\"]]\n",[14,655,656,677,691,697,717,752],{"__ignoreMap":250},[254,657,658,660,662,664,667,669,671,673,675],{"class":84,"line":256},[254,659,361],{"class":259},[254,661,264],{"class":263},[254,663,267],{"class":259},[254,665,666],{"class":270},"\"'Raw data'!A1:C200\"",[254,668,182],{"class":259},[254,670,391],{"class":390},[254,672,264],{"class":263},[254,674,397],{"class":396},[254,676,551],{"class":259},[254,678,679,682,684,686,689],{"class":84,"line":281},[254,680,681],{"class":259},"tax_rate ",[254,683,264],{"class":263},[254,685,267],{"class":259},[254,687,688],{"class":270},"\"TaxRate\"",[254,690,551],{"class":259},[254,692,693],{"class":84,"line":300},[254,694,696],{"emptyLinePlaceholder":695},true,"\n",[254,698,699,701,703,705,707,709,711,713,715],{"class":84,"line":594},[254,700,379],{"class":259},[254,702,264],{"class":263},[254,704,267],{"class":259},[254,706,540],{"class":270},[254,708,182],{"class":259},[254,710,391],{"class":390},[254,712,264],{"class":263},[254,714,397],{"class":396},[254,716,551],{"class":259},[254,718,719,722,725,728,730,733,735,737,740,743,746,749],{"class":84,"line":600},[254,720,721],{"class":259},"sales[",[254,723,724],{"class":270},"\"Net\"",[254,726,727],{"class":259},"] ",[254,729,264],{"class":263},[254,731,732],{"class":259}," sales[",[254,734,417],{"class":270},[254,736,727],{"class":259},[254,738,739],{"class":263},"\u002F",[254,741,742],{"class":259}," (",[254,744,745],{"class":396},"1",[254,747,748],{"class":263}," +",[254,750,751],{"class":259}," tax_rate)\n",[254,753,754,757,759,761,763,765,767],{"class":84,"line":619},[254,755,756],{"class":259},"sales[[",[254,758,411],{"class":270},[254,760,182],{"class":259},[254,762,417],{"class":270},[254,764,182],{"class":259},[254,766,724],{"class":270},[254,768,769],{"class":259},"]]\n",[10,771,772,773,775,776,779],{},"What ",[14,774,20],{}," cannot reference is another workbook. External references such as ",[14,777,778],{},"[Budget.xlsx]Sheet1!A1"," are\nnot available, and neither is reading a file from disk inside the formula. Data from another workbook, a CSV\nfile, a database or a web API has to be brought into this workbook first.",[33,781,42,786,42,789,42,792,42,794,42,798,42,804,42,809,42,814,42,818,42,822,42,825,42,830,42,833,42,836,42,841,42,844,42,847,42,852,42,855],{"viewBox":782,"role":36,"ariaLabelledBy":783,"xmlns":40,"style":41},"0 0 760 380",[784,785],"xlr-kinds-t","xlr-kinds-d",[44,787,788],{"id":784},"What each kind of xl() reference returns",[48,790,791],{"id":785},"A single cell returns a Python scalar, a range returns a DataFrame, a table with the All specifier returns a DataFrame that grows with the table, a named range returns whatever it refers to, and a Power Query name returns the query result.",[52,793],{"x":54,"y":54,"width":55,"height":156,"fill":57},[52,795],{"x":60,"y":60,"width":796,"height":797,"rx":63,"fill":64,"stroke":65,"style":66},"720","52",[68,799,803],{"x":800,"y":801,"style":802},"40","51","font-size:14px;font-weight:700;fill:var(--muted,#5b6780);text-anchor:start","xl(\"B1\")",[68,805,808],{"x":806,"y":801,"style":807},"320","font-size:12px;font-weight:400;fill:var(--muted,#5b6780);text-anchor:start","a scalar: int, float, str, bool or datetime",[52,810],{"x":60,"y":811,"width":796,"height":797,"rx":63,"fill":812,"stroke":813,"style":66},"84","#fdefd8","var(--gold,#b4740a)",[68,815,482],{"x":800,"y":816,"style":817},"115","font-size:14px;font-weight:700;fill:var(--gold-ink,#7a4e06);text-anchor:start",[68,819,821],{"x":806,"y":816,"style":820},"font-size:12px;font-weight:400;fill:var(--text,#172033);text-anchor:start","a DataFrame of a fixed rectangle",[52,823],{"x":60,"y":824,"width":796,"height":797,"rx":63,"fill":141,"stroke":142,"style":66},"148",[68,826,829],{"x":800,"y":827,"style":828},"179","font-size:14px;font-weight:700;fill:var(--teal-ink,#0b6157);text-anchor:start","xl(\"Sales[#All]\", headers=True)",[68,831,832],{"x":806,"y":827,"style":820},"a DataFrame that grows with the table",[52,834],{"x":60,"y":835,"width":796,"height":797,"rx":63,"fill":98,"stroke":89,"style":66},"212",[68,837,840],{"x":800,"y":838,"style":839},"243","font-size:14px;font-weight:700;fill:var(--brand-strong,#4338ca);text-anchor:start","xl(\"TaxRate\")",[68,842,843],{"x":806,"y":838,"style":820},"the value or frame the name points at",[52,845],{"x":60,"y":846,"width":796,"height":797,"rx":63,"fill":448,"stroke":449,"style":66},"276",[68,848,851],{"x":800,"y":849,"style":850},"307","font-size:14px;font-weight:700;fill:var(--accent-ink,#be185d);text-anchor:start","xl(\"Orders\")",[68,853,854],{"x":806,"y":849,"style":820},"the result of a Power Query query",[68,856,858],{"x":156,"y":857,"style":158},"360","tables are the default; ranges are for fixed, small blocks",[161,860,862],{"id":861},"step-5-bring-external-data-in-through-power-query","Step 5 — Bring external data in through Power Query",[10,864,865,866,869,870,873],{},"Power Query is the supported route for anything outside the workbook. Use ",[205,867,868],{},"Data → Get Data"," to connect to\nthe file, folder, database or web source, shape it in the Power Query editor, and load it — ",[205,871,872],{},"Close & Load To…\n→ Only Create Connection"," is enough. The query is then referenceable by its name.",[245,875,877],{"className":247,"code":876,"language":249,"meta":250,"style":250},"orders = xl(\"Orders\")                       # the Power Query query named Orders\norders[\"Month\"] = orders[\"OrderDate\"].dt.to_period(\"M\").astype(str)\norders.pivot_table(index=\"Month\", columns=\"Region\", values=\"Amount\", aggfunc=\"sum\")\n",[14,878,879,897,928],{"__ignoreMap":250},[254,880,881,884,886,888,891,894],{"class":84,"line":256},[254,882,883],{"class":259},"orders ",[254,885,264],{"class":263},[254,887,267],{"class":259},[254,889,890],{"class":270},"\"Orders\"",[254,892,893],{"class":259},")                       ",[254,895,896],{"class":277},"# the Power Query query named Orders\n",[254,898,899,902,905,907,909,912,915,918,921,924,926],{"class":84,"line":281},[254,900,901],{"class":259},"orders[",[254,903,904],{"class":270},"\"Month\"",[254,906,727],{"class":259},[254,908,264],{"class":263},[254,910,911],{"class":259}," orders[",[254,913,914],{"class":270},"\"OrderDate\"",[254,916,917],{"class":259},"].dt.to_period(",[254,919,920],{"class":270},"\"M\"",[254,922,923],{"class":259},").astype(",[254,925,238],{"class":396},[254,927,551],{"class":259},[254,929,930,933,936,938,940,942,945,947,949,951,954,956,958,960,963,965,968],{"class":84,"line":300},[254,931,932],{"class":259},"orders.pivot_table(",[254,934,935],{"class":390},"index",[254,937,264],{"class":263},[254,939,904],{"class":270},[254,941,182],{"class":259},[254,943,944],{"class":390},"columns",[254,946,264],{"class":263},[254,948,411],{"class":270},[254,950,182],{"class":259},[254,952,953],{"class":390},"values",[254,955,264],{"class":263},[254,957,417],{"class":270},[254,959,182],{"class":259},[254,961,962],{"class":390},"aggfunc",[254,964,264],{"class":263},[254,966,967],{"class":270},"\"sum\"",[254,969,551],{"class":259},[10,971,972,973,976,977,200],{},"This split of responsibilities is worth embracing rather than resenting. Power Query handles credentials,\nrefresh and the connection itself; Python does the analysis. Refresh the query (",[205,974,975],{},"Data → Refresh All",") and\nevery Python formula that references it recalculates on the new data. For the equivalent pipeline outside\nExcel entirely, see ",[27,978,980],{"href":979},"\u002Fadvanced-data-transformation-and-cleaning\u002Fmoving-data-between-excel-and-databases\u002Fexport-sql-query-results-to-excel-with-python\u002F","Export SQL Query Results to Excel with Python",[161,982,984],{"id":983},"step-6-check-the-types-you-received","Step 6 — Check the types you received",[10,986,987,988,991,992,995],{},"The conversion from Excel cells to pandas follows rules set in the workbook's initialization code\n(",[205,989,990],{},"Formulas → Initialization","), and it is worth confirming what arrived before building on it. Numbers stored\nas text stay text, blank cells arrive as missing values, and a column mixing numbers and text ends up with the\n",[14,993,994],{},"object"," type.",[245,997,999],{"className":247,"code":998,"language":249,"meta":250,"style":250},"sales = xl(\"Sales[#All]\", headers=True)\nsummary = {\n    \"rows\": len(sales),\n    \"dtypes\": sales.dtypes.astype(str).to_dict(),\n    \"blank amounts\": int(sales[\"Amount\"].isna().sum()),\n}\nsummary\n",[14,1000,1001,1021,1031,1044,1057,1074,1079],{"__ignoreMap":250},[254,1002,1003,1005,1007,1009,1011,1013,1015,1017,1019],{"class":84,"line":256},[254,1004,379],{"class":259},[254,1006,264],{"class":263},[254,1008,267],{"class":259},[254,1010,540],{"class":270},[254,1012,182],{"class":259},[254,1014,391],{"class":390},[254,1016,264],{"class":263},[254,1018,397],{"class":396},[254,1020,551],{"class":259},[254,1022,1023,1026,1028],{"class":84,"line":281},[254,1024,1025],{"class":259},"summary ",[254,1027,264],{"class":263},[254,1029,1030],{"class":259}," {\n",[254,1032,1033,1036,1038,1041],{"class":84,"line":300},[254,1034,1035],{"class":270},"    \"rows\"",[254,1037,319],{"class":259},[254,1039,1040],{"class":396},"len",[254,1042,1043],{"class":259},"(sales),\n",[254,1045,1046,1049,1052,1054],{"class":84,"line":594},[254,1047,1048],{"class":270},"    \"dtypes\"",[254,1050,1051],{"class":259},": sales.dtypes.astype(",[254,1053,238],{"class":396},[254,1055,1056],{"class":259},").to_dict(),\n",[254,1058,1059,1062,1064,1066,1069,1071],{"class":84,"line":600},[254,1060,1061],{"class":270},"    \"blank amounts\"",[254,1063,319],{"class":259},[254,1065,230],{"class":396},[254,1067,1068],{"class":259},"(sales[",[254,1070,417],{"class":270},[254,1072,1073],{"class":259},"].isna().sum()),\n",[254,1075,1076],{"class":84,"line":619},[254,1077,1078],{"class":259},"}\n",[254,1080,1081],{"class":84,"line":624},[254,1082,1083],{"class":259},"summary\n",[10,1085,1086,1087,1090,1091,1095],{},"Returning a small dictionary or DataFrame like this while you develop a workbook is the Python in Excel\nversion of a debugger print. You can also use ",[14,1088,1089],{},"print()",", whose output appears in the Diagnostics pane rather\nthan in the cell. Cleaning mixed columns once they are in pandas uses exactly the same techniques as anywhere\nelse — ",[27,1092,1094],{"href":1093},"\u002Fadvanced-data-transformation-and-cleaning\u002Fcleaning-excel-data-with-pandas\u002Fconvert-excel-text-columns-to-numbers-with-pandas\u002F","Convert Excel Text Columns to Numbers with pandas","\napplies unchanged.",[161,1097,1099],{"id":1098},"common-pitfalls","Common pitfalls",[1101,1102,1103,1119],"table",{},[1104,1105,1106],"thead",{},[1107,1108,1109,1113,1116],"tr",{},[1110,1111,1112],"th",{},"Symptom",[1110,1114,1115],{},"Cause",[1110,1117,1118],{},"Fix",[1120,1121,1122,1139,1153,1167,1184,1201],"tbody",{},[1107,1123,1124,1128,1133],{},[1125,1126,1127],"td",{},"Header text appears as the first data row",[1125,1129,1130,1132],{},[14,1131,350],{}," missing",[1125,1134,1135,1136,1138],{},"Add ",[14,1137,350],{}," to range and table references",[1107,1140,1141,1144,1147],{},[1125,1142,1143],{},"New rows not included in results",[1125,1145,1146],{},"Reference is a fixed range",[1125,1148,1149,1150],{},"Convert the data to a table and use ",[14,1151,1152],{},"Table[#All]",[1107,1154,1155,1161,1164],{},[1125,1156,1157,1160],{},[14,1158,1159],{},"NameError"," on a variable from another cell",[1125,1162,1163],{},"That cell calculates later",[1125,1165,1166],{},"Python cells run across each row, then down; move the definition above or left",[1107,1168,1169,1178,1181],{},[1125,1170,1171,1174,1175],{},[14,1172,1173],{},"#PYTHON!"," when calling ",[14,1176,1177],{},"pd.read_excel",[1125,1179,1180],{},"External file access is not supported",[1125,1182,1183],{},"Load the file with Power Query and reference the query",[1107,1185,1186,1192,1198],{},[1125,1187,1188,1191],{},[14,1189,1190],{},"#CALC!"," on a large reference",[1125,1193,1194,1195],{},"Data over the size limit, or a volatile source such as ",[14,1196,1197],{},"RAND()",[1125,1199,1200],{},"Reference less data; remove volatile inputs",[1107,1202,1203,1206,1209],{},[1125,1204,1205],{},"Result does not update after editing data",[1125,1207,1208],{},"Workbook in Manual or Partial calculation",[1125,1210,1211],{},"Press F9, or switch back to Automatic",[10,1213,1214,1215,1218,1219,1222],{},"The calculation-order row matters more than it appears. Python cells on a sheet run in row-major order — across\nrow 1 from column A, then across row 2, and so on — and sheets run in order too. A helper function defined in\ncell ",[14,1216,1217],{},"A10"," is not available to a formula in ",[14,1220,1221],{},"A5",". Keeping definitions in a block at the top-left of the first sheet\navoids the whole class of problem.",[161,1224,1226],{"id":1225},"performance-and-scale-notes","Performance and scale notes",[10,1228,1229,1230,1232],{},"Each reference is serialised and sent to the cloud runtime when the formula calculates, and the data involved\nin a single calculation is capped at 100 MB. Referencing a whole table of a few thousand rows is quick;\nreferencing entire columns or a sheet's full used range sends far more than the formula needs. Reference the\nnarrowest table or range that contains the data, and when several formulas use the same large table, read it\nonce in an early cell and reuse the variable in later ones rather than calling ",[14,1231,20],{}," repeatedly.",[10,1234,1235,1236,1239],{},"For workbooks with many Python cells, switch to ",[205,1237,1238],{},"Partial"," calculation while you edit so Python formulas only\nrecalculate when you press F9. That keeps the grid responsive while you work on the code.",[161,1241,1243],{"id":1242},"conclusion","Conclusion",[10,1245,1246,1248,1249,1251,1252,1254],{},[14,1247,20],{}," is the whole interface between a Python formula and its workbook. Use single-cell references for\nparameters, ",[14,1250,350],{}," for any block of records, and ",[14,1253,1152],{}," as the default for data that will grow.\nReach other sheets and defined names with ordinary Excel reference syntax, bring anything external in through\nPower Query, and confirm the types you received before building analysis on them. Keep references narrow and\ndefinitions early, and the rest is ordinary pandas.",[161,1256,1258],{"id":1257},"frequently-asked-questions","Frequently asked questions",[10,1260,1261,1264],{},[205,1262,1263],{},"Can xl() write values back to cells?","\nNo. xl() only reads. A Python formula returns its result to its own cell, which can spill into neighbouring cells when you choose Excel values as the output type.",[10,1266,1267,1270,1271,1274],{},[205,1268,1269],{},"Can I reference a table column directly?","\nRead the table with Table",[254,1272,1273],{},"#All"," and headers=True, then select the column in pandas. That keeps the column names exactly as they appear in the table header.",[10,1276,1277,1280,1281,1283],{},[205,1278,1279],{},"Why does xl() return a DataFrame for a single row?","\nAny reference with more than one cell returns a DataFrame. Take the first row with .iloc",[254,1282,54],{}," if you want a Series, or reference a single cell to get a scalar.",[10,1285,1286,1289],{},[205,1287,1288],{},"Can I read another open workbook?","\nNo. External workbook references are not supported. Load the other workbook's data with Power Query and reference the query by name.",[10,1291,1292,1295],{},[205,1293,1294],{},"Do references update if I insert rows above the data?","\nYes, the same way Excel formulas do — the reference text is adjusted. Table references are unaffected by inserted rows elsewhere on the sheet.",[161,1297,1299],{"id":1298},"related","Related",[166,1301,1302,1308,1315,1322,1329],{},[169,1303,1304,1305,1307],{},"Up one level: ",[27,1306,30],{"href":29}," — how =PY formulas fit alongside scripts that automate Excel from outside.",[169,1309,1310,1314],{},[27,1311,1313],{"href":1312},"\u002Fgetting-started-with-python-excel-automation\u002Fusing-python-in-excel\u002Freturn-dataframes-and-values-from-python-in-excel-cells\u002F","Return DataFrames and Values from Python in Excel Cells"," — the other half of the conversation: getting results back.",[169,1316,1317,1321],{},[27,1318,1320],{"href":1319},"\u002Fgetting-started-with-python-excel-automation\u002Fusing-python-in-excel\u002Ffix-python-in-excel-errors\u002F","Fix Python in Excel Errors"," — #PYTHON!, #CALC!, #BUSY! and the rest.",[169,1323,1324,1328],{},[27,1325,1327],{"href":1326},"\u002Fgetting-started-with-python-excel-automation\u002Freading-excel-files-with-pandas\u002F","Reading Excel Files with Pandas"," — reading the same data from a script instead of a cell.",[169,1330,1331,1335],{},[27,1332,1334],{"href":1333},"\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"," — defining the names xl() can reference.",[1337,1338,1339],"style",{},"html pre.shiki code .skGVy, html code.shiki .skGVy{--shiki-default:#24292E;--shiki-dark:#F0F3F6}html pre.shiki code .s-kum, html code.shiki .s-kum{--shiki-default:#D73A49;--shiki-dark:#FF9492}html pre.shiki code .srMev, html code.shiki .srMev{--shiki-default:#032F62;--shiki-dark:#ADDCFF}html pre.shiki code .s-wDw, html code.shiki .s-wDw{--shiki-default:#6A737D;--shiki-dark:#BDC4CC}html pre.shiki code .sSjpA, html code.shiki .sSjpA{--shiki-default:#005CC5;--shiki-dark:#FF9492}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 .sa561, html code.shiki .sa561{--shiki-default:#E36209;--shiki-dark:#FFB757}html pre.shiki code .sP0c6, html code.shiki .sP0c6{--shiki-default:#005CC5;--shiki-dark:#91CBFF}",{"title":250,"searchDepth":281,"depth":281,"links":1341},[1342,1343,1344,1345,1346,1347,1348,1349,1350,1351,1352,1353],{"id":163,"depth":281,"text":164},{"id":223,"depth":281,"text":224},{"id":343,"depth":281,"text":344},{"id":502,"depth":281,"text":503},{"id":640,"depth":281,"text":641},{"id":861,"depth":281,"text":862},{"id":983,"depth":281,"text":984},{"id":1098,"depth":281,"text":1099},{"id":1225,"depth":281,"text":1226},{"id":1242,"depth":281,"text":1243},{"id":1257,"depth":281,"text":1258},{"id":1298,"depth":281,"text":1299},"2026-09-17","Everything a =PY cell knows about your workbook comes through xl(). Reference single cells, ranges with headers, Excel tables, other sheets, named ranges and Power Query results.","md",[1358,1360,1362,1364,1366],{"q":1263,"a":1359},"No. xl() only reads. A Python formula returns its result to its own cell, which can spill into neighbouring cells when you choose Excel values as the output type.",{"q":1269,"a":1361},"Read the table with Table[#All] and headers=True, then select the column in pandas. That keeps the column names exactly as they appear in the table header.",{"q":1279,"a":1363},"Any reference with more than one cell returns a DataFrame. Take the first row with .iloc[0] if you want a Series, or reference a single cell to get a scalar.",{"q":1288,"a":1365},"No. External workbook references are not supported. Load the other workbook's data with Power Query and reference the query by name.",{"q":1294,"a":1367},"Yes, the same way Excel formulas do — the reference text is adjusted. Table references are unaffected by inserted rows elsewhere on the sheet.","reference cells ranges and tables with xl in python in excel",null,{"breadcrumb":1371},[1372,1374,1377],{"name":1373,"item":739},"Home",{"name":1375,"item":1376},"Getting Started with Python Excel Automation","\u002Fgetting-started-with-python-excel-automation\u002F",{"name":30,"item":29},"\u002Fgetting-started-with-python-excel-automation\u002Fusing-python-in-excel\u002Freference-cells-ranges-and-tables-with-xl-in-python-in-excel",{"title":5,"description":1380},"How the xl() function works in Python in Excel: single cells, ranges and headers=True, Table[#All] references, other sheets, named ranges, Power Query queries and the types you get back.","reference-cells-ranges-and-tables-with-xl-in-python-in-excel","getting-started-with-python-excel-automation\u002Fusing-python-in-excel\u002Freference-cells-ranges-and-tables-with-xl-in-python-in-excel\u002Findex",[1384],"python-in-excel","how-to","TuyBHMVQ4FSaIkOSRkNxmjPYMyHs8xw9ht37KhJiWP4",[1388,1392],{"title":1389,"path":1390,"stem":1391,"children":-1},"Python in Excel vs openpyxl and xlwings","\u002Fgetting-started-with-python-excel-automation\u002Fusing-python-in-excel\u002Fpython-in-excel-vs-openpyxl-and-xlwings","getting-started-with-python-excel-automation\u002Fusing-python-in-excel\u002Fpython-in-excel-vs-openpyxl-and-xlwings\u002Findex",{"title":1313,"path":1393,"stem":1394,"children":-1},"\u002Fgetting-started-with-python-excel-automation\u002Fusing-python-in-excel\u002Freturn-dataframes-and-values-from-python-in-excel-cells","getting-started-with-python-excel-automation\u002Fusing-python-in-excel\u002Freturn-dataframes-and-values-from-python-in-excel-cells\u002Findex",[1396,1398],{"path":1397,"title":1375},"\u002Fgetting-started-with-python-excel-automation",{"path":1399,"title":30},"\u002Fgetting-started-with-python-excel-automation\u002Fusing-python-in-excel",[],[1402,1405,1408,1411,1414,1417],{"path":1403,"title":1404,"kind":1385},"\u002Fgetting-started-with-python-excel-automation\u002Fusing-python-in-excel\u002Fclean-data-with-pandas-in-python-in-excel","Clean Data with pandas in Python in Excel",{"path":1406,"title":1320,"kind":1407},"\u002Fgetting-started-with-python-excel-automation\u002Fusing-python-in-excel\u002Ffix-python-in-excel-errors","fix",{"path":1409,"title":1410,"kind":1385},"\u002Fgetting-started-with-python-excel-automation\u002Fusing-python-in-excel\u002Fforecast-a-time-series-with-python-in-excel","Forecast a Time Series with Python in Excel",{"path":1412,"title":1413,"kind":1385},"\u002Fgetting-started-with-python-excel-automation\u002Fusing-python-in-excel\u002Fget-external-data-into-python-in-excel","Get External Data into Python in Excel with Power Query",{"path":1415,"title":1416,"kind":1385},"\u002Fgetting-started-with-python-excel-automation\u002Fusing-python-in-excel\u002Fplot-charts-with-matplotlib-in-python-in-excel","Plot Charts with matplotlib in Python in Excel",{"path":1390,"title":1389,"kind":1418},"compare",1790972075435]