01Read a whole table into a DataFrame with xl() in a =PY cellVerified

In a =PY cell, xl("TableName[#All]", headers=True) hands the whole table to Python as a pandas DataFrame with its headers. Two-dimensional ranges become DataFrames by default, so you can group and aggregate right away.

Approach and steps
  1. Format the ledger as an Excel table and name it (for example, RequestLedger)
  2. Type =PY in a cell and pick PY to switch the cell into the Python editor
  3. Read the whole table with xl("RequestLedger[#All]", headers=True); [#All] covers the entire table and headers=True treats the first row as column names
  4. Aggregate the DataFrame with groupby; the value of the last expression is returned to the cell
  5. To read a plain range instead, pass its address, such as xl("B1:C4")
PythonRuns in the Microsoft Cloud
# Python in Excel cell (=PY). Table name: RequestLedger
df = xl("RequestLedger[#All]", headers=True)

# Count requests and total findings by document type
summary = (
    df.groupby("種別")
      .agg(件数=("依頼ID", "count"), 指摘件数計=("指摘件数", "sum"))
      .sort_values("件数", ascending=False)
)
summary
Output(2026-09-12)
         件数  指摘件数計
種別                
社内通知     11     42
プレスリリース  10     34
Web 記事    7     42
契約書       6     27
提案書       6     26
rows: 40 total: 40
Example instruction for Copilot

Write Python in Excel cell code that reads the RequestLedger table with xl() including headers, then lists the count of requests and the total findings per document type, sorted by count. Do not read files or use the network.

Caution

xl() reads cell values only; the code cannot see formulas, charts, or PivotTables in the workbook. Add [#All] to read the entire table. Calculation runs in the Microsoft Cloud, so an internet connection is required. Check that the totals add up to the row count of the source table.

Availability
Python in Excel works in Excel for Microsoft 365 on Windows, Mac, and the web (not iPad, iPhone, or Android). Qualifying subscriptions get standard compute and automatic calculation; premium compute and manual/partial modes need the Python in Excel add-on license.
Requires
pandas 3.0.5
Tested
run locally with xl() replaced by sample data (2026-09-12, Python 3.12.10 (venv) / Windows 11, pandas 3.0.5)
Source
Microsoft Support, "Get started with Python in Excel"
Microsoft Support, "Python in Excel DataFrames"
Verified
2026-09-13 (v1)
Supporting passages from the sources
For a table with headers named MyTable, use xl("MyTable[#All]", headers=True). The [#All] specifier ensures that the entire table is analyzed in the Python formula, and headers=True ensures that the table headers are processed correctly.
Python in Excel uses a DataFrame as the default object for two-dimensional ranges.
The Python code doesn't have access to other properties in the workbook, such as formulas, charts, PivotTables, macros, or VBA code.

02Keep group labels as a column when returning a summary as Excel valuesVerified

A =PY result can come back as a Python object or as Excel values. When a DataFrame is returned as Excel values, its index column appears only under certain conditions, so groupby with as_index=False keeps the group labels as an ordinary column.

Approach and steps
  1. Return intermediate results that later Python cells reuse as a Python object (the cell shows a card icon)
  2. Switch final results used by charts or conditional formatting to Excel values with the Python output menu in the formula bar
  3. Use groupby(..., as_index=False) so the group labels become a column instead of the index
  4. Keep the cells to the right and below empty; if the output range already holds data, the cell returns #SPILL!
PythonRuns in the Microsoft Cloud
# Python in Excel cell (=PY), output type: Excel value
df = xl("RequestLedger[#All]", headers=True)

by_dept = (
    df.groupby("依頼部署", as_index=False)   # department stays a column
      .agg(件数=("依頼ID", "count"), 平均指摘=("指摘件数", "mean"))
      .round({"平均指摘": 1})
)
by_dept
Output(2026-09-12)
依頼部署  件数  平均指摘
 人事部  11   4.1
 営業部  10   4.6
 広報部  19   4.2
index is numeric: True
Example instruction for Copilot

Write Python in Excel cell code that summarizes the RequestLedger table by department with the request count and the mean number of findings rounded to one decimal. The output will be Excel values, so keep the department names as a column, not the index.

Caution

Results converted to Excel values are translated to their closest Excel equivalent; keep a Python object when a later Python calculation needs it. A DataFrame whose index is not numeric (such as the output of describe()) also outputs its index column, so check the column layout.

Availability
Python in Excel works in Excel for Microsoft 365 on Windows, Mac, and the web. The output type can also be changed from the right-click menu.
Requires
pandas 3.0.5
Tested
run locally with xl() replaced by sample data (2026-09-12, Python 3.12.10 (venv) / Windows 11, pandas 3.0.5)
Source
Microsoft Support, "Python in Excel DataFrames"
pandas, "pandas.DataFrame.groupby"
Verified
2026-09-13 (v1)
Supporting passages from the sources
When the output type of a DataFrame is set to Excel values, the DataFrame only outputs the index column if one of the following conditions is met. If values of the index column are not numeric (like the result of describe() or group_by()). If the index column name has been set.
Return object with group labels as the index.
If you plan to reuse the result in a future Python calculation, it's recommended to return the result as a Python object.

03Place variables to match the row-major calculation order of Python cellsVerified

Python cells on a worksheet calculate in row-major order: across each row from column A, then down to the next row, and worksheet by worksheet. Put the cell that defines a variable above, or to the left of, every cell that uses it.

Approach and steps
  1. Put the cell that loads the table and fixes data types (creating df) at the top left, returned as a Python object
  2. Put summary cells that use df in a later row or to its right
  3. When analysis spans several sheets, keep the data and variable cells on earlier sheets
  4. Keep import statements and settings on the first worksheet
  5. To pause recalculation while you work, use Partial or Manual calculation and press F9 to recalculate
PythonRuns in the Microsoft Cloud
# --- Cell A1 (=PY, Python object): load and clean once ---
df = xl("RequestLedger[#All]", headers=True)
df["依頼日"] = pd.to_datetime(df["依頼日"])
df["完了日"] = pd.to_datetime(df["完了日"])
df

# --- Cell A2 (=PY, Excel value): calculated after A1 (row-major order) ---
done = df[df["状態"] == "完了"].copy()
done["日数"] = (done["完了日"] - done["依頼日"]).dt.days
done.groupby("種別")["日数"].median()
Output(2026-09-12)
           日数
種別           
Web 記事    6.0
プレスリリース   3.0
契約書       7.5
提案書       5.0
社内通知     12.0
completed rows: 14
Example instruction for Copilot

Write Python in Excel code split into two cells. The first reads the RequestLedger table and converts the request and completion dates to datetime. The second computes the median days to completion per document type for completed rows. Say which cell must come first on the sheet.

Caution

Referencing a variable defined in a lower row or a later sheet fails because it is calculated first. When a dependent value changes, all Python formulas recalculate in sequence. In Manual or Partial mode, stale values remain until you recalculate, so recalculate before reporting.

Availability
Automatic calculation is included with qualifying Microsoft 365 subscriptions. Manual and Partial calculation modes require the Python in Excel add-on license.
Requires
pandas 3.0.5
Tested
run locally with xl() replaced by sample data (2026-09-12, Python 3.12.10 (venv) / Windows 11, pandas 3.0.5)
Source
Microsoft Support, "Get started with Python in Excel"
Microsoft Support, "Python in Excel availability"
Verified
2026-09-13 (v1)
Supporting passages from the sources
But in a Python in Excel worksheet, Python cells calculate in row-major order. The cell calculations run across a row (from column A to column XFD), and then across each following row down the worksheet.
The row-major calculation order also applies across worksheets within a workbook and is based on the order of the worksheets within the workbook.
To ensure that your libraries are imported before your Python formulas run, enter your import statements and any settings on the first worksheet in your workbook.

04Check which libraries the runtime provides and keep imports up frontVerified

Python in Excel runs a curated set of libraries provided by Anaconda; packages installed in your local Python are not reflected. Import additional libraries in a cell, and use importlib to check whether a module is present before relying on it.

Approach and steps
  1. Matplotlib, NumPy, pandas, seaborn, and statsmodels are imported by default under aliases such as np and pd
  2. Pass the import names you want to importlib.util.find_spec in a Python cell to check that they exist
  3. Import statements differ by library (for example, beautifulsoup4 uses from bs4 import BeautifulSoup)
  4. Keep your import statements in the Formulas > Initialization task pane or on the first worksheet
PythonRuns in the Microsoft Cloud
# Python in Excel cell (=PY): which optional libraries does this runtime provide?
import importlib.util

wanted = ["bs4", "sklearn", "scipy", "networkx"]
found = {name: importlib.util.find_spec(name) is not None for name in wanted}
pd.Series(found, name="available")
Output(2026-09-12)
bs4         False
sklearn      True
scipy        True
networkx     True
Name: available
Example instruction for Copilot

Write Python in Excel cell code that uses importlib to check whether bs4, sklearn, scipy, and networkx are available and returns a Series of names and True/False. Do not try to install anything.

Caution

Libraries cannot make network requests or reach files on your machine. The libraries page calls the Initialization task pane read-only, while the initialization settings page says you can add and edit imports there; check in your own Excel. Changing initialization settings also affects Copilot in Excel with Python.

Availability
Python in Excel works in Excel for Microsoft 365 on Windows, Mac, and the web. Microsoft updates Python and the libraries periodically; existing workbooks keep calculating against the environment they were created on, and you are prompted to upgrade.
Requires
pandas 3.0.5
Tested
run locally with xl() replaced by sample data (2026-09-12, Python 3.12.10 (venv) / Windows 11, pandas 3.0.5)
Source
Microsoft Support, "Open-source libraries and Python in Excel"
Microsoft Support, "Introduction to Python in Excel"
Microsoft Support, "Python in Excel initialization settings"
Verified
2026-09-13 (v1)
Supporting passages from the sources
In addition to the core libraries, you can import additional libraries available through Anaconda.
If you have a local version of Python installed on your computer, any customizations you've made to that Python installation won't be reflected in Python in Excel calculations.
This task pane is currently read-only and shows the initialization settings for your Python in Excel runtime.
Changing initialization settings affects how Python behaves in your workbook. Any changes can impact both Python in Excel and Copilot in Excel with Python.

05Bring outside data in with Power Query and read it by query name with xl()Verified

Python in Excel code has no network or local file access, so pandas.read_csv or read_excel on an outside file will not work. Create a Power Query query instead and receive it as a DataFrame with xl("QueryName").

Approach and steps
  1. Choose the source, such as a CSV file, under Data > Get Data
  2. In Load To..., choose Only Create Connection to create the query without loading it onto a sheet
  3. In a =PY cell, write xl("QueryName") to receive the data as a DataFrame
  4. Importing external data with Power Query for Python in Excel is not available in Excel on the web, so build the query in desktop Excel
PythonRuns in the Microsoft Cloud
# Python in Excel cell (=PY)
# "RequestsQuery" is a Power Query connection (Load To... > Only Create Connection).
# pd.read_csv("C:/...") would not work here: the code has no file or network access.
df = xl("RequestsQuery")

open_items = df[df["状態"] != "完了"]
open_items.groupby("担当者")["依頼ID"].count().rename("未完了件数")
Output(2026-09-12)
担当者
担当A    10
担当B     7
担当C     3
担当D     6
Name: 未完了件数
Example instruction for Copilot

Write Python in Excel cell code that reads the Power Query connection RequestsQuery with xl() and counts requests that are not complete per assignee. Do not read files directly with pandas.read_csv or similar.

Caution

Power Query is the only way to import external data for Python in Excel. Python formulas in a workbook opened from the internet do not run in Protected View. Confirm whether the query source is current on the query side, not from the Python result.

Availability
Using Power Query imports with Python in Excel works in desktop Excel (Windows, Mac); it is not available in Excel on the web.
Requires
pandas 3.0.5
Tested
run locally with xl() replaced by sample data (2026-09-12, Python 3.12.10 (venv) / Windows 11, pandas 3.0.5)
Source
Microsoft Support, "Use Power Query to import data for Python in Excel"
Microsoft Support, "Data security and Python in Excel"
Microsoft Support, "Get started with Python in Excel"
Verified
2026-09-13 (v1)
Supporting passages from the sources
Power Query is the only way to import external data for use with Python in Excel.
The Python code doesn't have access to your computer, devices, or account. The Python code doesn't have network access.
To protect your security, common external data functions in Python, such as pandas.read_csv and pandas.read_excel, aren't compatible with Python in Excel.
Importing external data with Power Query to use with Python in Excel is not available for Excel on the web.

06List the code in Python cells with FORMULATEXT for reviewVerified

Behind every Python cell is a =PY(python_code, return_type) formula, and FORMULATEXT returns it as text. Listing that text on a review sheet makes the code easy to read side by side during review or handover.

Approach and steps
  1. Create a review sheet and put the address of each Python cell in column A
  2. In column B, enter =FORMULATEXT(reference) to pull out the =PY(...) text
  3. A last argument of 1 means the cell returns a Python object; 0 means it returns an Excel value
  4. The PY function cannot be typed in the formula bar or combined with other functions, so use the review sheet for reading only
Excel
Review sheet (row 2; fill down for more cells)
A2: Sheet1!C1
B2: =FORMULATEXT(Sheet1!C1)
C2: =IF(RIGHT(B2,3)=",1)","Python object",IF(RIGHT(B2,3)=",0)","Excel value","check"))

Example of the text returned in B2 (syntax from the PY function reference):
=PY("xl(""Table1[#All]"", headers=True)",1)
Example instruction for Copilot

Write formulas for a review sheet that list the code of the Python cells in Sheet1!C1:C5 with FORMULATEXT and show whether each cell returns a Python object or an Excel value.

Caution

The column C check assumes the FORMULATEXT text ends in ,1) or ,0) as in the documented syntax; look at the text in your own workbook to confirm. People still need to read the code; FORMULATEXT says nothing about whether the result is right.

Availability
Python in Excel works in Excel for Microsoft 365 on Windows, Mac, and the web. Add-ins can also write and read the PY function.
Tested
not executable (configuration, HTTP or formula) (2026-09-12)
Source
Microsoft Support, "PY function"
Verified
2026-09-13 (v1)
Supporting passages from the sources
The PY function syntax is primarily used by add-ins to directly insert or read Python formulas. It can also be seen when using the FORMULATEXT function on a cell containing a Python formula.
The PY function cannot be used with any other Excel functions. If used with other functions, a formula cannot be entered.
0 indicates Excel value. 1 indicates Python object.

07Read a ledger with openpyxl read_only and data_onlyVerified

When reading xlsx files in local Python, load_workbook(read_only=True) streams large files with little memory. data_only=True returns the value Excel last stored instead of the formula. openpyxl does not calculate formulas, so a formula never saved by Excel reads as None.

Approach and steps
  1. Open a large ledger with load_workbook(..., read_only=True) and stream rows with iter_rows(values_only=True)
  2. Close a read-only workbook explicitly with close() when you are done
  3. Keep the default to get formula text, or open with data_only=True to get the values Excel stored
  4. A cell that returns None under data_only has no stored value until the file is opened and saved in Excel
PythonRuns locally
from openpyxl import load_workbook

SRC = "samples/request_ledger.xlsx"        # input, not modified
AFTER = "samples/excel_ledger_after.xlsx"  # has a formula sheet saved by openpyxl

# 1) read_only: stream rows with low memory, then close explicitly
wb = load_workbook(SRC, read_only=True)
ws = wb.worksheets[0]
header = next(ws.iter_rows(max_row=1, values_only=True))
status_col = header.index("状態")
open_count = sum(1 for r in ws.iter_rows(min_row=2, values_only=True) if r[status_col] != "完了")
wb.close()
print("open requests:", open_count)

# 2) formula text vs stored value
formula = load_workbook(AFTER)["集計"]["B2"].value
stored = load_workbook(AFTER, data_only=True)["集計"]["B2"].value
print("formula:", formula)
print("stored value:", stored)  # None: openpyxl wrote the formula but never calculated it
Output(2026-09-12)
open requests: 26
formula: =COUNTIF(依頼台帳!G:G,A2)
stored value: None
Example instruction for Copilot

Write openpyxl code that opens request_ledger.xlsx in read_only mode, counts rows whose status is not complete, and closes it; then read a formula cell in another workbook with and without data_only. Do not modify any file.

Caution

openpyxl does not read every item in an Excel file, so shapes are lost if you open and save a file under the same name; never overwrite the source. Read-only workbooks return a different cell type and cannot be written. Check values against a file that Excel has recalculated and saved.

Availability
openpyxl (the tested version is recorded in code.tested). Runs in local Python, not in Python in Excel.
Requires
openpyxl 3.1.5
Tested
run and checked locally (2026-09-12, Python 3.12.10 (venv) / Windows 11, openpyxl 3.1.5)
Source
openpyxl, "Tutorial"
openpyxl, "Optimised Modes"
Verified
2026-09-13 (v1)
Supporting passages from the sources
data_only controls whether cells with formulae have either the formula (default) or the value stored the last time Excel read the sheet.
The workbook must be explicitly closed with the close() method.
shapes will be lost from existing files if they are opened and saved with the same name.

08Summarize a ledger with pandas and write several sheets to a new workbookVerified

In local Python, read the ledger with pandas.read_excel, aggregate it with groupby, and write several sheets to a new workbook through ExcelWriter. An existing file with the same name is overwritten, so always write to a new name.

Approach and steps
  1. Read the first sheet into a DataFrame with read_excel(sheet_name=0)
  2. Derive a month column from the request date and use groupby for type-by-status and monthly counts
  3. Inside with pd.ExcelWriter(output), call to_excel once per sheet name
  4. Read the output back with read_excel(sheet_name=None) and check the sheet names and the total count
PythonRuns locally
import pandas as pd

SRC = "samples/request_ledger.xlsx"
OUT = "out_ledger_summary.xlsx"   # new file; the source is never overwritten

df = pd.read_excel(SRC, sheet_name=0)
df["依頼月"] = pd.to_datetime(df["依頼日"]).dt.strftime("%Y-%m")

by_type = df.groupby(["種別", "状態"])["依頼ID"].count().unstack(fill_value=0)
by_month = (df.groupby("依頼月", as_index=False)
              .agg(件数=("依頼ID", "count"), 指摘件数計=("指摘件数", "sum")))

with pd.ExcelWriter(OUT, engine="openpyxl") as writer:
    by_type.to_excel(writer, sheet_name="種別x状態")
    by_month.to_excel(writer, sheet_name="月別", index=False)

# Read back and reconcile with the source
check = pd.read_excel(OUT, sheet_name=None)
print("sheets:", list(check))
print(by_month.to_string(index=False))
print("rows in source:", len(df), "| total in 月別:", int(check["月別"]["件数"].sum()))
Output(2026-09-12)
sheets: ['種別x状態', '月別']
    依頼月  件数  指摘件数計
2026-07  21     95
2026-08  19     76
rows in source: 40 | total in 月別: 40
Example instruction for Copilot

Write pandas code that reads request_ledger.xlsx and writes a type-by-status count table and a monthly table of counts and total findings to separate sheets of a new workbook, out_ledger_summary.xlsx. Do not overwrite the source, and read the output back to print the total count.

Caution

ExcelWriter defaults to write mode, so passing an existing file name overwrites it; never reuse the source name. The output holds values only, not Excel formulas or PivotTables. Check that the totals match the source row count.

Availability
pandas and openpyxl (tested versions are recorded in code.tested). Runs in local Python; in Python in Excel, pandas.read_excel cannot read outside files.
Requires
pandas 3.0.5, openpyxl 3.1.5
Tested
run and checked locally (2026-09-12, Python 3.12.10 (venv) / Windows 11, pandas 3.0.5, openpyxl 3.1.5)
Source
pandas, "pandas.DataFrame.to_excel"
pandas, "pandas.read_excel"
Verified
2026-09-13 (v1)
Supporting passages from the sources
To write to multiple sheets it is necessary to create an ExcelWriter object with a target file name, and specify a sheet in the file to write to.
Note that creating an ExcelWriter object with a file name that already exists will overwrite the existing file because the default mode is write.
Read an Excel file into a DataFrame.