<?xml version="1.0" encoding="UTF-8"?>
<rss  xmlns:atom="http://www.w3.org/2005/Atom" 
      xmlns:media="http://search.yahoo.com/mrss/" 
      xmlns:content="http://purl.org/rss/1.0/modules/content/" 
      xmlns:dc="http://purl.org/dc/elements/1.1/" 
      version="2.0">
<channel>
<title>Boardflare</title>
<link>https://boardflare.com/posts/</link>
<atom:link href="https://boardflare.com/posts/index.xml" rel="self" type="application/rss+xml"/>
<description>Technical insights and tool updates</description>
<image>
<url>https://boardflare.com/img/boardflare-social-card.png</url>
<title>Boardflare</title>
<link>https://boardflare.com/posts/</link>
<height>76</height>
<width>144</width>
</image>
<generator>quarto-1.10.18</generator>
<lastBuildDate>Thu, 20 Aug 2026 00:00:00 GMT</lastBuildDate>
<item>
  <title>Microsoft Python in Excel vs. Boardflare: Which Should You Use?</title>
  <link>https://boardflare.com/posts/2026/microsoft-python-in-excel-vs-boardflare/</link>
  <description><![CDATA[ 





<p>Microsoft Python in Excel and Boardflare Python for Excel both let a workbook use Python without requiring a separate desktop Python installation. The important difference is not whether they “support Python.” It is <strong>where the Python program lives and what execution model surrounds it</strong>.</p>
<p>Microsoft makes Python part of Excel’s native calculation surface: you author Python in worksheet cells, reference workbook data with <code>xl()</code>, and Microsoft runs the code in a managed cloud container. Boardflare makes a reactive <a href="https://docs.marimo.io/">marimo</a> notebook the Python program: the notebook declares workbook inputs, marimo tracks Python dependencies, and selected values or functions are published back to Excel.</p>
<p>That leads to a practical recommendation:</p>
<ul>
<li><strong>Start with Microsoft Python in Excel</strong> when the Python is bounded analysis that naturally belongs in the grid, when Python object cells or Power Query references matter, or when Microsoft’s managed no-network execution boundary is an organizational advantage.</li>
<li><strong>Evaluate Boardflare</strong> when the Python has become a substantial multi-step program, when dependency-driven notebook execution and interactive controls matter, when you want the complete source as a <code>.py</code> file, or when ordinary Excel formulas need to call reusable Python functions.</li>
<li><strong>Use external Python instead of either</strong> when the real requirement is unrestricted local files, desktop automation, scheduled jobs, database pipelines, or native packages that do not fit a managed-cloud or browser/WebAssembly runtime.</li>
</ul>
<p>This comparison was researched and verified against current Microsoft documentation and the Boardflare implementation on <strong>August 20, 2026</strong>. Both products can change, so deployment-sensitive details should be rechecked against the linked documentation.</p>
<!-- more -->
<section id="the-decision-starts-with-the-shape-of-the-program" class="level2">
<h2 class="anchored" data-anchor-id="the-decision-starts-with-the-shape-of-the-program">The decision starts with the shape of the program</h2>
<p>A feature checklist can make these products look more similar than they are. Both can use pandas, read worksheet ranges, run substantial calculations, and return results to Excel. But they organize the program differently.</p>
<p>Microsoft documents Python in Excel as Python formulas in worksheet cells. Its <a href="https://support.microsoft.com/en-us/excel/python/get-started-with-python-in-excel">Get started guide</a> explains that Python cells calculate in <strong>row-major order</strong>, including across worksheets according to worksheet order. When a dependent value changes, Python formulas are recalculated sequentially. Microsoft’s <a href="https://support.microsoft.com/en-us/excel/python/python-in-excel-code-editor">Python Code Editor</a> gives those cells a larger editing surface and shows workbook Python by worksheet and cell.</p>
<p>Boardflare uses one marimo notebook as the primary Python artifact. marimo is explicitly <a href="https://docs.marimo.io/">reactive: dependent cells rerun when upstream values change</a>, and its notebooks are stored as Python source. In Boardflare, <code>bf.inputs()</code> declares workbook dependencies and <code>bf.publish()</code> exposes selected results or functions back to Excel. The maintained <strong><a href="../../../apps/excel/python/microsoft-python-in-excel-comparison/">technical comparison</a></strong> documents the exact integration and conversion behavior.</p>
<p>Conceptually, the difference looks like this:</p>
<pre class="text"><code>Microsoft Python in Excel                 Boardflare Python for Excel

Workbook                                  Workbook
├── Setup!B2  Python                      ├── worksheet inputs
├── Model!C8  Python                      ├── BF.OUTPUT formulas
├── Model!F20 Python                      └── BF.FUNCTION formulas
└── Report!B4 Python                               │
                                                  ▼
Program structure partly follows         One reactive marimo notebook
worksheet and cell position.              ├── imports
                                          ├── workbook inputs
                                          ├── transformations
                                          ├── models / checks
                                          ├── controls / charts
                                          └── published outputs / functions</code></pre>
<p>For a few analytical calculations, distributing Python through worksheet cells can be direct and intuitive. As the Python grows into something that looks more like a software program—with shared functions, multiple model stages, validation, controls, charts, and documentation—a notebook can provide a more coherent unit of code.</p>
</section>
<section id="at-a-glance" class="level2">
<h2 class="anchored" data-anchor-id="at-a-glance">At a glance</h2>
<table class="caption-top table">
<colgroup>
<col style="width: 33%">
<col style="width: 33%">
<col style="width: 33%">
</colgroup>
<thead>
<tr class="header">
<th>Dimension</th>
<th>Microsoft Python in Excel</th>
<th>Boardflare Python for Excel</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>Primary Python surface</td>
<td><code>PY</code> worksheet cells, with workbook-wide Code Editor</td>
<td>One reactive marimo notebook</td>
</tr>
<tr class="even">
<td>Execution model</td>
<td>Row-major Python-cell order; sequential recalculation</td>
<td>Python dependency graph; affected descendants rerun</td>
</tr>
<tr class="odd">
<td>Runtime</td>
<td>Microsoft-managed cloud container</td>
<td>Browser/WebAssembly Python through Pyodide</td>
</tr>
<tr class="even">
<td>Separate desktop Python install</td>
<td>No</td>
<td>No</td>
</tr>
<tr class="odd">
<td>Worksheet input model</td>
<td><code>xl()</code> ranges, names, tables, images, Power Query</td>
<td><code>bf.inputs()</code> / <code>bf.ref()</code> ranges, names, tables</td>
</tr>
<tr class="even">
<td>Python object in a worksheet cell</td>
<td>Yes</td>
<td>No generic Python-object cell</td>
</tr>
<tr class="odd">
<td>Reusable Python callable from ordinary Excel formulas</td>
<td><code>PY</code> itself cannot be composed with other Excel functions</td>
<td><code>BF.FUNCTION("name", ...)</code></td>
</tr>
<tr class="even">
<td>Complete Python source as <code>.py</code></td>
<td>No native whole-workbook <code>.py</code> export documented</td>
<td>Notebook can be uploaded/downloaded as marimo <code>.py</code> source</td>
</tr>
<tr class="odd">
<td>Arbitrary Python network requests</td>
<td>No</td>
<td>Browser-compatible HTTP, subject to CORS/authentication rules</td>
</tr>
<tr class="even">
<td>Package model</td>
<td>Microsoft/Anaconda curated environment</td>
<td>Pyodide-compatible packages/wheels</td>
</tr>
<tr class="odd">
<td>Interactive Python UI</td>
<td>Worksheet-centric</td>
<td>Notebook controls, charts, Markdown; optional App mode</td>
</tr>
<tr class="even">
<td>Enterprise isolation model</td>
<td>Microsoft 365 compliance boundary; no network/device/token access</td>
<td>Add-in/browser capability boundary; notebook code can make permitted browser requests</td>
</tr>
<tr class="odd">
<td>Recipient requirement</td>
<td>Eligible Microsoft 365 Python-in-Excel environment</td>
<td>Boardflare add-in/runtime and required package/API access</td>
</tr>
</tbody>
</table>
<p>The table deliberately does <strong>not</strong> declare a universal winner. Several rows are tradeoffs rather than advantages.</p>
</section>
<section id="microsoft-fits-especially-well-when-python-belongs-in-the-grid" class="level2">
<h2 class="anchored" data-anchor-id="microsoft-fits-especially-well-when-python-belongs-in-the-grid">Microsoft fits especially well when Python belongs in the grid</h2>
<p>Microsoft’s design is a natural extension of the Excel calculation model. Select a cell, choose <strong>Insert Python</strong>, write a calculation, and return either a Python object or an Excel value. The <a href="https://support.microsoft.com/en-us/excel/functions/py-function"><code>PY</code> function documentation</a> describes <code>xl()</code> references to ranges, names, tables, images, and Power Query connections.</p>
<p>That has important advantages.</p>
<section id="python-objects-can-remain-worksheet-objects" class="level3">
<h3 class="anchored" data-anchor-id="python-objects-can-remain-worksheet-objects">Python objects can remain worksheet objects</h3>
<p>Microsoft can return a DataFrame or another supported value as a Python object in a cell rather than immediately flattening it into worksheet values. Microsoft’s <a href="https://support.microsoft.com/en-us/excel/python/python-in-excel-dataframes">DataFrame documentation</a> shows DataFrames as object cards that can later be converted to Excel values.</p>
<p>That is useful when the worksheet itself is the analytical workspace and an intermediate Python object belongs at a particular coordinate.</p>
<p>Boardflare deliberately uses a different boundary. <code>BF.OUTPUT()</code> publishes Excel-compatible values; it does not emulate Microsoft’s generic Python-object cells. Rich intermediate Python state normally stays in the notebook.</p>
</section>
<section id="power-query-is-a-first-class-external-data-bridge" class="level3">
<h3 class="anchored" data-anchor-id="power-query-is-a-first-class-external-data-bridge">Power Query is a first-class external-data bridge</h3>
<p>Python in Excel has <strong>no arbitrary network access</strong>, but Microsoft provides a supported route for external data: bring it into the workbook with Power Query, then reference the query from Python. Microsoft calls Power Query <a href="https://support.microsoft.com/en-us/excel/python/use-power-query-to-import-data-for-python-in-excel">the external-data import path for Python in Excel</a>.</p>
<p>If an organization already has governed Power Query connections and wants Python analysis layered over them, that integration can be more valuable than direct Python HTTP access.</p>
<p>Boardflare currently has no equivalent public notebook input contract for Power Query connections. It can consume workbook ranges/tables and can make browser-compatible HTTP requests, but those are different integration models.</p>
</section>
<section id="the-security-boundary-is-deliberately-restrictive" class="level3">
<h3 class="anchored" data-anchor-id="the-security-boundary-is-deliberately-restrictive">The security boundary is deliberately restrictive</h3>
<p>Microsoft’s <a href="https://support.microsoft.com/en-us/excel/python/data-security-and-python-in-excel">data security documentation</a> is unusually explicit. Python runs in a hypervisor-isolated Microsoft Cloud container within the organization’s Microsoft 365 compliance boundary. The Python process has no network access, no access to the user’s computer or devices, and no user token; Microsoft also says data is not persisted in the cloud Python environment.</p>
<p>Those restrictions can be a <strong>feature</strong>. If policy requires workbook Python to be incapable of directly sending data to arbitrary internet endpoints, Microsoft’s no-network model is a strong design property rather than a limitation to work around.</p>
</section>
</section>
<section id="boardflare-fits-especially-well-when-the-python-has-become-a-program" class="level2">
<h2 class="anchored" data-anchor-id="boardflare-fits-especially-well-when-the-python-has-become-a-program">Boardflare fits especially well when the Python has become a program</h2>
<p>Boardflare’s design center is different: keep Excel for workbook data, assumptions, review, and delivery, while giving substantial Python work its own programming surface.</p>
<section id="dependency-driven-execution-is-independent-of-worksheet-position" class="level3">
<h3 class="anchored" data-anchor-id="dependency-driven-execution-is-independent-of-worksheet-position">Dependency-driven execution is independent of worksheet position</h3>
<p>Microsoft states that Python cells calculate in row-major order and that the rule extends across worksheets. That means worksheet position is part of the Python program’s execution order. Microsoft also states that when a dependency changes, Python formulas recalculate sequentially. Manual and Partial calculation modes can suspend that behavior when the user’s license supports those modes. See <a href="https://support.microsoft.com/en-us/excel/python/get-started-with-python-in-excel">Microsoft’s calculation guidance</a> and <a href="https://support.microsoft.com/en-us/excel/python/python-in-excel-availability">availability/licensing page</a>.</p>
<p>marimo instead builds a dependency graph from Python variable definitions and references. Change an upstream value and the affected downstream cells rerun. Moving a notebook cell visually does not redefine its dependencies merely because its screen position changed.</p>
<p>This does <strong>not</strong> prove that Boardflare is faster. Runtime performance depends on the calculation, data size, package implementation, transfer overhead, and compute environment. It does mean the models have different semantics as a program grows.</p>
</section>
<section id="one-implementation-can-become-a-reusable-excel-function" class="level3">
<h3 class="anchored" data-anchor-id="one-implementation-can-become-a-reusable-excel-function">One implementation can become a reusable Excel function</h3>
<p>Microsoft’s <code>PY</code> function is itself a worksheet calculation, and Microsoft states that <a href="https://support.microsoft.com/en-us/excel/functions/py-function"><code>PY</code> cannot be used with other Excel functions</a>. Boardflare can publish a Python callable once and let ordinary worksheet formulas invoke that implementation:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb2" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb2-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> discount(price, rate):</span>
<span id="cb2-2">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> price <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> (<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> rate)</span>
<span id="cb2-3"></span>
<span id="cb2-4">bf.publish(functions<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>{<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"discount"</span>: discount})</span></code></pre></div></div>
<pre class="excel"><code>=BF.FUNCTION("discount", A2, B2)</code></pre>
<p>That pattern is useful when the workbook needs hundreds of ordinary Excel formulas to call one centrally maintained Python algorithm. The tradeoff is that <code>BF.FUNCTION()</code> depends on the Boardflare notebook runtime being available; it is not a standalone server-side UDF service. See <strong><a href="../../../apps/excel/python/working-with-excel/#create-excel-functions">Working with Excel</a></strong> for the exact contract.</p>
</section>
<section id="the-notebook-can-also-be-the-interface" class="level3">
<h3 class="anchored" data-anchor-id="the-notebook-can-also-be-the-interface">The notebook can also be the interface</h3>
<p>A marimo notebook can contain Markdown, controls, tables, charts, validation messages, and reactive outputs. Boardflare can reopen the saved notebook in <strong>App mode</strong> when the same analysis becomes a repeatable operator-facing tool.</p>
<p>That is materially different from simply having a larger code editor. The notebook can be both the implementation and an interactive analytical surface beside Excel. Boardflare’s <strong><a href="../../../apps/excel/python/building-notebooks/">notebook guide</a></strong> explains the reactive/UI model, while <strong><a href="../../../apps/excel/python/app-mode-and-sharing/">App mode and sharing</a></strong> documents an important caveat: App mode changes presentation; it is not a security boundary or source-protection mechanism.</p>
</section>
<section id="the-complete-source-can-be-treated-as-source" class="level3">
<h3 class="anchored" data-anchor-id="the-complete-source-can-be-treated-as-source">The complete source can be treated as source</h3>
<p>marimo stores notebooks as Python <code>.py</code> files. Boardflare saves the notebook source with the workbook and supports uploading/downloading the <code>.py</code> representation.</p>
<p>That matters if the Python itself needs code review, backup, diffing, or version-control workflows. Boardflare does <strong>not</strong> currently claim built-in Git synchronization; the advantage is that the program has a normal source representation that can participate in those workflows.</p>
<p>Microsoft’s Code Editor improves large-code authoring substantially, but Microsoft does not currently document a native workflow that exports all Python cells in a workbook as one complete <code>.py</code> program. For a workbook where code portability is a formal requirement, that difference should be tested early.</p>
</section>
</section>
<section id="same-workbook-problem-two-different-program-shapes" class="level2">
<h2 class="anchored" data-anchor-id="same-workbook-problem-two-different-program-shapes">Same workbook problem, two different program shapes</h2>
<p>The distinction is easier to see with a concrete example. Boardflare’s <strong><a href="../../../templates/sales-scenario-analysis/">Sales Scenario Analysis</a></strong> ships two workbooks built from the same inputs and expected results: one using Microsoft Python in Excel and one using a Boardflare notebook.</p>
<p>The shared worksheet contains monthly units and prices. At a 10% discount, both implementations are validated against the same expected result:</p>
<table class="caption-top table">
<thead>
<tr class="header">
<th>Result</th>
<th style="text-align: right;">Expected value</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>Total units</td>
<td style="text-align: right;">650</td>
</tr>
<tr class="even">
<td>Base revenue</td>
<td style="text-align: right;">$10,890</td>
</tr>
<tr class="odd">
<td>Scenario revenue</td>
<td style="text-align: right;">$9,801</td>
</tr>
<tr class="even">
<td>Revenue change</td>
<td style="text-align: right;">-$1,089</td>
</tr>
</tbody>
</table>
<p>The Microsoft workbook expresses the analysis as a Python cell that reads the worksheet range and returns the summary:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb4" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb4-1">sales <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> xl(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"A5:C9"</span>, headers<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">True</span>)</span>
<span id="cb4-2">discount <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.10</span></span>
<span id="cb4-3">sales[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Base revenue"</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> sales[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Units"</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> sales[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Price ($)"</span>]</span>
<span id="cb4-4">sales[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Scenario revenue"</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> sales[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Base revenue"</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> (<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> discount)</span></code></pre></div></div>
<p>That is a good shape for a bounded calculation: source data in Excel, one Python analysis, result back in the grid.</p>
<p>The Boardflare version starts from the same worksheet range but keeps the model in a reactive notebook:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb5" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb5-1">inputs <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> bf.inputs(sales<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>bf.ref(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"A5:C9"</span>, headers<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">True</span>))</span>
<span id="cb5-2">analysis <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> inputs[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"sales"</span>].copy()</span>
<span id="cb5-3">analysis[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Base revenue"</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> analysis[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Units"</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> analysis[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Price ($)"</span>]</span>
<span id="cb5-4">analysis[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Scenario revenue"</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> analysis[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Base revenue"</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> (</span>
<span id="cb5-5">    <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">float</span>(discount.value) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">100</span></span>
<span id="cb5-6">)</span>
<span id="cb5-7">bf.publish(outputs<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>{<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"summary"</span>: summary})</span></code></pre></div></div>
<p>The notebook also owns an interactive discount slider and chart. Change a worksheet input or the slider and the dependent notebook cells update; the compact summary can be published back to Excel with <code>BF.OUTPUT("summary")</code>.</p>
<p>The useful conclusion is not that one implementation produces a better answer—they intentionally produce the same answer. It is that <strong>the same analytical problem can evolve into two different artifacts</strong>:</p>
<ul>
<li>a worksheet-centered Python calculation; or</li>
<li>a workbook-connected reactive application whose Python is centralized in a notebook.</li>
</ul>
<p>You can download both workbooks from the template page and evaluate the difference with the same data rather than relying on screenshots or vendor descriptions.</p>
</section>
<section id="runtime-and-packages-managed-cloud-vs.-browser-webassembly" class="level2">
<h2 class="anchored" data-anchor-id="runtime-and-packages-managed-cloud-vs.-browser-webassembly">Runtime and packages: managed cloud vs.&nbsp;browser WebAssembly</h2>
<p>Neither product uses your normal desktop Python installation.</p>
<section id="microsoft-curated-anaconda-environment-in-the-cloud" class="level3">
<h3 class="anchored" data-anchor-id="microsoft-curated-anaconda-environment-in-the-cloud">Microsoft: curated Anaconda environment in the cloud</h3>
<p>Microsoft provides a managed Python environment with core libraries including pandas, NumPy, Matplotlib, seaborn, and statsmodels, plus additional packages from its curated Anaconda distribution. The <a href="https://support.microsoft.com/en-us/excel/python/open-source-libraries-and-python-in-excel">library documentation</a> also reiterates that those libraries cannot make network requests or access local files from the user’s machine.</p>
<p>This gives Microsoft control over the environment and allows workbooks to remain associated with environment versions, which helps reproducibility. The tradeoff is that users cannot treat the runtime like an arbitrary local Conda environment.</p>
</section>
<section id="boardflare-pyodide-in-the-browser" class="level3">
<h3 class="anchored" data-anchor-id="boardflare-pyodide-in-the-browser">Boardflare: Pyodide in the browser</h3>
<p>Boardflare runs notebook Python through Pyodide/WebAssembly. <a href="https://pyodide.org/en/stable/">Pyodide</a> is CPython compiled for WebAssembly and includes or supports many scientific packages such as NumPy, pandas, SciPy, Matplotlib, and scikit-learn. Compatible pure-Python wheels and Pyodide-supported packages can be loaded in the browser.</p>
<p>But “runs in the browser” does not mean “desktop Python with a different window.” Pyodide documents <a href="https://pyodide.org/en/stable/usage/wasm-constraints.html">WebAssembly and browser constraints</a>, including limitations around sockets, operating-system modules, and browser networking policies. A package that works on a developer laptop may still be unsuitable in the browser runtime.</p>
<p>For either product, the right evaluation is to test the <strong>actual package set your workbook needs</strong>, including transitive dependencies—not to infer compatibility from the package name alone.</p>
</section>
</section>
<section id="network-access-is-a-tradeoff-not-a-score" class="level2">
<h2 class="anchored" data-anchor-id="network-access-is-a-tradeoff-not-a-score">Network access is a tradeoff, not a score</h2>
<p>This is one of the clearest differences.</p>
<p>Microsoft Python in Excel intentionally has no network access. External data should enter through workbook data or supported Power Query connections. That reduces the ways Python code can communicate outside the managed environment.</p>
<p>Boardflare notebook code can make browser-compatible HTTP requests. That can be valuable for a REST API or another service designed for browser clients, but <a href="https://pyodide.org/en/stable/usage/api/python-api/http.html">Pyodide networking remains subject to browser security rules</a>, including CORS and authentication constraints. It is not unrestricted socket/network access.</p>
<p>So the decision depends on the requirement:</p>
<table class="caption-top table">
<colgroup>
<col style="width: 50%">
<col style="width: 50%">
</colgroup>
<thead>
<tr class="header">
<th>Requirement</th>
<th>Better starting point</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>Python must be unable to call arbitrary external endpoints</td>
<td>Microsoft Python in Excel</td>
</tr>
<tr class="even">
<td>Python must call a CORS-compatible web API directly</td>
<td>Boardflare may fit better</td>
</tr>
<tr class="odd">
<td>Python must use raw sockets, desktop credentials, SSH, or unrestricted networking</td>
<td>External Python</td>
</tr>
</tbody>
</table>
<p>Boardflare’s <strong><a href="../../../apps/excel/python/advanced/security-and-data-flow/">Security and Data Flow</a></strong> documents its workbook/browser capability boundary and the separate data path created when notebook authors call external services.</p>
</section>
<section id="sharing-and-deployment-deserve-their-own-test" class="level2">
<h2 class="anchored" data-anchor-id="sharing-and-deployment-deserve-their-own-test">Sharing and deployment deserve their own test</h2>
<p>A workbook that works for its author can still fail as a deliverable.</p>
<p>Microsoft’s <a href="https://support.microsoft.com/en-us/excel/python/python-in-excel-availability">availability documentation</a> ties Python in Excel to qualifying Microsoft 365 subscriptions and supported platforms/update channels. Qualifying subscriptions include standard compute and automatic recalculation; Microsoft’s separate <a href="https://support.microsoft.com/en-us/office/python-in-excel-add-on-licensing-faq-6d90fc0e-f080-4799-9d28-9754c77fb308">add-on licensing FAQ</a> says the add-on provides premium compute plus Manual and Partial calculation modes.</p>
<p>Boardflare requires the Python for Excel add-in and its runtime. A recipient does not need desktop Python, but does need access to the add-in/notebook assets and to any package hosts or external APIs the authored notebook depends on. Those requirements are spelled out in <strong><a href="../../../apps/excel/python/app-mode-and-sharing/#recipient-requirements">App mode and sharing</a></strong>.</p>
<p>For either option, test the <strong>second-user experience</strong> before standardizing on it:</p>
<ol type="1">
<li>Send the workbook to someone who did not build it.</li>
<li>Open it on the platforms your organization actually uses.</li>
<li>Recalculate it from a cold start.</li>
<li>Confirm licensing/add-in/policy requirements.</li>
<li>Confirm package and external-data dependencies.</li>
<li>Confirm what users see when the Python runtime is unavailable or slow to start.</li>
<li>Save, close, reopen, and verify that the workbook reconstructs the expected state.</li>
</ol>
<p>This is more informative than comparing a feature list because deployment failures usually occur at the boundaries: identity, policy, runtime startup, packages, external data, and recipient configuration.</p>
</section>
<section id="which-should-you-use" class="level2">
<h2 class="anchored" data-anchor-id="which-should-you-use">Which should you use?</h2>
<p>The following scenarios are more useful than declaring an overall winner.</p>
<table class="caption-top table">
<colgroup>
<col style="width: 33%">
<col style="width: 33%">
<col style="width: 33%">
</colgroup>
<thead>
<tr class="header">
<th>Your workbook looks like this</th>
<th>Start with</th>
<th>Why</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>A few pandas/statistical calculations belong directly beside worksheet data</td>
<td><strong>Microsoft</strong></td>
<td>Native <code>PY</code> cells are direct and grid-centered</td>
</tr>
<tr class="even">
<td>You want DataFrames or other supported Python objects to live in worksheet cells</td>
<td><strong>Microsoft</strong></td>
<td>Python object output is built into the model</td>
</tr>
<tr class="odd">
<td>External data already arrives through governed Power Query connections</td>
<td><strong>Microsoft</strong></td>
<td><code>xl()</code> can reference Power Query connections directly</td>
</tr>
<tr class="even">
<td>Policy benefits from Python having no arbitrary network access</td>
<td><strong>Microsoft</strong></td>
<td>The cloud runtime deliberately removes network/device/token access</td>
</tr>
<tr class="odd">
<td>The Python has grown into a substantial multi-stage program</td>
<td><strong>Boardflare</strong></td>
<td>One notebook keeps functions, transformations, checks, controls, charts, and explanation together</td>
</tr>
<tr class="even">
<td>Execution should follow Python dependencies rather than worksheet/tab order</td>
<td><strong>Boardflare</strong></td>
<td>marimo uses a reactive dependency graph</td>
</tr>
<tr class="odd">
<td>One Python algorithm should be callable from many ordinary Excel formulas</td>
<td><strong>Boardflare</strong></td>
<td><code>BF.FUNCTION()</code> publishes a centralized callable</td>
</tr>
<tr class="even">
<td>The notebook itself should contain interactive controls and an app-style presentation</td>
<td><strong>Boardflare</strong></td>
<td>Reactive notebook UI + optional App mode</td>
</tr>
<tr class="odd">
<td>The whole program needs a portable <code>.py</code> representation for review/diff/backup</td>
<td><strong>Boardflare</strong></td>
<td>The notebook is Python source</td>
</tr>
<tr class="even">
<td>Python needs to call a browser-compatible REST API directly</td>
<td><strong>Boardflare</strong>, after testing CORS/auth</td>
<td>Browser HTTP is available within normal browser constraints</td>
</tr>
<tr class="odd">
<td>The workflow walks local folders, automates desktop apps, runs scheduled jobs, or needs unsupported native packages</td>
<td><strong>External Python</strong></td>
<td>Neither in-Excel runtime is designed as unrestricted desktop/server Python</td>
</tr>
</tbody>
</table>
<p>A good proof-of-concept should therefore start from your <strong>hardest architectural requirement</strong>, not your easiest pandas example. If Power Query integration, network isolation, reusable worksheet functions, a browser API, or source-control review is mandatory, test that first.</p>
</section>
<section id="the-practical-dividing-line" class="level2">
<h2 class="anchored" data-anchor-id="the-practical-dividing-line">The practical dividing line</h2>
<p>Microsoft Python in Excel fits best when <strong>Excel remains the program’s primary organizing surface</strong> and Python adds analysis to the grid. It has deep native integration, a managed environment, Python object cells, Power Query references, and a deliberately restrictive enterprise execution boundary.</p>
<p>Boardflare fits best when <strong>Excel remains important, but the Python deserves its own coherent program</strong>. A reactive notebook provides dependency-based execution, interactive controls, centralized source, explicit workbook inputs/outputs, reusable worksheet functions, and a path to app-style presentation.</p>
<p>Neither replaces ordinary Excel formulas where formulas are already clear. Neither replaces external Python when the real job is file-system, desktop, server, or batch automation.</p>
<p>For a deeper field-by-field comparison—including source limits, exact type conversion, input/output limits, worksheet-error behavior, and security boundaries—use the maintained <strong><a href="../../../apps/excel/python/microsoft-python-in-excel-comparison/">Boardflare vs.&nbsp;Microsoft Python in Excel technical comparison</a></strong>. To evaluate both approaches against the same calculations, start with the <strong><a href="../../../templates/">Python in Excel template library</a></strong>.</p>
</section>
<section id="primary-sources-used-for-this-review" class="level2">
<h2 class="anchored" data-anchor-id="primary-sources-used-for-this-review">Primary sources used for this review</h2>
<p>The Microsoft side of this article was checked against current first-party documentation on August 20, 2026:</p>
<ul>
<li><a href="https://support.microsoft.com/en-us/excel/python/introduction-to-python-in-excel">Introduction to Python in Excel</a> — runtime and platform model.</li>
<li><a href="https://support.microsoft.com/en-us/excel/python/get-started-with-python-in-excel">Get started with Python in Excel</a> — <code>xl()</code>, calculation order, recalculation, outputs, and external-data boundary.</li>
<li><a href="https://support.microsoft.com/en-us/excel/functions/py-function">PY function</a> — static Python source, supported Excel references, return types, and formula-composition restriction.</li>
<li><a href="https://support.microsoft.com/en-us/excel/python/python-in-excel-code-editor">Python in Excel code editor</a> — workbook-wide editing surface.</li>
<li><a href="https://support.microsoft.com/en-us/excel/python/python-in-excel-dataframes">Python in Excel DataFrames</a> — Python object and Excel-value output modes.</li>
<li><a href="https://support.microsoft.com/en-us/excel/python/data-security-and-python-in-excel">Data security and Python in Excel</a> — cloud isolation, network/device/token restrictions, workbook access, and environment persistence behavior.</li>
<li><a href="https://support.microsoft.com/en-us/excel/python/open-source-libraries-and-python-in-excel">Open-source libraries and Python in Excel</a> — managed package environment.</li>
<li><a href="https://support.microsoft.com/en-us/excel/python/use-power-query-to-import-data-for-python-in-excel">Use Power Query to import data for Python in Excel</a> — external-data integration.</li>
<li><a href="https://support.microsoft.com/en-us/excel/python/python-in-excel-availability">Python in Excel availability</a> and <a href="https://support.microsoft.com/en-us/office/python-in-excel-add-on-licensing-faq-6d90fc0e-f080-4799-9d28-9754c77fb308">add-on licensing FAQ</a> — eligibility, compute tiers, and calculation modes.</li>
</ul>
<p>The Boardflare side was checked against the current repository implementation and maintained documentation, especially <strong><a href="../../../apps/excel/python/advanced/architecture-and-runtime/">Architecture and Runtime</a></strong>, <strong><a href="../../../apps/excel/python/advanced/security-and-data-flow/">Security and Data Flow</a></strong>, and <strong><a href="../../../apps/excel/python/working-with-excel/">Working with Excel</a></strong>. The underlying notebook/runtime behavior is also consistent with the official <a href="https://docs.marimo.io/">marimo documentation</a> and <a href="https://pyodide.org/en/stable/">Pyodide documentation</a>.</p>


</section>

 ]]></description>
  <category>Excel</category>
  <category>Python</category>
  <category>Comparisons</category>
  <guid>https://boardflare.com/posts/2026/microsoft-python-in-excel-vs-boardflare/</guid>
  <pubDate>Thu, 20 Aug 2026 00:00:00 GMT</pubDate>
</item>
<item>
  <title>How AI Is Changing Python Development in Excel</title>
  <link>https://boardflare.com/posts/2026/ai-python-development-excel/</link>
  <description><![CDATA[ 





<p>AI is changing Python-and-Excel work less by making spreadsheets autonomous and more by changing <strong>who can build deterministic automation</strong>.</p>
<p>In the public practitioner discussions linked below, users describe asking assistants to write or revise VBA and Python, troubleshoot syntax and logic, and turn plain-language business rules into repeatable scripts. Some already know enough code to review the implementation; others start from domain knowledge and iterate against real test data. These are recurring observations from a purposive sample, not a survey of Excel users.</p>
<p>That distinction matters: the durable output is often ordinary Python or VBA that can be inspected, rerun, tested, and reconciled—not an AI answer that must be trusted every time the workbook is opened.</p>
<!-- more -->
<section id="what-the-linked-discussions-show" class="level2">
<h2 class="anchored" data-anchor-id="what-the-linked-discussions-show">What the linked discussions show</h2>
<p>The source material supports a qualitative pattern rather than a precise adoption statistic:</p>
<table class="caption-top table">
<thead>
<tr class="header">
<th>Observed pattern</th>
<th>What the sources describe</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>AI as an implementation partner</td>
<td>Users ask ChatGPT, Claude, or another coding assistant to draft VBA or Python, then run the result, report errors, and refine it. See the <a href="https://www.reddit.com/r/Accounting/comments/1v12xrz/how_i_use_ai_as_a_staff_accountant/">staff-accountant discussion</a> and an <a href="https://www.reddit.com/r/Accounting/comments/1hpy054/case_study_of_using_chatgpt_and_python_to_make/">accountant’s invoice-automation case study</a>.</td>
</tr>
<tr class="even">
<td>Python around Excel</td>
<td>Several users describe reading and writing workbooks from external Python for batch processing, AI-assisted text cleaning, or file-heavy automation. See <a href="https://www.reddit.com/r/excel/comments/1qtj5v3/what_do_you_use_python_for_in_excel/">Python as a middleman between Excel and Claude</a> and <a href="https://www.reddit.com/r/Accounting/comments/1hyiu1e/automating_everything_i_can_as_an_accountant/">an accountant’s Python automation examples</a>.</td>
</tr>
<tr class="odd">
<td>AI inside Excel</td>
<td>Microsoft’s documentation describes Copilot workbook edits and an advanced-analysis workflow that can create a separate sheet with Python-backed analysis; those capabilities are product-specific and availability-dependent. See <a href="https://support.microsoft.com/en-us/excel/get-direct-answers-to-your-data-analysis-questions">Copilot data analysis</a> and <a href="https://support.microsoft.com/en-us/excel/python/python-in-excel-availability">Python in Excel availability</a>.</td>
</tr>
<tr class="even">
<td>Human-owned rules and review</td>
<td>The discussions consistently treat domain knowledge, testing, and review as the user’s responsibility even when the assistant writes much of the syntax. An <a href="https://www.reddit.com/r/excel/comments/1qq59c6/anyone_actually_using_excel_ai_tools_at_work/">Excel AI-tools discussion</a> is a useful counterweight to vendor claims because it includes both use and skepticism.</td>
</tr>
</tbody>
</table>
<p>The useful finding is behavioral: AI assistance and self-written code are no longer opposites. In many workflows, the user still owns the logic and testing while an assistant supplies a growing share of the syntax. The linked discussions are self-selected anecdotes, so this article does not turn them into percentages or market-share estimates.</p>
<div class="cell" data-layout-align="default">
<div class="cell-output-display">
<div>
<p></p><figure class="figure"><p></p>
<div>
<pre class="mermaid mermaid-js">flowchart LR
    A[Business requirement] --&gt; B[AI-assisted draft]
    B --&gt; C[Inspectable Python / VBA]
    C --&gt; D[Test data]
    D --&gt; E{Correct and reconciled?}
    E --&gt;|No| F[Error / result back to assistant]
    F --&gt; B
    E --&gt;|Yes| G[Reusable deterministic tool]
</pre>
</div>
<p></p></figure><p></p>
</div>
</div>
</div>
</section>
<section id="external-chat-tools-describe-run-debug-repeat" class="level2">
<h2 class="anchored" data-anchor-id="external-chat-tools-describe-run-debug-repeat">External chat tools: describe, run, debug, repeat</h2>
<p>The most detailed automation stories in the reviewed sample often follow a simple loop:</p>
<ol type="1">
<li>describe the process and representative inputs;</li>
<li>ask for Python or VBA;</li>
<li>copy the code into the real execution environment;</li>
<li>run it on test data;</li>
<li>return tracebacks or unexpected output to the assistant;</li>
<li>refine the code;</li>
<li>retain the final script as a normal software artifact.</li>
</ol>
<p>That workflow is attractive because an external assistant can discuss Python, VBA, SQL, command-line behavior, PDFs, APIs, and file-system errors in one place. It is particularly useful when the automation extends beyond Excel.</p>
<p>One <a href="https://www.reddit.com/r/Accounting/comments/1hpy054/case_study_of_using_chatgpt_and_python_to_make/">property-management controller described using ChatGPT and Python for invoice processing</a>. The user reported adapting a base template to six vendors, identifying roughly ten more candidates, and uploading a 400-invoice monthly batch in roughly 3–4 minutes. That is an anecdotal, user-reported result rather than an independently measured benchmark, but it illustrates the pattern: a domain expert specifies the workflow, AI helps write the implementation, and the output becomes a repeatable script.</p>
<p>A separate <a href="https://www.reddit.com/r/Accounting/comments/1v12xrz/how_i_use_ai_as_a_staff_accountant/">staff-accountant discussion</a> emphasized using AI to build deterministic tools rather than asking a model to inspect a workbook and provide an unverifiable conclusion. The accountant supplies the requirements and reviews the resulting automation; the assistant handles much of the technical writing.</p>
</section>
<section id="integrated-copilot-less-copying-more-workbook-context" class="level2">
<h2 class="anchored" data-anchor-id="integrated-copilot-less-copying-more-workbook-context">Integrated Copilot: less copying, more workbook context</h2>
<p>Integrated Excel assistants solve a different friction problem: context and execution can stay closer to the workbook.</p>
<p>Microsoft’s current Copilot documentation distinguishes direct Python-backed analysis from an advanced-analysis mode. Direct answers can expose the generated code, while advanced analysis opens a new sheet, runs Python, and lets the user modify or insert the underlying code as a refreshable Python cell. That makes the analytical path more inspectable than a prose-only answer while avoiding the copy-and-paste loop for bounded workbook analysis. Availability still depends on the relevant Microsoft 365 product, client, and licensing context.</p>
<p>Official references:</p>
<ul>
<li><a href="https://support.microsoft.com/en-us/excel/get-direct-answers-to-your-data-analysis-questions">Get direct answers to your data analysis questions</a></li>
<li><a href="https://support.microsoft.com/en-us/excel/copilot/frequently-asked-questions-about-copilot-in-excel">Frequently asked questions about Copilot in Excel</a></li>
<li><a href="https://support.microsoft.com/en-us/excel/python/introduction-to-python-in-excel">Introduction to Python in Excel</a></li>
</ul>
<p>The tradeoff is that integrated analysis operates within the product’s supported workbook and runtime model. It is not a substitute for an external automation that must walk local folders, process arbitrary documents, run on a server schedule, or coordinate several desktop applications.</p>
</section>
<section id="deterministic-tools-versus-model-generated-conclusions" class="level2">
<h2 class="anchored" data-anchor-id="deterministic-tools-versus-model-generated-conclusions">Deterministic tools versus model-generated conclusions</h2>
<p>For consequential spreadsheet work, this is the most important architectural distinction.</p>
<p>Suppose an accountant needs to reconcile two systems. There are two very different requests:</p>
<p><strong>Request A:</strong> “Look at these files and tell me whether the accounts reconcile.”</p>
<p><strong>Request B:</strong> “Write a script that joins on these keys, applies these tolerance rules, produces an exceptions table, and proves that source totals reconcile to output totals.”</p>
<p>The second request creates something that can be:</p>
<ul>
<li>reviewed before use;</li>
<li>tested against known cases;</li>
<li>rerun next month;</li>
<li>version controlled;</li>
<li>reconciled independently;</li>
<li>logged when inputs are malformed;</li>
<li>handed to another maintainer.</li>
</ul>
<p>An LLM can still make a business-logic mistake in the generated code. The advantage is not that generated software is automatically correct; it is that the logic becomes explicit and testable. That review requirement is visible in the <a href="https://www.reddit.com/r/excel/comments/1qq59c6/anyone_actually_using_excel_ai_tools_at_work/">Excel AI-tools discussion</a>, where users describe plausible-but-wrong suggestions, security constraints, and the need to double-check outputs. The thread is anecdotal, but it is a useful counterweight to treating code generation itself as validation.</p>
</section>
<section id="the-domain-expert-still-has-to-specify-the-rules" class="level2">
<h2 class="anchored" data-anchor-id="the-domain-expert-still-has-to-specify-the-rules">The domain expert still has to specify the rules</h2>
<p>AI is weakest where the prompt silently assumes business knowledge that has never been made explicit.</p>
<p>A model cannot safely infer organization-specific rules such as:</p>
<ul>
<li>fiscal-calendar conventions;</li>
<li>entity and account mappings;</li>
<li>sign conventions;</li>
<li>revenue-recognition treatment;</li>
<li>which duplicates are legitimate;</li>
<li>missing-data policy;</li>
<li>outlier handling;</li>
<li>forecast horizons;</li>
<li>acceptable reconciliation tolerance;</li>
<li>when a human approval is required.</li>
</ul>
<p>The strongest practitioner stories are therefore not “AI replaced the accountant/analyst.” They are examples of a domain expert converting tacit knowledge into a specification and using AI to accelerate the implementation.</p>
</section>
<section id="what-minimum-skill-does-the-user-still-need" class="level2">
<h2 class="anchored" data-anchor-id="what-minimum-skill-does-the-user-still-need">What minimum skill does the user still need?</h2>
<p>A person does not need to become a full-time software engineer to benefit from AI-generated Python. They do need enough literacy to recognize dangerous or obviously incorrect behavior.</p>
<p>At minimum, recurring business automation owners should understand:</p>
<ul>
<li>data types and missing values;</li>
<li>DataFrame filtering, joins, and grouping;</li>
<li>functions, parameters, and return values;</li>
<li>file paths and overwrite behavior;</li>
<li>exceptions and tracebacks;</li>
<li>the difference between test and production inputs;</li>
<li>how to compare totals before and after a transformation;</li>
<li>how dependencies and credentials are supplied.</li>
</ul>
<p>This is also why a generated script should become maintained organizational code once it supports a recurring business process.</p>
</section>
<section id="a-review-pattern-for-finance-and-accounting-automation" class="level2">
<h2 class="anchored" data-anchor-id="a-review-pattern-for-finance-and-accounting-automation">A review pattern for finance and accounting automation</h2>
<p>For high-impact workflows, ask the assistant to produce controls along with the implementation.</p>
<p>A useful checklist is:</p>
<ol type="1">
<li><strong>Define inputs and outputs.</strong> State schemas, required columns, units, signs, and allowable missing values.</li>
<li><strong>Make assumptions explicit.</strong> Put mappings, thresholds, and dates in configuration rather than hiding them in prose.</li>
<li><strong>Add assertions.</strong> Check row counts, uniqueness, ranges, and required totals.</li>
<li><strong>Preserve source records.</strong> Never overwrite the only copy of an input file.</li>
<li><strong>Log exceptions.</strong> Skipped or malformed records should be visible.</li>
<li><strong>Reconcile.</strong> Compare source and output totals with documented tolerances.</li>
<li><strong>Test known cases.</strong> Include both expected successes and expected failures.</li>
<li><strong>Version the code.</strong> Record what changed and which version produced an output.</li>
</ol>
<p>The AI can generate much of this scaffolding. The owner still decides whether the controls prove what the business process actually requires.</p>
</section>
<section id="where-boardflares-notebook-ai-fits" class="level2">
<h2 class="anchored" data-anchor-id="where-boardflares-notebook-ai-fits">Where Boardflare’s notebook AI fits</h2>
<p>Boardflare uses AI on the <strong>authoring side</strong> of a workbook-connected notebook.</p>
<p>The notebook assistant is instructed on the public workbook API and marimo’s reactive programming rules. Depending on the authoring action, supplied notebook context can be used to create cells, revise a selected region, explain code, or provide inline completion.</p>
<p>The assistant does <strong>not</strong> become the runtime for the notebook. It does not receive an unrestricted tool that can execute arbitrary notebook code or mutate live workbook state on its own. The durable artifact remains inspectable notebook source plus explicit workbook inputs and published outputs/functions.</p>
<p>That creates the same pattern seen in the strongest practitioner evidence:</p>
<pre class="text"><code>Author intent
    ↓
AI-assisted implementation
    ↓
Inspectable reactive Python
    ↓
Validation and testing
    ↓
Saved workbook + notebook source
    ↓
Operator uses deterministic behavior</code></pre>
<p>See <a href="../../../apps/excel/python/ai-authoring/">AI authoring</a> for the current product behavior and <a href="../../../apps/excel/python/building-notebooks/#designing-maintainable-notebooks">Designing notebooks</a> for the notebook design guidance.</p>
</section>
<section id="what-to-expect-next" class="level2">
<h2 class="anchored" data-anchor-id="what-to-expect-next">What to expect next</h2>
<p>AI will continue reducing the amount of syntax a spreadsheet expert has to write manually. That does not remove the need for architecture, validation, or domain ownership. It makes those disciplines more important because more people can now produce code quickly.</p>
<p>The most useful question is therefore not “did a human or an AI write this Python?” It is:</p>
<blockquote class="blockquote">
<p><strong>Can another person inspect the logic, reproduce the result, detect bad inputs, and maintain the tool when the business rule changes?</strong></p>
</blockquote>
<p>That is the standard that turns AI-assisted code generation into dependable spreadsheet automation.</p>
</section>
<section id="methodology-and-limitations" class="level2">
<h2 class="anchored" data-anchor-id="methodology-and-limitations">Methodology and limitations</h2>
<p>This article is a qualitative synthesis of a purposive set of public practitioner discussions and official documentation. Representative sources include <a href="https://www.reddit.com/r/excel/comments/1qtj5v3/what_do_you_use_python_for_in_excel/">Python as a middleman between Excel and Claude</a>, <a href="https://www.reddit.com/r/Accounting/comments/1hpy054/case_study_of_using_chatgpt_and_python_to_make/">an invoice-processing case study</a>, <a href="https://www.reddit.com/r/Accounting/comments/1hyiu1e/automating_everything_i_can_as_an_accountant/">an accountant’s automation examples</a>, <a href="https://www.reddit.com/r/Accounting/comments/1v12xrz/how_i_use_ai_as_a_staff_accountant/">how a staff accountant uses AI</a>, and <a href="https://www.reddit.com/r/excel/comments/1qq59c6/anyone_actually_using_excel_ai_tools_at_work/">Excel users discussing AI tools at work</a>. The sources support qualitative observations about development workflows; they do not establish tool adoption, market share, productivity gains, or error rates across the broader Excel population.</p>


</section>

 ]]></description>
  <category>Excel</category>
  <category>Python</category>
  <category>AI</category>
  <category>Research</category>
  <guid>https://boardflare.com/posts/2026/ai-python-development-excel/</guid>
  <pubDate>Wed, 12 Aug 2026 00:00:00 GMT</pubDate>
</item>
<item>
  <title>What People Actually Use Python in Excel For</title>
  <link>https://boardflare.com/posts/2026/python-in-excel-use-cases/</link>
  <description><![CDATA[ 





<p>“Python in Excel” now describes several very different workflows. Sometimes Python executes inside an Excel workbook. Sometimes an add-in connects a browser or local Python runtime to Excel. And in many of the strongest production stories, Python runs completely outside Excel and the workbook remains the input, review, or delivery format.</p>
<p>To understand what users are actually doing rather than what product pages say they <em>could</em> do, this article synthesizes a purposive set of linked practitioner discussions and official documentation. The sources are not a representative sample of Excel users, but they reveal recurring ways people combine Python and Excel in practice.</p>
<!-- more -->
<section id="the-recurring-use-cases" class="level2">
<h2 class="anchored" data-anchor-id="the-recurring-use-cases">The recurring use cases</h2>
<p>The linked discussions point to six recurring application families. They overlap: one workflow can clean data, run a forecast, create a chart, and publish a workbook at the end.</p>
<table class="caption-top table">
<thead>
<tr class="header">
<th>Application family</th>
<th>What practitioners describe</th>
<th>Representative evidence</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>Data cleaning and reshaping</td>
<td>Joins, pivots, text cleanup, type conversion, deduplication, and normalization.</td>
<td><a href="https://www.reddit.com/r/excel/comments/1rj4ujd/why_do_advanced_users_move_from_power_query_to_python/">Why some users move from Power Query to Python</a></td>
</tr>
<tr class="even">
<td>Recurring automation and report production</td>
<td>Batch workbooks, invoice workflows, PDF processing, recurring reports, and file handling.</td>
<td><a href="https://www.reddit.com/r/Accounting/comments/1hyiu1e/automating_everything_i_can_as_an_accountant/">An accountant’s automation examples</a> and <a href="https://www.reddit.com/r/Accounting/comments/1hpy054/case_study_of_using_chatgpt_and_python_to_make/">an invoice-processing case study</a></td>
</tr>
<tr class="odd">
<td>Modeling, statistics, and forecasting</td>
<td>Optimization, time-series models, scenarios, simulation, and risk analysis.</td>
<td><a href="https://www.reddit.com/r/excel/comments/1kw4sq0/curiosity_what_are_some_cool_things_you_have_done_inserting_python_into_excel/">Practitioners describing optimization and ARIMA-style work</a> and <a href="https://support.microsoft.com/en-us/excel/python/open-source-libraries-and-python-in-excel">Microsoft’s supported scientific/statistical libraries</a></td>
</tr>
<tr class="even">
<td>Visualization and dashboards</td>
<td>Histograms, KPI graphics, model diagnostics, and specialized statistical plots.</td>
<td><a href="https://www.reddit.com/r/excel/comments/1kw4sq0/curiosity_what_are_some_cool_things_you_have_done_inserting_python_into_excel/">Practitioners describing plots, histograms, and KPI graphics</a> and <a href="https://support.microsoft.com/en-us/excel/python/open-source-libraries-and-python-in-excel">Microsoft’s Python visualization libraries</a></td>
</tr>
<tr class="odd">
<td>Validation, reconciliation, and controls</td>
<td>Exceptions, duplicate detection, control totals, cross-system comparisons, and malformed-input checks.</td>
<td><a href="https://www.reddit.com/r/Accounting/comments/1v12xrz/how_i_use_ai_as_a_staff_accountant/">How a staff accountant uses AI to build deterministic tools</a></td>
</tr>
<tr class="even">
<td>Custom functions and Excel integration</td>
<td>Reusable worksheet functions, workbook automation, notebooks, and add-in interfaces.</td>
<td><a href="https://learn.microsoft.com/en-us/office/dev/add-ins/excel/custom-functions-overview">Microsoft’s custom-functions documentation</a> and <a href="../../../apps/excel/python/working-with-excel/">Boardflare’s workbook integration guide</a></td>
</tr>
</tbody>
</table>
<div class="cell" data-layout-align="default">
<div class="cell-output-display">
<div>
<p></p><figure class="figure"><p></p>
<div>
<pre class="mermaid mermaid-js">flowchart LR
    A["Cleaning / ETL"]
    B["Automation / reports"]
    C["Modeling / forecasting"]
    D["Visualization"]
    E["Validation / reconciliation"]
    F["Functions / integration"]
    A ~~~ B ~~~ C ~~~ D ~~~ E ~~~ F
</pre>
</div>
<p></p></figure><p></p>
</div>
</div>
</div>
<p>The more useful conclusion is qualitative: Python is rarely valuable because someone wants “Python syntax in a spreadsheet.” It is valuable when a spreadsheet workflow has crossed into work that is easier to express as software.</p>
</section>
<section id="data-cleaning-and-reshaping" class="level2">
<h2 class="anchored" data-anchor-id="data-cleaning-and-reshaping">1. Data cleaning and reshaping</h2>
<p>The most common analytical use case in the linked discussions is pandas-style transformation of tabular data.</p>
<p>Practitioners repeatedly describe tasks such as:</p>
<ul>
<li>joining exports from different systems;</li>
<li>converting wide data to long form and back;</li>
<li>grouping and aggregating large tables;</li>
<li>correcting data types and missing values;</li>
<li>parsing irregular text;</li>
<li>normalizing JSON-like data;</li>
<li>deduplicating records;</li>
<li>applying regular expressions;</li>
<li>replacing long chains of helper columns.</li>
</ul>
<p>This is not automatically an argument against Power Query. Power Query is often the better choice when the transformation is transparent, refreshable through standard connectors, and maintained by Excel-oriented users.</p>
<p>Python becomes attractive when the transformation is easier to understand as a short program, needs a library that Excel does not provide directly, or is already part of a larger Python analytical model.</p>
</section>
<section id="automation-and-recurring-report-production" class="level2">
<h2 class="anchored" data-anchor-id="automation-and-recurring-report-production">2. Automation and recurring report production</h2>
<p>Repeatable automation is another recurring task family, but this is also where the phrase “Python in Excel” becomes misleading.</p>
<p>Users describe workflows such as:</p>
<ul>
<li>reading hundreds of XLSX or CSV files;</li>
<li>processing invoices and PDFs;</li>
<li>creating one workbook or worksheet per business entity;</li>
<li>renaming, moving, and archiving files;</li>
<li>refreshing reports;</li>
<li>combining data from APIs or databases;</li>
<li>creating recurring month-end or management-report packages.</li>
</ul>
<p>Those jobs generally require Python <strong>around Excel</strong>, not merely Python running inside a workbook.</p>
<p>A browser or managed workbook runtime is deliberately bounded. If the job needs unrestricted local folders, desktop applications, scheduled execution, email, or arbitrary system integration, external Python, VBA, or another automation service is usually a better architecture.</p>
<p>The workbook can still be the artifact stakeholders receive. Python simply does not need to live inside it.</p>
<p>A concrete accounting example shows the scale that can make this worthwhile. In a <a href="https://www.reddit.com/r/Accounting/comments/1hpy054/case_study_of_using_chatgpt_and_python_to_make/">property-management controller’s case study</a>, the author reported adapting a ChatGPT-assisted Python template to six invoice vendors, identifying roughly ten more candidates, and uploading a monthly batch of 400 invoices in roughly 3–4 minutes. The result is anecdotal and self-reported, not a benchmark, but it is representative of the recurring <strong>many files + deterministic rules + Excel output</strong> pattern in the source material.</p>
</section>
<section id="modeling-statistics-forecasting-and-simulation" class="level2">
<h2 class="anchored" data-anchor-id="modeling-statistics-forecasting-and-simulation">3. Modeling, statistics, forecasting, and simulation</h2>
<p>This is the category where Python inside an Excel-centered workflow is especially compelling.</p>
<p>Practitioners discuss:</p>
<ul>
<li>regression and nonlinear models;</li>
<li>time-series forecasting;</li>
<li>correlation and covariance analysis;</li>
<li>Monte Carlo simulation;</li>
<li>scenario analysis;</li>
<li>risk modeling;</li>
<li>demand and sales forecasts;</li>
<li>optimization;</li>
<li>specialized numerical methods.</li>
</ul>
<p>The hybrid pattern is straightforward:</p>
<pre class="text"><code>Excel assumptions and source data
              │
              ▼
        Python model
              │
      ┌───────┴────────┐
      ▼                ▼
interactive UI   worksheet outputs
      │                │
      └───────┬────────┘
              ▼
       stakeholder review</code></pre>
<p>Excel remains useful for assumptions, review, reconciliation, and distribution. Python owns the part that benefits from explicit code, numerical libraries, or multidimensional data structures.</p>
<p>The <a href="../../../templates/sales-scenario-analysis/">Sales Scenario Analysis</a> follows this pattern with workbook assumptions, reactive scenario controls, charts, and published worksheet results. The <a href="../../../templates/inventory-planner/">Demand &amp; Inventory Planner</a> shows the same notebook/workbook boundary for constrained replenishment decisions.</p>
</section>
<section id="visualization-and-dashboards" class="level2">
<h2 class="anchored" data-anchor-id="visualization-and-dashboards">4. Visualization and dashboards</h2>
<p>Python is also used for visualizations that are cumbersome to reproduce with normal Excel charts:</p>
<ul>
<li>heatmaps;</li>
<li>probability distributions;</li>
<li>correlation graphics;</li>
<li>model diagnostics;</li>
<li>specialized statistical plots;</li>
<li>application-specific dashboard graphics.</li>
</ul>
<p>The tradeoff is portability and editability. A Python-rendered chart can be analytically richer while still being less convenient for an Excel user who expects to restyle every element as a native Office chart.</p>
<p>The right question is not “which charting library is better?” It is whether the visualization is an analytical output of the model or a workbook artifact that users need to manipulate directly.</p>
</section>
<section id="validation-reconciliation-and-controls" class="level2">
<h2 class="anchored" data-anchor-id="validation-reconciliation-and-controls">5. Validation, reconciliation, and controls</h2>
<p>Accounting, finance, analytics, and operations discussions repeatedly show Python being used as a deterministic checking layer.</p>
<p>Typical work includes:</p>
<ul>
<li>reconciliations;</li>
<li>duplicate and exception detection;</li>
<li>control totals;</li>
<li>cross-system comparisons;</li>
<li>malformed-input checks;</li>
<li>completeness tests;</li>
<li>rule-based classifications.</li>
</ul>
<p>This is an important contrast with open-ended AI analysis. For high-consequence work, a short deterministic script with explicit checks can be rerun, tested, reviewed, and reconciled. The user does not have to trust a model’s unsupported conclusion.</p>
<p>The <a href="../../../templates/">published templates</a> illustrate that pattern inside a workbook-connected notebook: worksheet data and controls feed deterministic logic, which publishes results and diagnostics back to the spreadsheet.</p>
</section>
<section id="custom-functions-and-interactive-workbook-tools" class="level2">
<h2 class="anchored" data-anchor-id="custom-functions-and-interactive-workbook-tools">6. Custom functions and interactive workbook tools</h2>
<p>A separate group of users wants Python to behave less like an analysis cell and more like a reusable calculation or interactive layer for Excel.</p>
<p>They want:</p>
<ul>
<li>reusable worksheet functions;</li>
<li>buttons or application controls;</li>
<li>workbook object access;</li>
<li>interactive notebooks;</li>
<li>repeatable workflows;</li>
<li>a way to package code for other workbook users.</li>
</ul>
<p>This is where the current Python-in-Excel products diverge most sharply. Microsoft’s native Python centers Python calculation in worksheet cells. Browser add-ins such as Boardflare and xlwings Lite add different models for custom functions, notebook experiences, workbook interaction, and simplified interactive presentations. Local Python integrations can go further into desktop automation and unrestricted package environments.</p>
<p>The correct comparison is therefore not simply “does it run Python?” It is <strong>what kind of artifact does it let you deliver?</strong></p>
</section>
<section id="the-strongest-patterns-by-job-function" class="level2">
<h2 class="anchored" data-anchor-id="the-strongest-patterns-by-job-function">The strongest patterns by job function</h2>
<section id="accounting-and-controllership" class="level3">
<h3 class="anchored" data-anchor-id="accounting-and-controllership">Accounting and controllership</h3>
<p>The most credible accounting stories are deterministic automation and control workflows: invoice processing, reconciliations, journal-entry support, consolidation checks, FIFO calculations, recurring reports, and exception detection.</p>
<p>Many of these require file-system or document-processing access and therefore run outside Excel. Python inside the workbook makes more sense for analytical controls and review tools over data already present in the workbook.</p>
</section>
<section id="fpa-and-finance" class="level3">
<h3 class="anchored" data-anchor-id="fpa-and-finance">FP&amp;A and finance</h3>
<p>FP&amp;A users repeatedly combine Excel and Python for data reshaping, forecasting, scenarios, variance analysis, valuation, simulation, validation, and dashboard preparation.</p>
<p>This is one of the strongest hybrid cases because Excel is already the stakeholder interface. The Python layer does not need to replace the workbook; it can make the model behind it easier to build and maintain.</p>
</section>
<section id="data-analytics" class="level3">
<h3 class="anchored" data-anchor-id="data-analytics">Data analytics</h3>
<p>Analysts use pandas, SQL, text/JSON processing, statistical models, machine learning, and specialized visualization. They are also more likely to own the code directly and use AI as a coding assistant rather than as the final analytical authority.</p>
</section>
<section id="operations-and-supply-chain" class="level3">
<h3 class="anchored" data-anchor-id="operations-and-supply-chain">Operations and supply chain</h3>
<p>Common patterns include inventory and demand forecasting, lead-time analysis, optimization, recurring exports, report assembly, and data-quality checks. File- and system-heavy workflows usually remain external; interactive decision tools can fit inside the workbook.</p>
</section>
<section id="engineering-and-scientific-analysis" class="level3">
<h3 class="anchored" data-anchor-id="engineering-and-scientific-analysis">Engineering and scientific analysis</h3>
<p>Engineering work includes curve fitting, simulation, numerical methods, domain-specific calculations, statistics, and specialized plotting. Package compatibility becomes especially important because some scientific libraries depend on native components that are not available in every browser or managed runtime.</p>
<p>Boardflare’s <a href="../../../templates/nonlinear-curve-fitting/">Nonlinear Curve Fitting</a> and <a href="../../../templates/inventory-planner/">Demand &amp; Inventory Planner</a> are current templates for this pattern.</p>
</section>
</section>
<section id="ai-is-changing-who-writes-the-code" class="level2">
<h2 class="anchored" data-anchor-id="ai-is-changing-who-writes-the-code">AI is changing who writes the code</h2>
<p>A second theme in the practitioner evidence is that the person specifying the automation is increasingly able to create the code even when they are not a professional developer.</p>
<p>The common workflow is still surprisingly concrete:</p>
<ol type="1">
<li>explain the business process to ChatGPT, Claude, Copilot, or a coding agent;</li>
<li>ask for Python or VBA;</li>
<li>run the generated code against test data;</li>
<li>paste errors or unexpected output back into the assistant;</li>
<li>refine the script;</li>
<li>retain the resulting code as a deterministic tool.</li>
</ol>
<p>External chat tools appear more often than integrated Copilot in the detailed end-to-end automation stories we reviewed, although the sample is far too small and self-selected to infer market share.</p>
<p>The more important distinction is <strong>AI-generated software versus AI-generated answers</strong>. In accounting and finance especially, users value the ability to inspect and rerun the resulting script.</p>
<p>That is also how Boardflare positions notebook AI: the assistant helps create or revise the notebook; the durable artifact is ordinary notebook source that can be reviewed and tested.</p>
<p>For the code-sourcing evidence, practitioner examples, and review implications, see <strong><a href="../../../posts/2026/ai-python-development-excel/">How AI Is Changing Python Development in Excel</a></strong>.</p>
</section>
<section id="python-inside-excel-versus-python-around-excel" class="level2">
<h2 class="anchored" data-anchor-id="python-inside-excel-versus-python-around-excel">Python inside Excel versus Python around Excel</h2>
<p>A practical way to choose is to start with the operational boundary.</p>
<table class="caption-top table">
<colgroup>
<col style="width: 50%">
<col style="width: 50%">
</colgroup>
<thead>
<tr class="header">
<th>Requirement</th>
<th>Often the better starting point</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>Bounded analysis over workbook data</td>
<td>Native Python in Excel or browser Python</td>
</tr>
<tr class="even">
<td>Reactive notebook with interactive UI</td>
<td>Browser/add-in notebook runtime</td>
</tr>
<tr class="odd">
<td>Local files, many workbooks, PDFs, email, scheduling</td>
<td>External Python</td>
</tr>
<tr class="even">
<td>Transparent standard data shaping maintained by Excel users</td>
<td>Power Query</td>
</tr>
<tr class="odd">
<td>Workbook events and deep desktop object-model automation</td>
<td>VBA or an Excel-focused local integration</td>
</tr>
<tr class="even">
<td>Unsupported native Python dependencies</td>
<td>External or managed Python environment</td>
</tr>
</tbody>
</table>
<p>These categories can coexist in the same business process. A robust finance workflow might use SQL or external Python for ingestion, Boardflare for the interactive planning notebook, and ordinary Excel formulas for transparent reconciliations.</p>
</section>
<section id="what-not-to-conclude-from-this-research" class="level2">
<h2 class="anchored" data-anchor-id="what-not-to-conclude-from-this-research">What not to conclude from this research</h2>
<p>This review does <strong>not</strong> show that a particular percentage of Excel users clean data with Python, that Python is replacing Excel, or that one execution model is universally better.</p>
<p>The source set is self-selecting and intentionally biased toward people discussing technical workflows. Product capabilities also changed during the research window.</p>
<p>What the evidence does show is a recurring division of labor:</p>
<blockquote class="blockquote">
<p><strong>Python handles transformations, models, automation, and reusable logic; Excel remains valuable for assumptions, review, communication, and distribution.</strong></p>
</blockquote>
<p>That is a more useful starting point than asking whether Python should “replace” Excel.</p>
</section>
<section id="methodology" class="level2">
<h2 class="anchored" data-anchor-id="methodology">Methodology</h2>
<p>The review uses a purposive set of public practitioner discussions plus official product documentation. Representative sources include <a href="https://www.reddit.com/r/excel/comments/1qtj5v3/what_do_you_use_python_for_in_excel/">Python as a middleman between Excel and Claude</a>, <a href="https://www.reddit.com/r/excel/comments/1o1g0ba/what_do_you_guys_do_with_python_in_excel/">Python around Excel for real-world use cases</a>, <a href="https://www.reddit.com/r/Accounting/comments/1hyiu1e/automating_everything_i_can_as_an_accountant/">accounting automation examples</a>, <a href="https://www.reddit.com/r/excel/comments/1kw4sq0/curiosity_what_are_some_cool_things_you_have_done_inserting_python_into_excel/">a discussion spanning optimization, time series, preprocessing, and plotting</a>, and <a href="https://support.microsoft.com/en-us/excel/python/introduction-to-python-in-excel">Microsoft’s Python in Excel documentation</a>.</p>
<p>This is directional qualitative evidence, not representative adoption research. Engagement metrics, issue counts, and user-reported outcomes measure attention and experience rather than successful deployment.</p>
<p>For the current product landscape, continue with <strong><a href="../../../posts/2026/python-in-excel-alternatives/">Python in Excel Alternatives in 2026</a></strong>.</p>


</section>

 ]]></description>
  <category>Excel</category>
  <category>Python</category>
  <category>Research</category>
  <guid>https://boardflare.com/posts/2026/python-in-excel-use-cases/</guid>
  <pubDate>Sat, 08 Aug 2026 00:00:00 GMT</pubDate>
</item>
<item>
  <title>Python in Excel Alternatives in 2026</title>
  <link>https://boardflare.com/posts/2026/python-in-excel-alternatives/</link>
  <description><![CDATA[ 





<p>There are now several materially different ways to run Python with Excel. Comparing them only by “supports Python” hides the choices that actually determine whether a workflow will work: <strong>where Python executes, how it reaches workbook data, what packages it can load, whether it can create worksheet functions, and what another user receives when the workbook is shared</strong>. Those differences are real platform distinctions: Microsoft’s <a href="https://support.microsoft.com/en-us/excel/python/data-security-and-python-in-excel">Python in Excel security documentation</a> describes a managed cloud container, while <a href="https://pyodide.org/en/stable/">Pyodide</a> describes Python running in the browser through WebAssembly.</p>
<p>This review compares <strong>Microsoft Python in Excel, Boardflare Python for Excel, xlwings Lite, and Anaconda Code</strong>. It was originally published July 15, 2026 and reviewed against current product documentation on <strong>August 20, 2026</strong>. Because these products are changing quickly, treat it as a dated market snapshot and verify the linked official documentation before making a deployment decision.</p>
<p>For a much deeper maintained comparison of the first two—including row-major calculation, source storage/export, type conversion, data limits, reusable worksheet functions, packages, networking, and security boundaries—see <strong><a href="../../../apps/excel/python/microsoft-python-in-excel-comparison/">Boardflare Python for Excel vs.&nbsp;Microsoft Python in Excel</a></strong>.</p>
<!-- more -->
<section id="start-with-the-execution-model" class="level2">
<h2 class="anchored" data-anchor-id="start-with-the-execution-model">Start with the execution model</h2>
<pre class="text"><code>Python + Excel
│
├── Microsoft-managed cloud runtime
│   └── Microsoft Python in Excel
│
├── Browser / WebAssembly add-in runtime
│   ├── Boardflare Python for Excel
│   ├── xlwings Lite
│   └── Anaconda Code (Pyodide / WebR)
│
└── Local / external Python
    ├── xlwings desktop/server patterns
    ├── PyXLL
    └── pandas/openpyxl/COM/scripts</code></pre>
<p>The execution model affects far more than performance. It determines the security boundary, package environment, access to local files and web APIs, workbook integration model, deployment requirements, and how much of the runtime the organization must manage. Microsoft’s <a href="https://learn.microsoft.com/en-us/office/dev/add-ins/excel/excel-add-ins-overview">Excel add-in platform overview</a> and <a href="https://learn.microsoft.com/en-us/office/dev/add-ins/develop/configure-your-add-in-to-use-a-shared-runtime">Office shared-runtime documentation</a> explain the add-in side of that comparison.</p>
</section>
<section id="at-a-glance-comparison" class="level2">
<h2 class="anchored" data-anchor-id="at-a-glance-comparison">At-a-glance comparison</h2>
<table class="caption-top table">
<colgroup>
<col style="width: 20%">
<col style="width: 20%">
<col style="width: 20%">
<col style="width: 20%">
<col style="width: 20%">
</colgroup>
<thead>
<tr class="header">
<th>Dimension</th>
<th>Microsoft Python in Excel</th>
<th>Boardflare Python for Excel</th>
<th>xlwings Lite</th>
<th>Anaconda Code</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>Primary runtime</td>
<td>Microsoft Cloud</td>
<td>Browser / Pyodide</td>
<td>Browser / Pyodide</td>
<td>Excel add-in / Pyodide or WebR (WASM)</td>
</tr>
<tr class="even">
<td>Primary code surface</td>
<td>Worksheet <code>PY</code> cells</td>
<td>Reactive marimo notebook</td>
<td>Scripts, custom functions, notebooks</td>
<td>Excel code environment</td>
</tr>
<tr class="odd">
<td>Separate local Python install</td>
<td>No</td>
<td>No</td>
<td>No for Lite</td>
<td>No external desktop Python required for Code</td>
</tr>
<tr class="even">
<td>Interactive notebook surface</td>
<td>Worksheet-focused</td>
<td>Reactive marimo notebook + optional App mode</td>
<td>Stateful <code>.nb.py</code> notebook + App Mode</td>
<td>Code-oriented Excel environment</td>
</tr>
<tr class="odd">
<td>Worksheet custom-function model</td>
<td>Native <code>PY</code> calculation, not user-published Python UDFs</td>
<td><code>BF.FUNCTION()</code> plus focused Editor functions</td>
<td>Native custom functions</td>
<td>UDF support</td>
</tr>
<tr class="even">
<td>Explicit application output registry</td>
<td><code>PY</code> cell result</td>
<td><code>BF.OUTPUT()</code></td>
<td>Workflow-dependent workbook writes/UDFs</td>
<td>Workflow-dependent</td>
</tr>
<tr class="odd">
<td>Package/runtime model</td>
<td>Microsoft-managed package set</td>
<td>Pyodide/WebAssembly</td>
<td>Pyodide/WebAssembly</td>
<td>User-selectable Pyodide/WebR environment</td>
</tr>
<tr class="even">
<td>Main design center</td>
<td>Python analysis in Excel grid</td>
<td>Reactive notebook connected to workbook data, outputs, and functions</td>
<td>xlwings-style automation, notebooks, scripts, and UDFs in browser</td>
<td>Python/R code cells and UDFs inside the Excel add-in</td>
</tr>
</tbody>
</table>
<p>The table intentionally omits pricing and fine-grained licensing. Those change too quickly to freeze into an article without frequent maintenance.</p>
</section>
<section id="microsoft-python-in-excel" class="level2">
<h2 class="anchored" data-anchor-id="microsoft-python-in-excel">Microsoft Python in Excel</h2>
<p>Microsoft’s native Python feature uses the <code>PY</code> function and executes Python in a secure Microsoft Cloud runtime. Microsoft provides a managed set of libraries and integrates Python results directly into the Excel calculation surface.</p>
<p>Official documentation:</p>
<ul>
<li><a href="https://support.microsoft.com/en-us/excel/python/introduction-to-python-in-excel">Introduction to Python in Excel</a></li>
<li><a href="https://support.microsoft.com/en-us/excel/functions/py-function">PY function</a></li>
<li><a href="https://support.microsoft.com/en-us/excel/python/data-security-and-python-in-excel">Data security and Python in Excel</a></li>
<li><a href="https://support.microsoft.com/en-us/excel/python/python-in-excel-availability">Python in Excel availability</a></li>
<li><a href="https://support.microsoft.com/en-us/excel/python/use-power-query-to-import-data-for-python-in-excel">Use Power Query to import data for Python in Excel</a></li>
</ul>
<section id="strengths" class="level3">
<h3 class="anchored" data-anchor-id="strengths">Strengths</h3>
<ul>
<li>native Microsoft experience inside the grid;</li>
<li>no separate Python environment for the user to maintain;</li>
<li>strong fit for pandas/statistical analysis that starts from workbook data;</li>
<li>managed security and package environment;</li>
<li>Python results can feed the surrounding workbook.</li>
</ul>
</section>
<section id="tradeoffs" class="level3">
<h3 class="anchored" data-anchor-id="tradeoffs">Tradeoffs</h3>
<p>The same managed environment that simplifies deployment also imposes boundaries. Python is not running as an unrestricted local desktop process. External data access follows Microsoft’s supported worksheet/Power Query model, and arbitrary local packages, folders, operating-system automation, and general desktop integration are outside the core product design.</p>
</section>
<section id="best-fit" class="level3">
<h3 class="anchored" data-anchor-id="best-fit">Best fit</h3>
<p>Start here when the artifact is fundamentally <strong>an Excel workbook containing bounded Python analysis</strong> and the Microsoft-managed runtime fits the organization’s platform, security, package, and licensing requirements.</p>
</section>
</section>
<section id="boardflare-python-for-excel" class="level2">
<h2 class="anchored" data-anchor-id="boardflare-python-for-excel">Boardflare Python for Excel</h2>
<p>Boardflare uses a stock marimo reactive notebook running through Pyodide in the Office add-in browser environment. Workbook data enters through explicit <code>bf.inputs()</code> declarations. The notebook can publish values/tables through <code>BF.OUTPUT()</code> and short callable Python functions through <code>BF.FUNCTION()</code>.</p>
<p>Notebook source and startup preference are saved with the Excel workbook. The notebook is the primary authoring surface; optional <strong>Open as: App</strong> can present the same notebook more simply when an analysis becomes a repeatable tool.</p>
<p>Current product documentation: <a href="../../../apps/excel/python/">Python for Excel</a>. For the detailed two-way Microsoft comparison, see <a href="../../../apps/excel/python/microsoft-python-in-excel-comparison/">Boardflare vs.&nbsp;Microsoft Python in Excel</a>.</p>
<section id="strengths-1" class="level3">
<h3 class="anchored" data-anchor-id="strengths-1">Strengths</h3>
<ul>
<li>one coherent reactive notebook rather than Python logic distributed across worksheet cells;</li>
<li>explicit workbook input and published-output contracts;</li>
<li>interactive notebook UI through marimo;</li>
<li>published worksheet functions;</li>
<li>source travels with the workbook;</li>
<li>no separate desktop Python installation for workbook users;</li>
<li>the same notebook model can be demonstrated in the standalone Univer host.</li>
</ul>
</section>
<section id="tradeoffs-1" class="level3">
<h3 class="anchored" data-anchor-id="tradeoffs-1">Tradeoffs</h3>
<p>Boardflare inherits browser/WebAssembly constraints. Some native Python packages and desktop/system integrations are not appropriate for Pyodide. User-authored web requests are also subject to browser security and CORS behavior.</p>
<p>Boardflare App mode is a presentation experience rather than a permissions or source-protection boundary, and recipients need the Boardflare add-in when the workbook depends on Boardflare notebook execution.</p>
</section>
<section id="best-fit-1" class="level3">
<h3 class="anchored" data-anchor-id="best-fit-1">Best fit</h3>
<p>Evaluate Boardflare when <strong>the Python work is substantial enough to benefit from a coherent notebook while Excel still matters to the workflow</strong>. App mode becomes relevant when that notebook also needs to serve as a simplified repeatable interface.</p>
</section>
</section>
<section id="xlwings-lite" class="level2">
<h2 class="anchored" data-anchor-id="xlwings-lite">xlwings Lite</h2>
<p>xlwings Lite has evolved substantially. Its current documentation covers custom functions, automation scripts, browser/Pyodide execution, <code>.nb.py</code> notebooks, package installation, web API access, testing, multiple workbook-stored source files, and an App Mode that can expose scripts to end users without showing the editor. Its August 2026 changelog also documents pinned dependency resolution for reproducible workbooks and continued notebook improvements.</p>
<p>Official documentation:</p>
<ul>
<li><a href="https://lite.xlwings.org/">xlwings Lite</a></li>
<li><a href="https://lite.xlwings.org/notebooks">Notebooks</a></li>
<li><a href="https://lite.xlwings.org/custom-functions">Custom Functions</a></li>
<li><a href="https://lite.xlwings.org/app-mode">App Mode</a></li>
<li><a href="https://lite.xlwings.org/dependencies">Dependencies</a></li>
<li><a href="https://lite.xlwings.org/changelog">Changelog</a></li>
</ul>
<section id="strengths-2" class="level3">
<h3 class="anchored" data-anchor-id="strengths-2">Strengths</h3>
<ul>
<li>familiar xlwings-style workbook programming model;</li>
<li>browser runtime without requiring a normal desktop Python installation;</li>
<li>custom functions and scripts;</li>
<li>notebook workflow with regular <code>.nb.py</code> source files;</li>
<li>App Mode for end-user operation;</li>
<li>direct workbook-object-model style programming;</li>
<li>workbook-stored source files, dependency management, and pytest-oriented testing support;</li>
<li>current Lite builds also support workbook-managed file import/export and, on Windows desktop, mounted local-directory access through the add-in.</li>
</ul>
</section>
<section id="tradeoffs-2" class="level3">
<h3 class="anchored" data-anchor-id="tradeoffs-2">Tradeoffs</h3>
<p>The most important difference from Boardflare is not a missing checkbox. It is the programming model. xlwings Lite is organized around xlwings workbook APIs, scripts, custom functions, and a stateful notebook in which cells are run individually or in groups. Boardflare uses marimo’s dependency-reactive graph and emphasizes an explicit workbook-input registry plus explicit live output/function publication.</p>
<p>Teams choosing between them should prototype the real application rather than compare slogans such as “browser Python” or “app mode.” Host-dependent features also matter: for example, current xlwings Lite releases expose local-directory mounting on Windows desktop even though Python itself runs through the add-in’s Pyodide environment.</p>
</section>
<section id="best-fit-2" class="level3">
<h3 class="anchored" data-anchor-id="best-fit-2">Best fit</h3>
<p>Evaluate xlwings Lite when you want <strong>xlwings-style automation and UDFs in a browser-based Excel add-in</strong>, particularly if the team already knows the xlwings API.</p>
</section>
</section>
<section id="anaconda-code" class="level2">
<h2 class="anchored" data-anchor-id="anaconda-code">Anaconda Code</h2>
<p>Anaconda Code runs Python or R locally within Excel’s add-in environment using Pyodide or WebR. Current Anaconda documentation describes code cells, configurable package/runtime versions, worksheet references, linked or isolated execution, and user-defined functions. Anaconda Toolbox for Excel is a generally available product, while the <strong>Anaconda Code feature is still labeled beta</strong> in the current documentation.</p>
<p>Official documentation:</p>
<ul>
<li><a href="https://www.anaconda.com/docs/tools/excel/code">Anaconda Code</a></li>
<li><a href="https://www.anaconda.com/products/anaconda-toolbox">Anaconda Toolbox for Excel</a></li>
</ul>
<section id="strengths-3" class="level3">
<h3 class="anchored" data-anchor-id="strengths-3">Strengths</h3>
<ul>
<li>Python and R support;</li>
<li>environment/package control within the Excel experience;</li>
<li>worksheet references;</li>
<li>user-defined functions;</li>
<li>familiar Anaconda ecosystem positioning.</li>
</ul>
</section>
<section id="tradeoffs-3" class="level3">
<h3 class="anchored" data-anchor-id="tradeoffs-3">Tradeoffs</h3>
<p>The product model is different from Boardflare’s notebook-centered workbook workflow and from Microsoft’s managed <code>PY</code> calculation model. Because Code is still documented as beta, organizations should verify current support, deployment, and sharing behavior before standardizing on it.</p>
</section>
<section id="best-fit-3" class="level3">
<h3 class="anchored" data-anchor-id="best-fit-3">Best fit</h3>
<p>Evaluate Anaconda Code when the priority is <strong>an Anaconda-oriented Python/R coding environment inside Excel with configurable packages and UDFs</strong>.</p>
</section>
</section>
<section id="what-about-external-or-local-python" class="level2">
<h2 class="anchored" data-anchor-id="what-about-external-or-local-python">What about external or local Python?</h2>
<p>The four products above are not substitutes for every Python/Excel workflow.</p>
<p>If the job needs:</p>
<ul>
<li>broad or unattended local folder traversal beyond an add-in’s supported host bridge;</li>
<li>PDF/email processing;</li>
<li>scheduled jobs;</li>
<li>database pipelines;</li>
<li>desktop application automation;</li>
<li>unsupported native packages;</li>
<li>large multi-workbook batch processing;</li>
</ul>
<p>then an external Python environment may be the right answer. The workbook can remain the user-facing artifact without containing the whole runtime.</p>
<p>This distinction is visible in practitioner discussions: many successful “Python + Excel” automations use pandas, openpyxl, xlwings, COM, or scripts around Excel rather than Python executing in the workbook itself. The relevant external-runtime options have their own documentation: <a href="https://docs.xlwings.org/">xlwings</a>, <a href="https://openpyxl.readthedocs.io/">openpyxl</a>, and <a href="https://www.pyxll.com/docs/">PyXLL</a>.</p>
</section>
<section id="how-to-choose" class="level2">
<h2 class="anchored" data-anchor-id="how-to-choose">How to choose</h2>
<p>Ask these questions in order:</p>
<section id="what-is-the-artifact" class="level3">
<h3 class="anchored" data-anchor-id="what-is-the-artifact">1. What is the artifact?</h3>
<ul>
<li>A few Python calculations in a workbook?</li>
<li>A reusable custom function?</li>
<li>An interactive application another person operates?</li>
<li>A batch process that produces workbooks?</li>
</ul>
<p>The artifact is more important than the language.</p>
</section>
<section id="where-must-the-code-run" class="level3">
<h3 class="anchored" data-anchor-id="where-must-the-code-run">2. Where must the code run?</h3>
<p>If the workflow needs local system access, a browser or cloud sandbox may be the wrong runtime before package choice even enters the discussion.</p>
</section>
<section id="who-maintains-the-code" class="level3">
<h3 class="anchored" data-anchor-id="who-maintains-the-code">3. Who maintains the code?</h3>
<p>A workbook sent to non-programmers has a different deployment problem from an analyst’s personal notebook.</p>
</section>
<section id="what-package-and-network-boundaries-apply" class="level3">
<h3 class="anchored" data-anchor-id="what-package-and-network-boundaries-apply">4. What package and network boundaries apply?</h3>
<p>Browser/Pyodide environments support a large Python ecosystem, including many scientific packages, but not every native dependency. Microsoft’s environment is separately managed. Test the actual package set and external services early.</p>
</section>
<section id="how-does-the-second-user-open-it" class="level3">
<h3 class="anchored" data-anchor-id="how-does-the-second-user-open-it">5. How does the second user open it?</h3>
<p>This is the question product comparisons often skip. Test save/reopen behavior, required add-ins/licenses, startup, calculation, network access, and what the recipient sees when something goes wrong.</p>
</section>
</section>
<section id="bottom-line" class="level2">
<h2 class="anchored" data-anchor-id="bottom-line">Bottom line</h2>
<p>A useful shorthand is:</p>
<ul>
<li><strong>Microsoft Python in Excel:</strong> Python analysis integrated directly into the Excel grid.</li>
<li><strong>Boardflare:</strong> a reactive Python notebook connected to workbook inputs, outputs, and functions, with optional App mode for a simplified interactive presentation.</li>
<li><strong>xlwings Lite:</strong> browser-based xlwings automation, scripts, notebooks, and custom functions.</li>
<li><strong>Anaconda Code:</strong> Python/R code and UDFs in an Anaconda-managed Excel add-in environment.</li>
<li><strong>External Python:</strong> the right answer when the workflow is really system automation or a data pipeline that happens to produce or consume Excel files.</li>
</ul>
<p>The category will keep moving. The August 2026 xlwings changes alone show why feature checklists age quickly. That is why this article records a reviewed snapshot rather than pretending to be permanent product documentation.</p>


</section>

 ]]></description>
  <category>Excel</category>
  <category>Python</category>
  <category>Comparisons</category>
  <guid>https://boardflare.com/posts/2026/python-in-excel-alternatives/</guid>
  <pubDate>Wed, 15 Jul 2026 00:00:00 GMT</pubDate>
</item>
<item>
  <title>How We Built a Reactive Python Notebook Runtime Inside Excel</title>
  <link>https://boardflare.com/posts/2026/boardflare-python-architecture/</link>
  <description><![CDATA[ 





<p>The design goal for Boardflare’s Python experience was not simply “put a code editor in Excel.” It was to give substantial Python work a coherent reactive notebook while keeping the workbook directly connected as a source-data, review, output, and delivery surface.</p>
<p>That led to a runtime with several deliberately separate pieces: <strong>Excel’s long-lived shared runtime, a Boardflare host, a cross-origin marimo notebook, browser Python through Pyodide, Anywidget capabilities, a spreadsheet-host abstraction, workbook source persistence, and live worksheet outputs/functions</strong>. The underlying platform concepts are documented by Microsoft in its <a href="https://learn.microsoft.com/en-us/office/dev/add-ins/testing/runtimes">Office add-in runtime guide</a>, by <a href="https://docs.marimo.io/">marimo</a> as a reactive Python notebook, by <a href="https://pyodide.org/en/stable/">Pyodide</a> as Python compiled for the browser, and by <a href="https://anywidget.dev/en/getting-started/">anywidget</a> as a widget specification and toolkit.</p>
<p>This article explains why those pieces exist and how they fit together. The maintained specifications live in <strong><a href="../../../apps/excel/python/advanced/architecture-and-runtime/">Architecture and Runtime</a></strong> and <strong><a href="../../../apps/excel/python/advanced/security-and-data-flow/">Security and Data Flow</a></strong>.</p>
<!-- more -->
<section id="the-complete-picture" class="level2">
<h2 class="anchored" data-anchor-id="the-complete-picture">The complete picture</h2>
<p>A useful way to understand the system is to start with the full topology rather than with one API call:</p>
<div class="cell" data-layout-align="default">
<div class="cell-output-display">
<div>
<p></p><figure class="figure"><p></p>
<div>
<pre class="mermaid mermaid-js">flowchart TB
    subgraph Excel[Excel]
        WB[Workbook cells / ranges / names]
        XML[Workbook Custom XML\nsaved notebook source]
        CF[BF.OUTPUT / BF.FUNCTION]
        Shared[Long-lived Office shared runtime]
    end

    subgraph Boardflare[Boardflare parent host]
        UI[Task pane / Notebook surface]
        Session[Notebook session + capabilities]
        Bridge[Spreadsheet Bridge]
        Registry[Live publication registry]
    end

    subgraph Notebook[Separate-origin notebook iframe]
        Marimo[Stock marimo]
        Pyodide[Pyodide / browser CPython]
        Inputs[bf.inputs Anywidget]
        Publish[bf.publish Anywidget]
    end

    WB &lt;--&gt; Bridge
    XML &lt;--&gt; Session
    CF &lt;--&gt; Shared
    Shared --&gt; UI --&gt; Session
    Session &lt;--&gt;|validated MessagePorts| Marimo
    Marimo --&gt; Pyodide
    Pyodide --&gt; Inputs
    Pyodide --&gt; Publish
    Inputs &lt;--&gt;|workbook input capability| Session
    Publish &lt;--&gt;|output/function capability| Session
    Session &lt;--&gt; Bridge
    Session &lt;--&gt; Registry
    Registry &lt;--&gt; CF
</pre>
</div>
<p></p></figure><p></p>
</div>
</div>
</div>
<p>There are three ideas behind this shape:</p>
<ol type="1">
<li><strong>Excel remains useful.</strong> We do not require every assumption, input, or deliverable to move into the notebook.</li>
<li><strong>The notebook owns the Python program.</strong> Multi-step transformations, models, controls, charts, and explanations can live in one reactive source file instead of being distributed across worksheet cells.</li>
<li><strong>The boundary is explicit.</strong> Notebook Python gets workbook capabilities through a small public API rather than receiving unrestricted access to the add-in parent.</li>
</ol>
<p>For a workbook user, the consequence is simpler than the diagram: no separate desktop Python installation is required; declared worksheet inputs can drive reactive notebook recalculation; selected notebook results can flow back to worksheet formulas; and the saved artifact is notebook source in the workbook rather than a serialized Python process. AI authoring is optional and is not part of the calculation path.</p>
</section>
<section id="why-marimo-fits-spreadsheet-work" class="level2">
<h2 class="anchored" data-anchor-id="why-marimo-fits-spreadsheet-work">Why marimo fits spreadsheet work</h2>
<p>Spreadsheet users already expect dependency-driven recalculation. Change an input and downstream work should update.</p>
<p><a href="https://docs.marimo.io/">marimo</a> is a reactive Python notebook. Its documentation describes dependent cells rerunning when referenced values change and notebooks being stored as Python source rather than an opaque notebook database. That maps naturally to a workbook-connected model.</p>
<p>Boardflare adds workbook dependencies explicitly:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb1" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb1-1"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> boardflare <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">as</span> bf</span>
<span id="cb1-2"></span>
<span id="cb1-3">inputs <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> bf.inputs(</span>
<span id="cb1-4">    sales<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>bf.ref(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Sales!A1:D20"</span>, headers<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">True</span>),</span>
<span id="cb1-5">    scenario<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Assumptions!B2"</span>,</span>
<span id="cb1-6">)</span>
<span id="cb1-7">inputs</span></code></pre></div></div>
<p>Downstream cells read <code>inputs["sales"]</code> and <code>inputs["scenario"]</code> like ordinary Python values. When Excel changes one of those references, Boardflare refreshes the input model and marimo reruns dependent cells through its normal reactive graph.</p>
<p>The spreadsheet and notebook therefore do not need competing recalculation systems.</p>
</section>
<section id="why-run-python-in-the-browser" class="level2">
<h2 class="anchored" data-anchor-id="why-run-python-in-the-browser">Why run Python in the browser?</h2>
<p>A workbook is much easier to distribute when every recipient does not need to recreate the author’s desktop Python installation.</p>
<p>Marimo’s WebAssembly runtime uses <a href="https://pyodide.org/en/stable/">Pyodide</a> to run CPython in the browser. That provides a substantial Python environment without a separate local Python installation.</p>
<p>It also creates a clear compatibility boundary. Browser Python is not desktop/server Python. Pyodide documents limitations around <a href="https://pyodide.org/en/stable/usage/faq.html">local files and subprocesses</a>, <a href="https://pyodide.org/en/stable/usage/socket.html">raw sockets</a>, and browser networking such as <a href="https://pyodide.org/en/stable/usage/api/python-api/http.html">CORS</a>. Some native dependencies and desktop integrations therefore do not fit this environment.</p>
<p>That is a tradeoff, not something we try to hide: the browser runtime makes workbook distribution easier, while external Python remains a better fit for workloads that require unrestricted operating-system capabilities.</p>
</section>
<section id="keeping-marimo-stock" class="level2">
<h2 class="anchored" data-anchor-id="keeping-marimo-stock">Keeping marimo stock</h2>
<p>A major design decision was to put product-specific behavior <strong>around</strong> marimo rather than inside a private fork.</p>
<p>Marimo owns:</p>
<ul>
<li>notebook editing;</li>
<li>source serialization;</li>
<li>reactive dependency analysis;</li>
<li>Python execution;</li>
<li>notebook UI primitives.</li>
</ul>
<p>Boardflare owns:</p>
<ul>
<li>Excel/shared-runtime startup;</li>
<li>workbook source persistence;</li>
<li>workbook input/output capabilities;</li>
<li>worksheet functions;</li>
<li>product presentation and App mode;</li>
<li>AI provider/account policy;</li>
<li>the parent/notebook security boundary.</li>
</ul>
<p>That separation gives us a cleaner upgrade path and makes failures easier to classify. If an Excel formula cannot see a published result, for example, the question is usually about the live publication capability or startup lifecycle—not about a hidden modification to marimo internals.</p>
</section>
<section id="anywidget-is-the-notebook-side-capability-surface" class="level2">
<h2 class="anchored" data-anchor-id="anywidget-is-the-notebook-side-capability-surface">Anywidget is the notebook-side capability surface</h2>
<p>The public <code>boardflare</code> package returns <a href="https://anywidget.dev/en/afm/">Anywidget</a> models for the connections that need a live browser counterpart. Anywidget’s front-end specification explicitly separates one-time model initialization from per-view rendering, which is the lifecycle distinction Boardflare relies on here.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb2" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb2-1">inputs <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> bf.inputs(</span>
<span id="cb2-2">    assumptions<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>bf.ref(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Assumptions!A1:B8"</span>, headers<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">True</span>),</span>
<span id="cb2-3">)</span>
<span id="cb2-4">inputs</span></code></pre></div></div>
<p>and:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb3" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb3-1">publication <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> bf.publish(</span>
<span id="cb3-2">    outputs<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>{<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"summary"</span>: summary},</span>
<span id="cb3-3">    functions<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>{<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"discount"</span>: discount},</span>
<span id="cb3-4">)</span>
<span id="cb3-5">publication</span></code></pre></div></div>
<p>The displayed widget is not decorative. Its <strong>model</strong> owns the capability connection. That is why Boardflare documentation tells authors to keep <code>bf.inputs()</code> and <code>bf.publish()</code> displayed as cell results.</p>
<p>This model/view distinction matters. A widget model can render more than one visual view without multiplying workbook subscriptions, and destroying a view does not have to mean destroying the underlying capability.</p>
</section>
<section id="the-notebook-does-not-get-unrestricted-access-to-the-parent" class="level2">
<h2 class="anchored" data-anchor-id="the-notebook-does-not-get-unrestricted-access-to-the-parent">The notebook does not get unrestricted access to the parent</h2>
<p>The marimo runtime executes in a different-origin iframe. The parent establishes separate source, input, and outputs capabilities only after validating the connection.</p>
<div class="cell" data-layout-align="default">
<div class="cell-output-display">
<div>
<p></p><figure class="figure"><p></p>
<div>
<pre class="mermaid mermaid-js">sequenceDiagram
    participant Child as Notebook / Anywidget
    participant Parent as Boardflare parent
    participant Port as Dedicated MessagePort

    Child-&gt;&gt;Parent: Connect request
    Parent-&gt;&gt;Parent: Validate child window + exact origin
    Parent-&gt;&gt;Parent: Validate protocol + session + nonce
    Parent-&gt;&gt;Parent: Validate capability + generation
    Parent--&gt;&gt;Child: Transfer MessagePort
    Child&lt;&lt;-&gt;&gt;Port: Ongoing capability traffic
    Port&lt;&lt;-&gt;&gt;Parent: Active capability only
</pre>
</div>
<p></p></figure><p></p>
</div>
</div>
</div>
<p>The goal is not to claim that arbitrary Python is safe. Notebook source is executable code. The goal is to avoid making “whatever can call <code>postMessage</code>” equivalent to the workbook API.</p>
<p>The maintained <strong><a href="../../../apps/excel/python/advanced/security-and-data-flow/">Security and Data Flow</a></strong> page documents the current validation checks and trust boundaries in more detail.</p>
</section>
<section id="one-notebook-model-multiple-spreadsheet-hosts" class="level2">
<h2 class="anchored" data-anchor-id="one-notebook-model-multiple-spreadsheet-hosts">One notebook model, multiple spreadsheet hosts</h2>
<p>Notebook code should not care whether the spreadsheet underneath it is production Excel or the browser spreadsheet used for demos.</p>
<p>The shared <code>@boardflare/spreadsheet-bridge</code> package puts host-specific spreadsheet operations behind a common interface:</p>
<div class="cell" data-layout-align="default">
<div class="cell-output-display">
<div>
<p></p><figure class="figure"><p></p>
<div>
<pre class="mermaid mermaid-js">flowchart TD
    Notebook[Boardflare notebook integration] --&gt; Bridge[Spreadsheet Bridge]
    Bridge --&gt; ExcelDriver[Excel driver]
    Bridge --&gt; UniverDriver[Univer driver]
    ExcelDriver --&gt; Office[Office.js / Excel]
    UniverDriver --&gt; Univer[Univer browser workbook]
</pre>
</div>
<p></p></figure><p></p>
</div>
</div>
</div>
<p>The two hosts are deliberately not described as identical. Excel has workbook Custom XML persistence and a shared custom-function runtime. The public demo has a browser page/session lifecycle. The bridge lets the notebook model share useful concepts without erasing those host differences.</p>
</section>
<section id="publishing-selected-results-back-to-excel" class="level2">
<h2 class="anchored" data-anchor-id="publishing-selected-results-back-to-excel">Publishing selected results back to Excel</h2>
<p>A notebook does not have to end at a chart in the task pane. It can expose a deliberately small worksheet-facing API.</p>
<p>For values and tables:</p>
<pre class="excel"><code>=BF.OUTPUT("summary")</code></pre>
<p>For short callable Python functions:</p>
<pre class="excel"><code>=BF.FUNCTION("discount", A1, B1)</code></pre>
<p>Both are backed by a live registry owned by a displayed <code>bf.publish()</code> model.</p>
<div class="cell" data-layout-align="default">
<div class="cell-output-display">
<div>
<p></p><figure class="figure"><p></p>
<div>
<pre class="mermaid mermaid-js">sequenceDiagram
    participant Publish as bf.publish
    participant Host as Boardflare host
    participant Excel

    Publish-&gt;&gt;Host: Prepare values for workbook date system
    Host--&gt;&gt;Publish: Prepared
    Publish-&gt;&gt;Host: Claim complete output/function registry
    Host--&gt;&gt;Publish: Registry acknowledged
    Excel-&gt;&gt;Host: BF.OUTPUT subscription / BF.FUNCTION invocation
    Host--&gt;&gt;Excel: Live value or Python result
</pre>
</div>
<p></p></figure><p></p>
</div>
</div>
</div>
<p>The claim is atomic: a replacement publication does not tear down the prior successful registry until the replacement has validated and claimed successfully.</p>
<p>The publication widget can also show which worksheet formulas are actively consuming outputs/functions. The same information is available to Python through <code>publication.consumers</code>.</p>
</section>
<section id="why-excels-shared-runtime-matters" class="level2">
<h2 class="anchored" data-anchor-id="why-excels-shared-runtime-matters">Why Excel’s shared runtime matters</h2>
<p>Excel custom functions and a task pane can be configured to use the same long-lived JavaScript runtime. Microsoft’s <a href="https://learn.microsoft.com/en-us/office/dev/add-ins/develop/configure-your-add-in-to-use-a-shared-runtime">shared-runtime documentation</a> describes that arrangement; Boardflare uses the model so a worksheet formula can need Python even when the user has not visibly opened the Notebook tab first.</p>
<div class="cell" data-layout-align="default">
<div class="cell-output-display">
<div>
<p></p><figure class="figure"><p></p>
<div>
<pre class="mermaid mermaid-js">sequenceDiagram
    participant Excel
    participant Formula as BF.OUTPUT / BF.FUNCTION
    participant Shared as Boardflare shared runtime
    participant Notebook as marimo / Pyodide

    Excel-&gt;&gt;Formula: Recalculate workbook
    Formula-&gt;&gt;Shared: Subscribe / invoke
    Shared-&gt;&gt;Notebook: Mount saved notebook runtime
    Notebook-&gt;&gt;Shared: Subscribe workbook inputs
    Shared--&gt;&gt;Notebook: Initial workbook snapshot
    Notebook-&gt;&gt;Notebook: Reactive graph calculates
    Notebook-&gt;&gt;Shared: Claim publication registry
    Shared--&gt;&gt;Formula: Published value / function result
    Formula--&gt;&gt;Excel: Resolve streaming formula
</pre>
</div>
<p></p></figure><p></p>
</div>
</div>
</div>
<p>While that startup is still healthy but incomplete, Excel can keep a streaming function in its normal <code>#BUSY!</code> state rather than showing a fake placeholder result.</p>
</section>
<section id="authentication-is-not-part-of-calculation-startup" class="level2">
<h2 class="anchored" data-anchor-id="authentication-is-not-part-of-calculation-startup">Authentication is not part of calculation startup</h2>
<p>Another important separation is between the calculation runtime and Notebook AI eligibility.</p>
<p>Boardflare lets the notebook calculation runtime mount while Office authentication is still resolving. <code>BF.OUTPUT()</code> and <code>BF.FUNCTION()</code> therefore do not depend on a user opening sign-in UI.</p>
<p>Office identity is used separately to decide whether the Marimo AI authoring controls are enabled. At launch, Notebook AI is restricted to eligible work or school Microsoft identities; personal or unresolved identities receive the same notebook calculation runtime with AI disabled.</p>
<p>That separation prevents an optional authoring capability from becoming a hidden dependency of workbook calculation.</p>
</section>
<section id="persistence-is-source-not-a-frozen-python-process" class="level2">
<h2 class="anchored" data-anchor-id="persistence-is-source-not-a-frozen-python-process">Persistence is source, not a frozen Python process</h2>
<p>Boardflare does not try to serialize a live interpreter, DataFrames, widgets, subscriptions, or Python function objects into the workbook.</p>
<p>It saves the <strong>notebook source</strong> and its preferred Edit/App opening presentation. Reopening reconstructs the runtime:</p>
<div class="cell" data-layout-align="default">
<div class="cell-output-display">
<div>
<p></p><figure class="figure"><p></p>
<div>
<pre class="mermaid mermaid-js">flowchart TD
    Saved[Saved notebook source + opening mode]
    Runtime[Start marimo / Pyodide]
    Inputs[Hydrate bf.inputs]
    Graph[Run reactive graph]
    Publish[Claim bf.publish registry]
    Excel[Resolve worksheet consumers]

    Saved --&gt; Runtime --&gt; Inputs --&gt; Graph --&gt; Publish --&gt; Excel
</pre>
</div>
<p></p></figure><p></p>
</div>
</div>
</div>
<p>This source-first contract is easier to reason about and makes the durable artifact compatible with ordinary source practices such as review, diffing, backup, and version control when the author chooses to surface the <code>.py</code> file externally.</p>
</section>
<section id="uploading-source-is-intentionally-staged" class="level2">
<h2 class="anchored" data-anchor-id="uploading-source-is-intentionally-staged">Uploading source is intentionally staged</h2>
<p>The add-in can open an existing Marimo <code>.py</code> file, but choosing a file is <strong>not</strong> a persistence operation.</p>
<div class="cell" data-layout-align="default">
<div class="cell-output-display">
<div>
<p></p><figure class="figure"><p></p>
<div>
<pre class="mermaid mermaid-js">stateDiagram-v2
    [*] --&gt; Saved: saved workbook source or bundled starter
    Saved --&gt; Staged: upload .py
    Staged --&gt; Saved: Marimo Save + verified workbook write
    Staged --&gt; Saved: startup failure + Restore saved notebook
</pre>
</div>
<p></p></figure><p></p>
</div>
</div>
</div>
<p>The replacement source starts in a fresh Edit session. The previous workbook copy remains durable until the author explicitly saves the replacement and Boardflare verifies the workbook write. That gives a broken upload a recovery path without silently destroying the last saved notebook.</p>
<p>Download follows the same source-first philosophy: it exports source that Marimo has already submitted to Boardflare. It cannot magically serialize editor changes that were never saved.</p>
</section>
<section id="ai-stays-on-the-authoring-side" class="level2">
<h2 class="anchored" data-anchor-id="ai-stays-on-the-authoring-side">AI stays on the authoring side</h2>
<p>AI is useful here because it can accelerate writing and revising normal Python. It is not a required component of the calculation runtime.</p>
<p>An AI action can send the user’s prompt plus selected/supplied notebook context through Boardflare’s configured AI path. The response is authoring output. The durable artifact is still ordinary source that can be inspected and tested before a workbook is distributed.</p>
<p>That is an important distinction for analytical software: the workbook does not need a model to improvise the core business calculation every time it opens.</p>
</section>
<section id="the-legacy-function-path-stays-separate" class="level2">
<h2 class="anchored" data-anchor-id="the-legacy-function-path-stays-separate">The legacy function path stays separate</h2>
<p>Boardflare still supports workbooks created with the earlier standalone <strong>Functions Editor</strong>. Those functions use workbook settings, Excel Name Manager LAMBDAs, and <code>BOARDFLARE.EXEC</code>.</p>
<p>They do <strong>not</strong> execute through the notebook registry:</p>
<div class="cell" data-layout-align="default">
<div class="cell-output-display">
<div>
<p></p><figure class="figure"><p></p>
<div>
<pre class="mermaid mermaid-js">flowchart LR
    NotebookFormula[BF.OUTPUT / BF.FUNCTION] --&gt; NotebookRuntime[Live notebook registry]
    LegacyFormula[Legacy Name Manager function] --&gt; Exec[BOARDFLARE.EXEC] --&gt; LegacyWorker[Legacy runpy worker]
</pre>
</div>
<p></p></figure><p></p>
</div>
</div>
</div>
<p>Keeping that boundary explicit matters for compatibility. Notebook startup or bundle changes should not accidentally become prerequisites for established <code>BOARDFLARE.EXEC</code> workbooks.</p>
</section>
<section id="the-design-principle" class="level2">
<h2 class="anchored" data-anchor-id="the-design-principle">The design principle</h2>
<p>The individual libraries and runtime versions will change. The more durable architecture is the separation of responsibilities:</p>
<blockquote class="blockquote">
<p><strong>Excel remains the workbook data, review, and delivery surface. The reactive notebook is the coherent home for substantial Python work. Boardflare supplies explicit runtime, persistence, and worksheet bridges between them.</strong></p>
</blockquote>
<p>For current implementation details, limits, and security controls, use <strong><a href="../../../apps/excel/python/advanced/architecture-and-runtime/">Architecture and Runtime</a></strong> and <strong><a href="../../../apps/excel/python/advanced/security-and-data-flow/">Security and Data Flow</a></strong> rather than treating this dated launch article as a specification.</p>


</section>

 ]]></description>
  <category>Excel</category>
  <category>Python</category>
  <category>Architecture</category>
  <guid>https://boardflare.com/posts/2026/boardflare-python-architecture/</guid>
  <pubDate>Mon, 22 Jun 2026 00:00:00 GMT</pubDate>
</item>
<item>
  <title>Migrating Excel Workflows to Python: What to Move, What to Keep, and Where the Code Should Run</title>
  <link>https://boardflare.com/posts/2026/migrating-excel-workflows-to-python/</link>
  <description><![CDATA[ 





<p>“Move this spreadsheet to Python” sounds like a technical task, but the difficult decision is architectural: <strong>which parts of the workflow should move at all?</strong></p>
<p>A mature workbook can contain formulas, Power Query steps, VBA, manual procedures, external data connections, review controls, and business rules that users understand precisely because they are visible in Excel. Microsoft’s <a href="https://support.microsoft.com/en-us/excel/about-power-query-in-excel">Power Query documentation</a> describes Power Query as a refreshable way to connect, shape, combine, and load data, while <a href="https://learn.microsoft.com/en-us/office/dev/scripts/overview/excel">Office Scripts</a> cover repeatable workbook automation. Replacing all of that with Python can make the result <em>less</em> maintainable.</p>
<p>A better migration starts by separating the workflow into responsibilities.</p>
<!-- more -->
<section id="do-not-migrate-the-workbook-line-by-line" class="level2">
<h2 class="anchored" data-anchor-id="do-not-migrate-the-workbook-line-by-line">Do not migrate the workbook line by line</h2>
<p>Start with a map of the existing system:</p>
<pre class="text"><code>Inputs
  │
  ├── worksheet assumptions
  ├── imported tables
  ├── files / APIs / databases
  └── manual adjustments
  │
  ▼
Business logic
  │
  ├── formulas
  ├── Power Query
  ├── VBA
  └── external scripts
  │
  ▼
Outputs
  │
  ├── calculations
  ├── reports
  ├── charts
  ├── reconciliations
  └── files / emails / system updates</code></pre>
<p>Then classify each responsibility by what environment is best at it.</p>
</section>
<section id="what-should-usually-stay-in-excel" class="level2">
<h2 class="anchored" data-anchor-id="what-should-usually-stay-in-excel">What should usually stay in Excel</h2>
<p>Keep logic in Excel when its transparency is a feature.</p>
<p>Good examples include:</p>
<ul>
<li>simple formulas that business users can audit directly;</li>
<li>visible assumptions and overrides;</li>
<li>reconciliations and control totals;</li>
<li>presentation tables stakeholders modify frequently;</li>
<li>normal PivotTables or charts when native Excel editing matters;</li>
<li>Power Query steps that are already clear and reliably maintained by the owning team.</li>
</ul>
<p>Moving a transparent <code>SUMIFS</code> or a straightforward Power Query import into Python just because Python is available usually creates more code without creating more value.</p>
</section>
<section id="what-is-a-good-candidate-for-python" class="level2">
<h2 class="anchored" data-anchor-id="what-is-a-good-candidate-for-python">What is a good candidate for Python</h2>
<p>Python becomes more attractive when the existing workbook contains software-like logic that is difficult to express or maintain in spreadsheet primitives. This is an architectural recommendation, not a claim that Python is inherently better:</p>
<ul>
<li>repeated helper-sheet transformations;</li>
<li>simulation or optimization;</li>
<li>statistical models;</li>
<li>numerical algorithms;</li>
<li>complex text processing;</li>
<li>reusable domain calculations;</li>
<li>duplicated business logic;</li>
<li>logic that would benefit from unit tests;</li>
<li>interactive application behavior that is currently held together by macros and manual steps.</li>
</ul>
<p>The migration target should be a clearer boundary, not “more Python.” Runtime constraints should be checked before any rewrite. Microsoft’s native option <a href="https://support.microsoft.com/en-us/excel/python/data-security-and-python-in-excel">runs Python in a managed cloud container with workbook and Power Query inputs</a>, while browser runtimes such as Pyodide have their own <a href="https://pyodide.org/en/stable/usage/faq.html">WebAssembly and browser-environment limitations</a>. Those are different boundaries, but both are reasons to keep file- and system-heavy work outside an in-workbook runtime when the workflow depends on unrestricted operating-system access.</p>
</section>
<section id="worked-example-migrate-the-model-keep-the-workbook-contract" class="level2">
<h2 class="anchored" data-anchor-id="worked-example-migrate-the-model-keep-the-workbook-contract">Worked example: migrate the model, keep the workbook contract</h2>
<p>Consider a revenue-planning workbook that has evolved into a chain of copied formulas and helper sheets. Users still like entering assumptions in Excel and reviewing the final forecast there, but the model now includes scenario adjustments, uncertainty, simulation, and a reusable projection calculation.</p>
<p>The least useful migration would translate every helper-cell formula into one long Python script. A better migration changes the boundary.</p>
<section id="before" class="level3">
<h3 class="anchored" data-anchor-id="before">Before</h3>
<div class="cell" data-layout-align="default">
<div class="cell-output-display">
<div>
<p></p><figure class="figure"><p></p>
<div>
<pre class="mermaid mermaid-js">flowchart LR
    A[Drivers sheet] --&gt; B[Copied formulas]
    B --&gt; C[Helper sheets]
    C --&gt; D[Scenario macros]
    D --&gt; E[Forecast sheet]
    E --&gt; F[Management review]
</pre>
</div>
<p></p></figure><p></p>
</div>
</div>
</div>
</section>
<section id="after" class="level3">
<h3 class="anchored" data-anchor-id="after">After</h3>
<div class="cell" data-layout-align="default">
<div class="cell-output-display">
<div>
<p></p><figure class="figure"><p></p>
<div>
<pre class="mermaid mermaid-js">flowchart LR
    A[Drivers sheet] --&gt; B[bf.inputs]
    B --&gt; C[Reactive Python model]
    C --&gt; D[Scenario controls + validation]
    D --&gt; E[bf.publish]
    E --&gt; F[BF.OUTPUT forecast]
    E --&gt; G[BF.FUNCTION project_arr]
    F --&gt; H[Management review]
    G --&gt; H
</pre>
</div>
<p></p></figure><p></p>
</div>
</div>
</div>
<p>The workbook keeps the assumptions and review surface. Python takes ownership of the software-like model. The public contract can remain small:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb2" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb2-1"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> boardflare <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">as</span> bf</span>
<span id="cb2-2"></span>
<span id="cb2-3">inputs <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> bf.inputs(</span>
<span id="cb2-4">    assumptions<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>bf.ref(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Drivers!A4:B12"</span>, headers<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">True</span>),</span>
<span id="cb2-5">    historical<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>bf.ref(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Drivers!A15:B27"</span>, headers<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">True</span>),</span>
<span id="cb2-6">)</span>
<span id="cb2-7">inputs</span></code></pre></div></div>
<p>A later cell validates and calculates the forecast. The publication cell then makes only the intended results callable from the workbook:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb3" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb3-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> project_arr(months: <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">int</span>, growth_rate: <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">float</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.08</span>):</span>
<span id="cb3-2">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Domain calculation omitted here; this function is independently testable.</span></span>
<span id="cb3-3">    ...</span>
<span id="cb3-4"></span>
<span id="cb3-5">publication <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> bf.publish(</span>
<span id="cb3-6">    outputs<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>{<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"kpis"</span>: kpis, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"forecast"</span>: forecast},</span>
<span id="cb3-7">    functions<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>{<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"project_arr"</span>: project_arr},</span>
<span id="cb3-8">)</span>
<span id="cb3-9">publication</span></code></pre></div></div>
<p>Excel consumes the explicit contract:</p>
<pre class="excel"><code>=BF.OUTPUT("forecast")
=BF.FUNCTION("project_arr", 12, C6)</code></pre>
<p>A safe migration would run the old and new models side by side over representative scenarios, reconcile outputs within an agreed tolerance, and keep visible workbook control totals after the Python version becomes primary. The current <a href="../../../templates/sales-scenario-analysis/">Sales Scenario Analysis</a> demonstrates this target architecture; it is not evidence that every formula-heavy forecast should be migrated.</p>
</section>
</section>
<section id="what-should-remain-external" class="level2">
<h2 class="anchored" data-anchor-id="what-should-remain-external">What should remain external</h2>
<p>Some work should not be pulled into the workbook runtime at all. Microsoft’s <a href="https://support.microsoft.com/en-us/excel/python/data-security-and-python-in-excel">Python in Excel security documentation</a> explicitly describes the native runtime’s restricted access to the user’s computer, network, and workbook features, so these boundaries should be checked before choosing an in-workbook design.</p>
<p>Keep external Python, services, or other automation for tasks such as:</p>
<ul>
<li>traversing local folders;</li>
<li>processing hundreds of independent files;</li>
<li>scheduled jobs;</li>
<li>PDF/email/document ingestion;</li>
<li>database pipelines;</li>
<li>unrestricted API integrations;</li>
<li>desktop automation;</li>
<li>native packages that do not fit the workbook runtime.</li>
</ul>
<p>A strong architecture can use external Python for ingestion and still use Excel as the interactive decision and review layer.</p>
</section>
<section id="migrating-vba" class="level2">
<h2 class="anchored" data-anchor-id="migrating-vba">Migrating VBA</h2>
<p>VBA is not one thing. A macro can contain calculation logic, workbook manipulation, event handlers, formatting, file-system work, Outlook automation, and UI code in the same procedure.</p>
<p>Classify it before translating it.</p>
<table class="caption-top table">
<colgroup>
<col style="width: 50%">
<col style="width: 50%">
</colgroup>
<thead>
<tr class="header">
<th>VBA responsibility</th>
<th>Likely destination</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>Analytical calculation</td>
<td>Python model or function</td>
</tr>
<tr class="even">
<td>User assumptions</td>
<td>Excel cells/tables</td>
</tr>
<tr class="odd">
<td>Reusable worksheet calculation</td>
<td>Python custom function or retained Excel formula</td>
</tr>
<tr class="even">
<td>Model controls</td>
<td>Workbook UI or notebook application controls</td>
</tr>
<tr class="odd">
<td>File/folder/Outlook automation</td>
<td>VBA or external Python</td>
</tr>
<tr class="even">
<td>Formatting and sheet manipulation</td>
<td>Often keep in Excel/VBA-specific layer</td>
</tr>
<tr class="odd">
<td>Validation and reconciliations</td>
<td>Excel and/or deterministic Python checks</td>
</tr>
</tbody>
</table>
<p>A line-by-line VBA-to-Python translation often preserves the worst part of the original design: hidden mutable state and procedural dependencies.</p>
<p>Instead, try to replace the macro with explicit inputs, a testable calculation, and explicit outputs.</p>
</section>
<section id="migrating-formula-heavy-models" class="level2">
<h2 class="anchored" data-anchor-id="migrating-formula-heavy-models">Migrating formula-heavy models</h2>
<p>Long formulas and helper sheets are good migration candidates only when they have become difficult to reason about.</p>
<p>Look for:</p>
<ul>
<li>the same formula logic copied across many places;</li>
<li>nested formulas implementing a real domain algorithm;</li>
<li>large helper-sheet chains used only as intermediate state;</li>
<li>calculations that need simulation, optimization, or statistics;</li>
<li>formulas that cannot be tested independently of the workbook.</li>
</ul>
<p>Then migrate incrementally:</p>
<ol type="1">
<li>freeze a representative test workbook;</li>
<li>document the current inputs and outputs;</li>
<li>calculate the same result in Python;</li>
<li>reconcile both implementations over multiple scenarios;</li>
<li>move only the proven section;</li>
<li>retain visible control totals in Excel.</li>
</ol>
<p>The result should be easier to understand than the original model, not merely shorter on the worksheet.</p>
</section>
<section id="migrating-a-jupyter-notebook" class="level2">
<h2 class="anchored" data-anchor-id="migrating-a-jupyter-notebook">Migrating a Jupyter notebook</h2>
<p>A migration does not need to turn every notebook into an application. First decide which responsibilities belong in Excel and which substantial logic belongs in the Python notebook. A reactive notebook such as <a href="https://docs.marimo.io/">marimo</a> changes the execution model compared with a conventional Jupyter workflow, but it does not change the architectural question.</p>
<p>That boundary matters more than the notebook technology.</p>
<p>A migration should answer:</p>
<ul>
<li>Which values should remain workbook inputs or notebook controls?</li>
<li>Which workbook ranges should be explicit notebook inputs?</li>
<li>Which code cells are really reusable model functions?</li>
<li>Which outputs belong in the notebook UI?</li>
<li>Which results must return to worksheet formulas?</li>
<li>How should invalid inputs be shown?</li>
<li>What happens when a package or external service is unavailable?</li>
<li>If someone else will use it, do they need the full Edit surface or a simpler App presentation?</li>
</ul>
<p>With Boardflare, the target pattern is:</p>
<pre class="text"><code>Workbook inputs
      │
      ▼
bf.inputs(...)
      │
      ▼
Reactive marimo model
      │
      ├── validation
      ├── calculations
      ├── controls
      └── visualizations
      │
      ▼
bf.publish(...)
      │
      ├── BF.OUTPUT(...)
      └── BF.FUNCTION(...)</code></pre>
<p>The important migration is therefore <strong>spreadsheet logic → clear Excel/notebook responsibilities</strong>, not Jupyter syntax → marimo syntax. If the finished notebook later becomes a repeatable tool, <strong>Open as: App</strong> can provide a simplified presentation of that same source.</p>
</section>
<section id="migrating-external-python-into-excel" class="level2">
<h2 class="anchored" data-anchor-id="migrating-external-python-into-excel">Migrating external Python into Excel</h2>
<p>The right answer may be to move only part of the application.</p>
<p>For example:</p>
<pre class="text"><code>External Python / SQL
        │
        ├── ingestion
        ├── file processing
        ├── scheduled jobs
        └── governed preparation
        │
        ▼
Excel workbook
        │
        ├── assumptions
        ├── review
        └── stakeholder interface
        │
        ▼
Interactive Python layer
        │
        ├── scenarios
        ├── model logic
        └── application UI</code></pre>
<p>This keeps system automation in the environment designed for it while moving the interactive decision layer closer to users.</p>
</section>
<section id="a-practical-migration-sequence" class="level2">
<h2 class="anchored" data-anchor-id="a-practical-migration-sequence">A practical migration sequence</h2>
<section id="document-the-current-contract" class="level3">
<h3 class="anchored" data-anchor-id="document-the-current-contract">1. Document the current contract</h3>
<p>Write down:</p>
<ul>
<li>inputs;</li>
<li>outputs;</li>
<li>business rules;</li>
<li>manual steps;</li>
<li>external dependencies;</li>
<li>expected error conditions;</li>
<li>users and maintainers.</li>
</ul>
<p>If those cannot be described, the migration is not ready.</p>
</section>
<section id="preserve-a-known-good-baseline" class="level3">
<h3 class="anchored" data-anchor-id="preserve-a-known-good-baseline">2. Preserve a known-good baseline</h3>
<p>Keep representative workbooks and expected outputs. Important finance/accounting migrations should include reconciliations and independently checked examples.</p>
</section>
<section id="move-one-boundary-at-a-time" class="level3">
<h3 class="anchored" data-anchor-id="move-one-boundary-at-a-time">3. Move one boundary at a time</h3>
<p>Do not rewrite formulas, VBA, imports, UI, and reports simultaneously unless there is a compelling reason.</p>
</section>
<section id="add-validation-before-adding-features" class="level3">
<h3 class="anchored" data-anchor-id="add-validation-before-adding-features">4. Add validation before adding features</h3>
<p>Python makes it easier to create more sophisticated logic, but sophistication without input validation simply creates more sophisticated failures.</p>
</section>
<section id="test-the-second-user-workflow" class="level3">
<h3 class="anchored" data-anchor-id="test-the-second-user-workflow">5. Test the second-user workflow</h3>
<p>For a workbook-connected notebook, the acceptance test is not merely “the author’s notebook runs.” It is:</p>
<blockquote class="blockquote">
<p><strong>A second person can open the saved workbook, understand the controls, change inputs, get correct outputs, and recover from expected errors without maintaining the code.</strong></p>
</blockquote>
</section>
</section>
<section id="when-not-to-migrate" class="level2">
<h2 class="anchored" data-anchor-id="when-not-to-migrate">When not to migrate</h2>
<p>Do not move a workflow to Python because:</p>
<ul>
<li>Python is fashionable;</li>
<li>AI can generate the code;</li>
<li>a simple formula looks less impressive than a script;</li>
<li>the current Power Query workflow is boring but reliable;</li>
<li>the owning team cannot support the resulting runtime.</li>
</ul>
<p>A successful migration reduces complexity at the system level.</p>
</section>
<section id="where-boardflare-fits" class="level2">
<h2 class="anchored" data-anchor-id="where-boardflare-fits">Where Boardflare fits</h2>
<p>Boardflare is designed for the slice of this problem where <strong>Excel should remain part of the workflow but substantial Python logic benefits from a coherent reactive notebook</strong>.</p>
<p>It is not intended to replace external Python for arbitrary system automation, and it should not replace transparent spreadsheet logic that is already the clearest solution.</p>
<p>See the <a href="../../../apps/excel/python/">Python for Excel documentation</a> for the current product contract and the <a href="../../../templates/">Python in Excel template library</a> for runnable workbooks, interactive demos, and worked notebook patterns.</p>


</section>

 ]]></description>
  <category>Excel</category>
  <category>Python</category>
  <category>Migration</category>
  <guid>https://boardflare.com/posts/2026/migrating-excel-workflows-to-python/</guid>
  <pubDate>Wed, 03 Jun 2026 00:00:00 GMT</pubDate>
</item>
<item>
  <title>AI Add-ins for Excel</title>
  <link>https://boardflare.com/posts/2026/excel_ai_addins/</link>
  <description><![CDATA[ 





<p>AI add-ins for Excel now fall into a few practical families. The most visible category is the <strong>general-purpose Excel AI assistant</strong>: a chat or task-pane agent that can write formulas, explain workbook logic, clean data, summarize ranges, create charts, and sometimes edit the workbook directly. Those are capabilities exposed by the broader <a href="https://learn.microsoft.com/en-us/office/dev/add-ins/excel/excel-add-ins-overview">Excel add-in platform</a>, but each product supports a different subset.</p>
<!-- more -->
<p>The second major family is <strong>AI worksheet functions</strong>. These tools add formulas such as <code>=AI()</code>, prompt functions, classifiers, extractors, translators, and custom model functions that can be copied down thousands of rows. They are useful when the job is repetitive, row-by-row, and spreadsheet-native.</p>
<p>The third family is <strong>domain-specific AI</strong>, especially for finance. Finance and accounting add-ins make up a large share of this snapshot, covering financial modeling, FP&amp;A, reconciliation, market intelligence, NetSuite reporting, tax document extraction, bank statement conversion, commercial real estate underwriting, and capital markets research.</p>
<p>The catalog also includes tools for <strong>data extraction and cleaning, analytics, machine learning, proposal work, translation, compliance, audit, and specialized industry workflows</strong>. These are less universal than a general assistant but can be more valuable when they match the user’s exact job.</p>
<hr>
<section id="category-snapshot" class="level2">
<h2 class="anchored" data-anchor-id="category-snapshot">Category snapshot</h2>
<table class="caption-top table">
<thead>
<tr class="header">
<th>Category</th>
<th style="text-align: right;">Add-ins in supplied table</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>General-purpose Excel AI assistants</td>
<td style="text-align: right;">56</td>
</tr>
<tr class="even">
<td>AI worksheet functions and formula tools</td>
<td style="text-align: right;">12</td>
</tr>
<tr class="odd">
<td>Finance, accounting, and business workflow specialists</td>
<td style="text-align: right;">38</td>
</tr>
<tr class="even">
<td>Data extraction, cleaning, and enrichment</td>
<td style="text-align: right;">9</td>
</tr>
<tr class="odd">
<td>Analytics, machine learning, BI, and forecasting</td>
<td style="text-align: right;">12</td>
</tr>
<tr class="even">
<td>Audit, compliance, validation, and governance</td>
<td style="text-align: right;">4</td>
</tr>
<tr class="odd">
<td>Writing, translation, proposal, and content specialists</td>
<td style="text-align: right;">10</td>
</tr>
<tr class="even">
<td>Industry-specific specialists</td>
<td style="text-align: right;">5</td>
</tr>
</tbody>
</table>
<p>The headline pattern is clear within this snapshot: broad Excel agents dominate the list, while finance and data/document-preparation tools are also strongly represented. The categories are my classification of the catalog rows, not Microsoft marketplace categories. Extraction-first tools are grouped with data preparation, Arborchat is treated as a finance/market-intelligence tool despite using custom functions, and Sunhat is treated as a sustainability/ESG specialist rather than a generic writing tool.</p>
<p>The source is the <a href="https://appsource.microsoft.com/en-us/marketplace/cloudsIndustry?Preview=true&amp;page=1&amp;product=excel">Microsoft AppSource Excel catalog</a>, checked on May 16, 2026, plus the publisher documentation linked in the tables below. AppSource is dynamic; the individual listing links are the evidence for the product descriptions, while the counts are a dated manual classification of the catalog included in this article.</p>
<hr>
</section>
<section id="how-to-read-the-market" class="level2">
<h2 class="anchored" data-anchor-id="how-to-read-the-market">How to read the market</h2>
<section id="general-purpose-agents-are-the-default-choice-for-everyday-excel-help" class="level3">
<h3 class="anchored" data-anchor-id="general-purpose-agents-are-the-default-choice-for-everyday-excel-help">1. General-purpose agents are the default choice for everyday Excel help</h3>
<p>General agents are designed for users who want to ask Excel questions in normal language. They typically help with formulas, data cleaning, workbook summaries, formatting, pivots, charts, VBA or scripts, and troubleshooting. The most prominent examples in the supplied ordering include <strong>ChatGPT</strong>, <strong>Claude by Anthropic for Excel</strong>, <strong>Shortcut AI</strong>, <strong>GPT for Excel Word</strong>, <strong>TwistlyCells AI for Excel</strong>, <strong>Autopilot</strong>, <strong>Ghostwriter</strong>, <strong>AI-aided Formula Editor</strong>, <strong>Formula Bot</strong>, <strong>griddy</strong>, <strong>SheetXAI</strong>, <strong>OfficeAI for Excel</strong>, <strong>Incant</strong>, and <strong>CoreGPT AI for Excel</strong>.</p>
<p>For end users, these tools are attractive because they reduce the need to know exact Excel syntax. Instead of remembering the difference between <code>XLOOKUP</code>, <code>INDEX/MATCH</code>, dynamic arrays, Power Query steps, or chart setup, users can describe the outcome. The more advanced tools also claim to perform multi-step workbook edits, import or extract PDF data, generate charts, repair formulas, and explain the reasoning behind suggested changes.</p>
<p>The trade-off is that general agents vary widely in how much of the workbook they can read, how safely they apply edits, whether they provide citations or audit trails, what AI models they use, and how they handle private spreadsheet data. Users should test them on copied workbooks before allowing automatic changes to production spreadsheets. Some tools in this category are Office-wide rather than Excel-first: <strong>AI Perfect Assistant</strong> and <strong>Ghostwriter</strong>, for example, should be understood as general Office productivity assistants with Excel support.</p>
</section>
<section id="worksheet-function-add-ins-are-best-for-repeatable-row-by-row-ai" class="level3">
<h3 class="anchored" data-anchor-id="worksheet-function-add-ins-are-best-for-repeatable-row-by-row-ai">2. Worksheet-function add-ins are best for repeatable row-by-row AI</h3>
<p>Some add-ins focus less on a chat sidebar and more on Excel formulas. Examples include <strong>ZKutools Anywhere for Excel</strong>, <strong>GenAI Tools for Excel</strong>, <strong>Numerous.ai</strong>, <strong>Spreadsheet AI</strong>, <strong>SheetSavvy AI</strong>, <strong>Local GPT for Excel</strong>, <strong>nele.ai</strong>, <strong>Melder</strong>, <strong>Mindcase</strong>, <strong>xllify</strong>, and <strong>formulaML</strong>.</p>
<p>These are especially useful when the task looks like a spreadsheet operation: classify every support ticket, extract company names from every paragraph, translate every row, summarize every comment, run prompts over a large table, or apply a machine-learning prediction function. End users who already think in cells and formulas may prefer this pattern because results can be filled down, audited cell by cell, and combined with normal Excel logic.</p>
<p>The main things to check are cost per cell or token, rate limits, whether an API key is required, whether data leaves the workbook, and whether results can be refreshed predictably. A few tools are hybrids: <strong>TwistlyCells</strong> is categorized as a general assistant but also exposes worksheet-style AI tools, while <strong>Spreadsheet AI</strong> is categorized as a function tool but also includes a chat copilot. <strong>Mindcase</strong> stays in this group because of its formula interface, though its web-search and enrichment functions also make it relevant to data-research workflows.</p>
</section>
<section id="finance-is-the-largest-specialization-in-this-snapshot" class="level3">
<h3 class="anchored" data-anchor-id="finance-is-the-largest-specialization-in-this-snapshot">3. Finance is the largest specialization in this snapshot</h3>
<p>Finance and accounting tools are heavily represented. The supplied list includes broad finance copilots such as <strong>Tracelight</strong>, <strong>Finance in Microsoft 365 Copilot</strong>, <strong>Endex AI</strong>, <strong>EBITDAI</strong>, <strong>ElyxAI</strong>, <strong>CCH® Tagetik for Excel</strong>, <strong>Crunched</strong>, <strong>ModelMonkey</strong>, <strong>Toolkit</strong>, <strong>TabAI</strong>, <strong>Grid</strong>, <strong>Superjoin for Finance</strong>, <strong>SuiteReport</strong>, <strong>Sortino</strong>, <strong>Tenkay Model Updater</strong>, <strong>NoNighter Copilot</strong>, <strong>Condour for Excel</strong>, <strong>Arborchat</strong>, and <strong>Octagon</strong>. Adjacent tools cover accounting close, tax prep, tax-document extraction, commercial real estate underwriting, corporate development, private markets, and biotech finance.</p>
<p>These tools matter because finance workbooks are rarely simple tables. They contain assumptions, formulas, linked schedules, scenario logic, formatting conventions, and review requirements. A finance-specific agent can be more useful than a generic chat tool when it understands financial-model structure, variance analysis, reconciliation, audit trails, earnings updates, market intelligence, or FP&amp;A reporting workflows.</p>
<p>End users should be careful with this category. The value can be high, but so are the risks. Before adopting a finance add-in, teams should review workbook access, source traceability, model-change logs, export controls, user permissions, and whether the tool integrates with existing systems such as NetSuite, Xero, market-data providers, or company data warehouses.</p>
</section>
<section id="data-extraction-cleaning-and-enrichment-tools-solve-the-messy-input-problem" class="level3">
<h3 class="anchored" data-anchor-id="data-extraction-cleaning-and-enrichment-tools-solve-the-messy-input-problem">4. Data extraction, cleaning, and enrichment tools solve the “messy input” problem</h3>
<p>Several tools focus on getting messy information into usable spreadsheet form. Examples include <strong>ExtractSimple</strong>, <strong>Rocket Statements</strong>, <strong>Altavize</strong>, <strong>Formfit</strong>, <strong>Doczen</strong>, <strong>DataCheckr AI</strong>, <strong>PromptLoop</strong>, <strong>WranglesXL</strong>, <strong>Verodat</strong>, and <strong>Mindcase</strong>. These add-ins are useful when the problem is not analysis but preparation: PDFs, images, bank statements, unstructured text, duplicate records, web data, inconsistent names, missing values, or fields trapped in documents.</p>
<p>For end users, this category can save the most time when manual copy-paste is the bottleneck. The key evaluation question is not just whether the AI can extract data, but whether it can show confidence, preserve source traceability, validate outputs, and let the user correct or reuse extraction rules. <strong>Doczen</strong> is a good example of a hybrid here because its validation and changelog features also overlap with audit-style workflows.</p>
</section>
<section id="analytics-machine-learning-bi-and-forecasting-tools-serve-more-technical-workflows" class="level3">
<h3 class="anchored" data-anchor-id="analytics-machine-learning-bi-and-forecasting-tools-serve-more-technical-workflows">5. Analytics, machine learning, BI, and forecasting tools serve more technical workflows</h3>
<p>A separate group supports predictive analytics, natural-language BI, forecasting, model inference, and visualization. Examples include <strong>Analytic Solver Data Science</strong>, <strong>Azure Machine Learning</strong>, <strong>Modern Charts</strong>, <strong>Coherent Assistant</strong>, <strong>AutoQL for Excel</strong>, <strong>timegpt</strong>, <strong>teal ML</strong>, <strong>Wren AI for Excel</strong>, <strong>Timbr NLQ</strong>, <strong>Thinkdeeply AI Inference Assistant</strong>, <strong>Alchemite for R&amp;D</strong>, and <strong>formulaML</strong>.</p>
<p>These are best for users who already have structured data and want forecasts, predictions, SQL-style queries, governed analytics, or machine-learning outputs inside Excel. They are often less “chatty” than general assistants, but they can be more reliable for specific analytical tasks. <strong>Modern Charts</strong> is best described as analytics and visualization rather than machine learning, while <strong>Alchemite for R&amp;D</strong> belongs in machine learning but has a clear R&amp;D/materials/product-development orientation.</p>
</section>
<section id="writing-translation-proposals-and-document-workflows-extend-excel-beyond-numbers" class="level3">
<h3 class="anchored" data-anchor-id="writing-translation-proposals-and-document-workflows-extend-excel-beyond-numbers">6. Writing, translation, proposals, and document workflows extend Excel beyond numbers</h3>
<p>A smaller but important group helps with text-heavy Office workflows. Examples include <strong>MTrans for Office</strong>, <strong>Document Translator</strong>, <strong>Acrolinx for Microsoft 365 Office</strong>, <strong>Strategy-AI</strong>, <strong>GovEagle AI</strong>, <strong>Zen RFP</strong>, <strong>SiftHub</strong>, <strong>Copilot for Excel Spreadsheet</strong>, <strong>Pluralytics</strong>, <strong>Transcription</strong>, and <strong>MathPad</strong>.</p>
<p>These add-ins are relevant because Excel is often part of a larger document workflow: questionnaire tracking, RFP matrices, translations, marketing copy analysis, technical standards, or proposal response spreadsheets. They are usually most useful when paired with Word and PowerPoint, not just Excel.</p>
</section>
<section id="audit-compliance-validation-and-governance-tools-emphasize-control" class="level3">
<h3 class="anchored" data-anchor-id="audit-compliance-validation-and-governance-tools-emphasize-control">7. Audit, compliance, validation, and governance tools emphasize control</h3>
<p>Audit and governance tools focus less on drafting and more on evidence, validation, compliance, and traceability. Examples include <strong>Copilot Audit</strong>, <strong>Kolena AI Agents for Excel</strong>, <strong>Midship</strong>, and <strong>CRex Add-in for Excel</strong>.</p>
<p>These tools are most relevant when a spreadsheet is part of a formal review process. Users should look for source links, confidence scores, validation rules, review logs, and a clear way to inspect or override AI outputs.</p>
</section>
<section id="industry-specific-tools-are-narrower-but-can-be-powerful" class="level3">
<h3 class="anchored" data-anchor-id="industry-specific-tools-are-narrower-but-can-be-powerful">8. Industry-specific tools are narrower but can be powerful</h3>
<p>Some add-ins target a specific profession or industry: <strong>Archer</strong> for commercial real estate underwriting, <strong>Aidy</strong> for insurance and marketing analytics, <strong>llama.ai Excel Adapter</strong> for supply chain decision platforms, <strong>SafeTerm</strong> for medical coding, <strong>Cascade Intelligence</strong> for AEC opportunity intelligence, and <strong>Sunhat for Office</strong> for sustainability and ESG questionnaire workflows.</p>
<p>These should not be evaluated against general Excel assistants. They should be evaluated against the manual workflow they replace. A narrow tool that handles an industry-specific data format, compliance process, or proposal workflow may be more useful than a broadly capable AI assistant.</p>
<hr>
</section>
</section>
<section id="key-add-ins-to-know" class="level2">
<h2 class="anchored" data-anchor-id="key-add-ins-to-know">Key add-ins to know</h2>
<p>The following add-ins are not presented as a definitive ranking. They are the most prominent or representative options from the supplied list, with emphasis on items that appear early in the store-ordered source table or clearly represent a major category. Category placement reflects the follow-up verification of key listings, so a few tools are filed by their primary end-user workflow rather than by their source-table type label.</p>
<section id="general-purpose-excel-ai-assistants" class="level3">
<h3 class="anchored" data-anchor-id="general-purpose-excel-ai-assistants">General-purpose Excel AI assistants</h3>
<table class="caption-top table">
<thead>
<tr class="header">
<th>Store-order rank</th>
<th>Add-in</th>
<th>Publisher</th>
<th>Source category</th>
<th>Why it matters to end users</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>1</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200010215?tab=Overview">ChatGPT</a></td>
<td><a href="https://help.openai.com">OpenAI, LLC</a></td>
<td>General Agent</td>
<td>Sidebar assistant for building, analyzing, and updating spreadsheets in natural language.</td>
</tr>
<tr class="even">
<td>2</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200009404?tab=Overview">Claude by Anthropic for Excel</a></td>
<td><a href="https://support.claude.com/en/">Claude by Anthropic for Office</a></td>
<td>General Agent</td>
<td>Sidebar assistant that reads workbooks, explains formulas, and updates sheets with citations.</td>
</tr>
<tr class="odd">
<td>3</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200009152?tab=Overview">Shortcut AI</a></td>
<td><a href="https://shortcut.ai/home">Fundamental Research Labs</a></td>
<td>General Agent</td>
<td>Autonomous Excel assistant for multi-step spreadsheet tasks, including fixing errors and importing PDF data.</td>
</tr>
<tr class="even">
<td>4</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200005502?tab=Overview">GPT for Excel Word</a></td>
<td><a href="https://gptforwork.com">TALARIAN S. à r.l.</a></td>
<td>General Agent</td>
<td>Excel side-panel agent for formulas, formatting, cleanup, pivots, charts, and bulk row-by-row work.</td>
</tr>
<tr class="odd">
<td>6</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200005271?tab=Overview">TwistlyCells AI for Excel</a></td>
<td><a href="https://twistlycells.ai/">Twistly</a></td>
<td>General Agent</td>
<td>ChatGPT-style Excel assistant with tools like AI.ASK, AI.TABLE, AI.FILL, and AI.FORMULA.</td>
</tr>
<tr class="even">
<td>7</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200005669?tab=Overview">Autopilot</a></td>
<td><a href="https://ghostwriter-ai.com/GettingStartedwithGhostwriter.pdf">Smart Barn Technologies</a></td>
<td>General Agent</td>
<td>Conversation-style Office assistant for Word, Excel, and PowerPoint with selectable AI models.</td>
</tr>
<tr class="odd">
<td>10</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200006067?tab=Overview">AI Perfect Assistant for Office</a></td>
<td><a href="https://help.perfectassistant.ai/feedback/">OOO RD17</a></td>
<td>General Agent</td>
<td>Office assistant that drafts text, explains Excel formulas, and translates content.</td>
</tr>
<tr class="even">
<td>11</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200008745?tab=Overview">griddy</a></td>
<td><a href="https://getgriddy.ai/">griddy</a></td>
<td>General Agent</td>
<td>Natural-language Excel assistant for formulas, charts, and cleanup.</td>
</tr>
<tr class="odd">
<td>12</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200005107?tab=Overview">Ghostwriter</a></td>
<td><a href="https://ghostwriter-ai.com/GettingStartedwithGhostwriter.pdf">Smart Barn Technologies</a></td>
<td>General Agent</td>
<td>GPT assistant for Word, Excel, and PowerPoint with workbook/table analysis.</td>
</tr>
<tr class="even">
<td>13</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200001584?tab=Overview">AI-aided Formula Editor</a></td>
<td><a href="https://www.10studio.tech">Matrix Lead</a></td>
<td>General Agent</td>
<td>Workbook-aware chat copilot plus formula generation, explanation, and repair.</td>
</tr>
<tr class="odd">
<td>16</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200004935?tab=Overview">Formula Bot - AI in Spreadsheets</a></td>
<td><a href="https://formulabot.com">Formula Bot</a></td>
<td>General Agent</td>
<td>AI data analyst and spreadsheet copilot for formulas, charts, dashboards, and data preparation.</td>
</tr>
<tr class="even">
<td>23</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200008627?tab=Overview">AI Agent for Excel</a></td>
<td><a href="https://www.10studio.tech">Matrix Lead</a></td>
<td>General Agent</td>
<td>Autonomous Excel agent that suggests edits for modeling, cleanup, analysis, and web search.</td>
</tr>
<tr class="odd">
<td>40</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200006400?tab=Overview">Incant - AI Magic for Excel</a></td>
<td><a href="https://www.incant.app">Della Tech LLC</a></td>
<td>General Agent</td>
<td>GPT-powered Excel add-in that turns natural-language incantations into formulas and workbook actions such as formatting, charts, pivots, validation rules, sorting, filtering, and sheet changes.</td>
</tr>
</tbody>
</table>
</section>
<section id="ai-worksheet-functions-and-formula-tools" class="level3">
<h3 class="anchored" data-anchor-id="ai-worksheet-functions-and-formula-tools">AI worksheet functions and formula tools</h3>
<table class="caption-top table">
<thead>
<tr class="header">
<th>Store-order rank</th>
<th>Add-in</th>
<th>Publisher</th>
<th>Source category</th>
<th>Why it matters to end users</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>5</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200009190?tab=Overview">ZKutools Anywhere for Excel</a></td>
<td><a href="https://www.extendoffice.com/">ExtendOffice Ltd</a></td>
<td>Custom Functions</td>
<td>Adds 28 AI-powered Excel functions for analysis, extraction, translation, and formula generation.</td>
</tr>
<tr class="even">
<td>14</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200006231?tab=Overview">GenAI Tools for Excel</a></td>
<td><a href="https://www.busybee-apps.jp">BusyBee, Inc</a></td>
<td>Custom Functions</td>
<td>Five AI worksheet functions for ChatGPT, Gemini, and Claude; requires API keys.</td>
</tr>
<tr class="odd">
<td>19</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200005281?tab=Overview">Numerous.ai</a></td>
<td><a href="https://numerous.ai">NUMEROUSAI, INC</a></td>
<td>Custom Functions</td>
<td>Provides =AI and related worksheet functions for bulk text and formula tasks.</td>
</tr>
<tr class="even">
<td>22</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200006009?tab=Overview">Spreadsheet AI</a></td>
<td><a href="https://www.10studio.tech">SAS Matrix Lead</a></td>
<td>Custom Functions</td>
<td>Offers 17 AI spreadsheet functions plus a chat copilot.</td>
</tr>
<tr class="odd">
<td>46</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200007427?tab=Overview">Local GPT for Excel</a></td>
<td><a href="https://www.boardflare.com/">Boardflare</a></td>
<td>Custom Functions</td>
<td>Local custom function for private on-device AI in Excel.</td>
</tr>
<tr class="even">
<td>68</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200008575?tab=Overview">Melder - AI for Excel</a></td>
<td><a href="https://melder.io/">EchoSend Inc</a></td>
<td>Custom Functions</td>
<td>AI worksheet functions such as M.GEN, M.EXTRACT, and M.CATEGORIZE, plus document upload and per-answer citations.</td>
</tr>
<tr class="odd">
<td>87</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200007940?tab=Overview">Mindcase - Automate tasks with ChatGPT - AI Assistant for Research and Web Scraping</a></td>
<td><a href="https://www.mindcase.co">Mindcase Technologies</a></td>
<td>Custom Functions</td>
<td>Excel functions such as ASK, ASK_WEB, EXTRACT, COMPANY_DATA, and YAHOO_FINANCE for web search, scraping, enrichment, and structured data extraction.</td>
</tr>
</tbody>
</table>
</section>
<section id="finance-accounting-and-business-workflow-specialists" class="level3">
<h3 class="anchored" data-anchor-id="finance-accounting-and-business-workflow-specialists">Finance, accounting, and business workflow specialists</h3>
<table class="caption-top table">
<thead>
<tr class="header">
<th>Store-order rank</th>
<th>Add-in</th>
<th>Publisher</th>
<th>Source category</th>
<th>Why it matters to end users</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>8</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200008399?tab=Overview">Tracelight</a></td>
<td><a href="https://app.tracelight.ai">Tracelight</a></td>
<td>Domain Agent [Finance]</td>
<td>Finance-focused assistant for building, reviewing, and error-checking Excel models.</td>
</tr>
<tr class="even">
<td>9</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200006575?tab=Overview">Finance in Microsoft 365 Copilot</a></td>
<td><a href="https://learn.microsoft.com/en-us/copilot/finance/whats-new/excel-overview?WT.mc_id=copilotforfinance_inproduct_helppane#main">Microsoft Corporation</a></td>
<td>Domain Agent [Finance]</td>
<td>Finance Copilot for Excel reconciliation, data preparation, and variance analysis.</td>
</tr>
<tr class="odd">
<td>17</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200008783?tab=Overview">Endex AI</a></td>
<td><a href="https://endex.ai/">Endex</a></td>
<td>Domain Agent [Finance]</td>
<td>Finance-focused copilot for financial modeling, analysis, and workbook citations.</td>
</tr>
<tr class="even">
<td>41</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200009907?tab=Overview">CCH® Tagetik for Excel</a></td>
<td><a href="https://www.wolterskluwer.com/en">Wolters Kluwer</a></td>
<td>Domain Agent [Finance]</td>
<td>Finance reporting and analytics add-in with Ask AI for Excel 365.</td>
</tr>
<tr class="odd">
<td>48</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200009174?tab=Overview">Crunched</a></td>
<td><a href="https://www.usecrunched.com/">Crunched</a></td>
<td>Domain Agent [Finance]</td>
<td>Finance-focused Excel analyst for modeling, mistake detection, and audit trails.</td>
</tr>
<tr class="even">
<td>54</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200009786?tab=Overview">ModelMonkey</a></td>
<td><a href="https://modelmonkey.io/">YJ Squared LLP</a></td>
<td>Domain Agent [Finance]</td>
<td>Excel assistant for financial models, data analysis, formulas, and live data pulls.</td>
</tr>
<tr class="odd">
<td>60</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200007885?tab=Overview">Arborchat</a></td>
<td><a href="https://www.arborchat.ai">Speechless Financial Technology Company Limited</a></td>
<td>Custom Functions</td>
<td>Finance add-in with custom formulas for stock screening and company analysis.</td>
</tr>
<tr class="even">
<td>62</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200010338?tab=Overview">Toolkit</a></td>
<td><a href="https://jointoolkit.com">Toolkit</a></td>
<td>Domain Agent [Finance]</td>
<td>FP&amp;A agent that connects financial data and builds reports, forecasts, and models in Excel.</td>
</tr>
<tr class="odd">
<td>64</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200008952?tab=Overview">TabAI</a></td>
<td><a href="https://www.tabai.io/">New York AI Labs</a></td>
<td>Domain Agent [Finance]</td>
<td>AI analyst for financial modeling, reconciliation, PDF extraction, and workbook updates.</td>
</tr>
<tr class="even">
<td>105</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200008604?tab=Overview">SuiteReport</a></td>
<td><a href="https://suitereport.ai/">SuiteReport</a></td>
<td>Domain Agent [Finance]</td>
<td>NetSuite FP&amp;A add-in that connects NetSuite and bank data to Excel, generates board-ready reports, and uses AI for narratives, forecasts, and natural-language reporting.</td>
</tr>
<tr class="odd">
<td>114</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200007497?tab=Overview">CorpDev.Ai for Excel</a></td>
<td><a href="https://docs.corpdev.ai/corpdev.ai-docs">DealVerse AI LLC</a></td>
<td>Domain Agent [Corporate Development]</td>
<td>M&amp;A research assistant for target screening, analysis, and scoring in Excel.</td>
</tr>
<tr class="even">
<td>146</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200009380?tab=Overview">Octagon</a></td>
<td><a href="https://octagonai.co/docs/guide/agents">Octagon AI Inc.</a></td>
<td>Domain Agent [Finance]</td>
<td>Market-intelligence assistant with specialized agents for public and private company research.</td>
</tr>
</tbody>
</table>
</section>
<section id="data-extraction-cleaning-and-enrichment" class="level3">
<h3 class="anchored" data-anchor-id="data-extraction-cleaning-and-enrichment">Data extraction, cleaning, and enrichment</h3>
<table class="caption-top table">
<thead>
<tr class="header">
<th>Store-order rank</th>
<th>Add-in</th>
<th>Publisher</th>
<th>Source category</th>
<th>Why it matters to end users</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>79</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200003568?tab=Overview">WranglesXL</a></td>
<td><a href="https://wrangles.io">Wrangleworks Incorporated</a></td>
<td>Domain Agent [Data]</td>
<td>Excel data-wrangling add-in for cleaning, standardizing, classifying, extracting, mapping, and automating workbook data with configurable Wrangles and Recipes.</td>
</tr>
<tr class="even">
<td>94</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200008968?tab=Overview">ExtractSimple - AI Data Extraction for Excel</a></td>
<td><a href="https://extractsimple.com/">ExtractSimple.com</a></td>
<td>General Agent</td>
<td>In-Excel extraction add-in that uploads PDFs or images, extracts data into tables, supports custom column instructions and multiple tables or sheets, and works on Windows, macOS, and the web.</td>
</tr>
<tr class="odd">
<td>96</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200008719?tab=Overview">Altavize</a></td>
<td><a href="https://altavize.com">Altavize AI</a></td>
<td>Domain Agent [Data]</td>
<td>Excel text-analysis toolkit built on OpenAI models with structured pre- and post-processing, confidence scoring, categorization, extraction, anonymization, and data cleaning.</td>
</tr>
<tr class="even">
<td>97</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200008537?tab=Overview">Formfit - AI Data Cleaning</a></td>
<td><a href="https://www.formfit.io/">Betterfeed, Inc</a></td>
<td>Domain Agent [Data]</td>
<td>Excel data-cleaning add-in for standardizing names, removing duplicates, extracting structured fields from text, and saving reusable lookup tables.</td>
</tr>
<tr class="odd">
<td>106</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200009134?tab=Overview">Doczen for Excel</a></td>
<td><a href="https://www.doczen.com">DOCZEN</a></td>
<td>Domain Agent [Data]</td>
<td>Document-to-spreadsheet add-in that uploads PDFs or other files, extracts fields into cells or templates, validates results, and writes a changelog.</td>
</tr>
<tr class="even">
<td>107</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200009375?tab=Overview">DataCheckr AI</a></td>
<td><a href="https://datacheckr.ai/">aqaversant.com</a></td>
<td>Domain Agent [Data]</td>
<td>Workbook data-quality checker that scans ranges locally for missing data, duplicates, outliers, and format errors, then explains the issues and suggested fixes.</td>
</tr>
<tr class="odd">
<td>109</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200010381?tab=Overview">Rocket Statements</a></td>
<td><a href="https://www.rocketstatements.com/">Broad Arrow, Inc.</a></td>
<td>Domain Agent [Finance]</td>
<td>Bank-statement PDF add-in that uses AI OCR to extract transactions into Excel, CSV, or JSON and normalize them for bookkeeping.</td>
</tr>
<tr class="even">
<td>111</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200005194?tab=Overview">PromptLoop</a></td>
<td><a href="https://www.promptloop.com">Kiter Inc.</a></td>
<td>Domain Agent [Data]</td>
<td>AI research and enrichment platform with Excel integration for web search, scraping, and custom dataset tasks.</td>
</tr>
</tbody>
</table>
</section>
<section id="analytics-machine-learning-bi-and-forecasting" class="level3">
<h3 class="anchored" data-anchor-id="analytics-machine-learning-bi-and-forecasting">Analytics, machine learning, BI, and forecasting</h3>
<table class="caption-top table">
<thead>
<tr class="header">
<th>Store-order rank</th>
<th>Add-in</th>
<th>Publisher</th>
<th>Source category</th>
<th>Why it matters to end users</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>20</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200000019?tab=Overview">Analytic Solver Data Science</a></td>
<td><a href="https://www.solver.com/">Frontline Systems Inc.</a></td>
<td>Domain Agent [Analytics]</td>
<td>Excel add-in for forecasting, data mining, text mining, and machine-learning model training/scoring, with model deployment support.</td>
</tr>
<tr class="even">
<td>34</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA104379231?tab=Overview">Modern Charts</a></td>
<td><a href="https://www.moderncharts.net">Mzamose Holdings</a></td>
<td>Domain Agent [Analytics]</td>
<td>Chart builder that imports pasted Excel or CSV data and uses goal-driven AI to choose chart types, annotations, summaries, layouts, and branding.</td>
</tr>
<tr class="odd">
<td>36</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA104379638?tab=Overview">Azure Machine Learning</a></td>
<td><a href="https://learn.microsoft.com/en-us/previous-versions/azure/machine-learning/classic/excel-add-in-for-web-services#main">AML Team</a></td>
<td>Domain Agent [Machine Learning]</td>
<td>Legacy Excel add-in for Azure Machine Learning Studio (classic) web services; users paste a service URL and API key, then predict selected input ranges or enable auto-predict.</td>
</tr>
<tr class="even">
<td>55</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200006757?tab=Overview">Coherent Assistant</a></td>
<td><a href="https://docs.coherent.global/">Coherent</a></td>
<td>Domain Agent [Analytics]</td>
<td>Spark-connected Excel add-in that maps workbook inputs and outputs, exposes Xcall for Spark service APIs, and turns spreadsheet logic into production-ready APIs.</td>
</tr>
<tr class="odd">
<td>71</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200006429?tab=Overview">timegpt</a></td>
<td><a href="https://www.nixtla.io/">Nixtla</a></td>
<td>Domain Agent [Forecasting]</td>
<td>Excel forecasting add-in that uses Nixtla’s TimeGPT model for time-series predictions and requires a valid TimeGPT access token.</td>
</tr>
<tr class="even">
<td>90</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200004515?tab=Overview">AutoQL for Excel</a></td>
<td><a href="https://chata.ai/">Chata Technologies</a></td>
<td>Domain Agent [Analytics]</td>
<td>Governed natural-language analytics add-in that requires an AutoQL model, lets users query data in Excel, preview returned results, and insert them into spreadsheets.</td>
</tr>
<tr class="odd">
<td>142</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200009125?tab=Overview">Alchemite for R&amp;D</a></td>
<td><a href="https://docs.intellegens.com/">Intellegens Limited</a></td>
<td>Domain Agent [Machine Learning]</td>
<td>Excel add-in for building Alchemite machine-learning models, making predictions, and updating models from spreadsheet data.</td>
</tr>
</tbody>
</table>
</section>
<section id="audit-compliance-validation-and-governance" class="level3">
<h3 class="anchored" data-anchor-id="audit-compliance-validation-and-governance">Audit, compliance, validation, and governance</h3>
<table class="caption-top table">
<thead>
<tr class="header">
<th>Store-order rank</th>
<th>Add-in</th>
<th>Publisher</th>
<th>Source category</th>
<th>Why it matters to end users</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>37</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200007951?tab=Overview">Copilot Audit</a></td>
<td><a href="https://copilot-audit.com">NEXTBP</a></td>
<td>Domain Agent [Audit]</td>
<td>Audit-focused Excel agent for document extraction, cross-referencing, and validation.</td>
</tr>
<tr class="even">
<td>99</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200009745?tab=Overview">Kolena AI Agents for Excel</a></td>
<td><a href="https://docs.agents.kolena.com">Kolena Inc</a></td>
<td>Domain Agent [Audit]</td>
<td>Template-based Excel agent for document-heavy workflows with AI-powered extraction, validation, source traceability, and confidence scoring.</td>
</tr>
</tbody>
</table>
</section>
<section id="writing-translation-proposal-and-content-specialists" class="level3">
<h3 class="anchored" data-anchor-id="writing-translation-proposal-and-content-specialists">Writing, translation, proposal, and content specialists</h3>
<table class="caption-top table">
<thead>
<tr class="header">
<th>Store-order rank</th>
<th>Add-in</th>
<th>Publisher</th>
<th>Source category</th>
<th>Why it matters to end users</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>39</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200005016?tab=Overview">MTrans for Office</a></td>
<td><a href="https://dist.mtrans.online">株式会社ヒューマンサイエンス</a></td>
<td>Domain Agent [Translation]</td>
<td>One-click Office translation add-in for Word, Excel, PowerPoint, and Outlook with selectable DeepL, Google, Microsoft, and OpenAI engines, plus glossary, style, and OpenAI writing-assistance features.</td>
</tr>
<tr class="even">
<td>85</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200007484?tab=Overview">GovEagle AI</a></td>
<td><a href="https://www.goveagle.com/">Zenfetch</a></td>
<td>Domain Agent [Government Contracting]</td>
<td>GovCon proposal assistant that generates pink-team drafts, compliance and capability matrices, and proposal-ready responses from RFP materials and past-performance content.</td>
</tr>
<tr class="odd">
<td>131</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200007420?tab=Overview">SiftHub: AI Sales Platform</a></td>
<td><a href="https://www.sifthub.io/">SpeedUp Inc</a></td>
<td>Domain Agent [Sales]</td>
<td>Sales and presales assistant for RFPs, RFIs, infosec questionnaires, and draft responses in Excel and Word.</td>
</tr>
</tbody>
</table>
</section>
<section id="industry-specific-specialists" class="level3">
<h3 class="anchored" data-anchor-id="industry-specific-specialists">Industry-specific specialists</h3>
<table class="caption-top table">
<thead>
<tr class="header">
<th>Store-order rank</th>
<th>Add-in</th>
<th>Publisher</th>
<th>Source category</th>
<th>Why it matters to end users</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>77</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200002293?tab=Overview">llama.ai Excel Adapter</a></td>
<td><a href="https://llamasoft.com">Llamasoft, Inc.</a></td>
<td>Domain Agent [Supply Chain]</td>
<td>Supply-chain Excel connector that sends workbook data to the llama.ai enterprise decision platform; requires a valid llama.ai license and API key.</td>
</tr>
<tr class="even">
<td>88</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200009115?tab=Overview">Cascade Intelligence</a></td>
<td><a href="https://usecascade.ai/">Cascade Intelligence</a></td>
<td>Domain Agent [AEC]</td>
<td>AEC-focused opportunity-intelligence add-in that uses AI to surface matched RFPs and project signals, support bid/no-bid decisions, and assist with proposal work.</td>
</tr>
<tr class="odd">
<td>112</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200005386?tab=Overview">Aidy - Machine Learning Excel Add-in for Insurance Professional or Marketer</a></td>
<td><a href="https://aideaye.com/">Aide Aye Applications Inc.</a></td>
<td>Domain Agent [Insurance]</td>
<td>No-code machine-learning Excel add-in for insurance and marketing analytics, including fraud detection, claim reserving, and target list building.</td>
</tr>
<tr class="even">
<td>135</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200008065?tab=Overview">SafeTerm</a></td>
<td><a href="https://safeterm.blob.core.windows.net">ClinBAY Ltd</a></td>
<td>Domain Agent [Medical coding]</td>
<td>Automates initial MedDRA coding for medical terms.</td>
</tr>
<tr class="odd">
<td>140</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200008930?tab=Overview">Sunhat for Office</a></td>
<td><a href="https://help.sunhat.app/en/">Sunhat GmbH</a></td>
<td>Domain Agent [Sustainability]</td>
<td>Sustainability copilot for ESG questionnaires and evidence-backed responses in Office.</td>
</tr>
</tbody>
</table>
<hr>
</section>
</section>
<section id="practical-buying-guide-for-end-users" class="level2">
<h2 class="anchored" data-anchor-id="practical-buying-guide-for-end-users">Practical buying guide for end users</h2>
<section id="start-with-the-job-not-the-model" class="level3">
<h3 class="anchored" data-anchor-id="start-with-the-job-not-the-model">Start with the job, not the model</h3>
<p>A good selection process begins with the work pattern:</p>
<ul>
<li><strong>Ask-and-edit workbook help:</strong> choose a general-purpose Excel AI assistant.</li>
<li><strong>Thousands of similar prompts across rows:</strong> choose a worksheet-function add-in.</li>
<li><strong>Financial models, reconciliations, FP&amp;A, or earnings updates:</strong> choose a finance-specific add-in.</li>
<li><strong>PDFs, images, bank statements, or messy text:</strong> choose extraction and data-cleaning tools.</li>
<li><strong>Forecasting, predictions, or governed BI queries:</strong> choose analytics, ML, or NLQ tools.</li>
<li><strong>RFPs, translations, technical standards, or writing governance:</strong> choose document and content workflow tools.</li>
<li><strong>Industry-specific workflows such as ESG, CRE, insurance, supply chain, or medical coding:</strong> choose a vertical specialist.</li>
</ul>
</section>
<section id="test-with-a-safe-workbook" class="level3">
<h3 class="anchored" data-anchor-id="test-with-a-safe-workbook">Test with a safe workbook</h3>
<p>Before deploying any AI add-in, copy a representative workbook and test five things:</p>
<ol type="1">
<li><strong>Can it understand the workbook structure?</strong></li>
<li><strong>Can it explain what it changed?</strong></li>
<li><strong>Can the user preview changes before applying them?</strong></li>
<li><strong>Does it preserve formulas, formatting, links, and named ranges?</strong></li>
<li><strong>Can results be traced back to sources or prompts?</strong></li>
</ol>
</section>
<section id="check-data-handling-carefully" class="level3">
<h3 class="anchored" data-anchor-id="check-data-handling-carefully">Check data handling carefully</h3>
<p>Excel files often include confidential business data. Users should review whether the add-in sends workbook content to external AI models, whether it supports local or private processing, what permissions it requests, whether it stores prompts or outputs, and whether it supports enterprise controls.</p>
</section>
<section id="expect-overlap" class="level3">
<h3 class="anchored" data-anchor-id="expect-overlap">Expect overlap</h3>
<p>Many add-ins claim similar capabilities: formula generation, data cleanup, summarization, translation, charting, and analysis. The difference is usually in execution: workbook awareness, edit safety, speed, pricing, privacy, integrations, and domain knowledge.</p>
</section>
<section id="keep-humans-in-the-loop" class="level3">
<h3 class="anchored" data-anchor-id="keep-humans-in-the-loop">Keep humans in the loop</h3>
<p>For spreadsheet work, AI should speed up drafting, checking, extraction, and exploration. It should not become the final authority for financial models, compliance outputs, medical coding, tax prep, legal content, or strategic decisions without review.</p>
<hr>
</section>
</section>
<section id="suggested-end-user-shortlist-by-need" class="level2">
<h2 class="anchored" data-anchor-id="suggested-end-user-shortlist-by-need">Suggested end-user shortlist by need</h2>
<table class="caption-top table">
<colgroup>
<col style="width: 33%">
<col style="width: 33%">
<col style="width: 33%">
</colgroup>
<thead>
<tr class="header">
<th>End-user need</th>
<th>Representative add-ins</th>
<th>Why this group fits</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>Everyday Excel help</td>
<td>ChatGPT; Claude by Anthropic for Excel; Shortcut AI; GPT for Excel Word; Formula Bot; griddy; Incant</td>
<td>Best for formulas, cleanup, explanations, charts, and general workbook assistance.</td>
</tr>
<tr class="even">
<td>Formula-style bulk AI</td>
<td>ZKutools Anywhere; GenAI Tools for Excel; Numerous.ai; Spreadsheet AI; Local GPT; Melder; Mindcase; formulaML</td>
<td>Best when the task can be copied down a table or reused inside formulas.</td>
</tr>
<tr class="odd">
<td>Finance and FP&amp;A</td>
<td>Tracelight; Finance in Microsoft 365 Copilot; Endex AI; Arborchat; Crunched; ModelMonkey; Toolkit; TabAI; SuiteReport; Octagon</td>
<td>Best for modeling, variance analysis, reporting, reconciliations, market intelligence, and finance-specific workflows.</td>
</tr>
<tr class="even">
<td>Data extraction and cleaning</td>
<td>ExtractSimple; Rocket Statements; Doczen; Formfit; Altavize; DataCheckr AI; WranglesXL; PromptLoop</td>
<td>Best for PDFs, images, bank statements, unstructured text, duplicate cleanup, and data quality checks.</td>
</tr>
<tr class="odd">
<td>Analytics, BI, ML, and forecasting</td>
<td>Analytic Solver Data Science; Azure Machine Learning; Modern Charts; timegpt; teal ML; AutoQL; Timbr NLQ; Alchemite; Wren AI</td>
<td>Best for structured analytics, predictions, governed data access, forecasting, visualization, and ML workflows.</td>
</tr>
<tr class="even">
<td>RFPs, translation, and documents</td>
<td>MTrans; Document Translator; GovEagle AI; Zen RFP; SiftHub; Acrolinx; Pluralytics</td>
<td>Best when Excel supports a larger document, proposal, translation, or evidence workflow.</td>
</tr>
<tr class="odd">
<td>Audit and compliance</td>
<td>Copilot Audit; Kolena AI Agents; Midship; CRex</td>
<td>Best when evidence, validation, traceability, and compliance review matter.</td>
</tr>
<tr class="even">
<td>Industry-specific workflows</td>
<td>Archer; Aidy; llama.ai Excel Adapter; SafeTerm; Cascade Intelligence; Sunhat for Office</td>
<td>Best when the add-in matches a specific vertical workflow such as CRE, insurance, supply chain, medical coding, AEC, or ESG.</td>
</tr>
</tbody>
</table>
<hr>
</section>
<section id="appendix-complete-add-in-catalog-from-the-supplied-table" class="level2">
<h2 class="anchored" data-anchor-id="appendix-complete-add-in-catalog-from-the-supplied-table">Appendix: complete add-in catalog from the supplied table</h2>
<p>The appendices include every add-in row present in the supplied table, organized into end-user categories. The store-order rank preserves the original ordering from the source table. The “Listed type” column preserves the original type label from the source table, even when the end-user category has been adjusted after verification.</p>
<section id="appendix-1-general-purpose-excel-ai-assistants-56-add-ins" class="level3">
<h3 class="anchored" data-anchor-id="appendix-1-general-purpose-excel-ai-assistants-56-add-ins">Appendix 1: General-purpose Excel AI assistants (56 add-ins)</h3>
<table class="caption-top table">
<thead>
<tr class="header">
<th>Store-order rank</th>
<th>Add-in</th>
<th>Publisher</th>
<th>Listed type</th>
<th>Why it matters to end users</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>1</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200010215?tab=Overview">ChatGPT</a></td>
<td><a href="https://help.openai.com">OpenAI, LLC</a></td>
<td>General Agent</td>
<td>Sidebar assistant for building, analyzing, and updating spreadsheets in natural language.</td>
</tr>
<tr class="even">
<td>2</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200009404?tab=Overview">Claude by Anthropic for Excel</a></td>
<td><a href="https://support.claude.com/en/">Claude by Anthropic for Office</a></td>
<td>General Agent</td>
<td>Sidebar assistant that reads workbooks, explains formulas, and updates sheets with citations.</td>
</tr>
<tr class="odd">
<td>3</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200009152?tab=Overview">Shortcut AI</a></td>
<td><a href="https://shortcut.ai/home">Fundamental Research Labs</a></td>
<td>General Agent</td>
<td>Autonomous Excel assistant for multi-step spreadsheet tasks, including fixing errors and importing PDF data.</td>
</tr>
<tr class="even">
<td>4</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200005502?tab=Overview">GPT for Excel Word</a></td>
<td><a href="https://gptforwork.com">TALARIAN S. à r.l.</a></td>
<td>General Agent</td>
<td>Excel side-panel agent for formulas, formatting, cleanup, pivots, charts, and bulk row-by-row work.</td>
</tr>
<tr class="odd">
<td>6</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200005271?tab=Overview">TwistlyCells AI for Excel</a></td>
<td><a href="https://twistlycells.ai/">Twistly</a></td>
<td>General Agent</td>
<td>ChatGPT-style Excel assistant with tools like AI.ASK, AI.TABLE, AI.FILL, and AI.FORMULA.</td>
</tr>
<tr class="even">
<td>7</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200005669?tab=Overview">Autopilot</a></td>
<td><a href="https://ghostwriter-ai.com/GettingStartedwithGhostwriter.pdf">Smart Barn Technologies</a></td>
<td>General Agent</td>
<td>Conversation-style Office assistant for Word, Excel, and PowerPoint with selectable AI models.</td>
</tr>
<tr class="odd">
<td>10</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200006067?tab=Overview">AI Perfect Assistant for Office</a></td>
<td><a href="https://help.perfectassistant.ai/feedback/">OOO RD17</a></td>
<td>General Agent</td>
<td>Office assistant that drafts text, explains Excel formulas, and translates content.</td>
</tr>
<tr class="even">
<td>11</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200008745?tab=Overview">griddy</a></td>
<td><a href="https://getgriddy.ai/">griddy</a></td>
<td>General Agent</td>
<td>Natural-language Excel assistant for formulas, charts, and cleanup.</td>
</tr>
<tr class="odd">
<td>12</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200005107?tab=Overview">Ghostwriter</a></td>
<td><a href="https://ghostwriter-ai.com/GettingStartedwithGhostwriter.pdf">Smart Barn Technologies</a></td>
<td>General Agent</td>
<td>GPT assistant for Word, Excel, and PowerPoint with workbook/table analysis.</td>
</tr>
<tr class="even">
<td>13</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200001584?tab=Overview">AI-aided Formula Editor</a></td>
<td><a href="https://www.10studio.tech">Matrix Lead</a></td>
<td>General Agent</td>
<td>Workbook-aware chat copilot plus formula generation, explanation, and repair.</td>
</tr>
<tr class="odd">
<td>15</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200006037?tab=Overview">表格AI</a></td>
<td><a href="https://www.10studio.tech">SAS Matrix Lead</a></td>
<td>General Agent</td>
<td>ChatGPT-style Excel assistant that can use workbook ranges and cells in prompts.</td>
</tr>
<tr class="even">
<td>16</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200004935?tab=Overview">Formula Bot - AI in Spreadsheets</a></td>
<td><a href="https://formulabot.com">Formula Bot</a></td>
<td>General Agent</td>
<td>AI data analyst and spreadsheet copilot for formulas, charts, dashboards, and data preparation.</td>
</tr>
<tr class="odd">
<td>18</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200006772?tab=Overview">Sally Suite</a></td>
<td><a href="https://www.sheet-chat.site/en#">深圳市识途管理咨询有限公司</a></td>
<td>General Agent</td>
<td>Agentic office copilot for Excel, Word, and PowerPoint with chat and editing tools.</td>
</tr>
<tr class="even">
<td>21</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200008463?tab=Overview">SheetXAI - AI Agent for Excel</a></td>
<td><a href="https://sheetxai.com/">DDS Media Marketing LLC</a></td>
<td>General Agent</td>
<td>Plain-English assistant for spreadsheet tasks, content generation, and data extraction.</td>
</tr>
<tr class="odd">
<td>23</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200008627?tab=Overview">AI Agent for Excel</a></td>
<td><a href="https://www.10studio.tech">Matrix Lead</a></td>
<td>General Agent</td>
<td>Autonomous Excel agent that suggests edits for modeling, cleanup, analysis, and web search.</td>
</tr>
<tr class="even">
<td>24</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200009854?tab=Overview">Damian - AI agent for excel</a></td>
<td><a href="https://www.trydamian.com">trydamian</a></td>
<td>General Agent</td>
<td>Excel agent for formulas, data cleaning, PDFs/web scraping, and visualizations.</td>
</tr>
<tr class="odd">
<td>26</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200005401?tab=Overview">AI Assistant for Excel</a></td>
<td><a href="https://sonzea.mx">BIN XU</a></td>
<td>General Agent</td>
<td>Excel assistant for data analysis, formula generation, text classification, and translation.</td>
</tr>
<tr class="even">
<td>27</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200006230?tab=Overview">Power GPT</a></td>
<td><a href="https://power-reconcile.tech/">Appsense Inc.</a></td>
<td>General Agent</td>
<td>Excel assistant for formulas, coding, analysis, SQL, VBA, and regex.</td>
</tr>
<tr class="odd">
<td>28</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200008195?tab=Overview">Cassidy</a></td>
<td><a href="https://docs.cassidyai.com">Cassidy Inc.</a></td>
<td>General Agent</td>
<td>Excel and Word automation assistant powered by company data.</td>
</tr>
<tr class="even">
<td>31</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200006007?tab=Overview">R2 Copilot: Private AI for Excel</a></td>
<td><a href="https://r2copilot.ai">Stealth Mail</a></td>
<td>General Agent</td>
<td>Private Excel assistant with encrypted chat and text/formula help.</td>
</tr>
<tr class="odd">
<td>32</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200010173?tab=Overview">Copilot247</a></td>
<td><a href="https://copilot247.com/">Mosquitos Corporation</a></td>
<td>General Agent</td>
<td>Office add-in that analyzes Excel data, explains formulas, and summarizes workbooks.</td>
</tr>
<tr class="even">
<td>38</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200008478?tab=Overview">OfficeAI for Excel</a></td>
<td><a href="https://hub4ai.com/">Hub4AI</a></td>
<td>General Agent</td>
<td>Excel AI assistant with an =AI() formula and workflow automation.</td>
</tr>
<tr class="odd">
<td>40</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200006400?tab=Overview">Incant - AI Magic for Excel</a></td>
<td><a href="https://www.incant.app">Della Tech LLC</a></td>
<td>General Agent</td>
<td>GPT-powered Excel add-in that turns natural-language incantations into formulas and workbook actions such as formatting, charts, pivots, validation rules, sorting, filtering, and sheet changes.</td>
</tr>
<tr class="even">
<td>42</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200008989?tab=Overview">CoreGPT AI for Excel</a></td>
<td><a href="https://coregptapps.com/">Shhapps Ltd.&nbsp;Liability Co.</a></td>
<td>General Agent</td>
<td>ChatGPT-style Excel assistant with sidebar chat and formula-level functions.</td>
</tr>
<tr class="odd">
<td>43</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200008850?tab=Overview">DeepSeek AI for Excel</a></td>
<td><a href="https://actiteq.com">ActiTeQ</a></td>
<td>General Agent</td>
<td>Excel AI assistant for formulas, reports, analysis, and data cleanup.</td>
</tr>
<tr class="even">
<td>45</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200005123?tab=Overview">AHAU 260 for Office Documents</a></td>
<td><a href="https://ahausoftware.atlassian.net/wiki">AHAU SOFTWARE, UNIP, LDA</a></td>
<td>General Agent</td>
<td>Task-pane assistant for Word, Excel, and PowerPoint that links work items and drafts, summarizes, and acts on content.</td>
</tr>
<tr class="odd">
<td>47</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200006180?tab=Overview">AIExcelBot</a></td>
<td><a href="https://aiexcelbot.com">Dream Shake Media LLC</a></td>
<td>General Agent</td>
<td>ChatGPT-powered browser assistant and Excel/Google Sheets add-in for generating formulas from plain English, explaining complex formulas step by step, and writing or explaining VBA.</td>
</tr>
<tr class="even">
<td>49</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200003666?tab=Overview">Strategy-AI for Word, Excel and PowerPoint</a></td>
<td><a href="https://share.hsforms.com">Chinchilla Software Limited</a></td>
<td>General Agent</td>
<td>Office AI assistant that links documents and spreadsheets, then groups, tags, and categorizes content using outcome-based criteria to surface strategic items and opportunities.</td>
</tr>
<tr class="odd">
<td>52</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200009743?tab=Overview">Deckary</a></td>
<td><a href="https://deckary.com/">Deckary</a></td>
<td>General Agent</td>
<td>PowerPoint slide builder that generates consultant-style decks from prompts, links charts to Excel data, and offers brand controls and shortcuts.</td>
</tr>
<tr class="even">
<td>58</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200008230?tab=Overview">AI Mind Map Generator</a></td>
<td><a href="https://www.livepolls.app">NO FRIENDS LTD</a></td>
<td>General Agent</td>
<td>ChatGPT-based Office add-in that generates editable mind maps from text prompts, PDFs, videos, and web pages; available for Excel, PowerPoint, and Word.</td>
</tr>
<tr class="odd">
<td>61</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200005333?tab=Overview">FormulAI: AI for spreadsheets</a></td>
<td><a href="https://www.formulai.xyz/#">Mosaique, LLC</a></td>
<td>General Agent</td>
<td>Spreadsheet assistant for formula explanation, formula building, data queries, and simulation.</td>
</tr>
<tr class="even">
<td>69</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200004894?tab=Overview">BrainiacHelper</a></td>
<td><a href="https://brainiachelperstorage.z13.web.core.windows.net">Moetsi</a></td>
<td>General Agent</td>
<td>Task-pane add-in that uses an OpenAI API key to generate completions and return the result in Excel.</td>
</tr>
<tr class="odd">
<td>72</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200007379?tab=Overview">ChatLite</a></td>
<td><a href="https://exvtech.com/index.html">EXVTECH LLC</a></td>
<td>General Agent</td>
<td>Pay-as-you-go chat assistant for Excel, PowerPoint, and Word with 300+ models from OpenAI, Anthropic, Google, Perplexity, DeepSeek, and OpenRouter; conversation history stays local.</td>
</tr>
<tr class="even">
<td>74</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200007874?tab=Overview">AI Essay Writer</a></td>
<td><a href="https://www.livepolls.app">NO FRIENDS LTD</a></td>
<td>General Agent</td>
<td>Office add-in for drafting, outlining, expanding, and editing long-form essays; the listing also says it can read and make changes to the current document.</td>
</tr>
<tr class="odd">
<td>75</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200008703?tab=Overview">Image generator : Saifs AI</a></td>
<td><a href="https://saifytech.com/index">Saifs AI</a></td>
<td>General Agent</td>
<td>Office add-in that turns text prompts into custom, high-resolution images; the listing says it can read and make changes to the document and requires a subscription after two free tokens.</td>
</tr>
<tr class="even">
<td>76</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200010155?tab=Overview">Lato in Excel</a></td>
<td><a href="https://www.latotec.io/">Lato Technologies</a></td>
<td>General Agent</td>
<td>Excel agent for building models, fixing errors, formatting data, and answering questions on workbook data.</td>
</tr>
<tr class="odd">
<td>80</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200007165?tab=Overview">Nobie</a></td>
<td><a href="https://nobie.com">Nobie</a></td>
<td>General Agent</td>
<td>AI co-author for Excel models, scenarios, and audit trails.</td>
</tr>
<tr class="even">
<td>83</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200007518?tab=Overview">BatchGPT</a></td>
<td><a href="https://aifficientools.com">SharpNWise Development</a></td>
<td>General Agent</td>
<td>Batch prompt add-in that applies one prompt across hundreds or thousands of cells, with options for reasoning, online search, prompt reuse, and automatic range detection.</td>
</tr>
<tr class="odd">
<td>89</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200005565?tab=Overview">Array Assistant</a></td>
<td><a href="https://arrayassistant.ai">Array Assistant</a></td>
<td>General Agent</td>
<td>Taskpane assistant that uses AI to generate formulas, extract data, summarize text, clean data, build automations, and design VBA code.</td>
</tr>
<tr class="even">
<td>91</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200004483?tab=Overview">Tersho: AI formulas</a></td>
<td><a href="https://www.tersho.com">Tersho</a></td>
<td>General Agent</td>
<td>Formula assistant that turns plain-English requests into Excel formulas and explains selected formulas in English.</td>
</tr>
<tr class="odd">
<td>93</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200008526?tab=Overview">HyperPerfect</a></td>
<td><a href="https://help.hyperperfect.ai">HyperPerfect.</a></td>
<td>General Agent</td>
<td>Real-time workbook assistant that builds analyses, cleans data, fixes errors, applies formatting, and makes iterative edits inside the spreadsheet.</td>
</tr>
<tr class="even">
<td>95</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200010247?tab=Overview">Skywork AI for Excel – Analyze Data, Generate Charts &amp; Automate Work</a></td>
<td><a href="https://skywork.ai/">SKYWORK AI</a></td>
<td>General Agent</td>
<td>Natural-language Excel copilot for data analysis, chart generation, summaries, and routine spreadsheet automation.</td>
</tr>
<tr class="odd">
<td>98</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200008601?tab=Overview">Fina</a></td>
<td><a href="https://fina.charger.dev/">Charger Inc.</a></td>
<td>General Agent</td>
<td>Plain-English Excel copilot for spreadsheet work, analysis, custom formulas, and data visualization; offers free and Pro plans.</td>
</tr>
<tr class="even">
<td>100</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200005429?tab=Overview">FormulaIntern</a></td>
<td><a href="https://www.formulaintern.com">FormulaIntern</a></td>
<td>General Agent</td>
<td>Sidebar formula generator and explainer with translation, cleansing, summarization, and company lookup tools.</td>
</tr>
<tr class="odd">
<td>101</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200009621?tab=Overview">Pipedreamer AI</a></td>
<td><a href="https://pipedreamer.ai">Pipedreamer, Inc</a></td>
<td>General Agent</td>
<td>Prompt-driven Excel agent that writes formulas, runs auditable scripts/macros, and automates repetitive workbook work.</td>
</tr>
<tr class="even">
<td>102</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200009917?tab=Overview">xCell-On</a></td>
<td><a href="https://www.xcell-on.com">xCell-On</a></td>
<td>General Agent</td>
<td>Conversational Excel assistant that uses multiple AI models for data analysis, formula generation, and workflow automation.</td>
</tr>
<tr class="odd">
<td>108</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200010364?tab=Overview">AI Tools For Excel</a></td>
<td><a href="https://everestwebdeals.co/en/">Everest Web Deals LLC</a></td>
<td>General Agent</td>
<td>Preview-first Excel assistant for duplicate detection, formatting cleanup, formula generation, and error repair.</td>
</tr>
<tr class="even">
<td>110</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200005105?tab=Overview">Alphasheet (data processing in one sentence)</a></td>
<td><a href="https://doc.felo.me">Sparticle株式会社</a></td>
<td>General Agent</td>
<td>GPT-based Excel add-in that processes spreadsheet data from one-sentence prompts, such as extraction and transformation tasks.</td>
</tr>
<tr class="odd">
<td>118</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200010093?tab=Overview">Sally Suite (中国)</a></td>
<td><a href="https://www.sallybot.cn/#">深圳市识途管理咨询有限公司</a></td>
<td>General Agent</td>
<td>Office copilot centered on Word, with Excel analysis and PowerPoint creation.</td>
</tr>
<tr class="even">
<td>119</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200010102?tab=Overview">o11 For Excel</a></td>
<td><a href="https://o11.ai/">o11</a></td>
<td>General Agent</td>
<td>Natural-language Excel assistant for formulas, analysis, visualization, and error checks.</td>
</tr>
<tr class="odd">
<td>130</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200007360?tab=Overview">Devize Bot for Excel</a></td>
<td><a href="https://www.devize.com">Devize</a></td>
<td>General Agent</td>
<td>Workbook assistant that answers questions, autofills formulas, and creates basic charts.</td>
</tr>
<tr class="even">
<td>132</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200007495?tab=Overview">AI Sheets</a></td>
<td><a href="https://ai-sheets.airdesign.ai/">GALAPAGOS</a></td>
<td>General Agent</td>
<td>Spreadsheet AI toolkit with reusable templates for Excel and Google Sheets, using GPT, Claude, and Gemini for common workflow tasks.</td>
</tr>
<tr class="odd">
<td>137</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200008725?tab=Overview">SiYan AI</a></td>
<td><a href="https://siyan.cloud">佛山思延智能信息技术有限公司</a></td>
<td>General Agent</td>
<td>Office AI assistant across Word, Excel, PowerPoint, and Outlook.</td>
</tr>
<tr class="even">
<td>139</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200008823?tab=Overview">Bluebox</a></td>
<td><a href="https://blue-box.co">The Bluebox</a></td>
<td>General Agent</td>
<td>Excel assistant for data cleanup, formula writing, and finding spreadsheet answers.</td>
</tr>
<tr class="odd">
<td>141</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200009094?tab=Overview">HeyGPT</a></td>
<td><a href="https://heygpt.kinnovatech.com/#home">Kinnovatech</a></td>
<td>General Agent</td>
<td>Excel assistant for generating, summarizing, translating, and analyzing spreadsheet data.</td>
</tr>
<tr class="even">
<td>144</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200009235?tab=Overview">Ira Autopilot</a></td>
<td><a href="https://iraskills.ai/">Deven U Pandey</a></td>
<td>General Agent</td>
<td>Excel chatbot for formulas, VBA, and other spreadsheet automation tasks.</td>
</tr>
</tbody>
</table>
</section>
<section id="appendix-2-ai-worksheet-functions-and-formula-tools-12-add-ins" class="level3">
<h3 class="anchored" data-anchor-id="appendix-2-ai-worksheet-functions-and-formula-tools-12-add-ins">Appendix 2: AI worksheet functions and formula tools (12 add-ins)</h3>
<table class="caption-top table">
<thead>
<tr class="header">
<th>Store-order rank</th>
<th>Add-in</th>
<th>Publisher</th>
<th>Listed type</th>
<th>Why it matters to end users</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>5</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200009190?tab=Overview">ZKutools Anywhere for Excel</a></td>
<td><a href="https://www.extendoffice.com/">ExtendOffice Ltd</a></td>
<td>Custom Functions</td>
<td>Adds 28 AI-powered Excel functions for analysis, extraction, translation, and formula generation.</td>
</tr>
<tr class="even">
<td>14</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200006231?tab=Overview">GenAI Tools for Excel</a></td>
<td><a href="https://www.busybee-apps.jp">BusyBee, Inc</a></td>
<td>Custom Functions</td>
<td>Five AI worksheet functions for ChatGPT, Gemini, and Claude; requires API keys.</td>
</tr>
<tr class="odd">
<td>19</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200005281?tab=Overview">Numerous.ai</a></td>
<td><a href="https://numerous.ai">NUMEROUSAI, INC</a></td>
<td>Custom Functions</td>
<td>Provides =AI and related worksheet functions for bulk text and formula tasks.</td>
</tr>
<tr class="even">
<td>22</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200006009?tab=Overview">Spreadsheet AI</a></td>
<td><a href="https://www.10studio.tech">SAS Matrix Lead</a></td>
<td>Custom Functions</td>
<td>Offers 17 AI spreadsheet functions plus a chat copilot.</td>
</tr>
<tr class="odd">
<td>30</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200008555?tab=Overview">GenderAPI.io - Identify Gender from Names in Excel</a></td>
<td><a href="https://www.genderapi.io/">Ozan Soft</a></td>
<td>Custom Functions</td>
<td>Excel formulas for gender detection from names, emails, and usernames with country and confidence data.</td>
</tr>
<tr class="even">
<td>44</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200006524?tab=Overview">SheetSavvy AI</a></td>
<td><a href="https://www.sheetsavvyai.com/">AI Hunt</a></td>
<td>Custom Functions</td>
<td>Excel add-in with AI formulas like =SSAI() for text, tagging, and summarizing.</td>
</tr>
<tr class="odd">
<td>46</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200007427?tab=Overview">Local GPT for Excel</a></td>
<td><a href="https://www.boardflare.com/">Boardflare</a></td>
<td>Custom Functions</td>
<td>Local custom function for private on-device AI in Excel.</td>
</tr>
<tr class="even">
<td>57</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200008000?tab=Overview">nele.ai for Word &amp; Excel</a></td>
<td><a href="https://www.nele.ai/en">GAL Digital GmbH</a></td>
<td>Custom Functions</td>
<td>Adds NELE.PROMPT, NELE.CLASSIFY, NELE.EXTRACT, NELE.SUMMARIZE, and NELE.TRANSLATE in Excel.</td>
</tr>
<tr class="odd">
<td>68</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200008575?tab=Overview">Melder - AI for Excel</a></td>
<td><a href="https://melder.io/">EchoSend Inc</a></td>
<td>Custom Functions</td>
<td>AI worksheet functions such as M.GEN, M.EXTRACT, and M.CATEGORIZE, plus document upload and per-answer citations.</td>
</tr>
<tr class="even">
<td>87</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200007940?tab=Overview">Mindcase - Automate tasks with ChatGPT - AI Assistant for Research and Web Scraping</a></td>
<td><a href="https://www.mindcase.co">Mindcase Technologies</a></td>
<td>Custom Functions</td>
<td>Excel functions such as ASK, ASK_WEB, EXTRACT, COMPANY_DATA, and YAHOO_FINANCE for web search, scraping, enrichment, and structured data extraction.</td>
</tr>
<tr class="odd">
<td>120</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200010134?tab=Overview">xllify - create and deploy Excel custom functions with AI</a></td>
<td><a href="https://firebase.google.com/">Lexvica Limited</a></td>
<td>Custom Functions</td>
<td>Builds and deploys Excel custom functions from prompts or code.</td>
</tr>
<tr class="even">
<td>145</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200009298?tab=Overview">formulaML</a></td>
<td><a href="https://formulaml.com/">Sumpa Labs</a></td>
<td>Custom Functions</td>
<td>Provides 70+ ML worksheet functions, including =ML.REGRESSION.LINEAR(), for forecasting and classification.</td>
</tr>
</tbody>
</table>
</section>
<section id="appendix-3-finance-accounting-and-business-workflow-specialists-38-add-ins" class="level3">
<h3 class="anchored" data-anchor-id="appendix-3-finance-accounting-and-business-workflow-specialists-38-add-ins">Appendix 3: Finance, accounting, and business workflow specialists (38 add-ins)</h3>
<table class="caption-top table">
<thead>
<tr class="header">
<th>Store-order rank</th>
<th>Add-in</th>
<th>Publisher</th>
<th>Listed type</th>
<th>Why it matters to end users</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>8</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200008399?tab=Overview">Tracelight</a></td>
<td><a href="https://app.tracelight.ai">Tracelight</a></td>
<td>Domain Agent [Finance]</td>
<td>Finance-focused assistant for building, reviewing, and error-checking Excel models.</td>
</tr>
<tr class="even">
<td>9</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200006575?tab=Overview">Finance in Microsoft 365 Copilot</a></td>
<td><a href="https://learn.microsoft.com/en-us/copilot/finance/whats-new/excel-overview?WT.mc_id=copilotforfinance_inproduct_helppane#main">Microsoft Corporation</a></td>
<td>Domain Agent [Finance]</td>
<td>Finance Copilot for Excel reconciliation, data preparation, and variance analysis.</td>
</tr>
<tr class="odd">
<td>17</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200008783?tab=Overview">Endex AI</a></td>
<td><a href="https://endex.ai/">Endex</a></td>
<td>Domain Agent [Finance]</td>
<td>Finance-focused copilot for financial modeling, analysis, and workbook citations.</td>
</tr>
<tr class="even">
<td>25</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200009458?tab=Overview">Billables AI</a></td>
<td><a href="https://help.billables.ai/#main-content">Billables AI</a></td>
<td>Domain Agent [professional services]</td>
<td>Tracks work and drafts billable time entries for lawyers, accountants, and consultants.</td>
</tr>
<tr class="odd">
<td>29</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200009198?tab=Overview">EBITDAI</a></td>
<td><a href="https://ebitdai.co">EBITDAI LLC</a></td>
<td>Domain Agent [Finance]</td>
<td>Finance copilot for building and updating investor-grade financial models in Excel.</td>
</tr>
<tr class="even">
<td>33</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200008658?tab=Overview">ElyxAI - AI Agent for Excel</a></td>
<td><a href="https://getelyxai.com/">TCD Apps</a></td>
<td>Domain Agent [Finance]</td>
<td>Finance-focused agent that executes multi-step Excel workflows and supports =ELYX.AI() formulas.</td>
</tr>
<tr class="odd">
<td>41</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200009907?tab=Overview">CCH® Tagetik for Excel</a></td>
<td><a href="https://www.wolterskluwer.com/en">Wolters Kluwer</a></td>
<td>Domain Agent [Finance]</td>
<td>Finance reporting and analytics add-in with Ask AI for Excel 365.</td>
</tr>
<tr class="even">
<td>48</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200009174?tab=Overview">Crunched</a></td>
<td><a href="https://www.usecrunched.com/">Crunched</a></td>
<td>Domain Agent [Finance]</td>
<td>Finance-focused Excel analyst for modeling, mistake detection, and audit trails.</td>
</tr>
<tr class="odd">
<td>51</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200008734?tab=Overview">Elkar - AI analyst for Excel</a></td>
<td><a href="https://sheets.elkar.co">Breezy AI</a></td>
<td>Domain Agent [Finance]</td>
<td>Finance-focused Excel analyst for models, formula help, PDF extraction, charts, and dashboards.</td>
</tr>
<tr class="even">
<td>54</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200009786?tab=Overview">ModelMonkey</a></td>
<td><a href="https://modelmonkey.io/">YJ Squared LLP</a></td>
<td>Domain Agent [Finance]</td>
<td>Excel assistant for financial models, data analysis, formulas, and live data pulls.</td>
</tr>
<tr class="odd">
<td>56</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200008458?tab=Overview">AnalystPro Tracer</a></td>
<td><a href="https://www.analystpro.ai/">AnalystPro</a></td>
<td>Domain Agent [Finance]</td>
<td>Finance-focused model tracing, visualisation, and audit tool for spreadsheet models.</td>
</tr>
<tr class="even">
<td>59</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200007451?tab=Overview">Finnex - UI for AI in Excel</a></td>
<td><a href="https://www.finnex.ai">Finnex AI</a></td>
<td>Domain Agent [Finance]</td>
<td>Chat-based accounting assistant for invoices, financial reports, and Xero-linked analysis in Excel.</td>
</tr>
<tr class="odd">
<td>60</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200007885?tab=Overview">Arborchat</a></td>
<td><a href="https://www.arborchat.ai">Speechless Financial Technology Company Limited</a></td>
<td>Custom Functions</td>
<td>Finance add-in with custom formulas for stock screening and company analysis.</td>
</tr>
<tr class="even">
<td>62</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200010338?tab=Overview">Toolkit</a></td>
<td><a href="https://jointoolkit.com">Toolkit</a></td>
<td>Domain Agent [Finance]</td>
<td>FP&amp;A agent that connects financial data and builds reports, forecasts, and models in Excel.</td>
</tr>
<tr class="odd">
<td>64</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200008952?tab=Overview">TabAI</a></td>
<td><a href="https://www.tabai.io/">New York AI Labs</a></td>
<td>Domain Agent [Finance]</td>
<td>AI analyst for financial modeling, reconciliation, PDF extraction, and workbook updates.</td>
</tr>
<tr class="even">
<td>67</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200009779?tab=Overview">Grid</a></td>
<td><a href="https://lawrenceztang.com">Accruely</a></td>
<td>Domain Agent [Finance]</td>
<td>Accountant-focused Excel assistant for journal entries, accruals, reconciliations, and variance analysis.</td>
</tr>
<tr class="odd">
<td>73</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200007617?tab=Overview">Ombud Ombuddy for Excel</a></td>
<td><a href="https://www.ombud.com/">Ombud Inc.</a></td>
<td>Domain Agent [Revenue Operations]</td>
<td>Excel-facing RevOps copilot that searches Ombud content, reuses approved material, and helps format, structure, and populate documents and spreadsheets.</td>
</tr>
<tr class="even">
<td>78</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200009617?tab=Overview">Superjoin for Finance</a></td>
<td><a href="https://docs.superjoin.ai/introduction">Weekday Operation Vacation Private Limited</a></td>
<td>Domain Agent [Finance]</td>
<td>Finance-focused spreadsheet assistant for modeling, data analysis, dashboards, and automation.</td>
</tr>
<tr class="odd">
<td>81</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200009058?tab=Overview">Additive AI</a></td>
<td><a href="https://docs.additive.ai/en/">Additive AI</a></td>
<td>Domain Agent [Tax]</td>
<td>Tax document-processing add-in for extracting footnotes and moving results into workpapers.</td>
</tr>
<tr class="even">
<td>84</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200006464?tab=Overview">Archer</a></td>
<td><a href="https://www.help.archer.re/#main-content">Archer RE</a></td>
<td>Domain Agent [Commercial Real Estate]</td>
<td>CRE underwriting add-in that parses T12s and rent rolls, analyzes rent/expense/sale comps, inserts Archer templates, and syncs work to Archer’s cloud platform.</td>
</tr>
<tr class="odd">
<td>86</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200009379?tab=Overview">excelence-ai</a></td>
<td><a href="https://generativex.com/">GenerativeX inc,</a></td>
<td>Domain Agent [Finance]</td>
<td>Native Excel AI agent focused on financial and accounting workflows, with workbook editing, data extraction, reconciliation, reporting, and charting from chat commands.</td>
</tr>
<tr class="even">
<td>92</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200009058?tab=Overview">Additive AI</a></td>
<td><a href="https://docs.additive.ai/en/">Additive AI</a></td>
<td>Domain Agent [Finance]</td>
<td>Tax-document extraction add-in for accounting workflows and workpapers.</td>
</tr>
<tr class="odd">
<td>103</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200007377?tab=Overview">Filot</a></td>
<td><a href="https://www.filot.ai/">Filot AI</a></td>
<td>Domain Agent [Finance]</td>
<td>Capital-markets copilot for model creation, earnings updates, and source-traced data extraction with auditability.</td>
</tr>
<tr class="even">
<td>104</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200007787?tab=Overview">Apprentice AI</a></td>
<td><a href="https://workflow-executor.nabzai.com">Nabz AI</a></td>
<td>Domain Agent [Accounting]</td>
<td>Controller-focused month-end close assistant that automates repetitive close tasks and preserves traceability.</td>
</tr>
<tr class="odd">
<td>105</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200008604?tab=Overview">SuiteReport</a></td>
<td><a href="https://suitereport.ai/">SuiteReport</a></td>
<td>Domain Agent [Finance]</td>
<td>NetSuite FP&amp;A add-in that connects NetSuite and bank data to Excel, generates board-ready reports, and uses AI for narratives, forecasts, and natural-language reporting.</td>
</tr>
<tr class="even">
<td>113</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200006106?tab=Overview">Sortino</a></td>
<td><a href="https://www.sortinohq.com">Sortino, Inc.</a></td>
<td>Domain Agent [Finance]</td>
<td>Finance assistant that builds linked comps, DCFs, and 3-statement models.</td>
</tr>
<tr class="odd">
<td>114</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200007497?tab=Overview">CorpDev.Ai for Excel</a></td>
<td><a href="https://docs.corpdev.ai/corpdev.ai-docs">DealVerse AI LLC</a></td>
<td>Domain Agent [Corporate Development]</td>
<td>M&amp;A research assistant for target screening, analysis, and scoring in Excel.</td>
</tr>
<tr class="even">
<td>116</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200009578?tab=Overview">Form15 AI</a></td>
<td><a href="https://form15.ai/">Form15 AI</a></td>
<td>Domain Agent [Tax]</td>
<td>Tax-prep assistant for categorization, reconciliation, and tax research.</td>
</tr>
<tr class="odd">
<td>117</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200009814?tab=Overview">Billow AI</a></td>
<td><a href="https://thebillow.ai/">Billow Labs Inc</a></td>
<td>Domain Agent [Biotech Finance]</td>
<td>Biotech finance copilot for rNPV/DCF modeling, accruals, and scenario planning.</td>
</tr>
<tr class="even">
<td>123</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200005962?tab=Overview">Smartbooks.ai</a></td>
<td><a href="https://smartbooks.ai/webinar/">Smartbooks.ai</a></td>
<td>Domain Agent [Finance]</td>
<td>Finance software for automated management reporting, planning, and consolidation.</td>
</tr>
<tr class="odd">
<td>124</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200006298?tab=Overview">Waverly AI</a></td>
<td><a href="https://getwaverly.ai">Waverly</a></td>
<td>Domain Agent [Finance]</td>
<td>Finance copilot for diligence, data exploration, and Excel-to-PPT workflows.</td>
</tr>
<tr class="even">
<td>128</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200007313?tab=Overview">Structize AI</a></td>
<td><a href="https://docs.structize.com">Structize AI</a></td>
<td>Domain Agent [Finance]</td>
<td>Finance workflow assistant that extracts data from documents and cross-references it into Excel workbooks using LLMs.</td>
</tr>
<tr class="odd">
<td>129</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200007329?tab=Overview">Tenkay Model Updater</a></td>
<td><a href="https://tenkay.ai">Tenkay Corporation</a></td>
<td>Domain Agent [Finance]</td>
<td>Equity-research model updater that ingests earnings releases and refreshes public-company financial models in Excel.</td>
</tr>
<tr class="even">
<td>133</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200007590?tab=Overview">Brokvisor</a></td>
<td><a href="https://brokvisor.com/">Brokvisor</a></td>
<td>Domain Agent [Finance]</td>
<td>Finance assistant for portfolio analysis, tracking, and advisor workflows from Excel.</td>
</tr>
<tr class="odd">
<td>136</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200008683?tab=Overview">NoNighter Copilot</a></td>
<td><a href="https://nonighter.com">NoNighter Inc</a></td>
<td>Domain Agent [Finance]</td>
<td>Finance copilot for Wall Street modeling and analysis.</td>
</tr>
<tr class="even">
<td>138</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200008763?tab=Overview">Condour for Excel</a></td>
<td><a href="https://condour-excel-addin-server-d0dda6bha7dhdsfp.eastus2-01.azurewebsites.net">Sailvest</a></td>
<td>Domain Agent [Finance]</td>
<td>Financial-services copilot that connects Excel to Condour and pulls data from PDFs.</td>
</tr>
<tr class="odd">
<td>143</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200009168?tab=Overview">Alphagen for Excel and Word</a></td>
<td><a href="https://starlightai.ai">Starlight Labs Ltd</a></td>
<td>Domain Agent [Finance]</td>
<td>Word and Excel assistant for private markets, fund, and trust workflows, especially RFPs and DDQs.</td>
</tr>
<tr class="even">
<td>146</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200009380?tab=Overview">Octagon</a></td>
<td><a href="https://octagonai.co/docs/guide/agents">Octagon AI Inc.</a></td>
<td>Domain Agent [Finance]</td>
<td>Market-intelligence assistant with specialized agents for public and private company research.</td>
</tr>
</tbody>
</table>
</section>
<section id="appendix-4-data-extraction-cleaning-and-enrichment-9-add-ins" class="level3">
<h3 class="anchored" data-anchor-id="appendix-4-data-extraction-cleaning-and-enrichment-9-add-ins">Appendix 4: Data extraction, cleaning, and enrichment (9 add-ins)</h3>
<table class="caption-top table">
<thead>
<tr class="header">
<th>Store-order rank</th>
<th>Add-in</th>
<th>Publisher</th>
<th>Listed type</th>
<th>Why it matters to end users</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>79</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200003568?tab=Overview">WranglesXL</a></td>
<td><a href="https://wrangles.io">Wrangleworks Incorporated</a></td>
<td>Domain Agent [Data]</td>
<td>Excel data-wrangling add-in for cleaning, standardizing, classifying, extracting, mapping, and automating workbook data with configurable Wrangles and Recipes.</td>
</tr>
<tr class="even">
<td>94</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200008968?tab=Overview">ExtractSimple - AI Data Extraction for Excel</a></td>
<td><a href="https://extractsimple.com/">ExtractSimple.com</a></td>
<td>General Agent</td>
<td>In-Excel extraction add-in that uploads PDFs or images, extracts data into tables, supports custom column instructions and multiple tables or sheets, and works on Windows, macOS, and the web.</td>
</tr>
<tr class="odd">
<td>96</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200008719?tab=Overview">Altavize</a></td>
<td><a href="https://altavize.com">Altavize AI</a></td>
<td>Domain Agent [Data]</td>
<td>Excel text-analysis toolkit built on OpenAI models with structured pre- and post-processing, confidence scoring, categorization, extraction, anonymization, and data cleaning.</td>
</tr>
<tr class="even">
<td>97</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200008537?tab=Overview">Formfit - AI Data Cleaning</a></td>
<td><a href="https://www.formfit.io/">Betterfeed, Inc</a></td>
<td>Domain Agent [Data]</td>
<td>Excel data-cleaning add-in for standardizing names, removing duplicates, extracting structured fields from text, and saving reusable lookup tables.</td>
</tr>
<tr class="odd">
<td>106</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200009134?tab=Overview">Doczen for Excel</a></td>
<td><a href="https://www.doczen.com">DOCZEN</a></td>
<td>Domain Agent [Data]</td>
<td>Document-to-spreadsheet add-in that uploads PDFs or other files, extracts fields into cells or templates, validates results, and writes a changelog.</td>
</tr>
<tr class="even">
<td>107</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200009375?tab=Overview">DataCheckr AI</a></td>
<td><a href="https://datacheckr.ai/">aqaversant.com</a></td>
<td>Domain Agent [Data]</td>
<td>Workbook data-quality checker that scans ranges locally for missing data, duplicates, outliers, and format errors, then explains the issues and suggested fixes.</td>
</tr>
<tr class="odd">
<td>109</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200010381?tab=Overview">Rocket Statements</a></td>
<td><a href="https://www.rocketstatements.com/">Broad Arrow, Inc.</a></td>
<td>Domain Agent [Finance]</td>
<td>Bank-statement PDF add-in that uses AI OCR to extract transactions into Excel, CSV, or JSON and normalize them for bookkeeping.</td>
</tr>
<tr class="even">
<td>111</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200005194?tab=Overview">PromptLoop</a></td>
<td><a href="https://www.promptloop.com">Kiter Inc.</a></td>
<td>Domain Agent [Data]</td>
<td>AI research and enrichment platform with Excel integration for web search, scraping, and custom dataset tasks.</td>
</tr>
<tr class="odd">
<td>126</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200006977?tab=Overview">Verodat</a></td>
<td><a href="https://help.verodat.io/en/">Verodat</a></td>
<td>Domain Agent [Data]</td>
<td>Excel connector for Verodat’s AI-ready data layer that brings governed data and Copilot-style workflows into workbooks.</td>
</tr>
</tbody>
</table>
</section>
<section id="appendix-5-analytics-machine-learning-bi-and-forecasting-12-add-ins" class="level3">
<h3 class="anchored" data-anchor-id="appendix-5-analytics-machine-learning-bi-and-forecasting-12-add-ins">Appendix 5: Analytics, machine learning, BI, and forecasting (12 add-ins)</h3>
<table class="caption-top table">
<thead>
<tr class="header">
<th>Store-order rank</th>
<th>Add-in</th>
<th>Publisher</th>
<th>Listed type</th>
<th>Why it matters to end users</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>20</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200000019?tab=Overview">Analytic Solver Data Science</a></td>
<td><a href="https://www.solver.com/">Frontline Systems Inc.</a></td>
<td>Domain Agent [Analytics]</td>
<td>Excel add-in for forecasting, data mining, text mining, and machine-learning model training/scoring, with model deployment support.</td>
</tr>
<tr class="even">
<td>34</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA104379231?tab=Overview">Modern Charts</a></td>
<td><a href="https://www.moderncharts.net">Mzamose Holdings</a></td>
<td>Domain Agent [Analytics]</td>
<td>Chart builder that imports pasted Excel or CSV data and uses goal-driven AI to choose chart types, annotations, summaries, layouts, and branding.</td>
</tr>
<tr class="odd">
<td>36</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA104379638?tab=Overview">Azure Machine Learning</a></td>
<td><a href="https://learn.microsoft.com/en-us/previous-versions/azure/machine-learning/classic/excel-add-in-for-web-services#main">AML Team</a></td>
<td>Domain Agent [Machine Learning]</td>
<td>Legacy Excel add-in for Azure Machine Learning Studio (classic) web services; users paste a service URL and API key, then predict selected input ranges or enable auto-predict.</td>
</tr>
<tr class="even">
<td>53</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200009124?tab=Overview">Opti’ Easy Data Analysis Tool</a></td>
<td><a href="https://lequeux-thomas.com/">Thomas LEQUEUX Consulting</a></td>
<td>Domain Agent [Monitoring and Evaluation]</td>
<td>Excel add-in for KoboToolbox, ODK, XLSForm, and Google Sheets exports that generates tables, AI interpretations, executive summaries, and narrative reports with OptiBot.</td>
</tr>
<tr class="odd">
<td>55</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200006757?tab=Overview">Coherent Assistant</a></td>
<td><a href="https://docs.coherent.global/">Coherent</a></td>
<td>Domain Agent [Analytics]</td>
<td>Spark-connected Excel add-in that maps workbook inputs and outputs, exposes Xcall for Spark service APIs, and turns spreadsheet logic into production-ready APIs.</td>
</tr>
<tr class="even">
<td>71</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200006429?tab=Overview">timegpt</a></td>
<td><a href="https://www.nixtla.io/">Nixtla</a></td>
<td>Domain Agent [Forecasting]</td>
<td>Excel forecasting add-in that uses Nixtla’s TimeGPT model for time-series predictions and requires a valid TimeGPT access token.</td>
</tr>
<tr class="odd">
<td>82</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200004285?tab=Overview">teal ML</a></td>
<td><a href="https://tealml.atlassian.net">teal ML</a></td>
<td>Domain Agent [Forecasting]</td>
<td>Excel forecasting add-in that creates forecasts from workbook data in two clicks for business users.</td>
</tr>
<tr class="even">
<td>90</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200004515?tab=Overview">AutoQL for Excel</a></td>
<td><a href="https://chata.ai/">Chata Technologies</a></td>
<td>Domain Agent [Analytics]</td>
<td>Governed natural-language analytics add-in that requires an AutoQL model, lets users query data in Excel, preview returned results, and insert them into spreadsheets.</td>
</tr>
<tr class="odd">
<td>122</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200005737?tab=Overview">Thinkdeeply AI Inference Assistant</a></td>
<td><a href="https://marketplace.thinkdeeply.com/">Thinkdeeply</a></td>
<td>Domain Agent [Machine Learning]</td>
<td>No-code Excel add-in for model inference, classification, entity extraction, normalization, and deduplication.</td>
</tr>
<tr class="even">
<td>127</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200007192?tab=Overview">Wren AI for Excel</a></td>
<td><a href="https://getwren.ai/genbi?utm_source=web&amp;utm_medium=cannerdata&amp;utm_campaign=wrenai&amp;__hstc=70822351.149d5009d6f50dd1dbe1aa967ed1c98b.1776617083425.1776617083425.1776617083425.1&amp;__hssc=70822351.1.1776617083425&amp;__hsfp=3ae367daf8a44e3a8471c1b15d6175fd">Canner</a></td>
<td>Domain Agent [Analytics]</td>
<td>Excel export companion for Wren AI’s generative BI platform, used to move query results into Excel for further analysis.</td>
</tr>
<tr class="odd">
<td>134</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200007749?tab=Overview">Timbr NLQ</a></td>
<td><a href="https://share.hsforms.com">WP-Semantix Ltd.</a></td>
<td>Domain Agent [Analytics]</td>
<td>NLQ add-in that uses Timbr’s semantic layer to translate natural-language database questions into SQL and return results in Excel.</td>
</tr>
<tr class="even">
<td>142</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200009125?tab=Overview">Alchemite for R&amp;D</a></td>
<td><a href="https://docs.intellegens.com/">Intellegens Limited</a></td>
<td>Domain Agent [Machine Learning]</td>
<td>Excel add-in for building Alchemite machine-learning models, making predictions, and updating models from spreadsheet data.</td>
</tr>
</tbody>
</table>
</section>
<section id="appendix-6-audit-compliance-validation-and-governance-4-add-ins" class="level3">
<h3 class="anchored" data-anchor-id="appendix-6-audit-compliance-validation-and-governance-4-add-ins">Appendix 6: Audit, compliance, validation, and governance (4 add-ins)</h3>
<table class="caption-top table">
<thead>
<tr class="header">
<th>Store-order rank</th>
<th>Add-in</th>
<th>Publisher</th>
<th>Listed type</th>
<th>Why it matters to end users</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>37</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200007951?tab=Overview">Copilot Audit</a></td>
<td><a href="https://copilot-audit.com">NEXTBP</a></td>
<td>Domain Agent [Audit]</td>
<td>Audit-focused Excel agent for document extraction, cross-referencing, and validation.</td>
</tr>
<tr class="even">
<td>99</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200009745?tab=Overview">Kolena AI Agents for Excel</a></td>
<td><a href="https://docs.agents.kolena.com">Kolena Inc</a></td>
<td>Domain Agent [Audit]</td>
<td>Template-based Excel agent for document-heavy workflows with AI-powered extraction, validation, source traceability, and confidence scoring.</td>
</tr>
<tr class="odd">
<td>115</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200008291?tab=Overview">Midship</a></td>
<td><a href="https://midship.ai">Midship</a></td>
<td>Domain Agent [Audit]</td>
<td>SOX testing assistant that reviews evidence and creates Excel workpapers.</td>
</tr>
<tr class="even">
<td>121</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200005695?tab=Overview">CRex Add-in for Excel</a></td>
<td><a href="https://hmxhelp.zendesk.com/">HMX.ai</a></td>
<td>Domain Agent [Compliance]</td>
<td>Compliance and government-transparency add-in with a cognitive map, proprietary formula builder, and auditable what-if simulations.</td>
</tr>
</tbody>
</table>
</section>
<section id="appendix-7-writing-translation-proposal-and-content-specialists-10-add-ins" class="level3">
<h3 class="anchored" data-anchor-id="appendix-7-writing-translation-proposal-and-content-specialists-10-add-ins">Appendix 7: Writing, translation, proposal, and content specialists (10 add-ins)</h3>
<table class="caption-top table">
<thead>
<tr class="header">
<th>Store-order rank</th>
<th>Add-in</th>
<th>Publisher</th>
<th>Listed type</th>
<th>Why it matters to end users</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>35</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200008270?tab=Overview">Transcription - Transcribe Speech To Text</a></td>
<td><a href="https://www.livepolls.app">NO FRIENDS LTD</a></td>
<td>Domain Agent [Transcription]</td>
<td>Office transcription add-in that uploads audio or video and uses AI speech-to-text to generate transcripts or subtitles.</td>
</tr>
<tr class="even">
<td>39</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200005016?tab=Overview">MTrans for Office</a></td>
<td><a href="https://dist.mtrans.online">株式会社ヒューマンサイエンス</a></td>
<td>Domain Agent [Translation]</td>
<td>One-click Office translation add-in for Word, Excel, PowerPoint, and Outlook with selectable DeepL, Google, Microsoft, and OpenAI engines, plus glossary, style, and OpenAI writing-assistance features.</td>
</tr>
<tr class="odd">
<td>50</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200007699?tab=Overview">Document Translator</a></td>
<td><a href="https://www.transmonkey.ai/">NO FRIENDS LTD</a></td>
<td>Domain Agent [Translation]</td>
<td>LLM-based document translator for Excel, Word, PowerPoint, and PDF files that preserves the original layout and supports scanned documents.</td>
</tr>
<tr class="even">
<td>63</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200009552?tab=Overview">Copilot for Excel Spreadsheet</a></td>
<td><a href="https://standards-core.ai/">Standards Core</a></td>
<td>Domain Agent [Technical Writing]</td>
<td>Standards Core Office Copilot for technical and legal documents, with multi-model AI, translation, editing guidance, and Excel/Word integration.</td>
</tr>
<tr class="odd">
<td>65</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200009635?tab=Overview">MathPad</a></td>
<td><a href="https://mathpad.ai/">MathPad</a></td>
<td>Domain Agent [Math]</td>
<td>AI math workspace for Office with equation editing, handwriting OCR, step-by-step tutoring, and Excel support for inserting equations and extracting tables from images.</td>
</tr>
<tr class="even">
<td>66</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200006145?tab=Overview">Pluralytics</a></td>
<td><a href="https://pluralytics.com/">Pluralytics</a></td>
<td>Domain Agent [Marketing]</td>
<td>AI-powered language science platform that uses machine learning and behavioral science to optimize marketing messages; available in Excel, Word, and OneNote.</td>
</tr>
<tr class="odd">
<td>70</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200008104?tab=Overview">Acrolinx for Microsoft 365 Office</a></td>
<td><a href="https://support.acrolinx.com">Acrolinx GmbH</a></td>
<td>Domain Agent [Technical Writing]</td>
<td>Enterprise writing-governance add-in for organizations already using Acrolinx; enforces style guides, terminology, tone, and quality checks in Word, Excel, and PowerPoint.</td>
</tr>
<tr class="even">
<td>85</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200007484?tab=Overview">GovEagle AI</a></td>
<td><a href="https://www.goveagle.com/">Zenfetch</a></td>
<td>Domain Agent [Government Contracting]</td>
<td>GovCon proposal assistant that generates pink-team drafts, compliance and capability matrices, and proposal-ready responses from RFP materials and past-performance content.</td>
</tr>
<tr class="odd">
<td>125</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200006392?tab=Overview">Zen RFP</a></td>
<td><a href="https://www.zen-rfp.com">GUT Ventures</a></td>
<td>Domain Agent [RFP]</td>
<td>RFP and IT-questionnaire assistant that drafts answers from a knowledge base, supports collaboration, and tracks changes in Word and Excel.</td>
</tr>
<tr class="even">
<td>131</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200007420?tab=Overview">SiftHub: AI Sales Platform</a></td>
<td><a href="https://www.sifthub.io/">SpeedUp Inc</a></td>
<td>Domain Agent [Sales]</td>
<td>Sales and presales assistant for RFPs, RFIs, infosec questionnaires, and draft responses in Excel and Word.</td>
</tr>
</tbody>
</table>
</section>
<section id="appendix-8-industry-specific-specialists-5-add-ins" class="level3">
<h3 class="anchored" data-anchor-id="appendix-8-industry-specific-specialists-5-add-ins">Appendix 8: Industry-specific specialists (5 add-ins)</h3>
<table class="caption-top table">
<thead>
<tr class="header">
<th>Store-order rank</th>
<th>Add-in</th>
<th>Publisher</th>
<th>Listed type</th>
<th>Why it matters to end users</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>77</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200002293?tab=Overview">llama.ai Excel Adapter</a></td>
<td><a href="https://llamasoft.com">Llamasoft, Inc.</a></td>
<td>Domain Agent [Supply Chain]</td>
<td>Supply-chain Excel connector that sends workbook data to the llama.ai enterprise decision platform; requires a valid llama.ai license and API key.</td>
</tr>
<tr class="even">
<td>88</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200009115?tab=Overview">Cascade Intelligence</a></td>
<td><a href="https://usecascade.ai/">Cascade Intelligence</a></td>
<td>Domain Agent [AEC]</td>
<td>AEC-focused opportunity-intelligence add-in that uses AI to surface matched RFPs and project signals, support bid/no-bid decisions, and assist with proposal work.</td>
</tr>
<tr class="odd">
<td>112</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200005386?tab=Overview">Aidy - Machine Learning Excel Add-in for Insurance Professional or Marketer</a></td>
<td><a href="https://aideaye.com/">Aide Aye Applications Inc.</a></td>
<td>Domain Agent [Insurance]</td>
<td>No-code machine-learning Excel add-in for insurance and marketing analytics, including fraud detection, claim reserving, and target list building.</td>
</tr>
<tr class="even">
<td>135</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200008065?tab=Overview">SafeTerm</a></td>
<td><a href="https://safeterm.blob.core.windows.net">ClinBAY Ltd</a></td>
<td>Domain Agent [Medical coding]</td>
<td>Automates initial MedDRA coding for medical terms.</td>
</tr>
<tr class="odd">
<td>140</td>
<td><a href="https://marketplace.microsoft.com/en-us/product/WA200008930?tab=Overview">Sunhat for Office</a></td>
<td><a href="https://help.sunhat.app/en/">Sunhat GmbH</a></td>
<td>Domain Agent [Sustainability]</td>
<td>Sustainability copilot for ESG questionnaires and evidence-backed responses in Office.</td>
</tr>
</tbody>
</table>
<hr>
</section>
</section>
<section id="editorial-note-for-publication" class="level2">
<h2 class="anchored" data-anchor-id="editorial-note-for-publication">Editorial note for publication</h2>
<p>This article is intended as an orientation guide, not a procurement recommendation. The category adjustments in this version reflect a public-listing check of the key add-ins, but the add-in market changes quickly, and individual listings may change pricing, capabilities, supported platforms, or data-handling terms. End users should validate current marketplace listings, privacy policies, admin requirements, and enterprise licensing before adoption.</p>


</section>

 ]]></description>
  <category>Excel</category>
  <category>AI</category>
  <guid>https://boardflare.com/posts/2026/excel_ai_addins/</guid>
  <pubDate>Sat, 16 May 2026 00:00:00 GMT</pubDate>
</item>
<item>
  <title>Turn an Excel Workbook Into a Simple App With Tool Builder</title>
  <link>https://boardflare.com/posts/2026/tool-builder-addin/</link>
  <description><![CDATA[ 





<p>Most Excel files are already applications in disguise. They have inputs, rules, exceptions, and repeated handoffs. What they usually do not have is an interface built for the job people are actually trying to do.</p>
<p>According to the <a href="../../../apps/excel/builder/">Tool Builder guide</a>, Tool Builder enables you to create standalone HTML web applications using AI (like ChatGPT, Claude, or Gemini) and run them directly within your Excel workbook. The tool runs the app in a sandboxed iframe and stores application data in standard Excel tables, so the workbook acts as the <strong>host and data store</strong> for the app. You ask an AI tool to generate a small single-file web app, paste it into Tool Builder, and run it directly in the workbook. The workbook stays the source of truth, but you get a custom UI tailored to your workflow.</p>
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><img src="https://boardflare.com/posts/2026/tool-builder-addin/running.png" class="img-fluid figure-img"></p>
<figcaption>Running a Kanban Board Tool</figcaption>
</figure>
</div>
<!-- more -->
<p>That makes Tool Builder useful when the problem is not “how do I calculate this?” but “how do I make this workflow easier to use?”</p>
<section id="why-people-use-it" class="level2">
<h2 class="anchored" data-anchor-id="why-people-use-it">Why people use it</h2>
<p>Tool Builder is a good fit when:</p>
<ul>
<li>the data already lives in a workbook</li>
<li>people repeat the same review or update process every week</li>
<li>the raw sheet is harder to use than the underlying task</li>
<li>you want something faster than a custom internal app project</li>
<li>you want the finished tool to travel with the workbook</li>
</ul>
<p>That last part is important. The guide documents that Tool Builder stores the app and its table-backed data in the workbook itself, so the file carries the interface with it. You are not deploying a separate server or database just to make a spreadsheet easier to work with; normal Excel add-in sign-in and workbook-sharing requirements still apply.</p>
</section>
<section id="the-workflow-is-simple" class="level2">
<h2 class="anchored" data-anchor-id="the-workflow-is-simple">The workflow is simple</h2>
<p>Tool Builder works best as a short loop:</p>
<ol type="1">
<li>Start with a workbook problem.</li>
<li>Click Copy Guide in Tool Builder.</li>
<li>Paste the guide into a fresh chat with ChatGPT, Claude, Copilot, or another AI assistant.</li>
<li>Ask for a single-file HTML and JavaScript app for your workflow.</li>
<li>Paste the generated code into Tool Builder and run it in Excel.</li>
<li>Test it against real rows, then refine the prompt or the code.</li>
</ol>
<p>If you want to see the pattern before writing your own prompt, Tool Builder also lets you load an example tool first.</p>
</section>
<section id="what-makes-a-good-first-app" class="level2">
<h2 class="anchored" data-anchor-id="what-makes-a-good-first-app">What makes a good first app</h2>
<p>The best Tool Builder apps are small and specific. They feel more like focused work surfaces than general-purpose dashboards.</p>
<p>Strong starting points include:</p>
<ul>
<li>an expense or budget tracker</li>
<li>a project tracker or Kanban-style board</li>
<li>a guided data-entry form</li>
<li>an inventory or reorder screen</li>
<li>a review queue that surfaces exceptions first</li>
<li>a KPI dashboard built from workbook tables</li>
</ul>
<p>Some apps work on top of tables you already have. Others create their own workbook tables the first time they run. Both models are supported, which is why Tool Builder can work for both tracking workflows and reporting views.</p>
<p>If you want inspiration, the <a href="../../../apps/excel/builder/">Tool Builder for Excel guide</a> shows the product workflow, and the <a href="https://tools.boardflare.com/visualization/">visualization catalog</a> is a useful place to borrow dashboard and chart ideas.</p>


</section>

 ]]></description>
  <category>Excel</category>
  <category>Tool Builder</category>
  <category>AI</category>
  <guid>https://boardflare.com/posts/2026/tool-builder-addin/</guid>
  <pubDate>Tue, 17 Mar 2026 00:00:00 GMT</pubDate>
</item>
<item>
  <title>Excel’s New Regex Functions Versus Python’s re Module Capabilities</title>
  <link>https://boardflare.com/posts/2025/python-regex-excel/</link>
  <description><![CDATA[ 





<section id="excels-new-regex-functions-versus-pythons-re-module-capabilities" class="level1">
<h1>Excel’s New Regex Functions Versus Python’s <code>re</code> Module Capabilities</h1>
<p>This comprehensive post compares Excel’s newly introduced native regex functions (REGEXTEST, REGEXEXTRACT, and REGEXREPLACE) with Python’s long-established <code>re</code> module. We explore their respective capabilities, syntax variations, supported regex constructs, and advanced features to help you understand which tool is best suited for different text manipulation scenarios. Whether you’re working within a spreadsheet for interactive data exploration or building automated text processing pipelines in Python, this detailed analysis will highlight the strengths and limitations of each approach.</p>
<!-- more -->
<section id="background-of-regular-expressions" class="level2">
<h2 class="anchored" data-anchor-id="background-of-regular-expressions">Background of Regular Expressions</h2>
<p>Regular expressions (often abbreviated as regex or regexp) represent a highly specialized and powerful language for defining complex search patterns within text data. They are indispensable tools across various domains for tasks such as data validation, parsing semi-structured information, cleaning messy text, and extracting specific data points. Their ability to identify, match, and manipulate text based on intricate, predefined patterns significantly enhances efficiency and precision in data processing workflows. From validating email addresses and phone numbers to parsing log files or extracting specific keywords from documents, regex provides a flexible and robust mechanism for text manipulation.</p>
<p>For many years, users of Microsoft Excel, a ubiquitous tool for data management, faced significant limitations in performing advanced text manipulation directly within their spreadsheets. Achieving regex-like capabilities often required cumbersome combinations of basic text functions like LEN, FIND, REPLACE, SUBSTITUTE, LEFT, RIGHT, and MID. For more complex scenarios, users typically had to resort to writing Visual Basic for Applications (VBA) macros, which necessitated enabling specific references like “Microsoft VBScript Regular Expressions 5.5,” or acquiring third-party add-ins. This presented a considerable barrier for many users seeking to perform sophisticated text processing directly within their familiar spreadsheet environment.</p>
<p>However, a pivotal shift has recently occurred with the introduction of three brand-new native regex functions in Excel: REGEXTEST, REGEXREPLACE, and REGEXEXTRACT. These functions fundamentally change the landscape by bringing powerful pattern matching directly into the Excel formula bar. This enhancement represents a strategic move by Microsoft to significantly bolster Excel’s core data processing capabilities. It is not merely an incremental update but a fundamental re-tooling that empowers Excel to handle complex text patterns natively, reducing the reliance on external workarounds and positioning Excel as a more self-sufficient data manipulation platform. The anticipation of future integration into XLOOKUP and XMATCH further underscores this deeper embedding of regex power into Excel’s lookup and matching functionalities.</p>
<p>In stark contrast to Excel’s recent adoption, Python’s re module has long been a cornerstone of text processing in the programming world. As a built-in library, it has provided a comprehensive and highly flexible interface for regular expressions for years. It is widely utilized in diverse applications such as data validation, web scraping, log analysis, and complex string manipulations, making Python a go-to language for advanced text processing and automation.</p>
<p>This report aims to provide a granular comparison between Excel’s new native regex functions and Python’s established re module. By dissecting their respective capabilities, underlying regex engines, supported syntax, and advanced features, this analysis will highlight key distinctions and areas of overlap. The objective is to empower advanced data professionals and developers to make informed decisions on which tool is best suited for specific text manipulation tasks, considering factors like complexity, scalability, and integration into existing workflows.</p>
</section>
<section id="excels-new-native-regex-functions-capabilities-and-syntax" class="level2">
<h2 class="anchored" data-anchor-id="excels-new-native-regex-functions-capabilities-and-syntax">Excel’s New Native Regex Functions: Capabilities and Syntax</h2>
<p>Excel’s recent foray into native regular expression support is encapsulated in three distinct functions: REGEXTEST, REGEXEXTRACT, and REGEXREPLACE. These functions are designed to simplify and enhance complex text operations directly within Excel worksheets, offering a flexible and versatile alternative to combining numerous traditional text functions or resorting to VBA code. Their introduction eliminates the need for external add-ins for many advanced text manipulation scenarios, streamlining workflows for Excel users.</p>
<section id="detailed-syntax-and-argument-descriptions-for-each-function" class="level3">
<h3 class="anchored" data-anchor-id="detailed-syntax-and-argument-descriptions-for-each-function">Detailed Syntax and Argument Descriptions for Each Function</h3>
<p>Each of the new Excel regex functions follows a clear syntax, incorporating optional arguments for common modifications like case sensitivity and specific match occurrences.</p>
<ul>
<li>REGEXTEST(text, pattern, [case_sensitivity]): This function evaluates whether any part of the provided text string contains a match for the specified pattern. It returns TRUE if a match is found and FALSE otherwise, making it ideal for data validation or quick pattern checks.
<ul>
<li>text (required): The cell reference or range containing the text string(s) to be checked.</li>
<li>pattern (required): The regular expression to match, which must be enclosed in quotation marks.</li>
<li>[case_sensitivity] (optional): This argument determines if the match is case-sensitive. A value of 0 (the default) specifies a case-sensitive match, while 1 specifies a case-insensitive match.</li>
<li><em>Example:</em> <code>=REGEXTEST(A1,"[0-9]")</code> will return TRUE if cell A1 contains any numeric digit. Similarly, <code>=REGEXTEST(A3:A12,"[a-zA-Z]")</code> can be used across a range to identify cells containing alphabetic characters.</li>
</ul></li>
<li>REGEXEXTRACT(text, pattern, [return_mode], [case_sensitivity]): This function is designed to extract one or more parts of the supplied text that precisely match the defined pattern. It is invaluable for parsing messy data and pulling out specific pieces of information.
<ul>
<li>text (required): The cell reference or range containing the text string(s) from which to extract.</li>
<li>pattern (required): The regular expression that describes the specific text pattern to be extracted.</li>
<li>[return_mode] (optional): This argument specifies what should be extracted. A value of 0 (the default) returns only the first match found. 1 returns all non-overlapping matches. 2 returns the capture groups of the first match as separate parts, which is particularly useful for structured data extraction.</li>
<li>[case_sensitivity] (optional): Same as for REGEXTEST.</li>
<li><em>Example:</em> <code>=REGEXEXTRACT(B5,"\\d+")</code> extracts the first sequence of one or more digits from cell B5. For extracting all initial-capped words, a formula like <code>=REGEXEXTRACT(A2,"[A-Z][a-z]+",1)</code> can be used, returning an array of matches.</li>
</ul></li>
<li>REGEXREPLACE(text, pattern, replacement, [occurrence], [case_sensitivity]): This function allows for the replacement of parts of a text string that match a regex pattern with a specified replacement string. It offers a significantly more powerful and flexible alternative to Excel’s traditional SUBSTITUTE function for data cleaning and reformatting.
<ul>
<li>text (required): The cell reference or range containing the text string(s) within which replacements are to be made.</li>
<li>pattern (required): The regular expression that describes the text pattern to be replaced.</li>
<li>replacement (required): The text string that will replace the matched pattern instances.</li>
<li>[occurrence] (optional): This argument determines which instance of the pattern should be replaced. A value of 0 (the default) replaces all occurrences. A positive integer n replaces the nth occurrence from the start, while a negative integer -n replaces the nth occurrence searching from the end.</li>
<li>[case_sensitivity] (optional): Same as for REGEXTEST.</li>
<li><em>Example:</em> <code>=REGEXREPLACE(B5,"[^0-9]","")</code> can be used to remove all non-numeric characters from telephone numbers in a column. A more advanced use involves reordering text, such as <code>=REGEXREPLACE(A2,"([A-Z][a-z]+)([A-Z][a-z]+)","$2, $1")</code> to swap and reformat “FirstNameLastName” into “LastName, FirstName” using capturing groups.</li>
</ul></li>
</ul>
</section>
<section id="overview-of-supported-basic-regex-patterns-metacharacters-and-quantifiers" class="level3">
<h3 class="anchored" data-anchor-id="overview-of-supported-basic-regex-patterns-metacharacters-and-quantifiers">Overview of Supported Basic Regex Patterns, Metacharacters, and Quantifiers</h3>
<p>Excel’s new functions support a robust set of common regex constructs, enabling versatile pattern matching:</p>
<ul>
<li><strong>Literal Text:</strong> Matches the exact sequence of characters (e.g., ‘abc’ matches ‘abc’).</li>
<li><strong>Wildcard:</strong> The dot (.) matches any single character, with the exception of a newline character.</li>
<li><strong>Character Classes (Shorthands):</strong>
<ul>
<li><code>\\d</code>: Matches any digit (0-9).</li>
<li><code>\\w</code>: Matches any word character (letters, digits, or underscore).</li>
<li><code>\\s</code>: Matches any whitespace character (space, tab, newline).</li>
<li>Their negated counterparts (<code>\\D</code>, <code>\\W</code>, <code>\\S</code>) are also supported.</li>
</ul></li>
<li><strong>Custom Character Sets:</strong>
<ul>
<li><code>[abc]</code>: Matches any one character listed within the brackets (e.g., <code>gr[ae]y</code> matches ‘gray’ or ‘grey’).</li>
<li><code>[a-z]</code>: Matches any one character within the specified range (e.g., <code>[a-z]</code> matches any lowercase letter).</li>
<li></li>
</ul></li>
<li><strong>Quantifiers:</strong> These specify the number of occurrences of the preceding element:
<ul>
<li><code>a\*</code>: Matches zero or more occurrences of ‘a’.</li>
<li><code>a+</code>: Matches one or more occurrences of ‘a’.</li>
<li><code>a?</code>: Matches zero or one occurrence of ‘a’ (making it optional).</li>
<li><code>a{n}</code>: Matches exactly n occurrences of ‘a’.</li>
<li><code>a{n,m}</code>: Matches between n and m occurrences of ‘a’.</li>
<li><code>a{n,}</code>: Matches n or more occurrences of ‘a’.</li>
</ul></li>
<li><strong>Word Boundary:</strong> <code>\\b</code> matches a position that is a word boundary (e.g., <code>\\bcat\\b</code> matches ‘cat’ in ‘the cat sits’ but not ‘category’).</li>
<li><strong>Alternation:</strong> <code>a|b</code> matches either ‘a’ or ‘b’ (e.g., <code>cat|dog</code> matches ‘cat’ or ‘dog’).</li>
<li><strong>Grouping:</strong> Parentheses <code>()</code> are used to group parts of the regular expression. This allows applying quantifiers to a group or capturing the matched subexpression. Non-capturing groups <code>(?:...)</code> can be used when grouping is needed but the matched content doesn’t need to be captured.</li>
</ul>
</section>
<section id="handling-of-case-sensitivity-and-string-anchors" class="level3">
<h3 class="anchored" data-anchor-id="handling-of-case-sensitivity-and-string-anchors">Handling of Case Sensitivity and String Anchors (^, $)</h3>
<p>Case sensitivity is a configurable option for all three Excel regex functions. By default, matches are case-sensitive. However, users can easily disable this by setting the case_sensitivity argument to 1. This provides direct control over how character matching is performed.</p>
<p>The ^ (caret) and <img src="https://latex.codecogs.com/png.latex?(dollar%20sign)%20are%20crucial%20anchors%20in%20regex.%20In%20Excel's%20implementation,%20%5E%20matches%20the%20start%20of%20the%20entire%20string%20(cell%20content),%20and"> matches the end of the entire string. It is important to note that these anchors specifically match the beginning and end of the <em>complete cell content</em>, and not individual lines within a multi-line cell. For example, <code>^The</code> will match “The cat” but not “In The”, and <code>.com$</code> will match “example.com”.</p>
</section>
<section id="usage-of-capturing-groups-and-backreferences-n" class="level3">
<h3 class="anchored" data-anchor-id="usage-of-capturing-groups-and-backreferences-n">Usage of Capturing Groups and Backreferences ($n)</h3>
<p>Capturing groups, defined by parentheses <code>()</code>, are fundamental for extracting specific portions of a match or for reordering text during replacement operations. When REGEXEXTRACT is used with return_mode=2, it can return separate parts of a single match individually, corresponding to the captured groups.</p>
<p>In the context of REGEXREPLACE, backreferences allow the content matched by a capturing group to be reinserted into the replacement string. This is achieved using <code>$n</code>, where n corresponds to the numerical order of the capturing group. For instance, <code>$1</code> refers to the content of the first capturing group, <code>$2</code> to the second, and so on. This capability is instrumental for tasks like reordering names (e.g., “First Last” to “Last, First”) or restructuring data formats.</p>
</section>
<section id="underlying-regex-engine-pcre2-flavor" class="level3">
<h3 class="anchored" data-anchor-id="underlying-regex-engine-pcre2-flavor">Underlying Regex Engine: PCRE2 Flavor</h3>
<p>A critical technical detail underpinning Excel’s new regex capabilities is its choice of the <strong>PCRE2 (‘Perl Compatible Regular Expressions 2’) flavor</strong> for all three functions. PCRE2 is a robust, highly-featured, and widely adopted open-source regex engine. It is renowned for its close adherence to Perl 5 regex syntax and behavior, which is a de-facto standard in the regex world.</p>
<p>The adoption of PCRE2 brings several advantages: it supports comprehensive Unicode matching, allowing for accurate text processing across various languages and character sets. Furthermore, PCRE2 incorporates performance enhancements such as a Just-In-Time (JIT) compiler, which can significantly improve matching speed by compiling regular expressions into native machine code. It also features flexible memory management, utilizing the heap for backtracking information, which mitigates stack overflow issues that plagued older regex implementations. This strategic choice aligns Excel’s regex capabilities with a powerful and familiar industry standard, making it easier for users already accustomed to Perl-compatible regex in other environments to transition and leverage a vast online knowledge base.</p>
</section>
<section id="table-1-excel-regex-functions---syntax-and-core-parameters" class="level3">
<h3 class="anchored" data-anchor-id="table-1-excel-regex-functions---syntax-and-core-parameters">Table 1: Excel Regex Functions - Syntax and Core Parameters</h3>
<p>This table provides a concise, centralized reference for the fundamental structure and key arguments of each new Excel regex function. It serves as a practical guide for users to quickly grasp how to apply these functions for various text manipulation needs, directly addressing the “capabilities” aspect for Excel by summarizing its core usage.</p>
<table class="caption-top table">
<colgroup>
<col style="width: 25%">
<col style="width: 25%">
<col style="width: 25%">
<col style="width: 25%">
</colgroup>
<thead>
<tr class="header">
<th style="text-align: left;">Function</th>
<th style="text-align: left;">Purpose</th>
<th style="text-align: left;">Syntax</th>
<th style="text-align: left;">Key Arguments &amp; Defaults</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td style="text-align: left;">REGEXTEST</td>
<td style="text-align: left;">Checks if text matches a pattern. Returns TRUE/FALSE.</td>
<td style="text-align: left;">REGEXTEST(text, pattern, [case_sensitivity])</td>
<td style="text-align: left;">text (Required), pattern (Required), case_sensitivity (Optional; 0=Case-sensitive (default), 1=Case-insensitive)</td>
</tr>
<tr class="even">
<td style="text-align: left;">REGEXEXTRACT</td>
<td style="text-align: left;">Extracts parts of text that match a pattern.</td>
<td style="text-align: left;">REGEXEXTRACT(text, pattern, [return_mode], [case_sensitivity])</td>
<td style="text-align: left;">text (Required), pattern (Required), return_mode (Optional; 0=First match (default), 1=All matches, 2=Capture groups of first match), case_sensitivity (Optional; 0=Case-sensitive (default), 1=Case-insensitive)</td>
</tr>
<tr class="odd">
<td style="text-align: left;">REGEXREPLACE</td>
<td style="text-align: left;">Replaces parts of text that match a pattern with a replacement string.</td>
<td style="text-align: left;">REGEXREPLACE(text, pattern, replacement, [occurrence], [case_sensitivity])</td>
<td style="text-align: left;">text (Required), pattern (Required), replacement (Required), occurrence (Optional; 0=All occurrences (default), n=nth from start, -n=nth from end), case_sensitivity (Optional; 0=Case-sensitive (default), 1=Case-insensitive)</td>
</tr>
</tbody>
</table>
</section>
<section id="broader-implications-of-excels-new-regex-capabilities" class="level3">
<h3 class="anchored" data-anchor-id="broader-implications-of-excels-new-regex-capabilities">Broader Implications of Excel’s New Regex Capabilities</h3>
<p>Microsoft’s decision to implement PCRE2 rather than extending its older VBScript regex engine or creating a proprietary one is a significant strategic choice. This move immediately grants Excel users access to a vast ecosystem of PCRE2-specific patterns, online testing tools, and community knowledge, thereby significantly lowering the learning curve for those familiar with Perl-compatible regex and enhancing interoperability with other systems that also use PCRE2. This positions Excel as a more robust data manipulation tool in a multi-platform environment, implying a commitment to providing powerful, modern text processing within Excel. This reduces the need for users to export data to other environments solely for complex regex tasks.</p>
<p>The direct integration of these powerful regex functions into Excel’s cell-based formula environment is a fundamental shift. Previously, complex text operations often necessitated cumbersome nested traditional functions or the use of VBA macros, which could be intimidating for many users. Now, users can perform sophisticated text extraction, validation, and replacement interactively, seeing immediate results within the spreadsheet. The ability to define patterns in separate cells and reference them further enhances flexibility and reusability, making complex transformations more manageable and auditable. This significantly boosts productivity for common data cleaning and preparation tasks. It democratizes access to advanced text manipulation, enabling a broader base of Excel users to perform tasks that previously required specialized programming skills or external tools, thereby fostering greater self-sufficiency in data handling.</p>
<p>However, the power and flexibility of these new functions also introduce a notable, albeit unintended, consequence related to security. Recent analysis has demonstrated how REGEXEXTRACT can be leveraged for obfuscation of malicious code. By hiding PowerShell commands or other malicious components within large text strings in cells and using REGEXEXTRACT to dynamically reconstruct them at runtime, attackers can create highly evasive payloads. This technique has shown a significant drop in detection rates by traditional security heuristics compared to plain-text or conventionally obfuscated samples. This highlights a new and sophisticated attack vector within Excel documents, requiring security vendors to adapt their detection mechanisms. For organizations, it means an increased need for vigilance and potentially updated security policies regarding macro-enabled Excel files, as the very features designed for productivity can be repurposed for evasion.</p>
</section>
</section>
<section id="pythons-re-module-comprehensive-regex-powerhouse" class="level2">
<h2 class="anchored" data-anchor-id="pythons-re-module-comprehensive-regex-powerhouse">Python’s re Module: Comprehensive Regex Powerhouse</h2>
<p>Python’s re module stands as a cornerstone for text processing in the programming world, offering a comprehensive and highly flexible interface for working with regular expressions. As a built-in library, it is an essential tool for tasks ranging from data validation and web scraping to complex string manipulations and parsing large text files.</p>
<section id="core-functions-re.search-re.findall-re.sub-re.match-re.compile" class="level3">
<h3 class="anchored" data-anchor-id="core-functions-re.search-re.findall-re.sub-re.match-re.compile">Core Functions: re.search(), re.findall(), re.sub(), re.match(), re.compile()</h3>
<p>The re module provides a versatile set of functions designed for various regex operations:</p>
<ul>
<li><strong>re.search(pattern, string, flags=0)</strong>: This function scans through the string to find the <em>first</em> location where the pattern produces a match. If a match is found anywhere in the string, it returns a match object; otherwise, it returns None. The match object provides detailed information about the match, including its starting and ending positions.</li>
<li><strong>re.findall(pattern, string, flags=0)</strong>: This function is used to find <em>all non-overlapping occurrences</em> of the pattern in the string. It returns a list of all matches. If the pattern contains capturing groups, it returns a list of tuples, where each tuple contains the captured groups for each match.</li>
<li><strong>re.sub(pattern, repl, string, count=0, flags=0)</strong>: This function performs a substitution operation, replacing occurrences of the pattern in the string with the replacement string. The count argument can optionally limit the number of replacements performed. The repl argument can be a string (supporting backreferences) or even a function for more complex replacement logic.</li>
<li><strong>re.match(pattern, string, flags=0)</strong>: Unlike re.search(), re.match() specifically checks if the pattern matches at the <em>beginning</em> of the string. It returns a match object if the pattern matches at the start, and None otherwise. This function is useful for validating strings that must conform to a pattern from their very first character.</li>
<li><strong>re.compile(pattern, flags=0)</strong>: This function compiles a regular expression pattern into a regex object. Compiling patterns is a crucial performance optimization, especially when the same pattern is used multiple times within a program. It pre-processes the pattern, saving time on subsequent match operations.</li>
</ul>
</section>
<section id="extensive-support-for-basic-regex-patterns-special-sequences-and-quantifiers" class="level3">
<h3 class="anchored" data-anchor-id="extensive-support-for-basic-regex-patterns-special-sequences-and-quantifiers">Extensive Support for Basic Regex Patterns, Special Sequences, and Quantifiers</h3>
<p>Python’s re module supports a comprehensive set of metacharacters and quantifiers, largely consistent with Perl-style regular expressions.</p>
<ul>
<li><strong>Standard Metacharacters:</strong> Includes <code>.</code> (any character except newline), <code>^</code> (start of string/line), <code>$</code> (end of string/line), <code>\*</code> (zero or more), <code>+</code> (one or more), <code>?</code> (zero or one), <code>|</code> (OR), <code>[]</code> (character set), <code>()</code> (grouping).</li>
<li><strong>Special Sequences (Shorthands):</strong> <code>\\d</code> (any digit), <code>\\D</code> (any non-digit), <code>\\w</code> (any word character), <code>\\W</code> (any non-word character), <code>\\s</code> (any whitespace character), <code>\\S</code> (any non-whitespace character), <code>\\b</code> (word boundary), <code>\\B</code> (non-word boundary), <code>\\n</code> (newline).</li>
<li><strong>Quantifiers:</strong> Python supports fixed <code>{n}</code>, range <code>{n,m}</code>, and open-ended <code>{n,}</code> quantifiers, in addition to <code>\*</code>, <code>+</code>, <code>?</code>.</li>
<li><strong>Greedy vs.&nbsp;Non-Greedy:</strong> By default, all quantifiers in Python are “greedy,” meaning they attempt to match the longest possible string that satisfies the pattern. This behavior can be modified to “non-greedy” (or “minimal”) by appending a <code>?</code> to the quantifier (e.g., <code>\*?</code>, <code>+?</code>, <code>??</code>). This is a critical control mechanism for precise parsing, particularly when dealing with nested structures or multiple potential matches. Understanding this distinction is vital for writing accurate and efficient regular expressions.</li>
</ul>
</section>
<section id="the-significance-of-pythons-raw-string-notation-r" class="level3">
<h3 class="anchored" data-anchor-id="the-significance-of-pythons-raw-string-notation-r">The Significance of Python’s Raw String Notation (r”“)</h3>
<p>A key best practice when defining regular expression patterns in Python is the use of raw string notation (e.g., r”pattern”). This addresses a common conflict: both Python’s string literals and regular expressions use the backslash () as an escape character. For instance, \n in a standard Python string denotes a newline, but in regex, \n might match a literal newline character, or \d might denote a digit. If not using raw strings, to match a literal backslash in a regex, one might have to write <code>\\\\</code> in a Python string literal, which can quickly become cumbersome and error-prone.</p>
<p>Raw strings (r”…“) ensure that Python does not interpret backslashes as escape sequences within the string literal itself. This means the regex engine receives the pattern exactly as written, simplifying pattern creation and significantly reducing the potential for unexpected behavior or errors related to backslash interpretation.</p>
</section>
<section id="advanced-features-lookahead-and-lookbehind-assertions" class="level3">
<h3 class="anchored" data-anchor-id="advanced-features-lookahead-and-lookbehind-assertions">Advanced Features: Lookahead and Lookbehind Assertions</h3>
<p>Python’s re module provides full support for zero-width assertions, which are powerful constructs that allow matching a position in the string based on what follows or precedes it, without actually consuming any characters. This means they assert a condition without becoming part of the overall match.</p>
<ul>
<li><p><strong>Lookahead Assertions:</strong></p>
<ul>
<li>(?=…) (Positive Lookahead): This assertion succeeds if the regular expression inside it (…) matches immediately after the current position in the string. For example, <code>q(?=u)</code> matches a ‘q’ only if it is immediately followed by a ‘u’, but the ‘u’ itself is not included in the match.</li>
<li>(?!) (Negative Lookahead): This assertion succeeds if the contained expression <em>does not</em> match immediately after the current position. For example, <code>.*[.](./?!bat$)[^.]*$</code> can be used to match filenames that do not end with .bat.</li>
</ul></li>
<li><p><strong>Lookbehind Assertions:</strong></p>
<ul>
<li>(?&lt;=…) (Positive Lookbehind): This assertion succeeds if the regular expression inside it matches immediately <em>before</em> the current position in the string. For example, <code>(?&lt;=@)example</code> matches ‘example’ only if it is preceded by ‘@’.</li>
<li>(?&lt;!…) (Negative Lookbehind): This assertion succeeds if the contained expression <em>does not</em> match immediately before the current position. For example, <code>(?&lt;!a)b</code> matches a ‘b’ that is not preceded by an ‘a’.</li>
</ul>
<p>While many regex flavors impose fixed-width limitations on lookbehind patterns (requiring the engine to know how many characters to step back), Python’s re module (being PCRE-like) is more flexible and can handle variable-width lookbehinds for finite repetitions.</p></li>
</ul>
</section>
<section id="advanced-features-named-capturing-groups" class="level3">
<h3 class="anchored" data-anchor-id="advanced-features-named-capturing-groups">Advanced Features: Named Capturing Groups</h3>
<p>Python’s re module significantly enhances the readability and maintainability of complex regular expressions through the support of named capturing groups. Instead of relying solely on numerical indices, developers can assign descriptive names to captured substrings using the <code>(?P&lt;name&gt;...)</code> syntax.</p>
<ul>
<li><strong>Syntax and Retrieval:</strong> For instance, <code>(?P&lt;first&gt;\w+) (?P&lt;last&gt;\w+)</code> captures a first name and last name. Matches can then be retrieved from a match object using either their numerical index (<code>match.group(1)</code>) or their assigned name (<code>match.group('first')</code>). The <code>match.groupdict()</code> method conveniently returns all named groups as a dictionary, making it easy to access and process structured data.</li>
<li><strong>Backreferencing:</strong> Named groups can also be backreferenced <em>within the regex pattern itself</em> using <code>(?P=name)</code>. This is particularly useful for finding repeated patterns, such as <code>\b(?P&lt;word&gt;\w+)\s+(?P=word)\b</code> to identify doubled words like “the the”.</li>
<li><strong>Replacement Strings:</strong> In replacement strings used with <code>re.sub()</code>, named groups are referenced using <code>\g&lt;name&gt;</code> (e.g., <code>\g&lt;first&gt;</code>) or <code>\g&lt;number&gt;</code> (e.g., <code>\g&lt;1&gt;</code>). This syntax helps avoid ambiguity, especially when group numbers might conflict with literal digits in the replacement string (e.g., <code>\g&lt;2&gt;0</code> unambiguously refers to group 2 followed by ‘0’, whereas <code>\20</code> might be interpreted as group 20).</li>
</ul>
</section>
<section id="advanced-features-compilation-flags-for-fine-grained-control" class="level3">
<h3 class="anchored" data-anchor-id="advanced-features-compilation-flags-for-fine-grained-control">Advanced Features: Compilation Flags for Fine-Grained Control</h3>
<p>Python’s re module offers a rich set of compilation flags that provide granular control over how regular expressions behave during matching. These flags can be passed as an argument to functions like <code>re.search()</code>, <code>re.findall()</code>, <code>re.sub()</code>, <code>re.match()</code>, or <code>re.compile()</code>. Multiple flags can be combined using the bitwise OR operator (|).</p>
<ul>
<li><code>re.IGNORECASE</code> (<code>re.I</code>): Performs case-insensitive matching, meaning ‘a’ will match ‘A’ and vice-versa.</li>
<li><code>re.DOTALL</code> (<code>re.S</code>): Modifies the behavior of the <code>.</code> metacharacter to match any character, including newline characters. Without this flag, <code>.</code> matches everything <em>except</em> newlines.</li>
<li><code>re.MULTILINE</code> (<code>re.M</code>): Affects the behavior of the <code>^</code> and <code>$</code> anchors. When set, <code>^</code> matches not only the start of the string but also the start of each line within the string (immediately following a newline). Similarly, <code>$</code> matches the end of the string and the end of each line (immediately preceding a newline).</li>
<li><code>re.VERBOSE</code> (<code>re.X</code>): This flag allows for more readable regular expressions. It ignores whitespace within the pattern (unless escaped or within a character class) and enables comments (starting with # to the next newline). This is invaluable for breaking down long, complex patterns into manageable, documented sections, significantly aiding in debugging and maintenance.</li>
<li><code>re.ASCII</code> (<code>re.A</code>): When used with Unicode patterns, this flag makes special sequences like <code>\\w</code>, <code>\\b</code>, <code>\\s</code>, and <code>\\d</code> match only ASCII characters, overriding their default Unicode behavior.</li>
<li><code>re.LOCALE</code> (<code>re.L</code>): Makes <code>\\w</code>, <code>\\W</code>, <code>\\b</code>, <code>\\B</code>, and case-insensitive matching dependent on the current locale. While available, its use is generally discouraged in Python 3 due to the unreliability of the locale mechanism and better Unicode support by default.</li>
</ul>
</section>
<section id="robust-unicode-support-and-performance-considerations" class="level3">
<h3 class="anchored" data-anchor-id="robust-unicode-support-and-performance-considerations">Robust Unicode Support and Performance Considerations</h3>
<p>Python 3’s re module offers robust Unicode support by default for string patterns, ensuring that regex operations correctly handle a wide range of international characters, including those beyond the basic ASCII set.</p>
<p>For performance optimization, especially when the same regex pattern is used repeatedly (e.g., in a loop processing many strings), compiling the pattern into a regex object using <code>re.compile()</code> is highly recommended. This pre-processing step saves time by avoiding repeated parsing of the pattern, leading to significant efficiency gains for frequently executed regex operations.</p>
<p>It is important to note that complex regular expressions, particularly those involving extensive backtracking or deep nesting of repetitions, can sometimes lead to a RuntimeError indicating that the “maximum recursion limit exceeded.” This is a performance limitation related to the underlying matching engine’s recursive nature. However, Python’s re module provides a common strategy to mitigate this: restructuring the regex to use non-greedy quantifiers (e.g., *? instead of *) can often avoid deep recursion and, as a beneficial side effect, improve matching performance.</p>
</section>
<section id="table-2-python-re-module---key-functions-and-their-purpose" class="level3">
<h3 class="anchored" data-anchor-id="table-2-python-re-module---key-functions-and-their-purpose">Table 2: Python re Module - Key Functions and Their Purpose</h3>
<p>This table provides a concise overview of the most commonly used functions within Python’s re module. It helps users quickly understand its core capabilities and how they map to different text processing needs, such as searching for patterns, extracting all matches, performing replacements, or checking for matches at the beginning of a string. This directly addresses the “capabilities” aspect of the query for the re module.</p>
<table class="caption-top table">
<colgroup>
<col style="width: 25%">
<col style="width: 25%">
<col style="width: 25%">
<col style="width: 25%">
</colgroup>
<thead>
<tr class="header">
<th style="text-align: left;">Function Name</th>
<th style="text-align: left;">Purpose</th>
<th style="text-align: left;">Basic Syntax</th>
<th style="text-align: left;">Returns</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td style="text-align: left;">re.search()</td>
<td style="text-align: left;">Finds the first occurrence of a pattern anywhere in a string.</td>
<td style="text-align: left;">re.search(pattern, string, [flags])</td>
<td style="text-align: left;">Match object if found, else None</td>
</tr>
<tr class="even">
<td style="text-align: left;">re.findall()</td>
<td style="text-align: left;">Finds all non-overlapping occurrences of a pattern in a string.</td>
<td style="text-align: left;">re.findall(pattern, string, [flags])</td>
<td style="text-align: left;">List of strings or tuples</td>
</tr>
<tr class="odd">
<td style="text-align: left;">re.sub()</td>
<td style="text-align: left;">Replaces occurrences of a pattern with a specified string.</td>
<td style="text-align: left;">re.sub(pattern, repl, string, [count], [flags])</td>
<td style="text-align: left;">Modified string</td>
</tr>
<tr class="even">
<td style="text-align: left;">re.match()</td>
<td style="text-align: left;">Checks if a pattern matches at the <em>beginning</em> of a string.</td>
<td style="text-align: left;">re.match(pattern, string, [flags])</td>
<td style="text-align: left;">Match object if found at start, else None</td>
</tr>
<tr class="odd">
<td style="text-align: left;">re.compile()</td>
<td style="text-align: left;">Compiles a regex pattern into a regex object for repeated use.</td>
<td style="text-align: left;">re.compile(pattern, [flags])</td>
<td style="text-align: left;">Regex pattern object</td>
</tr>
</tbody>
</table>
</section>
<section id="broader-implications-of-pythons-re-module" class="level3">
<h3 class="anchored" data-anchor-id="broader-implications-of-pythons-re-module">Broader Implications of Python’s re Module</h3>
<p>Python’s re module, being an integral part of a full-fledged programming language, offers unparalleled programmatic control and scalability. This means regex operations can be seamlessly interwoven with other programming constructs like loops, conditional statements, file input/output, database interactions, and integration with vast data analysis libraries (e.g., Pandas). The explicit presence of <code>re.compile()</code> and mechanisms to handle recursion limits indicates a design philosophy geared towards efficiency and robustness for large-scale or iterative tasks. Python is inherently superior for automation, batch processing, building complex text analysis pipelines, and handling massive datasets where interactive, cell-based formulas in Excel would become impractical, unwieldy, or computationally inefficient. Its environment allows for sophisticated error handling and logging, which are critical for production systems.</p>
<p>Furthermore, features like named capturing groups and the <code>re.VERBOSE</code> flag are powerful tools for managing the complexity of advanced regular expressions. Named groups provide semantic meaning to captured substrings, making complex patterns self-documenting and easier to understand, especially in collaborative development. The <code>re.VERBOSE</code> flag allows developers to format long, intricate regex patterns across multiple lines with comments, significantly improving their readability, debuggability, and long-term maintainability—qualities often challenging to achieve with single-line Excel formulas. For projects involving highly complex or frequently evolving regex patterns, Python’s re module offers superior tools for pattern design, documentation, and collaborative development, ultimately reducing development time and the likelihood of errors.</p>
<p>Finally, Python’s comprehensive set of compilation flags provides developers with an exceptional degree of control over how the regex engine interprets patterns and the text being searched. This allows for precise tailoring of matching behavior to specific, often nuanced, requirements—such as handling case sensitivity, matching across newline characters, or defining character sets based on specific ASCII or Unicode properties. This level of explicit control is not directly exposed as arguments in Excel’s new functions. This detailed control makes Python’s re module more adaptable to a wider array of diverse and challenging text matching scenarios, particularly when dealing with internationalized text, highly specific data formats, or situations where default regex behaviors are insufficient.</p>
</section>
</section>
<section id="direct-comparison-feature-parity-and-key-distinctions" class="level2">
<h2 class="anchored" data-anchor-id="direct-comparison-feature-parity-and-key-distinctions">Direct Comparison: Feature Parity and Key Distinctions</h2>
<p>While both Excel’s new native functions and Python’s re module provide powerful regex capabilities, their underlying design philosophies, exposed features, and optimal use cases present significant distinctions.</p>
<section id="functional-equivalence-mapping-excels-functions-to-pythons-re-module-operations" class="level3">
<h3 class="anchored" data-anchor-id="functional-equivalence-mapping-excels-functions-to-pythons-re-module-operations">Functional Equivalence: Mapping Excel’s Functions to Python’s re Module Operations</h3>
<p>At a high level, Excel’s new regex functions have direct functional counterparts in Python’s re module:</p>
<ul>
<li>REGEXTEST (Excel) is functionally equivalent to performing a <code>re.search()</code> or <code>re.match()</code> operation in Python and then checking if a match object was returned (i.e., if <code>re.search(pattern, string)</code>:).</li>
<li>REGEXEXTRACT (Excel) aligns with Python’s <code>re.findall()</code> when extracting all matches. For extracting the first match or specific capturing groups, it maps to <code>re.search()</code> followed by accessing <code>match.group()</code> or <code>match.groups()</code>.</li>
<li>REGEXREPLACE (Excel) directly corresponds to Python’s <code>re.sub()</code> function, both designed for pattern-based text substitution.</li>
</ul>
</section>
<section id="regex-flavor-comparison-pcre2-excel-vs.-pythons-re-engine" class="level3">
<h3 class="anchored" data-anchor-id="regex-flavor-comparison-pcre2-excel-vs.-pythons-re-engine">Regex Flavor Comparison: PCRE2 (Excel) vs.&nbsp;Python’s re Engine</h3>
<p>Excel’s new functions explicitly utilize the <strong>PCRE2</strong> regex flavor. PCRE2 is highly compatible with Perl 5 regex syntax and is known for its extensive features, including robust Unicode support and performance optimizations like JIT compilation. Python’s re module implements its own regex engine, which is also highly capable and broadly compatible with PCRE/Perl-style regex. While both are powerful and share a common heritage, subtle differences in their default behaviors and the extent to which advanced features are exposed or implemented can exist.</p>
</section>
<section id="supported-regex-constructs-a-side-by-side-analysis" class="level3">
<h3 class="anchored" data-anchor-id="supported-regex-constructs-a-side-by-side-analysis">Supported Regex Constructs: A Side-by-Side Analysis</h3>
<p>Both Excel (PCRE2) and Python’s re module support the vast majority of standard regex metacharacters, character classes, and quantifiers. This includes common elements like . (any character), * (0 or more), + (1 or more), ? (0 or 1), | (OR), <code>[]</code> (character set), () (grouping).</p>
<p>A notable difference in syntax involves escaping. Both environments require backslashes () to escape special characters to match them literally (e.g., <code>\.</code> to match a literal dot). However, Python strongly recommends the use of raw string notation (r”“) for regex patterns to prevent Python’s own string literal escape interpretation, a consideration not present in Excel’s formula environment.</p>
</section>
<section id="advanced-feature-discrepancies" class="level3">
<h3 class="anchored" data-anchor-id="advanced-feature-discrepancies">Advanced Feature Discrepancies</h3>
<p>Despite their shared regex lineage, there are key differences in the support and exposure of advanced regex features:</p>
<ul>
<li><strong>Lookarounds:</strong>
<ul>
<li><strong>Excel (PCRE2):</strong> Excel’s documentation explicitly mentions the ability to “look ahead” to match patterns only when they occur before something else, implying support for positive lookahead <code>(?=...)</code> and negative lookahead <code>(?!...)</code>. However, the provided documentation for Excel’s new functions does not explicitly confirm native support for lookbehind assertions (<code>(?&lt;=...)</code>, <code>(?&lt;!...)</code>). While PCRE2 itself supports lookbehind, and even handles variable-width lookbehinds for finite repetitions, its exposure in Excel’s formula interface is not clearly stated. This is a point of potential limitation or unconfirmed feature for the new native functions, especially considering older VBA regex explicitly lacked lookbehind support.</li>
<li><strong>Python re:</strong> Python’s re module fully supports both positive/negative lookahead and lookbehind assertions. Its engine is notably flexible regarding variable-width patterns within lookbehinds, offering robust capabilities for complex conditional matching.</li>
</ul></li>
<li><strong>Named Capturing Groups:</strong>
<ul>
<li><strong>Excel (PCRE2):</strong> The provided documentation for Excel’s new functions (specifically REGEXREPLACE) only illustrates and mentions support for <em>numbered</em> capturing groups ($n). There is no explicit mention or example of named capturing groups (<code>(?P&lt;name&gt;...)</code> or <code>\k&lt;name&gt;</code>). This aligns with the fact that older VBA regex explicitly lacked named groups.</li>
<li><strong>Python re:</strong> Python’s re module explicitly supports named capturing groups (<code>(?P&lt;name&gt;...)</code>). These can be referenced by name (e.g., <code>match.group('name')</code>, <code>\g&lt;name&gt;</code>) or by numerical index, significantly improving the readability and maintainability of complex patterns.</li>
</ul></li>
<li><strong>Flags and Options:</strong>
<ul>
<li><strong>Excel (PCRE2):</strong> Excel’s new functions offer limited direct control over matching behavior via function arguments, primarily case_sensitivity (0 or 1). While the underlying PCRE2 engine boasts a wide array of flags for fine-grained control (e.g., DOTALL, MULTILINE, EXTENDED, CASELESS), Excel’s formula interface does not directly expose these as arguments.</li>
<li><strong>Python re:</strong> Python’s re module provides extensive control through a rich set of compilation flags (e.g., <code>re.IGNORECASE</code>, <code>re.DOTALL</code>, <code>re.MULTILINE</code>, <code>re.VERBOSE</code>), which can be combined using the bitwise OR operator (|). This allows for highly customized and precise matching behavior.</li>
</ul></li>
<li><strong>Atomic Grouping &amp; Possessive Quantifiers:</strong>
<ul>
<li><strong>Excel (PCRE2):</strong> PCRE2 generally supports atomic groups (<code>(?&gt;...)</code>) and possessive quantifiers (<code>*+</code>, <code>++</code>, <code>?+</code>, <code>{m,n}+</code>), which prevent backtracking and can optimize performance for certain patterns. However, Excel’s documentation does not explicitly confirm their support or usage within the native functions. Older VBA regex explicitly lacked these features.</li>
<li><strong>Python re:</strong> Python’s re module does not natively support atomic grouping or possessive quantifiers. Python’s primary mechanisms for controlling matching behavior are its default greedy quantifiers with backtracking and the explicit use of non-greedy quantifiers (<code>*?</code>).</li>
</ul></li>
<li><strong>Multiline Anchors (^ and $):</strong>
<ul>
<li><strong>Excel (PCRE2):</strong> In Excel, the ^ and $ anchors consistently match the start and end of the <em>entire cell string</em>, respectively. They do not match the start or end of individual lines within a multi-line cell.</li>
<li><strong>Python re:</strong> By default, ^ and $ in Python’s re module match the start and end of the <em>string</em>. However, when the <code>re.MULTILINE</code> (<code>re.M</code>) flag is set, their behavior changes to match the start and end of <em>each line</em> within the string. This difference in default behavior and optional control is significant for multi-line text processing.</li>
</ul></li>
<li><strong>Unicode Support:</strong>
<ul>
<li><strong>Excel (PCRE2):</strong> PCRE2 offers robust Unicode support. This means that character classes like \d, \w, and \s typically handle a wider range of international characters beyond just ASCII digits/letters. The extent to which Excel’s implementation fully leverages and exposes all PCRE2 Unicode character properties by default is not exhaustively detailed in the provided documentation, though PCRE2’s <code>PCRE2_UCP</code> option enables full Unicode character properties.</li>
<li><strong>Python re:</strong> Python 3’s re module handles Unicode characters effectively by default for string patterns. The <code>re.ASCII</code> flag can be used to restrict \d, \w, \s to ASCII-only matching if specifically required.</li>
</ul></li>
</ul>
</section>
<section id="integration-and-workflow" class="level3">
<h3 class="anchored" data-anchor-id="integration-and-workflow">Integration and Workflow</h3>
<ul>
<li><strong>Excel:</strong> The new regex functions are formula-based, making them ideal for interactive data exploration, ad-hoc analysis, and scenarios where data remains within the spreadsheet environment. They are easy to apply across ranges of cells and integrate seamlessly into existing Excel workflows.</li>
<li><strong>Python:</strong> The re module is programmatic, making it ideal for automation, scripting, large-scale data processing (e.g., processing entire directories of text files), and integration with other systems or applications. It requires a development environment and programming knowledge.</li>
</ul>
</section>
<section id="performance-and-scalability" class="level3">
<h3 class="anchored" data-anchor-id="performance-and-scalability">Performance and Scalability</h3>
<ul>
<li><strong>Excel:</strong> The underlying PCRE2 engine benefits from features like a JIT compiler and heap-based backtracking, which should provide good performance for in-cell operations. However, for extremely large datasets or highly complex patterns applied across vast numbers of cells, Excel’s overall calculation engine might still impose practical limitations.</li>
<li><strong>Python:</strong> Python offers explicit performance optimizations such as <code>re.compile()</code> for repeated pattern usage and strategies to mitigate recursion limits (e.g., using non-greedy quantifiers). Its programmatic nature allows for optimized handling of large text files or streaming data, making it generally more scalable for high-volume or computationally intensive regex tasks.</li>
</ul>
</section>
<section id="table-3-feature-comparison-excel-regex-vs.-python-re-module" class="level3">
<h3 class="anchored" data-anchor-id="table-3-feature-comparison-excel-regex-vs.-python-re-module">Table 3: Feature Comparison: Excel Regex vs.&nbsp;Python re Module</h3>
<p>This table is central to the comparison, offering a side-by-side view of specific regex features and their support in each environment. It directly addresses the “differences” aspect of the query in a structured, easy-to-digest format, synthesizing information from various sources to highlight both parity and discrepancies.</p>
<table class="caption-top table">
<colgroup>
<col style="width: 33%">
<col style="width: 33%">
<col style="width: 33%">
</colgroup>
<thead>
<tr class="header">
<th style="text-align: left;">Feature</th>
<th style="text-align: left;">Excel Regex (PCRE2-based)</th>
<th style="text-align: left;">Python re Module</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td style="text-align: left;">Core Functions</td>
<td style="text-align: left;">REGEXTEST, REGEXEXTRACT, REGEXREPLACE (Formula-based)</td>
<td style="text-align: left;">re.search(), re.findall(), re.sub(), re.match(), re.compile() (Programmatic)</td>
</tr>
<tr class="even">
<td style="text-align: left;">Regex Flavor</td>
<td style="text-align: left;">PCRE2</td>
<td style="text-align: left;">Python’s own engine (Perl-like)</td>
</tr>
<tr class="odd">
<td style="text-align: left;">Basic Metacharacters</td>
<td style="text-align: left;">Full support (<code>.</code>, <code>\*</code>, <code>+</code>, <code>?</code>, <code>|</code>, <code>[]</code>, <code>()</code>, <code>^</code>, <code>$</code>, <code>\\d</code>, <code>\\w</code>, <code>\\s</code>, <code>\\b</code>, etc.)</td>
<td style="text-align: left;">Full support (<code>.</code>, <code>\*</code>, <code>+</code>, <code>?</code>, <code>|</code>, <code>[]</code>, <code>()</code>, <code>^</code>, <code>$</code>, <code>\\d</code>, <code>\\w</code>, <code>\\s</code>, <code>\\b</code>, etc.)</td>
</tr>
<tr class="even">
<td style="text-align: left;">Case Sensitivity Control</td>
<td style="text-align: left;">Via case_sensitivity argument (0=sensitive, 1=insensitive)</td>
<td style="text-align: left;">Via re.IGNORECASE (re.I) flag</td>
</tr>
<tr class="odd">
<td style="text-align: left;">String Anchors (<code>^</code>, <code>$</code>)</td>
<td style="text-align: left;">Match start/end of <em>entire string</em> only</td>
<td style="text-align: left;">Match start/end of <em>string</em> by default; start/end of <em>line</em> with re.MULTILINE (re.M) flag</td>
</tr>
<tr class="even">
<td style="text-align: left;">Lookahead Assertions</td>
<td style="text-align: left;">Supported <code>(?=...)</code>, <code>(?!...)</code></td>
<td style="text-align: left;">Full support <code>(?=...)</code>, <code>(?!...)</code></td>
</tr>
<tr class="odd">
<td style="text-align: left;">Lookbehind Assertions</td>
<td style="text-align: left;">Not explicitly confirmed in native functions documentation (PCRE2 supports, but exposure in Excel is unclear)</td>
<td style="text-align: left;">Full support <code>(?&lt;=...)</code>, <code>(?&lt;!...)</code>, including variable-width for finite repetitions</td>
</tr>
<tr class="even">
<td style="text-align: left;">Named Capturing Groups</td>
<td style="text-align: left;">Not explicitly supported; uses numbered groups <code>$n</code></td>
<td style="text-align: left;">Full support <code>(?P&lt;name&gt;...)</code>, can be referenced by name (<code>\\g&lt;name&gt;</code>, <code>(?P=name)</code>)</td>
</tr>
<tr class="odd">
<td style="text-align: left;">Compilation Flags</td>
<td style="text-align: left;">Limited direct control via function arguments (only case_sensitivity)</td>
<td style="text-align: left;">Extensive control via multiple flags (re.DOTALL, re.VERBOSE, re.ASCII, etc.)</td>
</tr>
<tr class="even">
<td style="text-align: left;">Greedy/Non-Greedy Quantifiers</td>
<td style="text-align: left;">Default greedy (PCRE2); non-greedy <code>\*?</code> likely supported as part of PCRE2</td>
<td style="text-align: left;">Default greedy; explicit non-greedy <code>\*?</code>, <code>+?</code>, <code>??</code> supported</td>
</tr>
<tr class="odd">
<td style="text-align: left;">Atomic Grouping/Possessive Quantifiers</td>
<td style="text-align: left;">Not explicitly confirmed in native functions documentation (PCRE2 supports)</td>
<td style="text-align: left;">Not natively supported</td>
</tr>
<tr class="even">
<td style="text-align: left;">Multiline Anchors (<code>^</code> and <code>$</code>)</td>
<td style="text-align: left;">In Excel, the <code>^</code> and <code>$</code> anchors consistently match the start and end of the <em>entire cell string</em>, respectively. They do not match the start or end of individual lines within a multi-line cell.</td>
<td style="text-align: left;">By default, <code>^</code> and <code>$</code> in Python’s re module match the start and end of the <em>string</em>. However, when the re.MULTILINE (re.M) flag is set, their behavior changes to match the start and end of <em>each line</em> within the string.</td>
</tr>
<tr class="odd">
<td style="text-align: left;">Unicode Support</td>
<td style="text-align: left;">Robust via PCRE2 engine</td>
<td style="text-align: left;">Robust by default for string patterns; re.ASCII flag for ASCII-only</td>
</tr>
<tr class="even">
<td style="text-align: left;">Performance Optimization</td>
<td style="text-align: left;">Benefits from PCRE2 JIT compiler, heap-based backtracking</td>
<td style="text-align: left;">re.compile() for repeated use; strategies for recursion limits (<code>\*?</code>)</td>
</tr>
<tr class="odd">
<td style="text-align: left;">Workflow Paradigm</td>
<td style="text-align: left;">Formula-based, interactive, in-cell</td>
<td style="text-align: left;">Programmatic, scripting, automation, external files</td>
</tr>
</tbody>
</table>
</section>
<section id="broader-implications-of-the-feature-comparison" class="level3">
<h3 class="anchored" data-anchor-id="broader-implications-of-the-feature-comparison">Broader Implications of the Feature Comparison</h3>
<p>The comparison highlights a fundamental difference in the exposure of features, even when the underlying engine (PCRE2 for Excel) is highly capable. While Excel’s new functions leverage the powerful PCRE2 engine, its user interface (via function arguments) only exposes a limited subset of PCRE2’s full capabilities. For instance, only case_sensitivity is a direct argument, with no explicit flags for behaviors like DOTALL or MULTILINE directly exposed in the functions. In contrast, Python’s re module explicitly exposes a wide array of flags, allowing developers to fine-tune regex behavior. This indicates that Excel prioritizes ease of use and common scenarios for a broader user base, whereas Python caters to developers needing granular control. For advanced regex patterns requiring specific matching behaviors (e.g., matching across newlines, complex Unicode property matching beyond basic \d/\w), Python will likely remain the more flexible and capable tool, even if the underlying Excel engine theoretically supports such features. Users might encounter a “feature ceiling” within Excel’s formula interface for highly specialized regex needs.</p>
<p>The fundamental difference in interface—formula-based in Excel versus programmatic in Python—creates a direct link to optimal workflow. Excel’s strength lies in interactive, iterative data exploration and transformation directly within the spreadsheet, making it suitable for ad-hoc analysis. Python’s strength is in automation, batch processing, and integration with larger software systems, where repetitive tasks or massive datasets are involved. The lack of named groups and limited flag exposure in Excel makes complex regex patterns harder to manage and debug in a formula context compared to Python’s scripting environment. This implies that users should choose their tool not just based on regex feature parity, but primarily on the nature of the task: interactive, spreadsheet-centric tasks for Excel; automated, large-scale, or system-integrated tasks for Python.</p>
<p>Furthermore, the differing default behaviors of anchors (^, $) for multiline matching can lead to subtle but significant errors if a user is accustomed to one environment and assumes identical behavior in the other. In Excel, ^ and $ always match the start and end of the <em>entire cell string</em>. In Python, they match the start and end of the <em>string</em> by default, but with the <code>re.MULTILINE</code> flag, they match the start and end of <em>each line</em>. Similarly, Python’s explicit raw string notation is a crucial best practice that Excel users don’t need to consider, but Python users must master to avoid unexpected backslash interpretations. This highlights that users transitioning between Excel and Python regex need to be acutely aware of these default behavior differences and explicit syntax requirements to avoid frustrating debugging sessions and ensure correct pattern matching.</p>
</section>
</section>
<section id="practical-applications-and-recommendations" class="level2">
<h2 class="anchored" data-anchor-id="practical-applications-and-recommendations">Practical Applications and Recommendations</h2>
<p>Understanding the distinct capabilities and design philosophies of Excel’s new regex functions and Python’s re module is crucial for selecting the most appropriate tool for a given task. Neither tool is universally superior; rather, their strengths are complementary, aligning with different operational contexts and user profiles.</p>
<p>Excel’s new native regex functions are particularly well-suited for scenarios that prioritize interactivity, immediate results, and operations within the familiar spreadsheet environment:</p>
<ul>
<li><strong>Ad-hoc Data Cleaning and Validation:</strong> For quick, one-off tasks like removing unwanted characters (e.g., <code>=REGEXREPLACE(B5,"[^0-9]","")</code> to clean phone numbers), reformatting strings, or checking for the presence of specific patterns (e.g., <code>=REGEXTEST(A1,"[0-9]")</code>) within a single column or a small range of data.</li>
<li><strong>Interactive Data Extraction:</strong> When there’s a need to pull out specific pieces of information (e.g., numbers, names, email parts) from semi-structured text directly in a cell, REGEXEXTRACT provides an immediate and visible solution. This is highly beneficial for data exploration.</li>
<li><strong>Collaborative Data Analysis:</strong> When working with colleagues who are comfortable with Excel but not programming, the formula-based approach allows for transparent, auditable text processing that can be easily reviewed and modified by non-programmers.</li>
<li><strong>Small-scale Transformations:</strong> For datasets that fit comfortably within Excel’s row limitations and where the complexity doesn’t exceed what can be reasonably managed in formula form.</li>
</ul>
<p>Conversely, Python’s <code>re</code> module is the superior choice for scenarios requiring programmatic control, advanced features, or operations that exceed Excel’s practical limitations:</p>
<ul>
<li><strong>Large-scale Data Processing:</strong> When working with massive datasets (millions of records), multiple files, or text files that exceed Excel’s capacity. Python can process entire directories of log files, web scraping results, or database exports efficiently using loops and batch operations.</li>
<li><strong>Complex Pattern Requirements:</strong> For advanced regex features not exposed in Excel’s function interface, such as named capturing groups (<code>(?P&lt;name&gt;...)</code>), lookbehind assertions of variable width, atomic grouping, or fine-grained control over matching behavior through multiple flags (<code>re.DOTALL</code>, <code>re.VERBOSE</code>, <code>re.MULTILINE</code>).</li>
<li><strong>Automated and Scheduled Tasks:</strong> When text processing needs to be part of automated pipelines, ETL processes, or scheduled scripts. Python excels at unattended operations, error handling, and integration with other systems (databases, APIs, file systems).</li>
<li><strong>Multi-step Text Processing Workflows:</strong> For complex text analysis requiring multiple regex operations, conditional logic, or integration with other Python libraries (pandas for data manipulation, requests for web scraping, json for API responses). Excel’s formula-based approach becomes unwieldy for multi-step transformations.</li>
<li><strong>Performance-critical Applications:</strong> When processing speed is crucial, Python’s <code>re.compile()</code> optimization for repeated pattern usage, combined with the ability to implement efficient algorithms and data structures, often outperforms Excel’s calculation engine for intensive regex operations.</li>
<li><strong>Integration with Machine Learning and NLP:</strong> When regex is part of a larger text preprocessing pipeline for natural language processing, sentiment analysis, or machine learning models. Python’s ecosystem (NLTK, spaCy, scikit-learn) seamlessly integrates with regex operations.</li>
<li><strong>Log File Analysis and System Monitoring:</strong> For parsing server logs, application logs, or system outputs where patterns may span multiple lines, require precise timing analysis, or need to be aggregated across thousands of files. Python’s file handling and string processing capabilities far exceed what’s practical in Excel.</li>
<li><strong>Web Scraping and API Data Processing:</strong> When extracting structured data from HTML, XML, JSON responses, or other semi-structured formats where regex is combined with HTTP requests, DOM parsing, or API authentication. Python’s requests library and regex integration provide a powerful combination.</li>
<li><strong>Cross-platform and Deployment Scenarios:</strong> When the text processing solution needs to run on servers, cloud environments, or non-Windows systems where Excel may not be available. Python scripts are highly portable and can be deployed virtually anywhere.</li>
<li><strong>Version Control and Collaboration on Logic:</strong> When the regex patterns and processing logic need to be version-controlled, peer-reviewed, or maintained as part of a larger codebase. Python scripts integrate naturally with Git workflows and software development practices.</li>
</ul>
<p>The decision between Excel and Python should ultimately be driven by the scope, complexity, and operational context of the task. Excel excels in interactive, exploratory scenarios with moderate complexity, while Python dominates in automated, large-scale, and feature-rich applications.</p>
</section>
<section id="references" class="level2">
<h2 class="anchored" data-anchor-id="references">References</h2>
<ol type="1">
<li>Regular Expressions in Excel | Exceljet, accessed July 24, 2025, <a href="https://exceljet.net/articles/regular-expressions-in-excel">https://exceljet.net/articles/regular-expressions-in-excel</a></li>
<li>Excel RegEx examples: using regular expressions in formulas - Ablebits.com, accessed July 24, 2025, <a href="https://www.ablebits.com/office-addins-blog/excel-regex-formulas/">https://www.ablebits.com/office-addins-blog/excel-regex-formulas/</a></li>
<li>Excel(ent) Obfuscation: Regex Gone Rogue - Deep Instinct, accessed July 24, 2025, <a href="https://www.deepinstinct.com/blog/excellent-obfuscation-regex-gone-rogue">https://www.deepinstinct.com/blog/excellent-obfuscation-regex-gone-rogue</a></li>
<li>Mastering the Power of Regular Expressions with Python’s ‘re’ Module: A Comprehensive Guide with Examples | by Khaleel ur Rehman | Medium, accessed July 24, 2025, <a href="https://medium.com/@khaleel92/mastering-the-power-of-regular-expressions-with-pythons-re-module-a-comprehensive-guide-with-141b855ac403">https://medium.com/<span class="citation" data-cites="khaleel92/mastering-the-power-of-regular-expressions-with-pythons-re-module-a-comprehensive-guide-with-141b855ac403">@khaleel92/mastering-the-power-of-regular-expressions-with-pythons-re-module-a-comprehensive-guide-with-141b855ac403</span></a></li>
<li>Python Regular Expression (RegEX) - Simplilearn.com, accessed July 24, 2025, <a href="https://www.simplilearn.com/tutorials/python-tutorial/python-regular-expressions">https://www.simplilearn.com/tutorials/python-tutorial/python-regular-expressions</a></li>
<li>Introducing the new REGEX function set in Excel, accessed July 24, 2025, <a href="https://globalexcelsummit.com/post/introducing-the-new-regex-function-set-in-excel">https://globalexcelsummit.com/post/introducing-the-new-regex-function-set-in-excel</a></li>
<li>How to use Regular Expressions (Regex) in Microsoft Excel both in-cell and loops, accessed July 24, 2025, <a href="https://stackoverflow.com/questions/22542834/how-to-use-regular-expressions-regex-in-microsoft-excel-both-in-cell-and-loops">https://stackoverflow.com/questions/22542834/how-to-use-regular-expressions-regex-in-microsoft-excel-both-in-cell-and-loops</a></li>
<li>Excel gets Regular Expression functions - Office Watch, accessed July 24, 2025, <a href="https://office-watch.com/2025/huge-news-excel-gets-regular-expression-functions/">https://office-watch.com/2025/huge-news-excel-gets-regular-expression-functions/</a></li>
<li>Regular Expression HOWTO — Python 3.13.5 documentation, accessed July 24, 2025, <a href="https://docs.python.org/3/howto/regex.html">https://docs.python.org/3/howto/regex.html</a></li>
<li>REGEXTEST Function - Microsoft Support, accessed July 24, 2025, <a href="https://support.microsoft.com/en-us/office/regextest-function-7d38200b-5e5c-4196-b4e6-9bff73afbd31">https://support.microsoft.com/en-us/office/regextest-function-7d38200b-5e5c-4196-b4e6-9bff73afbd31</a></li>
<li>REGEXEXTRACT Function - Microsoft Support, accessed July 24, 2025, <a href="https://support.microsoft.com/en-us/office/regexextract-function-4b96c140-9205-4b6e-9fbe-6aa9e783ff57">https://support.microsoft.com/en-us/office/regexextract-function-4b96c140-9205-4b6e-9fbe-6aa9e783ff57</a></li>
<li>REGEXREPLACE Function - Microsoft Support, accessed July 24, 2025, <a href="https://support.microsoft.com/en-us/office/regexreplace-function-9c030bb2-5e47-4efc-bad5-4582d7100897">https://support.microsoft.com/en-us/office/regexreplace-function-9c030bb2-5e47-4efc-bad5-4582d7100897</a></li>
<li>PCRE2 - Perl-Compatible Regular Expressions - GitHub Pages, accessed July 24, 2025, <a href="https://pcre2project.github.io/pcre2/">https://pcre2project.github.io/pcre2/</a></li>
<li>Perl Compatible Regular Expressions - Wikipedia, accessed July 24, 2025, <a href="https://en.wikipedia.org/wiki/Perl_Compatible_Regular_Expressions">https://en.wikipedia.org/wiki/Perl_Compatible_Regular_Expressions</a></li>
<li>7.2. re — Regular expression operations — Jython v2.5.2 …, accessed July 24, 2025, <a href="https://www.jython.org/jython-old-sites/docs/library/re.html">https://www.jython.org/jython-old-sites/docs/library/re.html</a></li>
<li>Lookahead and Lookbehind Tutorial—Tips &amp;Tricks - RexEgg, accessed July 24, 2025, <a href="https://www.rexegg.com/regex-lookarounds.php">https://www.rexegg.com/regex-lookarounds.php</a></li>
<li>Regex Tutorial - Lookahead and Lookbehind Zero-Length Assertions, accessed July 24, 2025, <a href="https://www.regular-expressions.info/lookaround.html">https://www.regular-expressions.info/lookaround.html</a></li>
<li>Text.Regex.Pcre2 - Hackage, accessed July 24, 2025, <a href="https://hackage.haskell.org/package/pcre2/docs/Text-Regex-Pcre2.html">https://hackage.haskell.org/package/pcre2/docs/Text-Regex-Pcre2.html</a></li>
</ol>


</section>
</section>

 ]]></description>
  <category>Excel</category>
  <category>Python</category>
  <guid>https://boardflare.com/posts/2025/python-regex-excel/</guid>
  <pubDate>Fri, 25 Jul 2025 00:00:00 GMT</pubDate>
</item>
<item>
  <title>Python Statistical Functions for Excel</title>
  <link>https://boardflare.com/posts/2025/python-statistical-functions/</link>
  <description><![CDATA[ 





<blockquote class="blockquote">
<p><strong>Historical product note (August 2026):</strong> This article documents statistical functions from the earlier Example Functions / standalone function-authoring workflow. For current work, start with the <a href="../../../apps/excel/python/">reactive notebook product</a> and publish reusable worksheet functions through <a href="../../../apps/excel/python/working-with-excel/#create-excel-functions"><code>BF.FUNCTION()</code></a>.</p>
</blockquote>
<p>We are thrilled to announce the availability of Python-powered statistical functions for Excel users. This release brings the full power of Python’s <a href="https://docs.scipy.org/doc/scipy/reference/stats.html">scipy.stats</a> library directly into your spreadsheets with comprehensive distribution support, advanced statistical methods, and capabilities that go far beyond what native Excel functions provide. Our Python functions enable you to access full distribution support (PDF, CDF, quantiles, and more) for distributions not available in Excel, perform advanced analytics, and leverage the complete toolkit of scipy.stats directly from your spreadsheets.</p>
<!-- more -->
<section id="why-use-python-statistical-functions-in-excel" class="level2">
<h2 class="anchored" data-anchor-id="why-use-python-statistical-functions-in-excel">Why Use Python Statistical Functions in Excel?</h2>
<p>While Excel offers a range of built-in statistical functions, they are often limited in scope. Many distributions are missing, and even for supported distributions, Excel typically only provides basic PDF, CDF, or quantile calculations. In contrast, our Python functions offer:</p>
<ul>
<li><strong>Full distribution support</strong> (PDF, CDF, inverse CDF, survival, inverse survival)</li>
<li><strong>Comprehensive statistics</strong> (mean, median, variance, standard deviation)</li>
<li><strong>Flexible parameterization</strong> (location and scale for all distributions)</li>
<li><strong>Access to distributions not available in Excel</strong></li>
</ul>
</section>
<section id="comparison-table-python-vs.-native-excel-functions" class="level2">
<h2 class="anchored" data-anchor-id="comparison-table-python-vs.-native-excel-functions">Comparison Table: Python vs.&nbsp;Native Excel Functions</h2>
<table class="caption-top table">
<colgroup>
<col style="width: 14%">
<col style="width: 21%">
<col style="width: 63%">
</colgroup>
<thead>
<tr class="header">
<th>Excel Python Function</th>
<th>Native Excel Function(s)</th>
<th>Key Differences</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>BETA</td>
<td>BETA.DIST, BETA.INV</td>
<td>Python adds survival, inverse survival, full stats, and location/scale parameters.</td>
</tr>
<tr class="even">
<td>CAUCHY</td>
<td>—</td>
<td>Not available in Excel; Python provides full distribution and stats.</td>
</tr>
<tr class="odd">
<td>CHISQ</td>
<td>CHISQ.DIST, CHISQ.INV</td>
<td>Python adds survival, inverse survival, full stats, and location/scale parameters.</td>
</tr>
<tr class="even">
<td>EXPON</td>
<td>EXPON.DIST</td>
<td>Python adds quantile, survival, inverse survival, full stats, and location/scale.</td>
</tr>
<tr class="odd">
<td>F_DIST</td>
<td>F.DIST, F.INV</td>
<td>Python adds survival, inverse survival, full stats, and location/scale parameters.</td>
</tr>
<tr class="even">
<td>GAMMA</td>
<td>GAMMA.DIST, GAMMA.INV</td>
<td>Python adds survival, inverse survival, full stats, and location/scale parameters.</td>
</tr>
<tr class="odd">
<td>LAPLACE</td>
<td>—</td>
<td>Not available in Excel; Python provides full distribution and stats.</td>
</tr>
<tr class="even">
<td>LOGNORM</td>
<td>LOGNORM.DIST, LOGNORM.INV</td>
<td>Python adds survival, inverse survival, full stats, and location/scale parameters.</td>
</tr>
<tr class="odd">
<td>NORM</td>
<td>NORM.DIST, NORM.INV</td>
<td>Python adds survival, inverse survival, full stats, and location/scale parameters.</td>
</tr>
<tr class="even">
<td>PARETO</td>
<td>—</td>
<td>Not available in Excel; Python provides full distribution and stats.</td>
</tr>
<tr class="odd">
<td>T_DIST</td>
<td>T.DIST, T.DIST.2T, T.DIST.RT, T.INV, T.INV.2T</td>
<td>Python adds survival, inverse survival, full stats, and location/scale parameters.</td>
</tr>
<tr class="even">
<td>UNIFORM</td>
<td>RAND, RANDBETWEEN</td>
<td>Python provides full distribution (PDF, CDF, quantile, etc.) and stats, not available in Excel.</td>
</tr>
<tr class="odd">
<td>WEIBULL_MIN</td>
<td>WEIBULL.DIST</td>
<td>Python adds quantile, survival, inverse survival, full stats, and location/scale.</td>
</tr>
</tbody>
</table>
<p><strong>Legend:</strong> - PDF: Probability Density Function - CDF: Cumulative Distribution Function - Quantile: Inverse CDF - Survival: Survival Function (1 - CDF) - Stats: Mean, Median, Variance, Standard Deviation</p>
</section>
<section id="example-using-python-functions-in-excel" class="level2">
<h2 class="anchored" data-anchor-id="example-using-python-functions-in-excel">Example: Using Python Functions in Excel</h2>
<p>Suppose you want to compute the inverse CDF (quantile) for the Weibull distribution, which is not available in native Excel. With the new Python function, you can simply use:</p>
<pre class="excel"><code>=WEIBULL_MIN(0.95, 1.5, 0, 1, "icdf")</code></pre>
<p>Similarly, for distributions not available in Excel at all (like Pareto or Cauchy), you can now perform advanced statistical analysis directly in your spreadsheet.</p>
</section>
<section id="getting-started" class="level2">
<h2 class="anchored" data-anchor-id="getting-started">Getting Started</h2>
<p>To use these functions, add them from the list of Example Functions in our Python for Excel add-in. Then, simply call the functions as you would any Excel formula.</p>
<p>You can see the full list of available functions in our <a href="https://functions.boardflare.com/">Python Functions Repository</a>.</p>
</section>
<section id="excel-statistical-functions" class="level2">
<h2 class="anchored" data-anchor-id="excel-statistical-functions">Excel Statistical Functions</h2>
<table class="caption-top table">
<colgroup>
<col style="width: 43%">
<col style="width: 56%">
</colgroup>
<thead>
<tr class="header">
<th>Function</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>AVEDEV</td>
<td>Returns the average of the absolute deviations of data points from their mean</td>
</tr>
<tr class="even">
<td>AVERAGE</td>
<td>Returns the average of its arguments</td>
</tr>
<tr class="odd">
<td>AVERAGEA</td>
<td>Returns the average of its arguments, including numbers, text, and logical values</td>
</tr>
<tr class="even">
<td>AVERAGEIF</td>
<td>Returns the average (arithmetic mean) of all the cells in a range that meet a given criteria</td>
</tr>
<tr class="odd">
<td>AVERAGEIFS</td>
<td>Returns the average (arithmetic mean) of all cells that meet multiple criteria</td>
</tr>
<tr class="even">
<td>BETA.DIST</td>
<td>Returns the beta cumulative distribution function</td>
</tr>
<tr class="odd">
<td>BETA.INV</td>
<td>Returns the inverse of the cumulative distribution function for a specified beta distribution</td>
</tr>
<tr class="even">
<td>BINOM.DIST</td>
<td>Returns the individual term binomial distribution probability</td>
</tr>
<tr class="odd">
<td>BINOM.DIST.RANGE</td>
<td>Returns the probability of a trial result using a binomial distribution</td>
</tr>
<tr class="even">
<td>BINOM.INV</td>
<td>Returns the smallest value for which the cumulative binomial distribution is less than or equal to a criterion value</td>
</tr>
<tr class="odd">
<td>CHISQ.DIST</td>
<td>Returns the cumulative beta probability density function</td>
</tr>
<tr class="even">
<td>CHISQ.DIST.RT</td>
<td>Returns the one-tailed probability of the chi-squared distribution</td>
</tr>
<tr class="odd">
<td>CHISQ.INV</td>
<td>Returns the cumulative beta probability density function</td>
</tr>
<tr class="even">
<td>CHISQ.INV.RT</td>
<td>Returns the inverse of the one-tailed probability of the chi-squared distribution</td>
</tr>
<tr class="odd">
<td>CHISQ.TEST</td>
<td>Returns the test for independence</td>
</tr>
<tr class="even">
<td>CONFIDENCE.NORM</td>
<td>Returns the confidence interval for a population mean</td>
</tr>
<tr class="odd">
<td>CONFIDENCE.T</td>
<td>Returns the confidence interval for a population mean, using a Student’s t distribution</td>
</tr>
<tr class="even">
<td>CORREL</td>
<td>Returns the correlation coefficient between two data sets</td>
</tr>
<tr class="odd">
<td>COUNT</td>
<td>Counts how many numbers are in the list of arguments</td>
</tr>
<tr class="even">
<td>COUNTA</td>
<td>Counts how many values are in the list of arguments</td>
</tr>
<tr class="odd">
<td>COUNTBLANK</td>
<td>Counts the number of blank cells within a range</td>
</tr>
<tr class="even">
<td>COUNTIF</td>
<td>Counts the number of cells within a range that meet the given criteria</td>
</tr>
<tr class="odd">
<td>COUNTIFS</td>
<td>Counts the number of cells within a range that meet multiple criteria</td>
</tr>
<tr class="even">
<td>COVARIANCE.P</td>
<td>Returns covariance, the average of the products of paired deviations</td>
</tr>
<tr class="odd">
<td>COVARIANCE.S</td>
<td>Returns the sample covariance, the average of the products deviations for each data point pair in two data sets</td>
</tr>
<tr class="even">
<td>DEVSQ</td>
<td>Returns the sum of squares of deviations</td>
</tr>
<tr class="odd">
<td>EXPON.DIST</td>
<td>Returns the exponential distribution</td>
</tr>
<tr class="even">
<td>F.DIST</td>
<td>Returns the F probability distribution</td>
</tr>
<tr class="odd">
<td>F.DIST.RT</td>
<td>Returns the F probability distribution</td>
</tr>
<tr class="even">
<td>F.INV</td>
<td>Returns the inverse of the F probability distribution</td>
</tr>
<tr class="odd">
<td>F.INV.RT</td>
<td>Returns the inverse of the F probability distribution</td>
</tr>
<tr class="even">
<td>F.TEST</td>
<td>Returns the result of an F-test</td>
</tr>
<tr class="odd">
<td>FISHER</td>
<td>Returns the Fisher transformation</td>
</tr>
<tr class="even">
<td>FISHERINV</td>
<td>Returns the inverse of the Fisher transformation</td>
</tr>
<tr class="odd">
<td>FORECAST</td>
<td>Returns a value along a linear trend</td>
</tr>
<tr class="even">
<td>FORECAST.ETS</td>
<td>Returns a future value based on existing (historical) values by using the AAA version of the Exponential Smoothing (ETS) algorithm</td>
</tr>
<tr class="odd">
<td>FORECAST.ETS.CONFINT</td>
<td>Returns a confidence interval for the forecast value at the specified target date</td>
</tr>
<tr class="even">
<td>FORECAST.ETS.SEASONALITY</td>
<td>Returns the length of the repetitive pattern Excel detects for the specified time series</td>
</tr>
<tr class="odd">
<td>FORECAST.ETS.STAT</td>
<td>Returns a statistical value as a result of time series forecasting</td>
</tr>
<tr class="even">
<td>FORECAST.LINEAR</td>
<td>Returns a future value based on existing values</td>
</tr>
<tr class="odd">
<td>FREQUENCY</td>
<td>Returns a frequency distribution as a vertical array</td>
</tr>
<tr class="even">
<td>GAMMA</td>
<td>Returns the gamma function value</td>
</tr>
<tr class="odd">
<td>GAMMA.DIST</td>
<td>Returns the gamma distribution</td>
</tr>
<tr class="even">
<td>GAMMA.INV</td>
<td>Returns the inverse of the gamma cumulative distribution</td>
</tr>
<tr class="odd">
<td>GAMMALN</td>
<td>Returns the natural logarithm of the gamma function, Γ(x)</td>
</tr>
<tr class="even">
<td>GAMMALN.PRECISE</td>
<td>Returns the natural logarithm of the gamma function, Γ(x)</td>
</tr>
<tr class="odd">
<td>GAUSS</td>
<td>Returns 0.5 less than the standard normal cumulative distribution</td>
</tr>
<tr class="even">
<td>GEOMEAN</td>
<td>Returns the geometric mean</td>
</tr>
<tr class="odd">
<td>GROWTH</td>
<td>Returns values along an exponential trend</td>
</tr>
<tr class="even">
<td>HARMEAN</td>
<td>Returns the harmonic mean</td>
</tr>
<tr class="odd">
<td>HYPGEOM.DIST</td>
<td>Returns the hypergeometric distribution</td>
</tr>
<tr class="even">
<td>INTERCEPT</td>
<td>Returns the intercept of the linear regression line</td>
</tr>
<tr class="odd">
<td>KURT</td>
<td>Returns the kurtosis of a data set</td>
</tr>
<tr class="even">
<td>LARGE</td>
<td>Returns the k-th largest value in a data set</td>
</tr>
<tr class="odd">
<td>LINEST</td>
<td>Returns the parameters of a linear trend</td>
</tr>
<tr class="even">
<td>LOGEST</td>
<td>Returns the parameters of an exponential trend</td>
</tr>
<tr class="odd">
<td>LOGNORM.DIST</td>
<td>Returns the cumulative lognormal distribution</td>
</tr>
<tr class="even">
<td>LOGNORM.INV</td>
<td>Returns the inverse of the lognormal cumulative distribution</td>
</tr>
<tr class="odd">
<td>MAX</td>
<td>Returns the maximum value in a list of arguments</td>
</tr>
<tr class="even">
<td>MAXA</td>
<td>Returns the maximum value in a list of arguments, including numbers, text, and logical values</td>
</tr>
<tr class="odd">
<td>MAXIFS</td>
<td>Returns the maximum value among cells specified by a given set of conditions or criteria</td>
</tr>
<tr class="even">
<td>MEDIAN</td>
<td>Returns the median of the given numbers</td>
</tr>
<tr class="odd">
<td>MIN</td>
<td>Returns the minimum value in a list of arguments</td>
</tr>
<tr class="even">
<td>MINIFS</td>
<td>Returns the minimum value among cells specified by a given set of conditions or criteria.</td>
</tr>
<tr class="odd">
<td>MINA</td>
<td>Returns the smallest value in a list of arguments, including numbers, text, and logical values</td>
</tr>
<tr class="even">
<td>MODE.MULT</td>
<td>Returns a vertical array of the most frequently occurring, or repetitive values in an array or range of data</td>
</tr>
<tr class="odd">
<td>MODE.SNGL</td>
<td>Returns the most common value in a data set</td>
</tr>
<tr class="even">
<td>NEGBINOM.DIST</td>
<td>Returns the negative binomial distribution</td>
</tr>
<tr class="odd">
<td>NORM.DIST</td>
<td>Returns the normal cumulative distribution</td>
</tr>
<tr class="even">
<td>NORM.INV</td>
<td>Returns the inverse of the normal cumulative distribution</td>
</tr>
<tr class="odd">
<td>NORM.S.DIST</td>
<td>Returns the standard normal cumulative distribution</td>
</tr>
<tr class="even">
<td>NORM.S.INV</td>
<td>Returns the inverse of the standard normal cumulative distribution</td>
</tr>
<tr class="odd">
<td>PEARSON</td>
<td>Returns the Pearson product moment correlation coefficient</td>
</tr>
<tr class="even">
<td>PERCENTILE.EXC</td>
<td>Returns the k-th percentile of values in a range, where k is in the range 0 to 1, exclusive.</td>
</tr>
<tr class="odd">
<td>PERCENTILE.INC</td>
<td>Returns the k-th percentile of values in a range</td>
</tr>
<tr class="even">
<td>PERCENTRANK.EXC</td>
<td>Returns the rank of a value in a data set as a percentage (0 to 1, exclusive) of the data set</td>
</tr>
<tr class="odd">
<td>PERCENTRANK.INC</td>
<td>Returns the percentage rank of a value in a data set</td>
</tr>
<tr class="even">
<td>PERMUT</td>
<td>Returns the number of permutations for a given number of objects</td>
</tr>
<tr class="odd">
<td>PERMUTATIONA</td>
<td>Returns the number of permutations for a given number of objects (with repetitions) that can be selected from the total objects</td>
</tr>
<tr class="even">
<td>PHI</td>
<td>Returns the value of the density function for a standard normal distribution</td>
</tr>
<tr class="odd">
<td>POISSON.DIST</td>
<td>Returns the Poisson distribution</td>
</tr>
<tr class="even">
<td>PROB</td>
<td>Returns the probability that values in a range are between two limits</td>
</tr>
<tr class="odd">
<td>QUARTILE.EXC</td>
<td>Returns the quartile of the data set, based on percentile values from 0 to 1, exclusive</td>
</tr>
<tr class="even">
<td>QUARTILE.INC</td>
<td>Returns the quartile of a data set</td>
</tr>
<tr class="odd">
<td>RANK.AVG</td>
<td>Returns the rank of a number in a list of numbers</td>
</tr>
<tr class="even">
<td>RANK.EQ</td>
<td>Returns the rank of a number in a list of numbers</td>
</tr>
<tr class="odd">
<td>RSQ</td>
<td>Returns the square of the Pearson product moment correlation coefficient</td>
</tr>
<tr class="even">
<td>SKEW</td>
<td>Returns the skewness of a distribution</td>
</tr>
<tr class="odd">
<td>SKEW.P</td>
<td>Returns the skewness of a distribution based on a population: a characterization of the degree of asymmetry of a distribution around its mean</td>
</tr>
<tr class="even">
<td>SLOPE</td>
<td>Returns the slope of the linear regression line</td>
</tr>
<tr class="odd">
<td>SMALL</td>
<td>Returns the k-th smallest value in a data set</td>
</tr>
<tr class="even">
<td>STANDARDIZE</td>
<td>Returns a normalized value</td>
</tr>
<tr class="odd">
<td>STDEV.P</td>
<td>Calculates standard deviation based on the entire population</td>
</tr>
<tr class="even">
<td>STDEV.S</td>
<td>Estimates standard deviation based on a sample</td>
</tr>
<tr class="odd">
<td>STDEVA</td>
<td>Estimates standard deviation based on a sample, including numbers, text, and logical values</td>
</tr>
<tr class="even">
<td>STDEVPA</td>
<td>Calculates standard deviation based on the entire population, including numbers, text, and logical values</td>
</tr>
<tr class="odd">
<td>STEYX</td>
<td>Returns the standard error of the predicted y-value for each x in the regression</td>
</tr>
<tr class="even">
<td>T.DIST</td>
<td>Returns the Percentage Points (probability) for the Student t-distribution</td>
</tr>
<tr class="odd">
<td>T.DIST.2T</td>
<td>Returns the Percentage Points (probability) for the Student t-distribution</td>
</tr>
<tr class="even">
<td>T.DIST.RT</td>
<td>Returns the Student’s t-distribution</td>
</tr>
<tr class="odd">
<td>T.INV</td>
<td>Returns the t-value of the Student’s t-distribution as a function of the probability and the degrees of freedom</td>
</tr>
<tr class="even">
<td>T.INV.2T</td>
<td>Returns the inverse of the Student’s t-distribution</td>
</tr>
<tr class="odd">
<td>T.TEST</td>
<td>Returns the probability associated with a Student’s t-test</td>
</tr>
<tr class="even">
<td>TREND</td>
<td>Returns values along a linear trend</td>
</tr>
<tr class="odd">
<td>TRIMMEAN</td>
<td>Returns the mean of the interior of a data set</td>
</tr>
<tr class="even">
<td>VAR.P</td>
<td>Calculates variance based on the entire population</td>
</tr>
<tr class="odd">
<td>VAR.S</td>
<td>Estimates variance based on a sample</td>
</tr>
<tr class="even">
<td>VARA</td>
<td>Estimates variance based on a sample, including numbers, text, and logical values</td>
</tr>
<tr class="odd">
<td>VARPA</td>
<td>Calculates variance based on the entire population, including numbers, text, and logical values</td>
</tr>
<tr class="even">
<td>WEIBULL.DIST</td>
<td>Returns the Weibull distribution</td>
</tr>
<tr class="odd">
<td>Z.TEST</td>
<td>Returns the one-tailed probability-value of a z-test</td>
</tr>
</tbody>
</table>


</section>

 ]]></description>
  <category>Python</category>
  <category>Statistics</category>
  <category>Excel</category>
  <guid>https://boardflare.com/posts/2025/python-statistical-functions/</guid>
  <pubDate>Wed, 09 Jul 2025 00:00:00 GMT</pubDate>
</item>
<item>
  <title>Python Functions Repository</title>
  <link>https://boardflare.com/posts/2025/python-functions-repo/</link>
  <description><![CDATA[ 





<blockquote class="blockquote">
<p><strong>Historical product note (August 2026):</strong> This article describes the earlier function-repository/custom-function workflow. The current Python for Excel product is centered on a <a href="../../../apps/excel/python/">reactive notebook</a> that can publish worksheet functions through <a href="../../../apps/excel/python/working-with-excel/#create-excel-functions"><code>BF.FUNCTION()</code></a>. The separate functions repository may still be useful as historical/example material, but it is not the primary current authoring path.</p>
</blockquote>
<p>We’ve launched a repository of <a href="https://functions.boardflare.com/">Python Functions</a> that can be used in Excel as custom functions through the <a href="../../../apps/excel/python/">Python for Excel add-in</a> and as web apps via <a href="https://www.gradio.app/">Gradio</a>.</p>
<!-- more -->
<p>Our goal is to provide a broad range of example functions that demonstrate how Python can extend Excel’s capabilities, enabling users to perform complex calculations, data analysis, and automation tasks directly within their spreadsheets. These can be used to accelerate the building your own custom functions tailored to your specific business needs.</p>
<p>Please be aware that these functions are not rigorously tested, so they should not be used as-is for production purposes without further validation. They are provided purely as examples.</p>
<section id="why-use-python-functions-in-excel" class="level2">
<h2 class="anchored" data-anchor-id="why-use-python-functions-in-excel">Why Use Python Functions in Excel?</h2>
<p>While Excel is a powerful tool for calculations and data analysis, it has limitations when it comes to advanced analytics, automation, and integration. Python functions allow you to: - Perform advanced statistical analysis, optimization, and modeling using industry-standard libraries. - Connect to APIs, web data, and external sources with just a formula. - Analyze unstructured data, such as text, with natural language processing tools. - Build custom solutions that scale beyond what is possible with built-in Excel features.</p>
</section>
<section id="request-a-function" class="level2">
<h2 class="anchored" data-anchor-id="request-a-function">Request a Function</h2>
<p>If there is a function you’d like to see, please <a href="../../../company/support/">Contact us</a>.</p>


</section>

 ]]></description>
  <category>Python</category>
  <category>Excel</category>
  <guid>https://boardflare.com/posts/2025/python-functions-repo/</guid>
  <pubDate>Tue, 03 Jun 2025 00:00:00 GMT</pubDate>
</item>
<item>
  <title>Applications of AI in a Spreadsheet</title>
  <link>https://boardflare.com/posts/2025/applications-ai-spreadsheets/</link>
  <description><![CDATA[ 





<p>Spreadsheets have long been the workhorse of data organization, calculation, and analysis. From simple budgets to complex financial models, their grid-based structure provides a powerful way to manage information. However, dealing with unstructured text, complex data cleaning, pattern recognition beyond simple formulas, and generating insights often required manual effort or specialized tools outside the spreadsheet environment.</p>
<p>The integration of Artificial Intelligence (AI) directly into spreadsheet functions is changing this paradigm. Now, users can leverage the power of large language models (LLMs) and other AI techniques to perform tasks that were previously difficult or impossible within the confines of rows and columns. This document explores the diverse applications of AI in spreadsheets, transforming them from static data containers into dynamic tools for insight generation, automation, and enhanced productivity.</p>
<p>Discover how AI-powered functions like <code>AI_ASK</code>, <code>AI_EXTRACT</code>, <code>AI_FORMAT</code>, and others are revolutionizing spreadsheet workflows by enabling natural language interaction, intelligent data extraction, and automated pattern recognition. These capabilities transform spreadsheets into powerful tools for insight generation, data processing, and workflow automation across diverse business domains.</p>
<!-- more -->
<section id="core-ai-capabilities-in-spreadsheets" class="level2">
<h2 class="anchored" data-anchor-id="core-ai-capabilities-in-spreadsheets">Core AI Capabilities in Spreadsheets</h2>
<p>Modern AI spreadsheet functions bring several core capabilities directly to your data:</p>
<ol type="1">
<li><strong>Natural Language Understanding &amp; Generation:</strong> Interacting with your data using plain English, generating text, answering questions, and summarizing content (<code>AI_ASK</code>).</li>
<li><strong>Data Extraction &amp; Structuring:</strong> Pulling specific pieces of information from unstructured text and organizing it into tables (<code>AI_EXTRACT</code>, <code>AI_TABLE</code>).</li>
<li><strong>Data Cleaning &amp; Formatting:</strong> Standardizing inconsistent data formats (dates, addresses, names) automatically (<code>AI_FORMAT</code>).</li>
<li><strong>Pattern Recognition &amp; Completion:</strong> Identifying complex patterns in data and filling in missing values or extending series based on examples (<code>AI_FILL</code>).</li>
<li><strong>Classification &amp; Categorization:</strong> Assigning labels or categories to data based on criteria or examples (e.g., sentiment analysis, topic modeling) (<code>AI_CHOICE</code>).</li>
<li><strong>List Generation:</strong> Create lists based on prompts or existing data (<code>AI_LIST</code>).</li>
</ol>
</section>
<section id="available-ai-text-functions" class="level2">
<h2 class="anchored" data-anchor-id="available-ai-text-functions">Available AI Text Functions</h2>
<p>The following functions leverage AI to work with text data:</p>
<table class="caption-top table">
<thead>
<tr class="header">
<th>Function Name</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td><a href="https://functions.boardflare.com/">AI_ASK</a></td>
<td>Ask questions, summarize, generate text</td>
</tr>
<tr class="even">
<td><a href="https://functions.boardflare.com/">AI_CHOICE</a></td>
<td>Classify or categorize text</td>
</tr>
<tr class="odd">
<td><a href="https://functions.boardflare.com/">AI_EXTRACT</a></td>
<td>Extract specific information from text</td>
</tr>
<tr class="even">
<td><a href="https://functions.boardflare.com/">AI_FILL</a></td>
<td>Fill missing data or infer patterns</td>
</tr>
<tr class="odd">
<td><a href="https://functions.boardflare.com/">AI_FORMAT</a></td>
<td>Clean, standardize, or reformat text</td>
</tr>
<tr class="even">
<td><a href="https://functions.boardflare.com/">AI_LIST</a></td>
<td>Generate lists or extract items</td>
</tr>
<tr class="odd">
<td><a href="https://functions.boardflare.com/">AI_TABLE</a></td>
<td>Convert unstructured text into tables</td>
</tr>
</tbody>
</table>
<p>Let’s delve into practical applications of these capabilities.</p>
</section>
<section id="application-examples" class="level2">
<h2 class="anchored" data-anchor-id="application-examples">Application Examples</h2>
<section id="market-research-customer-feedback-analysis" class="level3">
<h3 class="anchored" data-anchor-id="market-research-customer-feedback-analysis">Market Research &amp; Customer Feedback Analysis</h3>
<p>AI functions can revolutionize how businesses analyze customer feedback, reviews, and survey responses.</p>
<p><strong>Sentiment Analysis:</strong> Quickly gauge customer feelings from text.</p>
<ul>
<li><strong>Input Data:</strong></li>
</ul>
<table class="caption-top table">
<thead>
<tr class="header">
<th style="text-align: left;">Customer ID</th>
<th style="text-align: left;">Feedback Text</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td style="text-align: left;">CUST-001</td>
<td style="text-align: left;">The new interface is amazing and so intuitive!</td>
</tr>
<tr class="even">
<td style="text-align: left;">CUST-002</td>
<td style="text-align: left;">I’m really frustrated with the latest update.</td>
</tr>
<tr class="odd">
<td style="text-align: left;">CUST-003</td>
<td style="text-align: left;">It’s okay, but I expected more features.</td>
</tr>
<tr class="even">
<td style="text-align: left;">CUST-004</td>
<td style="text-align: left;">Excellent customer support, resolved my issue fast.</td>
</tr>
</tbody>
</table>
<ul>
<li><strong>AI Application (<code>AI_CHOICE</code>):</strong> <code>=AI_CHOICE(B2, "Positive, Negative, Neutral")</code></li>
<li><strong>Output:</strong></li>
</ul>
<table class="caption-top table">
<colgroup>
<col style="width: 15%">
<col style="width: 71%">
<col style="width: 12%">
</colgroup>
<thead>
<tr class="header">
<th style="text-align: left;">Customer ID</th>
<th style="text-align: left;">Feedback Text</th>
<th style="text-align: left;">Sentiment</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td style="text-align: left;">CUST-001</td>
<td style="text-align: left;">The new interface is amazing and so intuitive!</td>
<td style="text-align: left;">Positive</td>
</tr>
<tr class="even">
<td style="text-align: left;">CUST-002</td>
<td style="text-align: left;">I’m really frustrated with the latest update.</td>
<td style="text-align: left;">Negative</td>
</tr>
<tr class="odd">
<td style="text-align: left;">CUST-003</td>
<td style="text-align: left;">It’s okay, but I expected more features.</td>
<td style="text-align: left;">Neutral</td>
</tr>
<tr class="even">
<td style="text-align: left;">CUST-004</td>
<td style="text-align: left;">Excellent customer support, resolved my issue fast.</td>
<td style="text-align: left;">Positive</td>
</tr>
</tbody>
</table>
<p><strong>Topic Extraction:</strong> Identify key themes mentioned in feedback.</p>
<ul>
<li><strong>Input Data:</strong> (Same as above)</li>
<li><strong>AI Application (<code>AI_EXTRACT</code>):</strong> <code>=AI_EXTRACT(B2, "the main topic")</code></li>
<li><strong>Output:</strong></li>
</ul>
<table class="caption-top table">
<colgroup>
<col style="width: 14%">
<col style="width: 64%">
<col style="width: 21%">
</colgroup>
<thead>
<tr class="header">
<th style="text-align: left;">Customer ID</th>
<th style="text-align: left;">Feedback Text</th>
<th style="text-align: left;">Main Topic</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td style="text-align: left;">CUST-001</td>
<td style="text-align: left;">The new interface is amazing and so intuitive!</td>
<td style="text-align: left;">User Interface</td>
</tr>
<tr class="even">
<td style="text-align: left;">CUST-002</td>
<td style="text-align: left;">I’m really frustrated with the latest update.</td>
<td style="text-align: left;">Software Update</td>
</tr>
<tr class="odd">
<td style="text-align: left;">CUST-003</td>
<td style="text-align: left;">It’s okay, but I expected more features.</td>
<td style="text-align: left;">Feature Request</td>
</tr>
<tr class="even">
<td style="text-align: left;">CUST-004</td>
<td style="text-align: left;">Excellent customer support, resolved my issue fast.</td>
<td style="text-align: left;">Customer Support</td>
</tr>
</tbody>
</table>
<p><strong>Summarization:</strong> Condense long reviews or comments.</p>
<ul>
<li><strong>Input Data:</strong></li>
</ul>
<table class="caption-top table">
<colgroup>
<col style="width: 5%">
<col style="width: 94%">
</colgroup>
<thead>
<tr class="header">
<th style="text-align: left;">Review ID</th>
<th style="text-align: left;">Full Review Text</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td style="text-align: left;">REV-101</td>
<td style="text-align: left;">This product exceeded my expectations. The build quality is solid, setup was straightforward, and it performs exactly as advertised. I did find the manual a bit confusing in one section, but overall, highly recommended.</td>
</tr>
<tr class="even">
<td style="text-align: left;">REV-102</td>
<td style="text-align: left;">Initially, I was skeptical, but after using it for a week, I’m impressed. It integrates well with my existing setup. The price point is fair for the value provided. Customer service was responsive when I had a question.</td>
</tr>
</tbody>
</table>
<ul>
<li><strong>AI Application (<code>AI_ASK</code>):</strong> <code>=AI_ASK("Summarize the following review in one sentence:", B2)</code></li>
<li><strong>Output:</strong></li>
</ul>
<table class="caption-top table">
<colgroup>
<col style="width: 8%">
<col style="width: 91%">
</colgroup>
<thead>
<tr class="header">
<th style="text-align: left;">Review ID</th>
<th style="text-align: left;">Summary</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td style="text-align: left;">REV-101</td>
<td style="text-align: left;">The reviewer highly recommends the product for its solid build quality and performance, despite a slightly confusing manual section.</td>
</tr>
<tr class="even">
<td style="text-align: left;">REV-102</td>
<td style="text-align: left;">The reviewer is impressed with the product’s performance, integration, fair price, and responsive customer service after initial skepticism.</td>
</tr>
</tbody>
</table>
</section>
<section id="sales-marketing-automation" class="level3">
<h3 class="anchored" data-anchor-id="sales-marketing-automation">Sales &amp; Marketing Automation</h3>
<p>Streamline lead management, content creation, and outreach personalization.</p>
<p><strong>Lead Qualification:</strong> Categorize leads based on descriptions or interactions.</p>
<ul>
<li><strong>Input Data:</strong></li>
</ul>
<table class="caption-top table">
<colgroup>
<col style="width: 9%">
<col style="width: 90%">
</colgroup>
<thead>
<tr class="header">
<th style="text-align: left;">Lead ID</th>
<th style="text-align: left;">Notes</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td style="text-align: left;">LEAD-50</td>
<td style="text-align: left;">Met at conference, interested in enterprise plan, budget &gt;$50k.</td>
</tr>
<tr class="even">
<td style="text-align: left;">LEAD-51</td>
<td style="text-align: left;">Downloaded whitepaper, student email address.</td>
</tr>
<tr class="odd">
<td style="text-align: left;">LEAD-52</td>
<td style="text-align: left;">Requested demo, VP of Operations at mid-size tech company.</td>
</tr>
<tr class="even">
<td style="text-align: left;">LEAD-53</td>
<td style="text-align: left;">Asked basic pricing questions via chat, seemed unsure of needs.</td>
</tr>
</tbody>
</table>
<ul>
<li><strong>AI Application (<code>AI_CHOICE</code>):</strong> <code>=AI_CHOICE(B2, "Hot, Warm, Cold")</code></li>
<li><strong>Output:</strong></li>
</ul>
<table class="caption-top table">
<colgroup>
<col style="width: 7%">
<col style="width: 77%">
<col style="width: 14%">
</colgroup>
<thead>
<tr class="header">
<th style="text-align: left;">Lead ID</th>
<th style="text-align: left;">Notes</th>
<th style="text-align: left;">Qualification</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td style="text-align: left;">LEAD-50</td>
<td style="text-align: left;">Met at conference, interested in enterprise plan, budget &gt;$50k.</td>
<td style="text-align: left;">Hot</td>
</tr>
<tr class="even">
<td style="text-align: left;">LEAD-51</td>
<td style="text-align: left;">Downloaded whitepaper, student email address.</td>
<td style="text-align: left;">Cold</td>
</tr>
<tr class="odd">
<td style="text-align: left;">LEAD-52</td>
<td style="text-align: left;">Requested demo, VP of Operations at mid-size tech company.</td>
<td style="text-align: left;">Hot</td>
</tr>
<tr class="even">
<td style="text-align: left;">LEAD-53</td>
<td style="text-align: left;">Asked basic pricing questions via chat, seemed unsure of needs.</td>
<td style="text-align: left;">Warm</td>
</tr>
</tbody>
</table>
<p><strong>Extracting Contact Information:</strong> Pull emails, phone numbers, or company names from text blocks.</p>
<ul>
<li><strong>Input Data:</strong></li>
</ul>
<table class="caption-top table">
<colgroup>
<col style="width: 100%">
</colgroup>
<thead>
<tr class="header">
<th style="text-align: left;">Source Text</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td style="text-align: left;">Met with John Doe (john.doe@example.com, 555-1234) from Acme Corp yesterday. Follow up next week.</td>
</tr>
<tr class="even">
<td style="text-align: left;">Received inquiry from Jane Smith at Beta Industries. Her email is jane.s@beta.co and phone is 555-987-6543.</td>
</tr>
</tbody>
</table>
<ul>
<li><strong>AI Application (<code>AI_EXTRACT</code>):</strong> <code>=AI_EXTRACT(A2, "the email address")</code></li>
<li><strong>Output:</strong></li>
</ul>
<table class="caption-top table">
<thead>
<tr class="header">
<th style="text-align: left;">Email Address</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td style="text-align: left;">john.doe@example.com</td>
</tr>
<tr class="even">
<td style="text-align: left;">jane.s@beta.co</td>
</tr>
</tbody>
</table>
</section>
<section id="data-cleaning-and-standardization" class="level3">
<h3 class="anchored" data-anchor-id="data-cleaning-and-standardization">Data Cleaning and Standardization</h3>
<p>AI can tackle messy data that traditional formulas struggle with.</p>
<p><strong>Formatting Addresses:</strong> Standardize inconsistent address formats.</p>
<ul>
<li><strong>Input Data:</strong></li>
</ul>
<table class="caption-top table">
<thead>
<tr class="header">
<th style="text-align: left;">Raw Address</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td style="text-align: left;">123 main st., anytown, ca 90210</td>
</tr>
<tr class="even">
<td style="text-align: left;">456 Oak Avenue, Springfield IL</td>
</tr>
<tr class="odd">
<td style="text-align: left;">789 elm rd apt 2b new york ny</td>
</tr>
</tbody>
</table>
<ul>
<li><strong>AI Application (<code>AI_FORMAT</code>):</strong> <code>=AI_FORMAT(A2, "Standard US Address format: Street, City, ST ZIP")</code></li>
<li><strong>Output:</strong></li>
</ul>
<table class="caption-top table">
<thead>
<tr class="header">
<th style="text-align: left;">Standardized Address</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td style="text-align: left;">123 Main St, Anytown, CA 90210</td>
</tr>
<tr class="even">
<td style="text-align: left;">456 Oak Ave, Springfield, IL 62704</td>
</tr>
<tr class="odd">
<td style="text-align: left;">789 Elm Rd Apt 2B, New York, NY 10001</td>
</tr>
</tbody>
</table>
<p><strong>Cleaning Names:</strong> Correct capitalization and potentially identify parts of names.</p>
<ul>
<li><strong>Input Data:</strong></li>
</ul>
<table class="caption-top table">
<thead>
<tr class="header">
<th style="text-align: left;">Raw Name</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td style="text-align: left;">john SMITH</td>
</tr>
<tr class="even">
<td style="text-align: left;">mary-anne jones</td>
</tr>
<tr class="odd">
<td style="text-align: left;">dr. peter pan</td>
</tr>
</tbody>
</table>
<ul>
<li><strong>AI Application (<code>AI_FORMAT</code>):</strong> <code>=AI_FORMAT(A2, "Proper Name Capitalization")</code></li>
<li><strong>Output:</strong></li>
</ul>
<table class="caption-top table">
<thead>
<tr class="header">
<th style="text-align: left;">Cleaned Name</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td style="text-align: left;">John Smith</td>
</tr>
<tr class="even">
<td style="text-align: left;">Mary-Anne Jones</td>
</tr>
<tr class="odd">
<td style="text-align: left;">Dr.&nbsp;Peter Pan</td>
</tr>
</tbody>
</table>
</section>
<section id="content-creation-brainstorming" class="level3">
<h3 class="anchored" data-anchor-id="content-creation-brainstorming">Content Creation &amp; Brainstorming</h3>
<p>Leverage AI to generate ideas and draft content directly within your spreadsheet planning environment.</p>
<p><strong>Generating Ideas:</strong> Brainstorm blog post titles, marketing slogans, or feature names.</p>
<ul>
<li><strong>Input Data:</strong></li>
</ul>
<table class="caption-top table">
<thead>
<tr class="header">
<th style="text-align: left;">Topic</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td style="text-align: left;">Sustainable Urban Gardening</td>
</tr>
<tr class="even">
<td style="text-align: left;">Productivity Hacks for Teams</td>
</tr>
<tr class="odd">
<td style="text-align: left;">Introduction to Quantum Computing</td>
</tr>
</tbody>
</table>
<ul>
<li><strong>AI Application (<code>AI_LIST</code>):</strong> <code>=AI_LIST("Generate 5 blog post titles about "&amp;A2)</code></li>
<li><strong>Output (Example for Row 1):</strong></li>
</ul>
<table class="caption-top table">
<thead>
<tr class="header">
<th style="text-align: left;">Generated Titles</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td style="text-align: left;">5 Easy Steps to Start Your Urban Garden Sustainably</td>
</tr>
<tr class="even">
<td style="text-align: left;">Balcony Bounty: Sustainable Gardening in Small Spaces</td>
</tr>
<tr class="odd">
<td style="text-align: left;">The Future is Green: Why Cities Need Sustainable Gardens</td>
</tr>
<tr class="even">
<td style="text-align: left;">Reduce Your Footprint: Composting Tips for Urban Gardeners</td>
</tr>
<tr class="odd">
<td style="text-align: left;">Grow Local: The Benefits of Sustainable Urban Agriculture</td>
</tr>
</tbody>
</table>
<p><strong>Creating Structured Data from Text:</strong> Turn meeting notes or descriptions into tables.</p>
<ul>
<li><strong>Input Data:</strong></li>
</ul>
<table class="caption-top table">
<colgroup>
<col style="width: 100%">
</colgroup>
<thead>
<tr class="header">
<th style="text-align: left;">Notes</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td style="text-align: left;">Meeting Summary 2025-04-23: Discussed Project Phoenix launch. Action: Alice to finalize marketing brief by EOD Friday. Action: Bob to update budget forecast by Monday. Decision: Launch date set for June 1st.</td>
</tr>
</tbody>
</table>
<ul>
<li><strong>AI Application (<code>AI_TABLE</code>):</strong> <code>=AI_TABLE(A2, "Action Item, Owner, Due Date")</code></li>
<li><strong>Output:</strong></li>
</ul>
<table class="caption-top table">
<thead>
<tr class="header">
<th style="text-align: left;">Action Item</th>
<th style="text-align: left;">Owner</th>
<th style="text-align: left;">Due Date</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td style="text-align: left;">Finalize marketing brief</td>
<td style="text-align: left;">Alice</td>
<td style="text-align: left;">Friday</td>
</tr>
<tr class="even">
<td style="text-align: left;">Update budget forecast</td>
<td style="text-align: left;">Bob</td>
<td style="text-align: left;">Monday</td>
</tr>
</tbody>
</table>
</section>
<section id="pattern-recognition-and-data-augmentation" class="level3">
<h3 class="anchored" data-anchor-id="pattern-recognition-and-data-augmentation">Pattern Recognition and Data Augmentation</h3>
<p><code>AI_FILL</code> allows you to go beyond simple series filling (like 1, 2, 3…) to recognize complex relationships and fill data based on examples.</p>
<ul>
<li><strong>Input Data &amp; Goal:</strong> Fill in the ‘Category’ based on the ‘Product SKU’ pattern.</li>
</ul>
<table class="caption-top table">
<thead>
<tr class="header">
<th style="text-align: left;">Product SKU</th>
<th style="text-align: left;">Description</th>
<th style="text-align: left;">Category</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td style="text-align: left;">ELEC-TV-001</td>
<td style="text-align: left;">55” Smart TV</td>
<td style="text-align: left;">Electronics</td>
</tr>
<tr class="even">
<td style="text-align: left;">FURN-SOFA-005</td>
<td style="text-align: left;">3-Seater Couch</td>
<td style="text-align: left;">Furniture</td>
</tr>
<tr class="odd">
<td style="text-align: left;">ELEC-CAM-010</td>
<td style="text-align: left;">Digital Camera</td>
<td style="text-align: left;">Electronics</td>
</tr>
<tr class="even">
<td style="text-align: left;">KITC-MIX-002</td>
<td style="text-align: left;">Stand Mixer</td>
<td style="text-align: left;"></td>
</tr>
<tr class="odd">
<td style="text-align: left;">FURN-TABLE-003</td>
<td style="text-align: left;">Dining Table</td>
<td style="text-align: left;"></td>
</tr>
<tr class="even">
<td style="text-align: left;">ELEC-PHONE-007</td>
<td style="text-align: left;">Smartphone</td>
<td style="text-align: left;"></td>
</tr>
</tbody>
</table>
<ul>
<li><strong>AI Application (<code>AI_FILL</code>):</strong> Using example_range of the first 3 rows and fill_range of the remaining 3 rows with missing categories</li>
<li><strong>Output:</strong></li>
</ul>
<table class="caption-top table">
<thead>
<tr class="header">
<th style="text-align: left;">Product SKU</th>
<th style="text-align: left;">Description</th>
<th style="text-align: left;">Category</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td style="text-align: left;">ELEC-TV-001</td>
<td style="text-align: left;">55” Smart TV</td>
<td style="text-align: left;">Electronics</td>
</tr>
<tr class="even">
<td style="text-align: left;">FURN-SOFA-005</td>
<td style="text-align: left;">3-Seater Couch</td>
<td style="text-align: left;">Furniture</td>
</tr>
<tr class="odd">
<td style="text-align: left;">ELEC-CAM-010</td>
<td style="text-align: left;">Digital Camera</td>
<td style="text-align: left;">Electronics</td>
</tr>
<tr class="even">
<td style="text-align: left;">KITC-MIX-002</td>
<td style="text-align: left;">Stand Mixer</td>
<td style="text-align: left;">Kitchen</td>
</tr>
<tr class="odd">
<td style="text-align: left;">FURN-TABLE-003</td>
<td style="text-align: left;">Dining Table</td>
<td style="text-align: left;">Furniture</td>
</tr>
<tr class="even">
<td style="text-align: left;">ELEC-PHONE-007</td>
<td style="text-align: left;">Smartphone</td>
<td style="text-align: left;">Electronics</td>
</tr>
</tbody>
</table>
<ul>
<li><strong>Industry Inference Example:</strong> Use <code>AI_FILL</code> to infer the likely industry of a company based on its name and a few examples (e.g., provide examples like “Tech Innovations Inc.” -&gt; “Technology”, “Global Logistics Co.” -&gt; “Logistics”).</li>
</ul>
</section>
</section>
<section id="combining-ai-functions-for-complex-workflows" class="level2">
<h2 class="anchored" data-anchor-id="combining-ai-functions-for-complex-workflows">Combining AI Functions for Complex Workflows</h2>
<p>The true power emerges when combining these functions. Imagine analyzing product feedback:</p>
<ol type="1">
<li><strong>Paste Raw Feedback:</strong> Place raw customer feedback text into Column A.</li>
<li><strong>Extract Product Name (<code>AI_EXTRACT</code>):</strong> In Column B, use <code>=AI_EXTRACT(A2, "the product name mentioned")</code>.</li>
<li><strong>Analyze Sentiment (<code>AI_CHOICE</code>):</strong> In Column C, use <code>=AI_CHOICE(A2, "Positive, Negative, Neutral")</code>.</li>
<li><strong>Extract Key Topics (<code>AI_LIST</code>):</strong> In Column D, use <code>=AI_LIST(A2, "List key topics or features mentioned")</code>.</li>
<li><strong>Summarize Feedback (<code>AI_ASK</code>):</strong> In Column E, use <code>=AI_ASK("Summarize the feedback in one sentence:", A2)</code>.</li>
</ol>
<p>This creates a structured dashboard from unstructured text, ready for pivoting, filtering, and further analysis – all within the spreadsheet.</p>
</section>
<section id="tips-for-effective-use" class="level2">
<h2 class="anchored" data-anchor-id="tips-for-effective-use">Tips for Effective Use</h2>
<ul>
<li><strong>Be Specific with Prompts:</strong> The clearer your instruction (for <code>AI_ASK</code>, <code>AI_FORMAT</code>, <code>AI_EXTRACT</code>, etc.), the better the result. Instead of “fix this”, try “Format as YYYY-MM-DD date”.</li>
<li><strong>Provide Good Examples:</strong> For functions like <code>AI_FILL</code> or <code>AI_CHOICE</code> (when used with examples), ensure your examples accurately represent the desired output and cover different scenarios.</li>
<li><strong>Start Small:</strong> Test AI functions on a subset of your data first to understand their behavior and refine your prompts.</li>
<li><strong>Review Results:</strong> AI is powerful but not infallible. Always review the generated results for accuracy, especially for critical data.</li>
<li><strong>Understand Limitations:</strong> Be aware of potential biases in the AI models and any usage limits or costs associated with the functions.</li>
<li><strong>Consult Documentation:</strong> For detailed usage, parameters, and more examples, see the linked documentation for each function in the table above.</li>
</ul>
</section>
<section id="conclusion" class="level2">
<h2 class="anchored" data-anchor-id="conclusion">Conclusion</h2>
<p>Integrating AI into spreadsheets transforms them from passive calculators into active partners in data analysis and workflow automation. By leveraging natural language processing, pattern recognition, and data structuring capabilities, users can:</p>
<ul>
<li>Quickly extract insights from unstructured text.</li>
<li>Automate tedious data cleaning and formatting tasks.</li>
<li>Generate creative content and ideas efficiently.</li>
<li>Build more sophisticated and automated workflows.</li>
</ul>
<p>As AI technology continues to evolve, its applications within the familiar spreadsheet environment will only grow, further empowering users to unlock the value hidden within their data. This shift marks a significant evolution, making advanced data manipulation and insight generation accessible to a much broader audience.</p>


</section>

 ]]></description>
  <category>Excel</category>
  <category>AI</category>
  <guid>https://boardflare.com/posts/2025/applications-ai-spreadsheets/</guid>
  <pubDate>Sun, 20 Apr 2025 00:00:00 GMT</pubDate>
</item>
<item>
  <title>Python for Excel Code Editor</title>
  <link>https://boardflare.com/posts/2025/python-excel-code-editor/</link>
  <description><![CDATA[ 





<blockquote class="blockquote">
<p><strong>Historical product note (August 2026):</strong> This article documents Boardflare’s earlier standalone Functions Editor workflow. The current Python for Excel experience is centered on a <a href="../../../apps/excel/python/">reactive notebook</a> with notebook-published <code>BF.FUNCTION()</code> functions. The retained <a href="../../../apps/excel/python/functions-editor/">Legacy Functions Editor</a> remains available for older standalone-function workflows.</p>
</blockquote>
<p>We’re excited to announce a major update to our Python for Excel add-in that makes it easier than ever to create Excel LAMBDA functions from Python code. The new code editor provides a familiar VS Code-like experience right inside Excel, with features like syntax highlighting, function management, and integrated testing.</p>
<!-- more -->
<section id="key-features" class="level2">
<h2 class="anchored" data-anchor-id="key-features">Key Features</h2>
<section id="monaco-editor-integration" class="level3">
<h3 class="anchored" data-anchor-id="monaco-editor-integration">Monaco Editor Integration</h3>
<p>The add-in now includes the same editor (<a href="https://github.com/microsoft/monaco-editor">Monaco</a>) used in VS Code, providing: - Syntax highlighting for Python - Code completion and formatting - Error detection</p>
</section>
<section id="function-management" class="level3">
<h3 class="anchored" data-anchor-id="function-management">Function Management</h3>
<p>A new Functions tab lets you: - View all Python functions in your workbook - Edit existing functions - Delete unused functions - Import functions from Jupyter notebooks</p>
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><img src="https://boardflare.com/posts/2025/python-excel-code-editor/functions-tab.png" class="img-fluid figure-img"></p>
<figcaption>Functions Tab</figcaption>
</figure>
</div>
</section>
<section id="testing-integration" class="level3">
<h3 class="anchored" data-anchor-id="testing-integration">Testing Integration</h3>
<p>Write test cases directly in your Python code:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb1" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb1-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> hello(first, last):</span>
<span id="cb1-2">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">""" Returns a greeting. """</span></span>
<span id="cb1-3">    greeting <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">f"Hello </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>first<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> last<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">!"</span></span>
<span id="cb1-4">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> greeting</span>
<span id="cb1-5">    </span>
<span id="cb1-6"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Test cases for the function</span></span>
<span id="cb1-7">test_cases <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> [[<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Nancy"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Morgan"</span>], [<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Ming"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Lee"</span>]]</span>
<span id="cb1-8"></span>
<span id="cb1-9"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Excel usage: =HELLO("Nancy", "Morgan")</span></span></code></pre></div></div>
<p>Click “Test” to run your cases and see results in the Output tab.</p>
</section>
</section>
<section id="how-it-works" class="level2">
<h2 class="anchored" data-anchor-id="how-it-works">How It Works</h2>
<p>Creating a Python-powered LAMBDA function is now a two-step process:</p>
<ol type="1">
<li>Write your Python function in the editor</li>
<li>Click Save to create the LAMBDA</li>
</ol>
<p>The Python code is stored in workbook settings and a corresponding LAMBDA function is automatically created in Excel’s name manager. For example, this Python function:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb2" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb2-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> inches_to_mm(inches):</span>
<span id="cb2-2">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">""" Converts inches to millimeters. """</span></span>
<span id="cb2-3">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> inches <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">25.4</span></span></code></pre></div></div>
<p>Creates this LAMBDA in Excel:</p>
<pre class="excel"><code>=LAMBDA(inches, BOARDFLARE.EXEC("workbook-settings:inches_to_mm", inches))</code></pre>
</section>
<section id="jupyter-notebook-integration" class="level2">
<h2 class="anchored" data-anchor-id="jupyter-notebook-integration">Jupyter Notebook Integration</h2>
<p>A particularly exciting feature is the ability to import functions from Jupyter notebooks. You can: - Import from our example notebooks - Load notebooks from GitHub Gists - Use the notebooks as templates for your own functions</p>
<p>This makes it easy to maintain a library of functions in notebooks and import them into Excel as needed.</p>
</section>
<section id="try-it-out" class="level2">
<h2 class="anchored" data-anchor-id="try-it-out">Try It Out</h2>
<p>To get started with the new code editor:</p>
<ol type="1">
<li>Install the <a href="https://appsource.microsoft.com/en-us/product/office/WA200007447?tab=Overview">Python for Excel add-in</a></li>
<li>Open the task pane and go to the Editor tab</li>
<li>Try writing a simple function or import one of our examples</li>
<li>Click Save to create your LAMBDA function</li>
</ol>
<p>The code editor is available now in version 1.1.0 of the add-in. For more details, check out our <a href="../../../apps/excel/python/">updated documentation</a>.</p>
</section>
<section id="whats-next" class="level2">
<h2 class="anchored" data-anchor-id="whats-next">What’s Next?</h2>
<p>We’re continuing to improve the editor experience. Coming soon: - Support for optional arguments - More example notebooks - Enhanced type conversion options</p>
<p>Let us know what features you’d like to see next!</p>


</section>

 ]]></description>
  <category>Excel</category>
  <category>Python</category>
  <category>Add-ins</category>
  <guid>https://boardflare.com/posts/2025/python-excel-code-editor/</guid>
  <pubDate>Sat, 18 Jan 2025 00:00:00 GMT</pubDate>
</item>
<item>
  <title>Fuzzy Matching with Python in Excel</title>
  <link>https://boardflare.com/posts/2024/fuzzy-matching-python-excel/</link>
  <description><![CDATA[ 





<blockquote class="blockquote">
<p><strong>Historical product note (August 2026):</strong> The <code>BOARDFLARE.RUNPY</code> workflow shown later in this article belongs to an earlier version of Boardflare Python for Excel. For current work, start with the <a href="../../../apps/excel/python/">reactive notebook workflow</a> and its <a href="../../../apps/excel/python/troubleshooting-and-reference/#workbook-api">workbook API</a>.</p>
</blockquote>
<p>Fuzzy matching is a technique used to find strings that are approximately equal, e.g.&nbsp;“Microsoft” and “Microsoft Inc”. This is particularly useful in scenarios where exact matches are not possible due to typographical errors, variations in spelling, or other inconsistencies. In this post, we will explore how to perform fuzzy matching with <a href="https://techcommunity.microsoft.com/t5/excel-blog/python-in-excel-available-now/ba-p/4240212">Python in Excel</a> using the <a href="https://github.com/nltk/nltk">NLTK</a> library.</p>
<p>Our <a href="https://functions.boardflare.com/">text_distance</a> function for fuzzy matching is similar to that used in our <a href="../../../apps/excel/fuzzy-match/">Fuzzy Match</a> app, but supports many more algorithms and can be readily modified to your specific needs. Actually, we’ve recently updated our <a href="../../../resources/tasks/nlp/fuzzy-match/">Fuzzy Match tutorial</a> with more details.</p>
<!-- more -->
<section id="nltk-library" class="level2">
<h2 class="anchored" data-anchor-id="nltk-library">NLTK Library</h2>
<p>The <a href="https://www.nltk.org/">Natural Language Toolkit (NLTK)</a> is a powerful library for natural language processing. It provides various tools and algorithms for text processing, including tokenization, stemming, lemmatization, and distance metrics. We will focus on using NLTK to calculate similarity scores between strings for fuzzy matching.</p>
<p>An example of calculating the similarity of two strings using <code>edit_distance</code> is shown below:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb1" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb1-1"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">from</span> nltk.metrics.distance <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> edit_distance</span>
<span id="cb1-2"></span>
<span id="cb1-3">string1 <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"apple"</span></span>
<span id="cb1-4">string2 <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"apples"</span></span>
<span id="cb1-5">distance <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> edit_distance(string1, string2)</span>
<span id="cb1-6"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span>(distance)</span></code></pre></div></div>
<p>In this example, the <code>edit_distance</code> function calculates the minimum number of single-character edits required to change one string into the other. The output will be <code>1</code>, indicating that the strings ‘apple’ and ‘apples’ have an edit distance of 1.</p>
<p>NLTK supports various distance metrics for calculating similarity between strings, including:</p>
<ul>
<li><strong>Jaccard Distance</strong>: Measures the similarity between two sets by comparing the intersection and union of the sets.</li>
<li><strong>Levenshtein Distance</strong>: Calculates the minimum number of single-character edits required to change one word into the other.</li>
<li><strong>Jaro Similarity</strong>: Measures the similarity between two strings by considering the number of matching characters and transpositions.</li>
</ul>
</section>
<section id="python-function" class="level2">
<h2 class="anchored" data-anchor-id="python-function">Python Function</h2>
<p>We’ve created the <code>nltk_distance</code> function to handle the typical use-case in Excel of finding a match for a <code>lookup_value</code> in a <code>lookup_array</code>, similar to how the <code>XMATCH</code> function works. It normalizes the edit_distance results to a similarity score of 0-1 for easier comparison. The function is as follows:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb2" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb2-1"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> nltk</span>
<span id="cb2-2"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> pandas <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">as</span> pd</span>
<span id="cb2-3"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">from</span> nltk.metrics.distance <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> edit_distance, jaccard_distance, jaro_similarity</span>
<span id="cb2-4"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">from</span> nltk.util <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> ngrams</span>
<span id="cb2-5"></span>
<span id="cb2-6"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> nltk_distance(lookup_value, lookup_array_df, algorithm):</span>
<span id="cb2-7">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">"""</span></span>
<span id="cb2-8"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">    Calculate the similarity between a lookup_value and a lookup_array using various distance algorithms.</span></span>
<span id="cb2-9"></span>
<span id="cb2-10"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">    Parameters:</span></span>
<span id="cb2-11"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">    lookup_value (str or pd.DataFrame): The string or DataFrame to search for.</span></span>
<span id="cb2-12"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">    lookup_array_df (pd.DataFrame): The DataFrame to search within.</span></span>
<span id="cb2-13"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">    algorithm (str): The algorithm to use for calculating similarity. Options are 'levenshtein', 'jaccard', and 'jaro'. Default is 'jaccard'.</span></span>
<span id="cb2-14"></span>
<span id="cb2-15"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">    Returns:</span></span>
<span id="cb2-16"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">    list: A list of lists where each sublist contains the index (1-based) and the similarity score of the most similar item in the lookup_array.</span></span>
<span id="cb2-17"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">    """</span></span>
<span id="cb2-18">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Define a dictionary to map algorithm names to functions</span></span>
<span id="cb2-19">    algo_funcs <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> {</span>
<span id="cb2-20">        <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'levenshtein'</span>: <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">lambda</span> x, y: <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> edit_distance(x, y) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">max</span>(<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">len</span>(x), <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">len</span>(y)),</span>
<span id="cb2-21">        <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'jaccard'</span>: <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">lambda</span> x, y: <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> jaccard_distance(<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">set</span>(ngrams(x, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>)), <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">set</span>(ngrams(y, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>))),</span>
<span id="cb2-22">        <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'jaro'</span>: jaro_similarity</span>
<span id="cb2-23">    }</span>
<span id="cb2-24">    </span>
<span id="cb2-25">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Get the algorithm function from the dictionary</span></span>
<span id="cb2-26">    algo_func <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> algo_funcs.get(algorithm)</span>
<span id="cb2-27">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> algo_func <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">is</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">None</span>:</span>
<span id="cb2-28">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">raise</span> <span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">ValueError</span>(<span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">f"Unsupported algorithm: </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>algorithm<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span>)</span>
<span id="cb2-29">    </span>
<span id="cb2-30">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Flatten the DataFrame to a list</span></span>
<span id="cb2-31">    lookup_array <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> lookup_array_df.values.flatten().tolist()</span>
<span id="cb2-32">    </span>
<span id="cb2-33">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Check if lookup_value is a DataFrame</span></span>
<span id="cb2-34">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">isinstance</span>(lookup_value, pd.DataFrame):</span>
<span id="cb2-35">        lookup_value_list <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> lookup_value.values.flatten().tolist()</span>
<span id="cb2-36">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">else</span>:</span>
<span id="cb2-37">        lookup_value_list <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> [lookup_value]</span>
<span id="cb2-38">    </span>
<span id="cb2-39">    results <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> [] </span>
<span id="cb2-40">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> lookup_value_item <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> lookup_value_list:</span>
<span id="cb2-41">        <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Calculate similarity scores and round to 2 decimal places</span></span>
<span id="cb2-42">        scores <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> [(index <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>, <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">round</span>(algo_func(lookup_value_item, item), <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>)) <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> index, item <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">enumerate</span>(lookup_array)]</span>
<span id="cb2-43">        </span>
<span id="cb2-44">        <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Sort based on scores in descending order</span></span>
<span id="cb2-45">        scores.sort(key<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">lambda</span> x: x[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>], reverse<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">True</span>)</span>
<span id="cb2-46">        <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Append the top index and score to results as a list</span></span>
<span id="cb2-47">        results.append(<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">list</span>(scores[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>]))</span>
<span id="cb2-48"></span>
<span id="cb2-49">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># results is 2D list, e.g. [[1, 0.75], [2, 0.85]]</span></span>
<span id="cb2-50">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> results</span>
<span id="cb2-51"></span>
<span id="cb2-52">nltk_distance(arg1, arg2, arg3)</span></code></pre></div></div>
<p>The <code>nltk_distance</code> function takes three arguments:</p>
<ul>
<li><code>lookup_value</code>: The string or DataFrame to search for, e.g.&nbsp;“apple” or <code>pd.DataFrame(["apple", "banana"])</code>.</li>
<li><code>lookup_array_df</code>: The DataFrame to search within, e.g.&nbsp;<code>pd.DataFrame(["apples", "bananas", "cherries"])</code>.</li>
<li><code>algorithm</code>: The algorithm to use for calculating similarity. Options are <code>'levenshtein'</code>, <code>'jaccard'</code>, and <code>'jaro'</code>.</li>
</ul>
<p>The function returns a list of lists, where each sublist contains the index (1-based), similar to <code>XMATCH</code>, and the similarity score of the most similar item in the <code>lookup_array</code>. For example, <code>[[1, 0.75], [2, 0.85]]</code> indicates that the most similar item to the first <code>lookup_value</code> has an index of 1 and a similarity score of 0.75, and the most similar item to the second <code>lookup_value</code> has an index of 2 and a similarity score of 0.85. This matches the array output expected by Excel.</p>
</section>
<section id="use-in-excel" class="level2">
<h2 class="anchored" data-anchor-id="use-in-excel">Use in Excel</h2>
<section id="excel-py" class="level3">
<h3 class="anchored" data-anchor-id="excel-py">EXCEL PY()</h3>
<p>In an Excel PY() cell, start by assigning the values of the function arguments <code>arg1, arg2, arg3</code> to the appropriate data in the workbook, then paste the function code below it. For example, if the range <code>A6:A10</code> contains the lookup values, the range <code>B6:B27</code> contains the lookup array, and the cell <code>C6</code> contains the algorithm name, we get the following in the Excel PY() cell:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb3" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb3-1"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>PY(</span>
<span id="cb3-2">arg1 <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> xl(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"A6:A10"</span>) <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># lookup_value</span></span>
<span id="cb3-3">arg2 <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> xl(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"B6:B27"</span>) <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># lookup_array_df</span></span>
<span id="cb3-4">arg3 <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> xl(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"C6"</span>) <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># algorithm</span></span>
<span id="cb3-5"></span>
<span id="cb3-6"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> nltk_distance(lookup_value, lookup_array_df, algorithm):</span>
<span id="cb3-7"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># ... function code omitted for brevity ...</span></span>
<span id="cb3-8">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> results</span>
<span id="cb3-9"></span>
<span id="cb3-10">nltk_distance(arg1, arg2, arg3)</span>
<span id="cb3-11">)</span></code></pre></div></div>
</section>
<section id="boardflare.runpy" class="level3">
<h3 class="anchored" data-anchor-id="boardflare.runpy">BOARDFLARE.RUNPY()</h3>
<p>Assuming the code is contained in cell A1, we can get the same result using the <code>BOARDFLARE.RUNPY</code> function as follows:</p>
<pre class="excel"><code>=BOARDFLARE.RUNPY(A1, A6:A10, B6:B27, C6)</code></pre>
<p>Since <code>nltk_distance</code> is in our functions library, you can call it using the path <code>text/fuzzy-match/nltk_distance.ipynb</code>, and the latest code will be downloaded and executed. For example:</p>
<pre class="excel"><code>=BOARDFLARE.RUNPY("text/fuzzy-match/nltk_distance.ipynb", A6:A10, B6:B27, C6)</code></pre>
<p>One of the benefits of using the <code>BOARDFLARE.RUNPY</code> function is that we can further customize it in Excel using a LAMBDA function. For example, if we want to set a similarity threshold, as follows:</p>
<pre class="excel"><code>=LAMBDA(lookup_value, lookup_array, [similarity_threshold], [algorithm],
    LET(
        threshold, IF(ISOMITTED(similarity_threshold), 0.7, similarity_threshold),
        algo, IF(ISOMITTED(algorithm), "jaccard", algorithm),
        result, BOARDFLARE.RUNPY("text/fuzzy-match/nltk_distance.ipynb", lookup_value, lookup_array, algo),
        index, INDEX(result, 1),
        score, INDEX(result, 2),
        IF(score &gt;= threshold, index, "No match")
    )
)</code></pre>
</section>
</section>
<section id="conclusion" class="level2">
<h2 class="anchored" data-anchor-id="conclusion">Conclusion</h2>
<p>Fuzzy matching is a powerful tool for handling approximate string matching in various applications. The <code>nltk_distance</code> Python function provides a flexible and easy-to-use interface for performing fuzzy matching using different algorithms. It can be run efficiently in Excel using either the <code>Excel PY()</code> or <code>BOARDFLARE.RUNPY</code> functions, enabling users to leverage the power of Python within their Excel workbooks.</p>


</section>

 ]]></description>
  <category>Excel</category>
  <category>Python</category>
  <guid>https://boardflare.com/posts/2024/fuzzy-matching-python-excel/</guid>
  <pubDate>Mon, 04 Nov 2024 00:00:00 GMT</pubDate>
</item>
<item>
  <title>Azure Sentiment Analysis in Excel</title>
  <link>https://boardflare.com/posts/2024/azure-sentiment-analysis/</link>
  <description><![CDATA[ 





<blockquote class="blockquote">
<p><strong>Historical product note (August 2026):</strong> The <code>BOARDFLARE.RUNPY</code> workflow shown later in this article belongs to an earlier version of Boardflare Python for Excel. For current work, start with the <a href="../../../apps/excel/python/">reactive notebook workflow</a> and its <a href="../../../apps/excel/python/troubleshooting-and-reference/#workbook-api">workbook API</a>.</p>
</blockquote>
<p>Azure Sentiment Analysis is a powerful cloud-based service that goes beyond simple sentiment scoring by providing aspect-based sentiment analysis, allowing you to extract sentiment for specific aspects of text (like “food” and “service” in customer reviews). This post demonstrates how to integrate this service with Excel using Python to analyze text data and return results in a tabular format.</p>
<!-- more -->
<section id="background" class="level2">
<h2 class="anchored" data-anchor-id="background">Background</h2>
<p>Azure Sentiment Analysis is a cloud-based service, part of <a href="https://learn.microsoft.com/en-us/azure/ai-services/language-service/sentiment-opinion-mining/overview?tabs=prebuilt">Azure AI Language</a>, that uses machine learning to analyze text for sentiment and opinions. It returns an array containing the sentiment analysis results with sentiment polarity at the document, sentence, and aspect levels. It also provides the opinions used at the aspect level. This is often referred to as <a href="https://paperswithcode.com/task/aspect-based-sentiment-analysis">aspect-based sentiment analysis</a>.</p>
<p>For example, given the text “I love the food, but the service was terrible”, instead of just getting a single sentiment score, which in this case isn’t that useful, we can extract the sentiment for each aspect, such as <code>food</code> = positive and <code>service</code> = negative.</p>
<p>The table below is a contrived example where the aspects have purposely been made to relate to either a <code>food</code> or <code>service</code> type aspect. These aspects were not extracted by the Azure Sentiment Analysis service, but are used here to illustrate the concept of aspect-based sentiment analysis.</p>
<table class="caption-top table">
<colgroup>
<col style="width: 17%">
<col style="width: 38%">
<col style="width: 44%">
</colgroup>
<thead>
<tr class="header">
<th>Review</th>
<th>“Food” Aspect</th>
<th>“Service” Aspect</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>“The pizza was amazing but our waitress seemed uninterested”</td>
<td>pizza</td>
<td>waitress</td>
</tr>
<tr class="even">
<td>“Delicious pasta, though service was slow tonight”</td>
<td>pasta</td>
<td>service</td>
</tr>
<tr class="odd">
<td>“The cuisine is outstanding but the staff was rude”</td>
<td>cuisine</td>
<td>staff</td>
</tr>
<tr class="even">
<td>“Bland menu items and the waiter forgot our order”</td>
<td>menu items</td>
<td>waiter</td>
</tr>
<tr class="odd">
<td>“Great appetizers but long wait times for seating”</td>
<td>appetizers</td>
<td>wait times</td>
</tr>
<tr class="even">
<td>“Fresh ingredients, friendly servers made our night”</td>
<td>ingredients</td>
<td>servers</td>
</tr>
<tr class="odd">
<td>“Tasty dishes but poor customer service experience”</td>
<td>dishes</td>
<td>customer service</td>
</tr>
<tr class="even">
<td>“Mediocre food quality and inattentive waitstaff”</td>
<td>food quality</td>
<td>waitstaff</td>
</tr>
<tr class="odd">
<td>“Excellent menu selection, prompt table service”</td>
<td>menu selection</td>
<td>table service</td>
</tr>
<tr class="even">
<td>“Superb entrees but slow kitchen and rude host”</td>
<td>entrees</td>
<td>kitchen/host</td>
</tr>
</tbody>
</table>
<p>Notice how the words used to describe <code>food</code> and <code>service</code> related aspects are varied, so trying to group them by keyword isn’t practical as the following different words are used for <code>food</code>: pizza, pasta, cuisine, menu items, appetizers, ingredients, dishes, food quality, menu selection, entrees.</p>
<p>To properly summarize the results we need to group the aspects together using <a href="https://en.wikipedia.org/wiki/Semantic_similarity">semantic similarity</a>, typically into clusters of related words. This is beyond the scope of this article.</p>
</section>
<section id="python-function" class="level2">
<h2 class="anchored" data-anchor-id="python-function">Python Function</h2>
<p>To access the Azure Sentiment Analysis service from Excel, we’re going to create a Python function that calls the Azure API and returns the sentiment analysis results. We’ll use the <code>azure-ai-textanalytics</code> Python library which provides a simple interface to the Azure Text Analytics service. In our function we’ll pass in the array of text to analyze, the Azure key, and the Azure endpoint. We want the results in a tabular format, so we need to flatten the structure so that each row contains the sentiment analysis results for a single aspect, and thus there are multiple rows per review.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb1" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb1-1"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">from</span> azure.ai.textanalytics <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> TextAnalyticsClient</span>
<span id="cb1-2"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">from</span> azure.core.credentials <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> AzureKeyCredential</span>
<span id="cb1-3"></span>
<span id="cb1-4"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> azure_sentiment(documents, language_key, language_endpoint):</span>
<span id="cb1-5">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Check if documents is a string, list, or DataFrame</span></span>
<span id="cb1-6">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">isinstance</span>(documents, <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">str</span>):</span>
<span id="cb1-7">        documents <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> [documents]</span>
<span id="cb1-8">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">elif</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">isinstance</span>(documents, pd.DataFrame):</span>
<span id="cb1-9">        documents <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> documents.values.flatten().tolist()  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Convert df to list</span></span>
<span id="cb1-10"></span>
<span id="cb1-11">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Authenticate the client using your key and endpoint </span></span>
<span id="cb1-12">    ta_credential <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> AzureKeyCredential(language_key)</span>
<span id="cb1-13">    client <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> TextAnalyticsClient(</span>
<span id="cb1-14">            endpoint<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>language_endpoint, </span>
<span id="cb1-15">            credential<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>ta_credential)</span>
<span id="cb1-16"></span>
<span id="cb1-17">    result <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> client.analyze_sentiment(documents, show_opinion_mining<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">True</span>)</span>
<span id="cb1-18">    doc_result <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> [doc <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> doc <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> result <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">not</span> doc.is_error]</span>
<span id="cb1-19"></span>
<span id="cb1-20">    data <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> []</span>
<span id="cb1-21"></span>
<span id="cb1-22">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> idx, document <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">enumerate</span>(doc_result):</span>
<span id="cb1-23">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> sentence <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> document.sentences:</span>
<span id="cb1-24">            <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> mined_opinion <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> sentence.mined_opinions:</span>
<span id="cb1-25">                target <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> mined_opinion.target</span>
<span id="cb1-26">                <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> assessment <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> mined_opinion.assessments:</span>
<span id="cb1-27">                    data.append([</span>
<span id="cb1-28">                        idx <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>,  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># 1-based index</span></span>
<span id="cb1-29">                        document.sentiment,</span>
<span id="cb1-30">                        document.confidence_scores.positive,</span>
<span id="cb1-31">                        document.confidence_scores.neutral,</span>
<span id="cb1-32">                        document.confidence_scores.negative,</span>
<span id="cb1-33">                        sentence.text,</span>
<span id="cb1-34">                        sentence.sentiment,</span>
<span id="cb1-35">                        sentence.confidence_scores.positive,</span>
<span id="cb1-36">                        sentence.confidence_scores.neutral,</span>
<span id="cb1-37">                        sentence.confidence_scores.negative,</span>
<span id="cb1-38">                        target.text,</span>
<span id="cb1-39">                        target.sentiment,</span>
<span id="cb1-40">                        target.confidence_scores.positive,</span>
<span id="cb1-41">                        target.confidence_scores.negative,</span>
<span id="cb1-42">                        assessment.text,</span>
<span id="cb1-43">                        assessment.sentiment,</span>
<span id="cb1-44">                        assessment.confidence_scores.positive,</span>
<span id="cb1-45">                        assessment.confidence_scores.negative</span>
<span id="cb1-46">                    ])</span>
<span id="cb1-47">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> data</span>
<span id="cb1-48"></span>
<span id="cb1-49">azure_sentiment(arg1, arg2, arg3)</span></code></pre></div></div>
</section>
<section id="output" class="level2">
<h2 class="anchored" data-anchor-id="output">Output</h2>
<p>The figure below illustrates an example of the results returned by the Azure Sentiment Analysis service for a single document that contains two sentences as follows: <code>The food and service were unacceptable. The concierge was nice, however..</code>.</p>
<div class="cell" data-layout-align="default">
<div class="cell-output-display">
<div>
<p></p><figure class="figure"><p></p>
<div>
<pre class="mermaid mermaid-js">flowchart TD
    Doc["Document: 'The **food** and **service** were **unacceptable**. The **concierge** was **nice**, however.'&lt;br&gt;Sentiment: mixed&lt;br&gt;pos:0.3 neu:0.17 neg:0.52"]
    
    Doc --&gt; S1[Sentence: 'The **food** and **service** were **unacceptable**.'&lt;br&gt;Sentiment: negative&lt;br&gt;pos:0.0 neu:0.0 neg:1.0]
    Doc --&gt; S2[Sentence: 'The **concierge** was **nice**, however.'&lt;br&gt;Sentiment: positive&lt;br&gt;pos:0.61 neu:0.35 neg:0.05]
    
    S1 --&gt; A1[Aspect: **food**&lt;br&gt;Sentiment: negative&lt;br&gt;pos:0.01 neg:0.99]
    S1 --&gt; A2[Aspect: **service**&lt;br&gt;Sentiment: negative&lt;br&gt;pos:0.01 neg:0.99]
    S2 --&gt; A3[Aspect: **concierge**&lt;br&gt;Sentiment: positive&lt;br&gt;pos:1.0 neg:0.0]
    
    A1 --&gt; O1[Opinion: **unacceptable**&lt;br&gt;Sentiment: negative&lt;br&gt;pos:0.01 neg:0.99]
    A2 --&gt; O2[Opinion: **unacceptable**&lt;br&gt;Sentiment: negative&lt;br&gt;pos:0.01 neg:0.99]
    A3 --&gt; O3[Opinion: **nice**&lt;br&gt;Sentiment: positive&lt;br&gt;pos:1.0 neg:0.0]

</pre>
</div>
<p></p></figure><p></p>
</div>
</div>
</div>
<p>The results are then flattened or denormalized into a tabular format where each row contains the sentiment analysis results for a single aspect and duplicates the parent sentence and document. The columns in the output include the document index, document sentiment, document confidence scores, sentence text, sentence sentiment, sentence confidence scores, aspect text, aspect sentiment, aspect confidence scores, opinion text, opinion sentiment, and opinion confidence scores.</p>
</section>
<section id="excel-integration" class="level2">
<h2 class="anchored" data-anchor-id="excel-integration">Excel Integration</h2>
<p>To run this function from Excel we need to use the <code>BOARDFLARE.RUNPY</code> function which is available in the <a href="../../../apps/excel/python/">Boardflare Python for Excel add-in</a>. This function allows you to run Python code from Excel and return the results in a tabular format. The <code>BOARDFLARE.RUNPY</code> function takes a path to the Python code as the first argument, followed by the arguments to pass to the Python function.</p>
<pre class="excel"><code>=BOARDFLARE.RUNPY("text/sentiment-analysis/azure_sentiment.ipynb", A1:A10, "your-azure-key", "your-azure-endpoint")</code></pre>
</section>
<section id="results" class="level2">
<h2 class="anchored" data-anchor-id="results">Results</h2>
<p>As shown in the workbook, running the table of reviews earlier through the Azure Sentiment Analysis generates the following high-level sentiment analysis results:</p>
<table class="caption-top table">
<colgroup>
<col style="width: 33%">
<col style="width: 33%">
<col style="width: 33%">
</colgroup>
<thead>
<tr class="header">
<th style="text-align: left;">Sentence</th>
<th style="text-align: left;">Aspect</th>
<th style="text-align: left;">Opinion</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td style="text-align: left;">The pizza was amazing but our waitress seemed uninterested</td>
<td style="text-align: left;">pizza</td>
<td style="text-align: left;">amazing</td>
</tr>
<tr class="even">
<td style="text-align: left;">The pizza was amazing but our waitress seemed uninterested</td>
<td style="text-align: left;">waitress</td>
<td style="text-align: left;">uninterested</td>
</tr>
<tr class="odd">
<td style="text-align: left;">Delicious pasta, though service was slow tonight</td>
<td style="text-align: left;">pasta</td>
<td style="text-align: left;">Delicious</td>
</tr>
<tr class="even">
<td style="text-align: left;">Delicious pasta, though service was slow tonight</td>
<td style="text-align: left;">service</td>
<td style="text-align: left;">slow</td>
</tr>
<tr class="odd">
<td style="text-align: left;">The cuisine is outstanding but the staff was rude</td>
<td style="text-align: left;">cuisine</td>
<td style="text-align: left;">outstanding</td>
</tr>
<tr class="even">
<td style="text-align: left;">The cuisine is outstanding but the staff was rude</td>
<td style="text-align: left;">staff</td>
<td style="text-align: left;">rude</td>
</tr>
<tr class="odd">
<td style="text-align: left;">Bland menu items and the waiter forgot our order</td>
<td style="text-align: left;">menu items</td>
<td style="text-align: left;">Bland</td>
</tr>
<tr class="even">
<td style="text-align: left;">Bland menu items and the waiter forgot our order</td>
<td style="text-align: left;">waiter</td>
<td style="text-align: left;">forgot</td>
</tr>
<tr class="odd">
<td style="text-align: left;">Great appetizers but long wait times for seating</td>
<td style="text-align: left;">appetizers</td>
<td style="text-align: left;">Great</td>
</tr>
<tr class="even">
<td style="text-align: left;">Fresh ingredients, friendly servers made our night</td>
<td style="text-align: left;">ingredients</td>
<td style="text-align: left;">Fresh</td>
</tr>
<tr class="odd">
<td style="text-align: left;">Fresh ingredients, friendly servers made our night</td>
<td style="text-align: left;">servers</td>
<td style="text-align: left;">friendly</td>
</tr>
<tr class="even">
<td style="text-align: left;">Tasty dishes but poor customer service experience</td>
<td style="text-align: left;">dishes</td>
<td style="text-align: left;">Tasty</td>
</tr>
<tr class="odd">
<td style="text-align: left;">Tasty dishes but poor customer service experience</td>
<td style="text-align: left;">customer service experience</td>
<td style="text-align: left;">poor</td>
</tr>
<tr class="even">
<td style="text-align: left;">Mediocre food quality and inattentive waitstaff</td>
<td style="text-align: left;">food quality</td>
<td style="text-align: left;">Mediocre</td>
</tr>
<tr class="odd">
<td style="text-align: left;">Mediocre food quality and inattentive waitstaff</td>
<td style="text-align: left;">waitstaff</td>
<td style="text-align: left;">inattentive</td>
</tr>
<tr class="even">
<td style="text-align: left;">Excellent menu selection, prompt table service</td>
<td style="text-align: left;">menu selection</td>
<td style="text-align: left;">Excellent</td>
</tr>
<tr class="odd">
<td style="text-align: left;">Excellent menu selection, prompt table service</td>
<td style="text-align: left;">table service</td>
<td style="text-align: left;">prompt</td>
</tr>
<tr class="even">
<td style="text-align: left;">Superb entrees but slow kitchen and rude host</td>
<td style="text-align: left;">entrees</td>
<td style="text-align: left;">Superb</td>
</tr>
<tr class="odd">
<td style="text-align: left;">Superb entrees but slow kitchen and rude host</td>
<td style="text-align: left;">kitchen</td>
<td style="text-align: left;">slow</td>
</tr>
<tr class="even">
<td style="text-align: left;">Superb entrees but slow kitchen and rude host</td>
<td style="text-align: left;">host</td>
<td style="text-align: left;">rude</td>
</tr>
</tbody>
</table>
<p>Most of the columns in the output were omitted for brevity.</p>
</section>
<section id="conclusion" class="level2">
<h2 class="anchored" data-anchor-id="conclusion">Conclusion</h2>
<p>In this article we have shown how to use the Azure Sentiment Analysis service from Excel to analyze sentiment and opinions in text. We have also shown how to flatten the results into a tabular format so that they can be easily analyzed in Excel. This is a powerful tool for analyzing sentiment in text data, and can be used in a variety of applications such as customer support, market research, finance, etc. We have left the task of summarizing the results into clusters of related aspects as an exercise for the reader.</p>


</section>

 ]]></description>
  <category>Excel</category>
  <category>AI</category>
  <category>Azure</category>
  <guid>https://boardflare.com/posts/2024/azure-sentiment-analysis/</guid>
  <pubDate>Fri, 01 Nov 2024 00:00:00 GMT</pubDate>
</item>
<item>
  <title>Python in Excel Functions</title>
  <link>https://boardflare.com/posts/2024/align-with-python-excel/</link>
  <description><![CDATA[ 





<blockquote class="blockquote">
<p><strong>Historical product note (August 2026):</strong> This article documents the earlier <code>BOARDFLARE.RUNPY</code> function workflow. The current Python for Excel product is centered on a <a href="../../../apps/excel/python/">reactive notebook</a> that can publish reusable worksheet functions through <a href="../../../apps/excel/python/troubleshooting-and-reference/#workbook-api"><code>BF.FUNCTION()</code></a>.</p>
</blockquote>
<p>Since we launched Boardflare’s Python for Excel add-in over a month ago, we’ve heard from users that they would like to see more pre-made Python functions that they can use as-is or modify to suit their needs. As we’ve started buiding out a collection of Python functions, we realized that we could align our API with Microsoft’s <a href="https://techcommunity.microsoft.com/t5/excel-blog/python-in-excel-available-now/ba-p/4240212">Python in Excel</a> so that the same code could be used in both with minimal modification.</p>
<!-- more -->
<section id="boardflare.runpy-function" class="level2">
<h2 class="anchored" data-anchor-id="boardflare.runpy-function">🆕 BOARDFLARE.RUNPY function</h2>
<p>To achieve compatibility with Python in Excel, we’ve introduced a new <code>BOARDFLARE.RUNPY</code> function that handles both scalar and array inputs and outputs, and therefore replaces the original <code>BOARDFLARE.PY</code> and <code>BOARDFLARE.PY.ARR</code>functions which are now deprecated. We chose the name <code>RUNPY</code> to reduce potential confusion with Excel’s <code>PY</code> feature and we are not that creative with names.</p>
<p>Like Python in Excel, <code>BOARDFLARE.RUNPY</code> now converts Excel arrays into pandas DataFrames. It also returns the value of the last expression in the Python code, instead of using <code>pyout</code> as the output variable. This approach not only aligns with Python in Excel, but also with Jupyter notebooks.</p>
<p>The net result is that the same function code will work in both, with the only difference being how data is passed as arguments as shown in the following examples:</p>
<p>```python {5} # Using BOARDFLARE.RUNPY def add(a, b): return a + b</p>
<p>add(arg1,arg2)</p>
<pre><code>Assuming the code above is in cell `C2`, the arguments `arg1` and `arg2` are passed to the `BOARDFLARE.RUNPY` function as follows:

```excel
=BOARDFLARE.RUNPY(C2, A2, B2)</code></pre>
<p>With Python in Excel, the same code would be written as follows:</p>
<p>```python {5} # Using Excel’s PY def add(a, b): return a + b</p>
<p>add(xl(“A2”),xl(“B2”))</p>
<pre><code>
Here the `xl` function is used to reference the Excel cells `A2` and `B2` inside the Python code.  The upside of Microsoft's approach is everything is all in one cell, so is easier to make changes when developing code interactively.  The downside is that it is not a function, and therefore can't be used in Excel formulas or LAMBDA functions the way `BOARDFLARE.RUNPY` can.

## Functions collection

We're just getting started on building out a collection of ready-to-use Python [functions](https://functions.boardflare.com/) that can also be used as a starting point for building more complex functions.

For example, we've built a [text_distance](https://functions.boardflare.com/) function for fuzzy matching that is similar to that used in our [Fuzzy Match](/apps/excel/fuzzy-match/) app, but supports many more algorithms and can be readily modified to your specific needs.  Here's the code:

```python
import textdistance
import pandas as pd

def text_distance(needle, haystack_df, algorithm='jaccard'):
    # Get the algorithm function from textdistance
    algo_func = getattr(textdistance, algorithm)
    # Flatten the DataFrame to a list
    haystack = haystack_df.values.flatten().tolist()

    # Check if needle is a DataFrame
    if isinstance(needle, pd.DataFrame):
        needle_list = needle.values.flatten().tolist()
    else:
        needle_list = [needle]

    results = []
    for needle_item in needle_list:
        # Calculate similarity scores with normalization and round to 2 decimal places
        # Adjust index to be 1-based
        scores = [(index + 1, round(algo_func.normalized_similarity(needle_item, item), 2)) for index, item in enumerate(haystack)]
        # Sort based on scores in descending order
        scores.sort(key=lambda x: x[1], reverse=True)
        # Append the top index and score to results as a list
        results.append(list(scores[0]))

    # results is 2D list, e.g. [[1, 0.75], [2, 0.85]]
    return results

text_distance(arg1, arg2, arg3)</code></pre>
</section>
<section id="lambda-functions-using-python" class="level2">
<h2 class="anchored" data-anchor-id="lambda-functions-using-python">LAMBDA functions using Python</h2>
<p>One of the great features of <code>BOARDFLARE.RUNPY</code> is that it can be used to build LAMBDA functions that can be used in Excel formulas. For example, the <code>text_distance</code> function can be used to build a <code>FUZZYMATCH.TD</code> function that is similar to Excel’s <code>XMATCH</code> function, but with the added ability to set a similarity threshold. Here’s the code:</p>
<pre class="excel"><code>=LAMBDA(lookup_value, lookup_array, [similarity_threshold], [algorithm],
    LET(
        threshold, IF(ISOMITTED(similarity_threshold), 0.7, similarity_threshold),
        algo, IF(ISOMITTED(algorithm), "jaccard", algorithm),
        result, BOARDFLARE.RUNPY("text/fuzzy/text_distance.ipynb", lookup_value, lookup_array, algo),
        index, INDEX(result, 1),
        score, INDEX(result, 2),
        IF(score &gt;= threshold, index, "No match")
    )
)</code></pre>


</section>

 ]]></description>
  <category>Excel</category>
  <category>Python</category>
  <guid>https://boardflare.com/posts/2024/align-with-python-excel/</guid>
  <pubDate>Tue, 22 Oct 2024 00:00:00 GMT</pubDate>
</item>
<item>
  <title>Python in Excel Review</title>
  <link>https://boardflare.com/posts/2024/python-in-excel/</link>
  <description><![CDATA[ 





<blockquote class="blockquote">
<p><strong>Historical product note (August 2026):</strong> This 2024 review reflects product capabilities and competitor status at the time it was published. Boardflare Python for Excel is now centered on a <a href="../../../apps/excel/python/">reactive notebook application workflow</a>, and several availability, runtime, package, AI, and product-comparison details below have changed. Use the maintained <a href="../../../apps/excel/python/microsoft-python-in-excel-comparison/">Boardflare vs.&nbsp;Microsoft Python in Excel comparison</a> for current technical guidance.</p>
</blockquote>
<p>Microsoft’s <a href="https://techcommunity.microsoft.com/t5/excel-blog/python-in-excel-available-now/ba-p/4240212">Python in Excel</a> has now reached GA. It enables the user to input Python code and it will return the result as either a Python object or Excel values. You can read in more detail how to use this function in the <a href="https://support.microsoft.com/en-us/office/introduction-to-python-in-excel-55643c2e-ff56-4168-b1ce-9428c8308545">official documentation</a>.</p>
<p>The Python in Excel feature is only available to Microsoft 365 subscribers, and access to the higher performance runtime requires a separate <a href="https://www.microsoft.com/en-us/microsoft-365/python-in-excel">add-on license</a>.</p>
<p>The purpose of this post is to focus on the strengths and potential weaknesses of this implementation and to explore alternatives.</p>
<!-- more -->
<section id="strengths" class="level2">
<h2 class="anchored" data-anchor-id="strengths">Strengths</h2>
<ul>
<li><p><strong>Directly reference cells</strong>: Users can reference cells in Excel directly from Python code using the python <code>xl</code> function, e.g.&nbsp;<code>foo = xl(A1)</code>. This makes it super easy to use Excel data in Python code, similar to how you would with Excel formulas.</p></li>
<li><p><strong>Outputs Python object or Excel values</strong>: Users can select whether the value returned is a Python object or Excel values. This is useful for when you want to use the output in further Python code or in Excel formulas.</p></li>
<li><p><strong>Consistent Python runtime</strong>: An Anaconda Python runtime running in the Microsoft cloud which provides a consistent version of packages and performance for all users regardless of their local machine.</p></li>
<li><p><strong>Microsoft Copilot integration</strong>: This is currently in beta, but provides a great way for non-programmers to get started with Python code in Excel.</p></li>
</ul>
</section>
<section id="potential-weaknesses" class="level2">
<h2 class="anchored" data-anchor-id="potential-weaknesses">Potential Weaknesses</h2>
<p>We realize all of these weaknesses could be considered strengths, depending on the needs of the target market, and we’re sure the Excel product team explicitly chose to do things this way for a reason. However, in some of the use-cases we’re familiar with, these could be considered weaknesses.</p>
<ul>
<li><p><strong>No custom packages</strong>: The Python runtime is limited to the packages available in the Anaconda distribution, which is quite comprehensive, but may lack something specific you need.</p></li>
<li><p><strong>No internet access</strong>: Your Python does not have access to the internet, so you cannot do things like access OpenAI models, call APIs, etc. This basically limits you to analyzing the data in your workbook.</p></li>
<li><p><strong>PY is not an Excel function</strong>: While <code>PY</code> appears to be an Excel function, you can’t use it as a function in formula. For example, if you want to create a LAMBDA that embeds some Python code using PY, e.g.&nbsp;<code>=LAMBDA(x, PY(x + 2))</code>, this does not work.</p></li>
<li><p><strong>Code is stored in workbook</strong>: The Python code is embedded directly in the xlsx file, which is consistent with the Excel paradigm. However, this means that any code changes must be copied manually to each workbook containing it rather than being managed centrally with version control.</p></li>
<li><p><strong>Code does not run locally</strong>: Since the Python runtime is in the Microsoft cloud, the code cannot run locally, which can create security issues for some, lack of offline capability, and a dependence on Microsoft cloud for performance.</p></li>
<li><p><strong>Python cells share state</strong>: The Python cells are executed in the order they appear in the workbook, and they share state, similar to a Jupyter notebook. This is both a positive and a negative, and can make it difficult to debug and understand the code.</p></li>
</ul>
<p>See also this great <a href="https://www.xlwings.org/blog/my-thoughts-on-python-in-excel">post by xlwings</a> on these and some other potential weaknesses.</p>
</section>
<section id="alternatives" class="level2">
<h2 class="anchored" data-anchor-id="alternatives">Alternatives</h2>
<section id="pyxll" class="level3">
<h3 class="anchored" data-anchor-id="pyxll">PyXLL</h3>
<p><a href="https://www.pyxll.com/index.html">PyXLL</a> is package for Windows only which enables developers to build traditional Excel add-ins (not modern web-based add-ins) using Python. The Python runtime is running on Windows so it is able to use virtually all Python libraries, including those that use C and C++ extensions.</p>
</section>
<section id="xlwings" class="level3">
<h3 class="anchored" data-anchor-id="xlwings">xlwings</h3>
<p><a href="https://www.xlwings.org/">xlwings</a> comes in two variants. The client product runs on Windows or Mac and is similar to PyXLL in terms of being able to build traditional Excel add-ins. The <a href="https://server.xlwings.org/en/latest/">xlwings Server</a> is used to create modern Excel web add-ins entirely in Python by deploying a web app using Python code, similar to <a href="https://streamlit.io/">Streamlit</a> or <a href="https://www.gradio.app/">Gradio</a>. This is a very clever strategy that eliminates the need for a separate Excel add-in web app which calls a Python API. They are also working on an xlwings Script version which will run in the browser, which sounds very promising.</p>
</section>
<section id="anaconda-code" class="level3">
<h3 class="anchored" data-anchor-id="anaconda-code">Anaconda Code</h3>
<p><a href="https://www.anaconda.com/">Anaconda</a> partnered with Microsoft to provide Python in Excel. Shortly after the the Python in Excel beta was released in August 2023, Anaconda released the <a href="https://www.anaconda.com/blog/anaconda-toolbox-brings-ai-assistant-no-code-development-to-python-in-excel">Anaconda Toolbox</a> which initially was focused on providing a no-code AI assistant for Python in Excel as well as a way to centralize the storage of external data. In July 2024, <a href="https://www.anaconda.com/blog/introducing-anaconda-code-add-in-for-microsoft-excel">Anaconda Code</a> was added to the toolbox, which enabled users to run Python code locally in Excel using <a href="https://pyscript.net/">PyScript</a>, which in turn uses <a href="https://pyodide.org/en/stable/">Pyodide</a>. This targeted a different set of users than the Microsoft implementation, as it allowed for internet access, custom packages, and local execution. It is unclear if this was planned all-along, or if it was a response to the limitations of the Microsoft implementation.</p>
<p>It uses the <code>REF(A1)</code> function syntax to reference cells in Excel from within Python code, similar to the <code>xl(A1)</code>syntax used by Python in Excel.</p>
</section>
<section id="python-for-excel" class="level3">
<h3 class="anchored" data-anchor-id="python-for-excel">Python for Excel</h3>
<p>Boardflare’s Python for Excel was just launched into beta and is the latest addition to the available options. It is a free add-in that is similar to Anaconda Code in that it enables users to run Python code locally in Excel using <a href="https://pyodide.org/en/stable/">Pyodide</a>.</p>
<p>Some of the key benefits are as follows:</p>
<p>🆓 Free add-in, no Microsoft 365 license required.<br> 🌐 Works in Excel for web as well as desktop.<br> ☁️ Runtime has network access for API calls.<br> 📦 Import custom packages (pure Python only).<br> 🔒 Runs locally, so no data is shared outside Excel.<br> ✅ Can be used inside formulas and LAMBDA functions.<br> ➡️ Code can be centralized and loaded from a URL.<br> 🚀 Performance is only limited by your CPU.<br></p>
</section>
</section>
<section id="conclusion" class="level2">
<h2 class="anchored" data-anchor-id="conclusion">Conclusion</h2>
<p>Python in Excel is a great addition to the Excel ecosystem, and we’re excited to see how it evolves. There are now several options available for running Python code in Excel, each with their own strengths and weaknesses. We hope this post has helped you understand the differences between them and choose the one that best fits your needs.</p>


</section>

 ]]></description>
  <category>Excel</category>
  <category>Python</category>
  <guid>https://boardflare.com/posts/2024/python-in-excel/</guid>
  <pubDate>Mon, 16 Sep 2024 00:00:00 GMT</pubDate>
</item>
<item>
  <title>Excel TRANSLATE Function</title>
  <link>https://boardflare.com/posts/2024/translate-excel/</link>
  <description><![CDATA[ 





<p>Microsoft announced a new Excel <a href="https://techcommunity.microsoft.com/t5/microsoft-365-insider-blog/new-translation-functions-in-excel-translate-and-detectlanguage/ba-p/4231456">TRANSLATE function</a> that allows users to translate text directly within their spreadsheets. This function is similar to the <a href="https://support.google.com/docs/answer/3093331?hl=en">GOOGLETRANSLATE</a> function in Google Sheets and provides a convenient way to work with multilingual data in Excel. In this article, we’ll explore the syntax and usage of the TRANSLATE function in Excel.</p>
<p>It is currently available to Beta Channel users on Windows and Mac. It is unclear if this will offer unlimited free use once it reaches GA.</p>
<!-- more -->
<section id="functions" class="level2">
<h2 class="anchored" data-anchor-id="functions">Functions</h2>
<section id="translate" class="level3">
<h3 class="anchored" data-anchor-id="translate">TRANSLATE</h3>
<p>The <a href="https://support.microsoft.com/en-us/office/translate-function-d34f71c7-2ffe-409a-9a63-5eb5e91aa3dd">TRANSLATE() function</a> translates text from one language to another using Microsoft Translation Services.</p>
<p><code>=TRANSLATE(text, [source_language], [target_language])</code></p>
<p>The function has the following arguments:</p>
<ul>
<li><strong>text</strong>: The text to translate, either in quotation marks or as a cell reference.</li>
<li><strong>source_language</strong> (optional): The language code of the source language (e.g., “en” for English, “es” for Spanish). If not specified, the language is auto-detected. Specifying the language is recommended for shorter texts.</li>
<li><strong>target_language</strong> (optional): The language code of the target language (e.g., “en” for English, “es” for Spanish). If not specified, the system language is used.</li>
</ul>
<p>Supported languages and their codes can be found in <a href="https://learn.microsoft.com/en-us/azure/ai-services/Translator/language-support">Supported Languages and Language Codes</a>.</p>
<p>For example, to translate the text “Hello, World!” in cell A1 to Spanish, use:</p>
<p><code>=TRANSLATE(A1, "en", "es")</code></p>
<p>Here, the source language is English (“en”) and the target language is Spanish (“es”). The translated text “Hola mundo!” will appear in the cell with the formula.</p>
</section>
<section id="detectlanguage" class="level3">
<h3 class="anchored" data-anchor-id="detectlanguage">DETECTLANGUAGE</h3>
<p>The <a href="https://support.microsoft.com/en-us/office/detectlanguage-function-0748e285-1912-4d24-b735-57d18142fa3b">DETECTLANGUAGE()</a> function is used to identify the language in a specified text or range.</p>
<p>The syntax for the DETECTLANGUAGE() function is as follows:</p>
<p><code>=DETECTLANGUAGE(text)</code></p>
<p>The function has the following arguments:</p>
<ul>
<li><strong>text</strong> - The text or reference to cells containing text.</li>
</ul>
<p><a href="https://learn.microsoft.com/en-us/azure/ai-services/Translator/language-support">Supported Languages</a>.</p>
<p>For example, if you have the following text in cell A1: “Hola mundo!” and you want to find out what the language of the text is. You can use the DETECTLANGUAGE() function as follows:</p>
<p><code>=DETECTLANGUAGE(A1)</code></p>
<p>This will return the detected language for the text in cell A1. The language code “es” for Spanish will be displayed in the cell where you entered the formula.</p>
</section>
</section>
<section id="alternatives" class="level2">
<h2 class="anchored" data-anchor-id="alternatives">Alternatives</h2>
<p>The TRANSLATE function is similar to the <a href="../googletranslate-excel/">GOOGLETRANSLATE function</a> in Google Sheets and the <a href="../../../apps/excel/translate/">Translate for Excel</a> function provided by BoardFlare.</p>
<p>The main advantages of Boardflare’s <a href="../../../apps/excel/translate/">Translate for Excel</a> are as follows: - no throttling or quotas on usage. - your data stays in Excel and is not shared.</p>


</section>

 ]]></description>
  <category>Excel</category>
  <category>AI</category>
  <guid>https://boardflare.com/posts/2024/translate-excel/</guid>
  <pubDate>Thu, 27 Jun 2024 00:00:00 GMT</pubDate>
</item>
<item>
  <title>GOOGLETRANSLATE for Excel</title>
  <link>https://boardflare.com/posts/2024/googletranslate-excel/</link>
  <description><![CDATA[ 





<p>This post explores a GOOGLETRANSLATE function for Excel that brings Google Sheets’ translation capabilities to Excel. Unlike the Google Sheets version, this implementation translates text locally on your computer using machine learning models, ensuring your data stays private without requiring any API calls or external services.</p>
<!-- more -->
<blockquote class="blockquote">
<p>Updated: Microsoft has announced their own new native <a href="https://techcommunity.microsoft.com/t5/microsoft-365-insider-blog/new-translation-functions-in-excel-translate-and-detectlanguage/ba-p/4231456">TRANSLATE function</a> for Excel. See <a href="../translate-excel/">this post</a>.</p>
</blockquote>
<section id="googletranslate" class="level2">
<h2 class="anchored" data-anchor-id="googletranslate">GOOGLETRANSLATE</h2>
<p><a href="https://support.google.com/docs/answer/3093331?hl=en">GOOGLETRANSLATE</a> is a popular function in Google Sheets that allows users to translate text directly within their spreadsheets. It’s a powerful tool for working with multilingual data and has become an essential feature for many users. It translates text from one language to another with a simple function syntax of GOOGLETRANSLATE(text, [source_language], [target_language]).</p>
</section>
<section id="translate-for-excel" class="level2">
<h2 class="anchored" data-anchor-id="translate-for-excel">Translate for Excel</h2>
<p>Translate for Excel is a function similar to GOOGLETRANSLATE, but for Excel. It uses a machine learning model to translate text directly within your spreadsheet. This means your data never leaves your document, ensuring privacy and security. Since it runs on your CPU, there are no usage limits or api fees.</p>
</section>
<section id="key-features" class="level2">
<h2 class="anchored" data-anchor-id="key-features">Key Features</h2>
<p>Translate for Excel offers several key features:</p>
<ul>
<li><strong>Translation of 20 languages to or from English</strong>: We plan to expand the languages supported and enable translation between any pair of languages.</li>
<li><strong>Unlimited free use</strong>: There are no usage limits or fees.</li>
<li><strong>Local operation</strong>: The function runs on your computer, so your data remains secure.</li>
</ul>
</section>
<section id="how-to-use-translate-for-excel" class="level2">
<h2 class="anchored" data-anchor-id="how-to-use-translate-for-excel">How to Use Translate for Excel</h2>
<p>Using Translate for Excel is simple. The function requires only the text you want to translate and the language code of the input text. Here’s how you can use it:</p>
<pre class="excel"><code>=BOARDFLARE.TRANSLATE(text, source_language, target_language)</code></pre>
<p>For example, to translate a cell A1 from Spanish to English, you would use:</p>
<pre class="excel"><code>=BOARDFLARE.TRANSLATE(A1, "es", "en"    )</code></pre>
</section>
<section id="installation" class="level2">
<h2 class="anchored" data-anchor-id="installation">Installation</h2>
<p>You can install Translate for Excel from the Microsoft AppSource store or directly from Excel.</p>
</section>
<section id="conclusion" class="level2">
<h2 class="anchored" data-anchor-id="conclusion">Conclusion</h2>
<p>Translate for Excel fills a significant gap in Excel’s functionality, providing a powerful translation tool directly within your spreadsheet. While it’s not as fast as GOOGLETRANSLATE, it offers the advantage of privacy, security, and unlimited free use. We’re excited to see how this function will empower Excel users to work more effectively with multilingual data.</p>


</section>

 ]]></description>
  <category>Excel</category>
  <category>Google Sheets</category>
  <guid>https://boardflare.com/posts/2024/googletranslate-excel/</guid>
  <pubDate>Wed, 29 May 2024 00:00:00 GMT</pubDate>
</item>
<item>
  <title>Creating a Web Worker with Google Apps Script</title>
  <link>https://boardflare.com/posts/2024/apps-script-web-workers/</link>
  <description><![CDATA[ 





<p>Learn how to create a web worker with Google Apps Script to enable background processing while keeping the UI responsive. This guide covers the inline worker pattern, which allows you to serve worker code directly from your Google Apps Script project and take advantage of module workers for ESM-only libraries.</p>
<!-- more -->
<section id="background" class="level2">
<h2 class="anchored" data-anchor-id="background">Background</h2>
<p>In Google Sheets extensions, Google Apps Script is used to serve the HTML page for the sidebar in the UI. To do machine learning (or any other intensive processing) client-side, ideally you want to use a <a href="https://web.dev/articles/workers-basics">web worker</a> so the UI can remain responsive (e.g.&nbsp;to report on progress, cancel the operation, etc.) and also to enable multi-threaded processing.</p>
</section>
<section id="problem" class="level2">
<h2 class="anchored" data-anchor-id="problem">Problem</h2>
<p>Google Apps Script doesn’t support serving a worker script directly from a file.</p>
</section>
<section id="solution" class="level2">
<h2 class="anchored" data-anchor-id="solution">Solution</h2>
<p>We’ll use the <a href="https://web.dev/articles/workers-basics#inline_workers">inline worker</a> pattern. The first step is to put the worker code in an html file in the Google Apps Script project, e.g.&nbsp;<code>worker.html</code>, with no html tags as shown below.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb1" style="background: #f1f3f5;"><pre class="sourceCode html code-with-copy"><code class="sourceCode html"><span id="cb1-1">self.onmessage = function(e) {</span>
<span id="cb1-2">  console.log('Message received from main script');</span>
<span id="cb1-3">  var workerResult = 'Result: ' + (e.data[0] * e.data[1]);</span>
<span id="cb1-4">  console.log('Posting message back to main script');</span>
<span id="cb1-5">  self.postMessage(workerResult);</span>
<span id="cb1-6">}</span></code></pre></div></div>
<p>Next, we inline the worker code in the main HTML file using a Google Apps scriptlet to assign the text contents of the worker.html to a variable. Note the <code>&lt;?!=</code> syntax with the exclamation mark to prevent escaping of the script. After that we create a blob and object URL, and then a new Worker using the object URL. In our case we use the <code>type: 'module'</code> option on the Worker constructor, which creates a <a href="https://web.dev/articles/module-workers">module worker</a>, which we need for the ESM-only library we are using in the worker.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb2" style="background: #f1f3f5;"><pre class="sourceCode html code-with-copy"><code class="sourceCode html"><span id="cb2-1"><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">&lt;!DOCTYPE</span> html<span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">&gt;</span></span>
<span id="cb2-2"><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">&lt;</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">html</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">&gt;</span></span>
<span id="cb2-3">  <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">&lt;</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">head</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">&gt;</span></span>
<span id="cb2-4">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">&lt;</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">base</span><span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;"> target</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"_top"</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">&gt;</span></span>
<span id="cb2-5">  <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">&lt;/</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">head</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">&gt;</span></span>
<span id="cb2-6">  <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">&lt;</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">body</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">&gt;</span></span>
<span id="cb2-7">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">&lt;</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">script</span><span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;"> type=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"module"</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">&gt;</span></span>
<span id="cb2-8">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">var</span> workerScript <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="vs" style="color: #20794D;
background-color: null;
font-style: inherit;">`&lt;?!= HtmlService.createTemplateFromFile('worker').evaluate().getContent() ?&gt;`</span></span>
<span id="cb2-9">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">var</span> blob <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">new</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">Blob</span>([workerScript]<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> {<span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">type</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'application/javascript'</span>})<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb2-10">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">var</span> workerUrl <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> URL<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">createObjectURL</span>(blob)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb2-11">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">var</span> worker <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">new</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">Worker</span>(workerUrl<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> {<span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">type</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'module'</span>})<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb2-12">    worker<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">onmessage</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">function</span>(e) {</span>
<span id="cb2-13">      <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">console</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">log</span>(e<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">data</span>)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb2-14">    }<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb2-15">    worker<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">postMessage</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Start processing data'</span>)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb2-16">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">&lt;/</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">script</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">&gt;</span></span>
<span id="cb2-17">  <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">&lt;/</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">body</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">&gt;</span></span>
<span id="cb2-18"><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">&lt;/</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">html</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">&gt;</span></span></code></pre></div></div>
<p>One problem with this approach is that <code>worker.html</code>, without script tags, is not treated by a code editor as JavaScript, so no syntax highlighting, etc. You could add script tags in the <code>worker.html</code> file to fix this and then strip them back out again from the string in <code>workerScript</code> before passing it into the blob. In our case we’re developing the worker code in a plain web app first before copying it into the Google Apps Script project, so this isn’t an issue.</p>


</section>

 ]]></description>
  <category>Google Sheets</category>
  <category>Add-ins</category>
  <guid>https://boardflare.com/posts/2024/apps-script-web-workers/</guid>
  <pubDate>Thu, 18 Apr 2024 00:00:00 GMT</pubDate>
</item>
</channel>
</rss>
