<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/">
    <channel>
        <title>Boardflare - Python Functions for Spreadsheets Blog</title>
        <link>https://boardflare.com/posts/</link>
        <description>Boardflare - Python Functions for Spreadsheets Blog</description>
        <lastBuildDate>Tue, 17 Mar 2026 00:00:00 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <language>en</language>
        <item>
            <title><![CDATA[Turn an Excel Workbook Into a Simple App With Tool Builder]]></title>
            <link>https://boardflare.com/posts/2026/tool-builder-addin/</link>
            <guid>https://boardflare.com/posts/2026/tool-builder-addin/</guid>
            <pubDate>Tue, 17 Mar 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[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.]]></description>
            <content:encoded><![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>Tool Builder is a way to add that interface without leaving Excel. 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. The app becomes the simpler surface around it.</p>
<!-- -->
<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>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="why-people-use-it">Why people use it<a href="https://boardflare.com/posts/2026/tool-builder-addin/#why-people-use-it" class="hash-link" aria-label="Direct link to Why people use it" title="Direct link to Why people use it" translate="no">​</a></h2>
<p>Tool Builder is a good fit when:</p>
<ul>
<li class="">the data already lives in a workbook</li>
<li class="">people repeat the same review or update process every week</li>
<li class="">the raw sheet is harder to use than the underlying task</li>
<li class="">you want something faster than a custom internal app project</li>
<li class="">you want the finished tool to travel with the workbook</li>
</ul>
<p>That last part is important. Tool Builder stores the app inside the workbook itself, so the file carries the interface with it. You are not deploying a separate server, database, or app-specific sign-in flow just to make a spreadsheet easier to work with.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="the-workflow-is-simple">The workflow is simple<a href="https://boardflare.com/posts/2026/tool-builder-addin/#the-workflow-is-simple" class="hash-link" aria-label="Direct link to The workflow is simple" title="Direct link to The workflow is simple" translate="no">​</a></h2>
<p>Tool Builder works best as a short loop:</p>
<ol>
<li class="">Start with a workbook problem.</li>
<li class="">Click Copy Guide in Tool Builder.</li>
<li class="">Paste the guide into a fresh chat with ChatGPT, Claude, Copilot, or another AI assistant.</li>
<li class="">Ask for a single-file HTML and JavaScript app for your workflow.</li>
<li class="">Paste the generated code into Tool Builder and run it in Excel.</li>
<li class="">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>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="what-makes-a-good-first-app">What makes a good first app<a href="https://boardflare.com/posts/2026/tool-builder-addin/#what-makes-a-good-first-app" class="hash-link" aria-label="Direct link to What makes a good first app" title="Direct link to What makes a good first app" translate="no">​</a></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 class="">an expense or budget tracker</li>
<li class="">a project tracker or Kanban-style board</li>
<li class="">a guided data-entry form</li>
<li class="">an inventory or reorder screen</li>
<li class="">a review queue that surfaces exceptions first</li>
<li class="">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 class="" href="https://boardflare.com/apps/excel/builder/">Tool Builder for Excel guide</a> shows the product workflow, and the <a href="https://tools.boardflare.com/visualization/" target="_blank" rel="noopener noreferrer" class="">visualization catalog</a> is a useful place to borrow dashboard and chart ideas.</p>]]></content:encoded>
            <category>Excel</category>
            <category>Tool Builder</category>
            <category>AI</category>
        </item>
        <item>
            <title><![CDATA[Excel's New Regex Functions Versus Python's re Module Capabilities]]></title>
            <link>https://boardflare.com/posts/2025/python-regex-excel/</link>
            <guid>https://boardflare.com/posts/2025/python-regex-excel/</guid>
            <pubDate>Fri, 25 Jul 2025 00:00:00 GMT</pubDate>
            <description><![CDATA[A comprehensive comparison between Excel's new native regex functions (REGEXTEST, REGEXEXTRACT, REGEXREPLACE) and Python's powerful re module.]]></description>
            <content:encoded><![CDATA[<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>
<!-- -->
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="background-of-regular-expressions">Background of Regular Expressions<a href="https://boardflare.com/posts/2025/python-regex-excel/#background-of-regular-expressions" class="hash-link" aria-label="Direct link to Background of Regular Expressions" title="Direct link to Background of Regular Expressions" translate="no">​</a></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>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="excels-new-native-regex-functions-capabilities-and-syntax">Excel's New Native Regex Functions: Capabilities and Syntax<a href="https://boardflare.com/posts/2025/python-regex-excel/#excels-new-native-regex-functions-capabilities-and-syntax" class="hash-link" aria-label="Direct link to Excel's New Native Regex Functions: Capabilities and Syntax" title="Direct link to Excel's New Native Regex Functions: Capabilities and Syntax" translate="no">​</a></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>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="detailed-syntax-and-argument-descriptions-for-each-function">Detailed Syntax and Argument Descriptions for Each Function<a href="https://boardflare.com/posts/2025/python-regex-excel/#detailed-syntax-and-argument-descriptions-for-each-function" class="hash-link" aria-label="Direct link to Detailed Syntax and Argument Descriptions for Each Function" title="Direct link to Detailed Syntax and Argument Descriptions for Each Function" translate="no">​</a></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 class="">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 class="">text (required): The cell reference or range containing the text string(s) to be checked.</li>
<li class="">pattern (required): The regular expression to match, which must be enclosed in quotation marks.</li>
<li class="">[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 class=""><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 class="">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 class="">text (required): The cell reference or range containing the text string(s) from which to extract.</li>
<li class="">pattern (required): The regular expression that describes the specific text pattern to be extracted.</li>
<li class="">[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 class="">[case_sensitivity] (optional): Same as for REGEXTEST.</li>
<li class=""><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 class="">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 class="">text (required): The cell reference or range containing the text string(s) within which replacements are to be made.</li>
<li class="">pattern (required): The regular expression that describes the text pattern to be replaced.</li>
<li class="">replacement (required): The text string that will replace the matched pattern instances.</li>
<li class="">[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 class="">[case_sensitivity] (optional): Same as for REGEXTEST.</li>
<li class=""><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>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="overview-of-supported-basic-regex-patterns-metacharacters-and-quantifiers">Overview of Supported Basic Regex Patterns, Metacharacters, and Quantifiers<a href="https://boardflare.com/posts/2025/python-regex-excel/#overview-of-supported-basic-regex-patterns-metacharacters-and-quantifiers" class="hash-link" aria-label="Direct link to Overview of Supported Basic Regex Patterns, Metacharacters, and Quantifiers" title="Direct link to Overview of Supported Basic Regex Patterns, Metacharacters, and Quantifiers" translate="no">​</a></h3>
<p>Excel's new functions support a robust set of common regex constructs, enabling versatile pattern matching:</p>
<ul>
<li class=""><strong>Literal Text:</strong> Matches the exact sequence of characters (e.g., 'abc' matches 'abc').</li>
<li class=""><strong>Wildcard:</strong> The dot (.) matches any single character, with the exception of a newline character.</li>
<li class=""><strong>Character Classes (Shorthands):</strong>
<ul>
<li class=""><code>\\d</code>: Matches any digit (0-9).</li>
<li class=""><code>\\w</code>: Matches any word character (letters, digits, or underscore).</li>
<li class=""><code>\\s</code>: Matches any whitespace character (space, tab, newline).</li>
<li class="">Their negated counterparts (<code>\\D</code>, <code>\\W</code>, <code>\\S</code>) are also supported.</li>
</ul>
</li>
<li class=""><strong>Custom Character Sets:</strong>
<ul>
<li class=""><code>[abc]</code>: Matches any one character listed within the brackets (e.g., <code>gr[ae]y</code> matches 'gray' or 'grey').</li>
<li class=""><code>[a-z]</code>: Matches any one character within the specified range (e.g., <code>[a-z]</code> matches any lowercase letter).</li>
<li class=""></li>
</ul>
</li>
<li class=""><strong>Quantifiers:</strong> These specify the number of occurrences of the preceding element:<!-- -->
<ul>
<li class=""><code>a\*</code>: Matches zero or more occurrences of 'a'.</li>
<li class=""><code>a+</code>: Matches one or more occurrences of 'a'.</li>
<li class=""><code>a?</code>: Matches zero or one occurrence of 'a' (making it optional).</li>
<li class=""><code>a{n}</code>: Matches exactly n occurrences of 'a'.</li>
<li class=""><code>a{n,m}</code>: Matches between n and m occurrences of 'a'.</li>
<li class=""><code>a{n,}</code>: Matches n or more occurrences of 'a'.</li>
</ul>
</li>
<li class=""><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 class=""><strong>Alternation:</strong> <code>a|b</code> matches either 'a' or 'b' (e.g., <code>cat|dog</code> matches 'cat' or 'dog').</li>
<li class=""><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>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="handling-of-case-sensitivity-and-string-anchors--">Handling of Case Sensitivity and String Anchors (^, $)<a href="https://boardflare.com/posts/2025/python-regex-excel/#handling-of-case-sensitivity-and-string-anchors--" class="hash-link" aria-label="Direct link to Handling of Case Sensitivity and String Anchors (^, $)" title="Direct link to Handling of Case Sensitivity and String Anchors (^, $)" translate="no">​</a></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 <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo stretchy="false">(</mo><mi>d</mi><mi>o</mi><mi>l</mi><mi>l</mi><mi>a</mi><mi>r</mi><mi>s</mi><mi>i</mi><mi>g</mi><mi>n</mi><mo stretchy="false">)</mo><mi>a</mi><mi>r</mi><mi>e</mi><mi>c</mi><mi>r</mi><mi>u</mi><mi>c</mi><mi>i</mi><mi>a</mi><mi>l</mi><mi>a</mi><mi>n</mi><mi>c</mi><mi>h</mi><mi>o</mi><mi>r</mi><mi>s</mi><mi>i</mi><mi>n</mi><mi>r</mi><mi>e</mi><mi>g</mi><mi>e</mi><mi>x</mi><mi mathvariant="normal">.</mi><mi>I</mi><mi>n</mi><mi>E</mi><mi>x</mi><mi>c</mi><mi>e</mi><msup><mi>l</mi><mo mathvariant="normal" lspace="0em" rspace="0em">′</mo></msup><mi>s</mi><mi>i</mi><mi>m</mi><mi>p</mi><mi>l</mi><mi>e</mi><mi>m</mi><mi>e</mi><mi>n</mi><mi>t</mi><mi>a</mi><mi>t</mi><mi>i</mi><mi>o</mi><mi>n</mi><msup><mo separator="true">,</mo><mi>m</mi></msup><mi>a</mi><mi>t</mi><mi>c</mi><mi>h</mi><mi>e</mi><mi>s</mi><mi>t</mi><mi>h</mi><mi>e</mi><mi>s</mi><mi>t</mi><mi>a</mi><mi>r</mi><mi>t</mi><mi>o</mi><mi>f</mi><mi>t</mi><mi>h</mi><mi>e</mi><mi>e</mi><mi>n</mi><mi>t</mi><mi>i</mi><mi>r</mi><mi>e</mi><mi>s</mi><mi>t</mi><mi>r</mi><mi>i</mi><mi>n</mi><mi>g</mi><mo stretchy="false">(</mo><mi>c</mi><mi>e</mi><mi>l</mi><mi>l</mi><mi>c</mi><mi>o</mi><mi>n</mi><mi>t</mi><mi>e</mi><mi>n</mi><mi>t</mi><mo stretchy="false">)</mo><mo separator="true">,</mo><mi>a</mi><mi>n</mi><mi>d</mi></mrow><annotation encoding="application/x-tex">(dollar sign) are crucial anchors in regex. In Excel's implementation, ^ matches the start of the entire string (cell content), and</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1.0019em;vertical-align:-0.25em"></span><span class="mopen">(</span><span class="mord mathnormal">d</span><span class="mord mathnormal">o</span><span class="mord mathnormal" style="margin-right:0.0197em">l</span><span class="mord mathnormal" style="margin-right:0.0197em">l</span><span class="mord mathnormal">a</span><span class="mord mathnormal" style="margin-right:0.0278em">r</span><span class="mord mathnormal">s</span><span class="mord mathnormal">i</span><span class="mord mathnormal" style="margin-right:0.0359em">g</span><span class="mord mathnormal">n</span><span class="mclose">)</span><span class="mord mathnormal">a</span><span class="mord mathnormal" style="margin-right:0.0278em">r</span><span class="mord mathnormal" style="margin-right:0.0278em">ecr</span><span class="mord mathnormal">u</span><span class="mord mathnormal">c</span><span class="mord mathnormal">ia</span><span class="mord mathnormal" style="margin-right:0.0197em">l</span><span class="mord mathnormal">an</span><span class="mord mathnormal">c</span><span class="mord mathnormal">h</span><span class="mord mathnormal" style="margin-right:0.0278em">or</span><span class="mord mathnormal">s</span><span class="mord mathnormal">in</span><span class="mord mathnormal" style="margin-right:0.0278em">r</span><span class="mord mathnormal">e</span><span class="mord mathnormal" style="margin-right:0.0359em">g</span><span class="mord mathnormal">e</span><span class="mord mathnormal">x</span><span class="mord">.</span><span class="mord mathnormal" style="margin-right:0.0785em">I</span><span class="mord mathnormal">n</span><span class="mord mathnormal" style="margin-right:0.0576em">E</span><span class="mord mathnormal">x</span><span class="mord mathnormal">ce</span><span class="mord"><span class="mord mathnormal" style="margin-right:0.0197em">l</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.7519em"><span style="top:-3.063em;margin-right:0.05em"><span class="pstrut" style="height:2.7em"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">′</span></span></span></span></span></span></span></span></span><span class="mord mathnormal">s</span><span class="mord mathnormal">im</span><span class="mord mathnormal" style="margin-right:0.0197em">pl</span><span class="mord mathnormal">e</span><span class="mord mathnormal">m</span><span class="mord mathnormal">e</span><span class="mord mathnormal">n</span><span class="mord mathnormal">t</span><span class="mord mathnormal">a</span><span class="mord mathnormal">t</span><span class="mord mathnormal">i</span><span class="mord mathnormal">o</span><span class="mord mathnormal">n</span><span class="mpunct"><span class="mpunct">,</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.6644em"><span style="top:-3.063em;margin-right:0.05em"><span class="pstrut" style="height:2.7em"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">m</span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.1667em"></span><span class="mord mathnormal">a</span><span class="mord mathnormal">t</span><span class="mord mathnormal">c</span><span class="mord mathnormal">h</span><span class="mord mathnormal">es</span><span class="mord mathnormal">t</span><span class="mord mathnormal">h</span><span class="mord mathnormal">es</span><span class="mord mathnormal">t</span><span class="mord mathnormal">a</span><span class="mord mathnormal" style="margin-right:0.0278em">r</span><span class="mord mathnormal">t</span><span class="mord mathnormal">o</span><span class="mord mathnormal" style="margin-right:0.1076em">f</span><span class="mord mathnormal">t</span><span class="mord mathnormal">h</span><span class="mord mathnormal">ee</span><span class="mord mathnormal">n</span><span class="mord mathnormal">t</span><span class="mord mathnormal">i</span><span class="mord mathnormal" style="margin-right:0.0278em">r</span><span class="mord mathnormal">es</span><span class="mord mathnormal">t</span><span class="mord mathnormal" style="margin-right:0.0278em">r</span><span class="mord mathnormal">in</span><span class="mord mathnormal" style="margin-right:0.0359em">g</span><span class="mopen">(</span><span class="mord mathnormal">ce</span><span class="mord mathnormal" style="margin-right:0.0197em">l</span><span class="mord mathnormal" style="margin-right:0.0197em">l</span><span class="mord mathnormal">co</span><span class="mord mathnormal">n</span><span class="mord mathnormal">t</span><span class="mord mathnormal">e</span><span class="mord mathnormal">n</span><span class="mord mathnormal">t</span><span class="mclose">)</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.1667em"></span><span class="mord mathnormal">an</span><span class="mord mathnormal">d</span></span></span></span> 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>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="usage-of-capturing-groups-and-backreferences-n">Usage of Capturing Groups and Backreferences ($n)<a href="https://boardflare.com/posts/2025/python-regex-excel/#usage-of-capturing-groups-and-backreferences-n" class="hash-link" aria-label="Direct link to Usage of Capturing Groups and Backreferences ($n)" title="Direct link to Usage of Capturing Groups and Backreferences ($n)" translate="no">​</a></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>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="underlying-regex-engine-pcre2-flavor">Underlying Regex Engine: PCRE2 Flavor<a href="https://boardflare.com/posts/2025/python-regex-excel/#underlying-regex-engine-pcre2-flavor" class="hash-link" aria-label="Direct link to Underlying Regex Engine: PCRE2 Flavor" title="Direct link to Underlying Regex Engine: PCRE2 Flavor" translate="no">​</a></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>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="table-1-excel-regex-functions---syntax-and-core-parameters">Table 1: Excel Regex Functions - Syntax and Core Parameters<a href="https://boardflare.com/posts/2025/python-regex-excel/#table-1-excel-regex-functions---syntax-and-core-parameters" class="hash-link" aria-label="Direct link to Table 1: Excel Regex Functions - Syntax and Core Parameters" title="Direct link to Table 1: Excel Regex Functions - Syntax and Core Parameters" translate="no">​</a></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><thead><tr><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><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><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><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>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="broader-implications-of-excels-new-regex-capabilities">Broader Implications of Excel's New Regex Capabilities<a href="https://boardflare.com/posts/2025/python-regex-excel/#broader-implications-of-excels-new-regex-capabilities" class="hash-link" aria-label="Direct link to Broader Implications of Excel's New Regex Capabilities" title="Direct link to Broader Implications of Excel's New Regex Capabilities" translate="no">​</a></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>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="pythons-re-module-comprehensive-regex-powerhouse">Python's re Module: Comprehensive Regex Powerhouse<a href="https://boardflare.com/posts/2025/python-regex-excel/#pythons-re-module-comprehensive-regex-powerhouse" class="hash-link" aria-label="Direct link to Python's re Module: Comprehensive Regex Powerhouse" title="Direct link to Python's re Module: Comprehensive Regex Powerhouse" translate="no">​</a></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>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="core-functions-research-refindall-resub-rematch-recompile">Core Functions: re.search(), re.findall(), re.sub(), re.match(), re.compile()<a href="https://boardflare.com/posts/2025/python-regex-excel/#core-functions-research-refindall-resub-rematch-recompile" class="hash-link" aria-label="Direct link to Core Functions: re.search(), re.findall(), re.sub(), re.match(), re.compile()" title="Direct link to Core Functions: re.search(), re.findall(), re.sub(), re.match(), re.compile()" translate="no">​</a></h3>
<p>The re module provides a versatile set of functions designed for various regex operations:</p>
<ul>
<li class=""><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 class=""><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 class=""><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 class=""><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 class=""><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>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="extensive-support-for-basic-regex-patterns-special-sequences-and-quantifiers">Extensive Support for Basic Regex Patterns, Special Sequences, and Quantifiers<a href="https://boardflare.com/posts/2025/python-regex-excel/#extensive-support-for-basic-regex-patterns-special-sequences-and-quantifiers" class="hash-link" aria-label="Direct link to Extensive Support for Basic Regex Patterns, Special Sequences, and Quantifiers" title="Direct link to Extensive Support for Basic Regex Patterns, Special Sequences, and Quantifiers" translate="no">​</a></h3>
<p>Python's re module supports a comprehensive set of metacharacters and quantifiers, largely consistent with Perl-style regular expressions.</p>
<ul>
<li class=""><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 class=""><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 class=""><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 class=""><strong>Greedy vs. 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>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="the-significance-of-pythons-raw-string-notation-r">The Significance of Python's Raw String Notation (r"")<a href="https://boardflare.com/posts/2025/python-regex-excel/#the-significance-of-pythons-raw-string-notation-r" class="hash-link" aria-label="Direct link to The Significance of Python's Raw String Notation (r&quot;&quot;)" title="Direct link to The Significance of Python's Raw String Notation (r&quot;&quot;)" translate="no">​</a></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>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="advanced-features-lookahead-and-lookbehind-assertions">Advanced Features: Lookahead and Lookbehind Assertions<a href="https://boardflare.com/posts/2025/python-regex-excel/#advanced-features-lookahead-and-lookbehind-assertions" class="hash-link" aria-label="Direct link to Advanced Features: Lookahead and Lookbehind Assertions" title="Direct link to Advanced Features: Lookahead and Lookbehind Assertions" translate="no">​</a></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 class="">
<p><strong>Lookahead Assertions:</strong></p>
<ul>
<li class="">(?=...) (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 class="">(?!) (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 class="">
<p><strong>Lookbehind Assertions:</strong></p>
<ul>
<li class="">(?&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 class="">(?&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>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="advanced-features-named-capturing-groups">Advanced Features: Named Capturing Groups<a href="https://boardflare.com/posts/2025/python-regex-excel/#advanced-features-named-capturing-groups" class="hash-link" aria-label="Direct link to Advanced Features: Named Capturing Groups" title="Direct link to Advanced Features: Named Capturing Groups" translate="no">​</a></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 class=""><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 class=""><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 class=""><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>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="advanced-features-compilation-flags-for-fine-grained-control">Advanced Features: Compilation Flags for Fine-Grained Control<a href="https://boardflare.com/posts/2025/python-regex-excel/#advanced-features-compilation-flags-for-fine-grained-control" class="hash-link" aria-label="Direct link to Advanced Features: Compilation Flags for Fine-Grained Control" title="Direct link to Advanced Features: Compilation Flags for Fine-Grained Control" translate="no">​</a></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 class=""><code>re.IGNORECASE</code> (<code>re.I</code>): Performs case-insensitive matching, meaning 'a' will match 'A' and vice-versa.</li>
<li class=""><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 class=""><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 class=""><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 class=""><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 class=""><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>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="robust-unicode-support-and-performance-considerations">Robust Unicode Support and Performance Considerations<a href="https://boardflare.com/posts/2025/python-regex-excel/#robust-unicode-support-and-performance-considerations" class="hash-link" aria-label="Direct link to Robust Unicode Support and Performance Considerations" title="Direct link to Robust Unicode Support and Performance Considerations" translate="no">​</a></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>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="table-2-python-re-module---key-functions-and-their-purpose">Table 2: Python re Module - Key Functions and Their Purpose<a href="https://boardflare.com/posts/2025/python-regex-excel/#table-2-python-re-module---key-functions-and-their-purpose" class="hash-link" aria-label="Direct link to Table 2: Python re Module - Key Functions and Their Purpose" title="Direct link to Table 2: Python re Module - Key Functions and Their Purpose" translate="no">​</a></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><thead><tr><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><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><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><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><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><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>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="broader-implications-of-pythons-re-module">Broader Implications of Python's re Module<a href="https://boardflare.com/posts/2025/python-regex-excel/#broader-implications-of-pythons-re-module" class="hash-link" aria-label="Direct link to Broader Implications of Python's re Module" title="Direct link to Broader Implications of Python's re Module" translate="no">​</a></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>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="direct-comparison-feature-parity-and-key-distinctions">Direct Comparison: Feature Parity and Key Distinctions<a href="https://boardflare.com/posts/2025/python-regex-excel/#direct-comparison-feature-parity-and-key-distinctions" class="hash-link" aria-label="Direct link to Direct Comparison: Feature Parity and Key Distinctions" title="Direct link to Direct Comparison: Feature Parity and Key Distinctions" translate="no">​</a></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>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="functional-equivalence-mapping-excels-functions-to-pythons-re-module-operations">Functional Equivalence: Mapping Excel's Functions to Python's re Module Operations<a href="https://boardflare.com/posts/2025/python-regex-excel/#functional-equivalence-mapping-excels-functions-to-pythons-re-module-operations" class="hash-link" aria-label="Direct link to Functional Equivalence: Mapping Excel's Functions to Python's re Module Operations" title="Direct link to Functional Equivalence: Mapping Excel's Functions to Python's re Module Operations" translate="no">​</a></h3>
<p>At a high level, Excel's new regex functions have direct functional counterparts in Python's re module:</p>
<ul>
<li class="">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 class="">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 class="">REGEXREPLACE (Excel) directly corresponds to Python's <code>re.sub()</code> function, both designed for pattern-based text substitution.</li>
</ul>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="regex-flavor-comparison-pcre2-excel-vs-pythons-re-engine">Regex Flavor Comparison: PCRE2 (Excel) vs. Python's re Engine<a href="https://boardflare.com/posts/2025/python-regex-excel/#regex-flavor-comparison-pcre2-excel-vs-pythons-re-engine" class="hash-link" aria-label="Direct link to Regex Flavor Comparison: PCRE2 (Excel) vs. Python's re Engine" title="Direct link to Regex Flavor Comparison: PCRE2 (Excel) vs. Python's re Engine" translate="no">​</a></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>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="supported-regex-constructs-a-side-by-side-analysis">Supported Regex Constructs: A Side-by-Side Analysis<a href="https://boardflare.com/posts/2025/python-regex-excel/#supported-regex-constructs-a-side-by-side-analysis" class="hash-link" aria-label="Direct link to Supported Regex Constructs: A Side-by-Side Analysis" title="Direct link to Supported Regex Constructs: A Side-by-Side Analysis" translate="no">​</a></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>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="advanced-feature-discrepancies">Advanced Feature Discrepancies<a href="https://boardflare.com/posts/2025/python-regex-excel/#advanced-feature-discrepancies" class="hash-link" aria-label="Direct link to Advanced Feature Discrepancies" title="Direct link to Advanced Feature Discrepancies" translate="no">​</a></h3>
<p>Despite their shared regex lineage, there are key differences in the support and exposure of advanced regex features:</p>
<ul>
<li class=""><strong>Lookarounds:</strong>
<ul>
<li class=""><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 class=""><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 class=""><strong>Named Capturing Groups:</strong>
<ul>
<li class=""><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 class=""><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 class=""><strong>Flags and Options:</strong>
<ul>
<li class=""><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 class=""><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 class=""><strong>Atomic Grouping &amp; Possessive Quantifiers:</strong>
<ul>
<li class=""><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 class=""><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 class=""><strong>Multiline Anchors (^ and $):</strong>
<ul>
<li class=""><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 class=""><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 class=""><strong>Unicode Support:</strong>
<ul>
<li class=""><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 class=""><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>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="integration-and-workflow">Integration and Workflow<a href="https://boardflare.com/posts/2025/python-regex-excel/#integration-and-workflow" class="hash-link" aria-label="Direct link to Integration and Workflow" title="Direct link to Integration and Workflow" translate="no">​</a></h3>
<ul>
<li class=""><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 class=""><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>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="performance-and-scalability">Performance and Scalability<a href="https://boardflare.com/posts/2025/python-regex-excel/#performance-and-scalability" class="hash-link" aria-label="Direct link to Performance and Scalability" title="Direct link to Performance and Scalability" translate="no">​</a></h3>
<ul>
<li class=""><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 class=""><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>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="table-3-feature-comparison-excel-regex-vs-python-re-module">Table 3: Feature Comparison: Excel Regex vs. Python re Module<a href="https://boardflare.com/posts/2025/python-regex-excel/#table-3-feature-comparison-excel-regex-vs-python-re-module" class="hash-link" aria-label="Direct link to Table 3: Feature Comparison: Excel Regex vs. Python re Module" title="Direct link to Table 3: Feature Comparison: Excel Regex vs. Python re Module" translate="no">​</a></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><thead><tr><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><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><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><td style="text-align:left">Basic Metacharacters</td><td style="text-align:left">Full support (<code>.</code>, <code>\*</code>, <code>+</code>, <code>?</code>, `</td><td style="text-align:left"><code>, </code>[]<code>, </code>()<code>, </code>^<code>, </code>$<code>, </code>\d<code>, </code>\w<code>, </code>\s<code>, </code>\b`, etc.)</td></tr><tr><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><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><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><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><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><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><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><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><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><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><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><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>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="broader-implications-of-the-feature-comparison">Broader Implications of the Feature Comparison<a href="https://boardflare.com/posts/2025/python-regex-excel/#broader-implications-of-the-feature-comparison" class="hash-link" aria-label="Direct link to Broader Implications of the Feature Comparison" title="Direct link to Broader Implications of the Feature Comparison" translate="no">​</a></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 (^, <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo stretchy="false">)</mo><mi>f</mi><mi>o</mi><mi>r</mi><mi>m</mi><mi>u</mi><mi>l</mi><mi>t</mi><mi>i</mi><mi>l</mi><mi>i</mi><mi>n</mi><mi>e</mi><mi>m</mi><mi>a</mi><mi>t</mi><mi>c</mi><mi>h</mi><mi>i</mi><mi>n</mi><mi>g</mi><mi>c</mi><mi>a</mi><mi>n</mi><mi>l</mi><mi>e</mi><mi>a</mi><mi>d</mi><mi>t</mi><mi>o</mi><mi>s</mi><mi>u</mi><mi>b</mi><mi>t</mi><mi>l</mi><mi>e</mi><mi>b</mi><mi>u</mi><mi>t</mi><mi>s</mi><mi>i</mi><mi>g</mi><mi>n</mi><mi>i</mi><mi>f</mi><mi>i</mi><mi>c</mi><mi>a</mi><mi>n</mi><mi>t</mi><mi>e</mi><mi>r</mi><mi>r</mi><mi>o</mi><mi>r</mi><mi>s</mi><mi>i</mi><mi>f</mi><mi>a</mi><mi>u</mi><mi>s</mi><mi>e</mi><mi>r</mi><mi>i</mi><mi>s</mi><mi>a</mi><mi>c</mi><mi>c</mi><mi>u</mi><mi>s</mi><mi>t</mi><mi>o</mi><mi>m</mi><mi>e</mi><mi>d</mi><mi>t</mi><mi>o</mi><mi>o</mi><mi>n</mi><mi>e</mi><mi>e</mi><mi>n</mi><mi>v</mi><mi>i</mi><mi>r</mi><mi>o</mi><mi>n</mi><mi>m</mi><mi>e</mi><mi>n</mi><mi>t</mi><mi>a</mi><mi>n</mi><mi>d</mi><mi>a</mi><mi>s</mi><mi>s</mi><mi>u</mi><mi>m</mi><mi>e</mi><mi>s</mi><mi>i</mi><mi>d</mi><mi>e</mi><mi>n</mi><mi>t</mi><mi>i</mi><mi>c</mi><mi>a</mi><mi>l</mi><mi>b</mi><mi>e</mi><mi>h</mi><mi>a</mi><mi>v</mi><mi>i</mi><mi>o</mi><mi>r</mi><mi>i</mi><mi>n</mi><mi>t</mi><mi>h</mi><mi>e</mi><mi>o</mi><mi>t</mi><mi>h</mi><mi>e</mi><mi>r</mi><mi mathvariant="normal">.</mi><mi>I</mi><mi>n</mi><mi>E</mi><mi>x</mi><mi>c</mi><mi>e</mi><mi>l</mi><msup><mo separator="true">,</mo><mi>a</mi></msup><mi>n</mi><mi>d</mi></mrow><annotation encoding="application/x-tex">) 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 </annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em"></span><span class="mclose">)</span><span class="mord mathnormal" style="margin-right:0.1076em">f</span><span class="mord mathnormal" style="margin-right:0.0278em">or</span><span class="mord mathnormal">m</span><span class="mord mathnormal">u</span><span class="mord mathnormal" style="margin-right:0.0197em">l</span><span class="mord mathnormal">t</span><span class="mord mathnormal">i</span><span class="mord mathnormal" style="margin-right:0.0197em">l</span><span class="mord mathnormal">in</span><span class="mord mathnormal">e</span><span class="mord mathnormal">ma</span><span class="mord mathnormal">t</span><span class="mord mathnormal">c</span><span class="mord mathnormal">hin</span><span class="mord mathnormal" style="margin-right:0.0359em">g</span><span class="mord mathnormal">c</span><span class="mord mathnormal">an</span><span class="mord mathnormal" style="margin-right:0.0197em">l</span><span class="mord mathnormal">e</span><span class="mord mathnormal">a</span><span class="mord mathnormal">d</span><span class="mord mathnormal">t</span><span class="mord mathnormal">os</span><span class="mord mathnormal">u</span><span class="mord mathnormal">b</span><span class="mord mathnormal" style="margin-right:0.0197em">tl</span><span class="mord mathnormal">e</span><span class="mord mathnormal">b</span><span class="mord mathnormal">u</span><span class="mord mathnormal">t</span><span class="mord mathnormal">s</span><span class="mord mathnormal">i</span><span class="mord mathnormal" style="margin-right:0.0359em">g</span><span class="mord mathnormal">ni</span><span class="mord mathnormal" style="margin-right:0.1076em">f</span><span class="mord mathnormal">i</span><span class="mord mathnormal">c</span><span class="mord mathnormal">an</span><span class="mord mathnormal">t</span><span class="mord mathnormal" style="margin-right:0.0278em">er</span><span class="mord mathnormal" style="margin-right:0.0278em">r</span><span class="mord mathnormal" style="margin-right:0.0278em">or</span><span class="mord mathnormal">s</span><span class="mord mathnormal">i</span><span class="mord mathnormal" style="margin-right:0.1076em">f</span><span class="mord mathnormal">a</span><span class="mord mathnormal">u</span><span class="mord mathnormal" style="margin-right:0.0278em">ser</span><span class="mord mathnormal">i</span><span class="mord mathnormal">s</span><span class="mord mathnormal">a</span><span class="mord mathnormal">cc</span><span class="mord mathnormal">u</span><span class="mord mathnormal">s</span><span class="mord mathnormal">t</span><span class="mord mathnormal">o</span><span class="mord mathnormal">m</span><span class="mord mathnormal">e</span><span class="mord mathnormal">d</span><span class="mord mathnormal">t</span><span class="mord mathnormal">oo</span><span class="mord mathnormal">n</span><span class="mord mathnormal">ee</span><span class="mord mathnormal">n</span><span class="mord mathnormal" style="margin-right:0.0359em">v</span><span class="mord mathnormal">i</span><span class="mord mathnormal" style="margin-right:0.0278em">r</span><span class="mord mathnormal">o</span><span class="mord mathnormal">nm</span><span class="mord mathnormal">e</span><span class="mord mathnormal">n</span><span class="mord mathnormal">t</span><span class="mord mathnormal">an</span><span class="mord mathnormal">d</span><span class="mord mathnormal">a</span><span class="mord mathnormal">ss</span><span class="mord mathnormal">u</span><span class="mord mathnormal">m</span><span class="mord mathnormal">es</span><span class="mord mathnormal">i</span><span class="mord mathnormal">d</span><span class="mord mathnormal">e</span><span class="mord mathnormal">n</span><span class="mord mathnormal">t</span><span class="mord mathnormal">i</span><span class="mord mathnormal">c</span><span class="mord mathnormal">a</span><span class="mord mathnormal" style="margin-right:0.0197em">l</span><span class="mord mathnormal">b</span><span class="mord mathnormal">e</span><span class="mord mathnormal">ha</span><span class="mord mathnormal" style="margin-right:0.0359em">v</span><span class="mord mathnormal">i</span><span class="mord mathnormal" style="margin-right:0.0278em">or</span><span class="mord mathnormal">in</span><span class="mord mathnormal">t</span><span class="mord mathnormal">h</span><span class="mord mathnormal">eo</span><span class="mord mathnormal">t</span><span class="mord mathnormal">h</span><span class="mord mathnormal" style="margin-right:0.0278em">er</span><span class="mord">.</span><span class="mord mathnormal" style="margin-right:0.0785em">I</span><span class="mord mathnormal">n</span><span class="mord mathnormal" style="margin-right:0.0576em">E</span><span class="mord mathnormal">x</span><span class="mord mathnormal">ce</span><span class="mord mathnormal" style="margin-right:0.0197em">l</span><span class="mpunct"><span class="mpunct">,</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.6644em"><span style="top:-3.063em;margin-right:0.05em"><span class="pstrut" style="height:2.7em"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">a</span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.1667em"></span><span class="mord mathnormal">n</span><span class="mord mathnormal">d</span></span></span></span> 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>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="practical-applications-and-recommendations">Practical Applications and Recommendations<a href="https://boardflare.com/posts/2025/python-regex-excel/#practical-applications-and-recommendations" class="hash-link" aria-label="Direct link to Practical Applications and Recommendations" title="Direct link to Practical Applications and Recommendations" translate="no">​</a></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 class=""><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 class=""><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 class=""><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 class=""><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 class=""><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 class=""><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 class=""><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 class=""><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 class=""><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 class=""><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 class=""><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 class=""><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 class=""><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 class=""><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>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="references">References<a href="https://boardflare.com/posts/2025/python-regex-excel/#references" class="hash-link" aria-label="Direct link to References" title="Direct link to References" translate="no">​</a></h2>
<ol>
<li class="">Regular Expressions in Excel | Exceljet, accessed July 24, 2025, <a href="https://exceljet.net/articles/regular-expressions-in-excel" target="_blank" rel="noopener noreferrer" class="">https://exceljet.net/articles/regular-expressions-in-excel</a></li>
<li class="">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/" target="_blank" rel="noopener noreferrer" class="">https://www.ablebits.com/office-addins-blog/excel-regex-formulas/</a></li>
<li class="">Excel(ent) Obfuscation: Regex Gone Rogue - Deep Instinct, accessed July 24, 2025, <a href="https://www.deepinstinct.com/blog/excellent-obfuscation-regex-gone-rogue" target="_blank" rel="noopener noreferrer" class="">https://www.deepinstinct.com/blog/excellent-obfuscation-regex-gone-rogue</a></li>
<li class="">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" target="_blank" rel="noopener noreferrer" class="">https://medium.com/@khaleel92/mastering-the-power-of-regular-expressions-with-pythons-re-module-a-comprehensive-guide-with-141b855ac403</a></li>
<li class="">Python Regular Expression (RegEX) - Simplilearn.com, accessed July 24, 2025, <a href="https://www.simplilearn.com/tutorials/python-tutorial/python-regular-expressions" target="_blank" rel="noopener noreferrer" class="">https://www.simplilearn.com/tutorials/python-tutorial/python-regular-expressions</a></li>
<li class="">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" target="_blank" rel="noopener noreferrer" class="">https://globalexcelsummit.com/post/introducing-the-new-regex-function-set-in-excel</a></li>
<li class="">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" target="_blank" rel="noopener noreferrer" class="">https://stackoverflow.com/questions/22542834/how-to-use-regular-expressions-regex-in-microsoft-excel-both-in-cell-and-loops</a></li>
<li class="">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/" target="_blank" rel="noopener noreferrer" class="">https://office-watch.com/2025/huge-news-excel-gets-regular-expression-functions/</a></li>
<li class="">Regular Expression HOWTO — Python 3.13.5 documentation, accessed July 24, 2025, <a href="https://docs.python.org/3/howto/regex.html" target="_blank" rel="noopener noreferrer" class="">https://docs.python.org/3/howto/regex.html</a></li>
<li class="">REGEXTEST Function - Microsoft Support, accessed July 24, 2025, <a href="https://support.microsoft.com/en-us/office/regextest-function-7d38200b-5e5c-4196-b4e6-9bff73afbd31" target="_blank" rel="noopener noreferrer" class="">https://support.microsoft.com/en-us/office/regextest-function-7d38200b-5e5c-4196-b4e6-9bff73afbd31</a></li>
<li class="">REGEXEXTRACT Function - Microsoft Support, accessed July 24, 2025, <a href="https://support.microsoft.com/en-us/office/regexextract-function-4b96c140-9205-4b6e-9fbe-6aa9e783ff57" target="_blank" rel="noopener noreferrer" class="">https://support.microsoft.com/en-us/office/regexextract-function-4b96c140-9205-4b6e-9fbe-6aa9e783ff57</a></li>
<li class="">REGEXREPLACE Function - Microsoft Support, accessed July 24, 2025, <a href="https://support.microsoft.com/en-us/office/regexreplace-function-9c030bb2-5e47-4efc-bad5-4582d7100897" target="_blank" rel="noopener noreferrer" class="">https://support.microsoft.com/en-us/office/regexreplace-function-9c030bb2-5e47-4efc-bad5-4582d7100897</a></li>
<li class="">PCRE2 - Perl-Compatible Regular Expressions - GitHub Pages, accessed July 24, 2025, <a href="https://pcre2project.github.io/pcre2/" target="_blank" rel="noopener noreferrer" class="">https://pcre2project.github.io/pcre2/</a></li>
<li class="">Perl Compatible Regular Expressions - Wikipedia, accessed July 24, 2025, <a href="https://en.wikipedia.org/wiki/Perl_Compatible_Regular_Expressions" target="_blank" rel="noopener noreferrer" class="">https://en.wikipedia.org/wiki/Perl_Compatible_Regular_Expressions</a></li>
<li class="">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" target="_blank" rel="noopener noreferrer" class="">https://www.jython.org/jython-old-sites/docs/library/re.html</a></li>
<li class="">Lookahead and Lookbehind Tutorial—Tips &amp;Tricks - RexEgg, accessed July 24, 2025, <a href="https://www.rexegg.com/regex-lookarounds.php" target="_blank" rel="noopener noreferrer" class="">https://www.rexegg.com/regex-lookarounds.php</a></li>
<li class="">Regex Tutorial - Lookahead and Lookbehind Zero-Length Assertions, accessed July 24, 2025, <a href="https://www.regular-expressions.info/lookaround.html" target="_blank" rel="noopener noreferrer" class="">https://www.regular-expressions.info/lookaround.html</a></li>
<li class="">Text.Regex.Pcre2 - Hackage, accessed July 24, 2025, <a href="https://hackage.haskell.org/package/pcre2/docs/Text-Regex-Pcre2.html" target="_blank" rel="noopener noreferrer" class="">https://hackage.haskell.org/package/pcre2/docs/Text-Regex-Pcre2.html</a></li>
</ol>]]></content:encoded>
            <category>Excel</category>
            <category>Python</category>
        </item>
        <item>
            <title><![CDATA[Python Statistical Functions for Excel]]></title>
            <link>https://boardflare.com/posts/2025/python-statistical-functions/</link>
            <guid>https://boardflare.com/posts/2025/python-statistical-functions/</guid>
            <pubDate>Wed, 09 Jul 2025 00:00:00 GMT</pubDate>
            <description><![CDATA[Access the full power of scipy.stats in Excel with our new Python-powered statistical functions, offering comprehensive distribution support and advanced analytics.]]></description>
            <content:encoded><![CDATA[<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" target="_blank" rel="noopener noreferrer" class="">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>
<!-- -->
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="why-use-python-statistical-functions-in-excel">Why Use Python Statistical Functions in Excel?<a href="https://boardflare.com/posts/2025/python-statistical-functions/#why-use-python-statistical-functions-in-excel" class="hash-link" aria-label="Direct link to Why Use Python Statistical Functions in Excel?" title="Direct link to Why Use Python Statistical Functions in Excel?" translate="no">​</a></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 class=""><strong>Full distribution support</strong> (PDF, CDF, inverse CDF, survival, inverse survival)</li>
<li class=""><strong>Comprehensive statistics</strong> (mean, median, variance, standard deviation)</li>
<li class=""><strong>Flexible parameterization</strong> (location and scale for all distributions)</li>
<li class=""><strong>Access to distributions not available in Excel</strong></li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="comparison-table-python-vs-native-excel-functions">Comparison Table: Python vs. Native Excel Functions<a href="https://boardflare.com/posts/2025/python-statistical-functions/#comparison-table-python-vs-native-excel-functions" class="hash-link" aria-label="Direct link to Comparison Table: Python vs. Native Excel Functions" title="Direct link to Comparison Table: Python vs. Native Excel Functions" translate="no">​</a></h2>
<table><thead><tr><th>Excel Python Function</th><th>Native Excel Function(s)</th><th>Key Differences</th></tr></thead><tbody><tr><td>BETA</td><td>BETA.DIST, BETA.INV</td><td>Python adds survival, inverse survival, full stats, and location/scale parameters.</td></tr><tr><td>CAUCHY</td><td>—</td><td>Not available in Excel; Python provides full distribution and stats.</td></tr><tr><td>CHISQ</td><td>CHISQ.DIST, CHISQ.INV</td><td>Python adds survival, inverse survival, full stats, and location/scale parameters.</td></tr><tr><td>EXPON</td><td>EXPON.DIST</td><td>Python adds quantile, survival, inverse survival, full stats, and location/scale.</td></tr><tr><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><td>GAMMA</td><td>GAMMA.DIST, GAMMA.INV</td><td>Python adds survival, inverse survival, full stats, and location/scale parameters.</td></tr><tr><td>LAPLACE</td><td>—</td><td>Not available in Excel; Python provides full distribution and stats.</td></tr><tr><td>LOGNORM</td><td>LOGNORM.DIST, LOGNORM.INV</td><td>Python adds survival, inverse survival, full stats, and location/scale parameters.</td></tr><tr><td>NORM</td><td>NORM.DIST, NORM.INV</td><td>Python adds survival, inverse survival, full stats, and location/scale parameters.</td></tr><tr><td>PARETO</td><td>—</td><td>Not available in Excel; Python provides full distribution and stats.</td></tr><tr><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><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><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></p>
<ul>
<li class="">PDF: Probability Density Function</li>
<li class="">CDF: Cumulative Distribution Function</li>
<li class="">Quantile: Inverse CDF</li>
<li class="">Survival: Survival Function (1 - CDF)</li>
<li class="">Stats: Mean, Median, Variance, Standard Deviation</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="example-using-python-functions-in-excel">Example: Using Python Functions in Excel<a href="https://boardflare.com/posts/2025/python-statistical-functions/#example-using-python-functions-in-excel" class="hash-link" aria-label="Direct link to Example: Using Python Functions in Excel" title="Direct link to Example: Using Python Functions in Excel" translate="no">​</a></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>
<div class="language-excel codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-excel codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">=WEIBULL_MIN(0.95, 1.5, 0, 1, "icdf")</span><br></div></code></pre></div></div>
<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>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="getting-started">Getting Started<a href="https://boardflare.com/posts/2025/python-statistical-functions/#getting-started" class="hash-link" aria-label="Direct link to Getting Started" title="Direct link to Getting Started" translate="no">​</a></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://tools.boardflare.com/" target="_blank" rel="noopener noreferrer" class="">Python Functions Repository</a>.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="excel-statistical-functions">Excel Statistical Functions<a href="https://boardflare.com/posts/2025/python-statistical-functions/#excel-statistical-functions" class="hash-link" aria-label="Direct link to Excel Statistical Functions" title="Direct link to Excel Statistical Functions" translate="no">​</a></h2>
<table><thead><tr><th>Function</th><th>Description</th></tr></thead><tbody><tr><td>AVEDEV</td><td>Returns the average of the absolute deviations of data points from their mean</td></tr><tr><td>AVERAGE</td><td>Returns the average of its arguments</td></tr><tr><td>AVERAGEA</td><td>Returns the average of its arguments, including numbers, text, and logical values</td></tr><tr><td>AVERAGEIF</td><td>Returns the average (arithmetic mean) of all the cells in a range that meet a given criteria</td></tr><tr><td>AVERAGEIFS</td><td>Returns the average (arithmetic mean) of all cells that meet multiple criteria</td></tr><tr><td>BETA.DIST</td><td>Returns the beta cumulative distribution function</td></tr><tr><td>BETA.INV</td><td>Returns the inverse of the cumulative distribution function for a specified beta distribution</td></tr><tr><td>BINOM.DIST</td><td>Returns the individual term binomial distribution probability</td></tr><tr><td>BINOM.DIST.RANGE</td><td>Returns the probability of a trial result using a binomial distribution</td></tr><tr><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><td>CHISQ.DIST</td><td>Returns the cumulative beta probability density function</td></tr><tr><td>CHISQ.DIST.RT</td><td>Returns the one-tailed probability of the chi-squared distribution</td></tr><tr><td>CHISQ.INV</td><td>Returns the cumulative beta probability density function</td></tr><tr><td>CHISQ.INV.RT</td><td>Returns the inverse of the one-tailed probability of the chi-squared distribution</td></tr><tr><td>CHISQ.TEST</td><td>Returns the test for independence</td></tr><tr><td>CONFIDENCE.NORM</td><td>Returns the confidence interval for a population mean</td></tr><tr><td>CONFIDENCE.T</td><td>Returns the confidence interval for a population mean, using a Student's t distribution</td></tr><tr><td>CORREL</td><td>Returns the correlation coefficient between two data sets</td></tr><tr><td>COUNT</td><td>Counts how many numbers are in the list of arguments</td></tr><tr><td>COUNTA</td><td>Counts how many values are in the list of arguments</td></tr><tr><td>COUNTBLANK</td><td>Counts the number of blank cells within a range</td></tr><tr><td>COUNTIF</td><td>Counts the number of cells within a range that meet the given criteria</td></tr><tr><td>COUNTIFS</td><td>Counts the number of cells within a range that meet multiple criteria</td></tr><tr><td>COVARIANCE.P</td><td>Returns covariance, the average of the products of paired deviations</td></tr><tr><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><td>DEVSQ</td><td>Returns the sum of squares of deviations</td></tr><tr><td>EXPON.DIST</td><td>Returns the exponential distribution</td></tr><tr><td>F.DIST</td><td>Returns the F probability distribution</td></tr><tr><td>F.DIST.RT</td><td>Returns the F probability distribution</td></tr><tr><td>F.INV</td><td>Returns the inverse of the F probability distribution</td></tr><tr><td>F.INV.RT</td><td>Returns the inverse of the F probability distribution</td></tr><tr><td>F.TEST</td><td>Returns the result of an F-test</td></tr><tr><td>FISHER</td><td>Returns the Fisher transformation</td></tr><tr><td>FISHERINV</td><td>Returns the inverse of the Fisher transformation</td></tr><tr><td>FORECAST</td><td>Returns a value along a linear trend</td></tr><tr><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><td>FORECAST.ETS.CONFINT</td><td>Returns a confidence interval for the forecast value at the specified target date</td></tr><tr><td>FORECAST.ETS.SEASONALITY</td><td>Returns the length of the repetitive pattern Excel detects for the specified time series</td></tr><tr><td>FORECAST.ETS.STAT</td><td>Returns a statistical value as a result of time series forecasting</td></tr><tr><td>FORECAST.LINEAR</td><td>Returns a future value based on existing values</td></tr><tr><td>FREQUENCY</td><td>Returns a frequency distribution as a vertical array</td></tr><tr><td>GAMMA</td><td>Returns the gamma function value</td></tr><tr><td>GAMMA.DIST</td><td>Returns the gamma distribution</td></tr><tr><td>GAMMA.INV</td><td>Returns the inverse of the gamma cumulative distribution</td></tr><tr><td>GAMMALN</td><td>Returns the natural logarithm of the gamma function, Γ(x)</td></tr><tr><td>GAMMALN.PRECISE</td><td>Returns the natural logarithm of the gamma function, Γ(x)</td></tr><tr><td>GAUSS</td><td>Returns 0.5 less than the standard normal cumulative distribution</td></tr><tr><td>GEOMEAN</td><td>Returns the geometric mean</td></tr><tr><td>GROWTH</td><td>Returns values along an exponential trend</td></tr><tr><td>HARMEAN</td><td>Returns the harmonic mean</td></tr><tr><td>HYPGEOM.DIST</td><td>Returns the hypergeometric distribution</td></tr><tr><td>INTERCEPT</td><td>Returns the intercept of the linear regression line</td></tr><tr><td>KURT</td><td>Returns the kurtosis of a data set</td></tr><tr><td>LARGE</td><td>Returns the k-th largest value in a data set</td></tr><tr><td>LINEST</td><td>Returns the parameters of a linear trend</td></tr><tr><td>LOGEST</td><td>Returns the parameters of an exponential trend</td></tr><tr><td>LOGNORM.DIST</td><td>Returns the cumulative lognormal distribution</td></tr><tr><td>LOGNORM.INV</td><td>Returns the inverse of the lognormal cumulative distribution</td></tr><tr><td>MAX</td><td>Returns the maximum value in a list of arguments</td></tr><tr><td>MAXA</td><td>Returns the maximum value in a list of arguments, including numbers, text, and logical values</td></tr><tr><td>MAXIFS</td><td>Returns the maximum value among cells specified by a given set of conditions or criteria</td></tr><tr><td>MEDIAN</td><td>Returns the median of the given numbers</td></tr><tr><td>MIN</td><td>Returns the minimum value in a list of arguments</td></tr><tr><td>MINIFS</td><td>Returns the minimum value among cells specified by a given set of conditions or criteria.</td></tr><tr><td>MINA</td><td>Returns the smallest value in a list of arguments, including numbers, text, and logical values</td></tr><tr><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><td>MODE.SNGL</td><td>Returns the most common value in a data set</td></tr><tr><td>NEGBINOM.DIST</td><td>Returns the negative binomial distribution</td></tr><tr><td>NORM.DIST</td><td>Returns the normal cumulative distribution</td></tr><tr><td>NORM.INV</td><td>Returns the inverse of the normal cumulative distribution</td></tr><tr><td>NORM.S.DIST</td><td>Returns the standard normal cumulative distribution</td></tr><tr><td>NORM.S.INV</td><td>Returns the inverse of the standard normal cumulative distribution</td></tr><tr><td>PEARSON</td><td>Returns the Pearson product moment correlation coefficient</td></tr><tr><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><td>PERCENTILE.INC</td><td>Returns the k-th percentile of values in a range</td></tr><tr><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><td>PERCENTRANK.INC</td><td>Returns the percentage rank of a value in a data set</td></tr><tr><td>PERMUT</td><td>Returns the number of permutations for a given number of objects</td></tr><tr><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><td>PHI</td><td>Returns the value of the density function for a standard normal distribution</td></tr><tr><td>POISSON.DIST</td><td>Returns the Poisson distribution</td></tr><tr><td>PROB</td><td>Returns the probability that values in a range are between two limits</td></tr><tr><td>QUARTILE.EXC</td><td>Returns the quartile of the data set, based on percentile values from 0 to 1, exclusive</td></tr><tr><td>QUARTILE.INC</td><td>Returns the quartile of a data set</td></tr><tr><td>RANK.AVG</td><td>Returns the rank of a number in a list of numbers</td></tr><tr><td>RANK.EQ</td><td>Returns the rank of a number in a list of numbers</td></tr><tr><td>RSQ</td><td>Returns the square of the Pearson product moment correlation coefficient</td></tr><tr><td>SKEW</td><td>Returns the skewness of a distribution</td></tr><tr><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><td>SLOPE</td><td>Returns the slope of the linear regression line</td></tr><tr><td>SMALL</td><td>Returns the k-th smallest value in a data set</td></tr><tr><td>STANDARDIZE</td><td>Returns a normalized value</td></tr><tr><td>STDEV.P</td><td>Calculates standard deviation based on the entire population</td></tr><tr><td>STDEV.S</td><td>Estimates standard deviation based on a sample</td></tr><tr><td>STDEVA</td><td>Estimates standard deviation based on a sample, including numbers, text, and logical values</td></tr><tr><td>STDEVPA</td><td>Calculates standard deviation based on the entire population, including numbers, text, and logical values</td></tr><tr><td>STEYX</td><td>Returns the standard error of the predicted y-value for each x in the regression</td></tr><tr><td>T.DIST</td><td>Returns the Percentage Points (probability) for the Student t-distribution</td></tr><tr><td>T.DIST.2T</td><td>Returns the Percentage Points (probability) for the Student t-distribution</td></tr><tr><td>T.DIST.RT</td><td>Returns the Student's t-distribution</td></tr><tr><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><td>T.INV.2T</td><td>Returns the inverse of the Student's t-distribution</td></tr><tr><td>T.TEST</td><td>Returns the probability associated with a Student's t-test</td></tr><tr><td>TREND</td><td>Returns values along a linear trend</td></tr><tr><td>TRIMMEAN</td><td>Returns the mean of the interior of a data set</td></tr><tr><td>VAR.P</td><td>Calculates variance based on the entire population</td></tr><tr><td>VAR.S</td><td>Estimates variance based on a sample</td></tr><tr><td>VARA</td><td>Estimates variance based on a sample, including numbers, text, and logical values</td></tr><tr><td>VARPA</td><td>Calculates variance based on the entire population, including numbers, text, and logical values</td></tr><tr><td>WEIBULL.DIST</td><td>Returns the Weibull distribution</td></tr><tr><td>Z.TEST</td><td>Returns the one-tailed probability-value of a z-test</td></tr></tbody></table>]]></content:encoded>
            <category>Python</category>
            <category>Statistics</category>
            <category>Excel</category>
        </item>
        <item>
            <title><![CDATA[Python Functions Repository]]></title>
            <link>https://boardflare.com/posts/2025/python-functions-repo/</link>
            <guid>https://boardflare.com/posts/2025/python-functions-repo/</guid>
            <pubDate>Tue, 03 Jun 2025 00:00:00 GMT</pubDate>
            <description><![CDATA[We've launched a new repository of Python functions that can be used directly in Excel via our add-in or as standalone web apps.]]></description>
            <content:encoded><![CDATA[<p>We've launched a repository of <a href="https://tools.boardflare.com/" target="_blank" rel="noopener noreferrer" class="">Python Functions</a> that can be used in Excel as custom functions through the <a class="" href="https://boardflare.com/apps/excel/python/">Python for Excel add-in</a> and as web apps via <a href="https://www.gradio.app/" target="_blank" rel="noopener noreferrer" class="">Gradio</a>.</p>
<!-- -->
<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>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="why-use-python-functions-in-excel">Why Use Python Functions in Excel?<a href="https://boardflare.com/posts/2025/python-functions-repo/#why-use-python-functions-in-excel" class="hash-link" aria-label="Direct link to Why Use Python Functions in Excel?" title="Direct link to Why Use Python Functions in Excel?" translate="no">​</a></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:</p>
<ul>
<li class="">Perform advanced statistical analysis, optimization, and modeling using industry-standard libraries.</li>
<li class="">Connect to APIs, web data, and external sources with just a formula.</li>
<li class="">Analyze unstructured data, such as text, with natural language processing tools.</li>
<li class="">Build custom solutions that scale beyond what is possible with built-in Excel features.</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="request-a-function">Request a Function<a href="https://boardflare.com/posts/2025/python-functions-repo/#request-a-function" class="hash-link" aria-label="Direct link to Request a Function" title="Direct link to Request a Function" translate="no">​</a></h2>
<p>If there is a function you'd like to see, please <a class="" href="https://boardflare.com/company/support/">Contact us</a>.</p>]]></content:encoded>
            <category>Python</category>
            <category>Excel</category>
        </item>
        <item>
            <title><![CDATA[Applications of AI in a Spreadsheet]]></title>
            <link>https://boardflare.com/posts/2025/applications-ai-spreadsheets/</link>
            <guid>https://boardflare.com/posts/2025/applications-ai-spreadsheets/</guid>
            <pubDate>Sun, 20 Apr 2025 00:00:00 GMT</pubDate>
            <description><![CDATA[Explore how AI-powered functions like AI_ASK, AI_EXTRACT, and AI_FORMAT are revolutionizing spreadsheet workflows by enabling natural language interaction and intelligent data processing.]]></description>
            <content:encoded><![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>
<!-- -->
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="core-ai-capabilities-in-spreadsheets">Core AI Capabilities in Spreadsheets<a href="https://boardflare.com/posts/2025/applications-ai-spreadsheets/#core-ai-capabilities-in-spreadsheets" class="hash-link" aria-label="Direct link to Core AI Capabilities in Spreadsheets" title="Direct link to Core AI Capabilities in Spreadsheets" translate="no">​</a></h2>
<p>Modern AI spreadsheet functions bring several core capabilities directly to your data:</p>
<ol>
<li class=""><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 class=""><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 class=""><strong>Data Cleaning &amp; Formatting:</strong> Standardizing inconsistent data formats (dates, addresses, names) automatically (<code>AI_FORMAT</code>).</li>
<li class=""><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 class=""><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 class=""><strong>List Generation:</strong> Create lists based on prompts or existing data (<code>AI_LIST</code>).</li>
</ol>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="available-ai-text-functions">Available AI Text Functions<a href="https://boardflare.com/posts/2025/applications-ai-spreadsheets/#available-ai-text-functions" class="hash-link" aria-label="Direct link to Available AI Text Functions" title="Direct link to Available AI Text Functions" translate="no">​</a></h2>
<p>The following functions leverage AI to work with text data:</p>
<table><thead><tr><th>Function Name</th><th>Description</th></tr></thead><tbody><tr><td><a href="https://tools.boardflare.com/" target="_blank" rel="noopener noreferrer" class="">AI_ASK</a></td><td>Ask questions, summarize, generate text</td></tr><tr><td><a href="https://tools.boardflare.com/" target="_blank" rel="noopener noreferrer" class="">AI_CHOICE</a></td><td>Classify or categorize text</td></tr><tr><td><a href="https://tools.boardflare.com/" target="_blank" rel="noopener noreferrer" class="">AI_EXTRACT</a></td><td>Extract specific information from text</td></tr><tr><td><a href="https://tools.boardflare.com/" target="_blank" rel="noopener noreferrer" class="">AI_FILL</a></td><td>Fill missing data or infer patterns</td></tr><tr><td><a href="https://tools.boardflare.com/" target="_blank" rel="noopener noreferrer" class="">AI_FORMAT</a></td><td>Clean, standardize, or reformat text</td></tr><tr><td><a href="https://tools.boardflare.com/" target="_blank" rel="noopener noreferrer" class="">AI_LIST</a></td><td>Generate lists or extract items</td></tr><tr><td><a href="https://tools.boardflare.com/" target="_blank" rel="noopener noreferrer" class="">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>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="application-examples">Application Examples<a href="https://boardflare.com/posts/2025/applications-ai-spreadsheets/#application-examples" class="hash-link" aria-label="Direct link to Application Examples" title="Direct link to Application Examples" translate="no">​</a></h2>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="market-research--customer-feedback-analysis">Market Research &amp; Customer Feedback Analysis<a href="https://boardflare.com/posts/2025/applications-ai-spreadsheets/#market-research--customer-feedback-analysis" class="hash-link" aria-label="Direct link to Market Research &amp; Customer Feedback Analysis" title="Direct link to Market Research &amp; Customer Feedback Analysis" translate="no">​</a></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 class=""><strong>Input Data:</strong></li>
</ul>
<table><thead><tr><th style="text-align:left">Customer ID</th><th style="text-align:left">Feedback Text</th></tr></thead><tbody><tr><td style="text-align:left">CUST-001</td><td style="text-align:left">The new interface is amazing and so intuitive!</td></tr><tr><td style="text-align:left">CUST-002</td><td style="text-align:left">I'm really frustrated with the latest update.</td></tr><tr><td style="text-align:left">CUST-003</td><td style="text-align:left">It's okay, but I expected more features.</td></tr><tr><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 class=""><strong>AI Application (<code>AI_CHOICE</code>):</strong> <code>=AI_CHOICE(B2, "Positive, Negative, Neutral")</code></li>
<li class=""><strong>Output:</strong></li>
</ul>
<table><thead><tr><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><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><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><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><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 class=""><strong>Input Data:</strong> (Same as above)</li>
<li class=""><strong>AI Application (<code>AI_EXTRACT</code>):</strong> <code>=AI_EXTRACT(B2, "the main topic")</code></li>
<li class=""><strong>Output:</strong></li>
</ul>
<table><thead><tr><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><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><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><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><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 class=""><strong>Input Data:</strong></li>
</ul>
<table><thead><tr><th style="text-align:left">Review ID</th><th style="text-align:left">Full Review Text</th></tr></thead><tbody><tr><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><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 class=""><strong>AI Application (<code>AI_ASK</code>):</strong> <code>=AI_ASK("Summarize the following review in one sentence:", B2)</code></li>
<li class=""><strong>Output:</strong></li>
</ul>
<table><thead><tr><th style="text-align:left">Review ID</th><th style="text-align:left">Summary</th></tr></thead><tbody><tr><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><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>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="sales--marketing-automation">Sales &amp; Marketing Automation<a href="https://boardflare.com/posts/2025/applications-ai-spreadsheets/#sales--marketing-automation" class="hash-link" aria-label="Direct link to Sales &amp; Marketing Automation" title="Direct link to Sales &amp; Marketing Automation" translate="no">​</a></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 class=""><strong>Input Data:</strong></li>
</ul>
<table><thead><tr><th style="text-align:left">Lead ID</th><th style="text-align:left">Notes</th></tr></thead><tbody><tr><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><td style="text-align:left">LEAD-51</td><td style="text-align:left">Downloaded whitepaper, student email address.</td></tr><tr><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><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 class=""><strong>AI Application (<code>AI_CHOICE</code>):</strong> <code>=AI_CHOICE(B2, "Hot, Warm, Cold")</code></li>
<li class=""><strong>Output:</strong></li>
</ul>
<table><thead><tr><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><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><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><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><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 class=""><strong>Input Data:</strong></li>
</ul>
<table><thead><tr><th style="text-align:left">Source Text</th></tr></thead><tbody><tr><td style="text-align:left">Met with John Doe (<a href="mailto:john.doe@example.com" target="_blank" rel="noopener noreferrer" class="">john.doe@example.com</a>, 555-1234) from Acme Corp yesterday. Follow up next week.</td></tr><tr><td style="text-align:left">Received inquiry from Jane Smith at Beta Industries. Her email is <a href="mailto:jane.s@beta.co" target="_blank" rel="noopener noreferrer" class="">jane.s@beta.co</a> and phone is 555-987-6543.</td></tr></tbody></table>
<ul>
<li class=""><strong>AI Application (<code>AI_EXTRACT</code>):</strong> <code>=AI_EXTRACT(A2, "the email address")</code></li>
<li class=""><strong>Output:</strong></li>
</ul>
<table><thead><tr><th style="text-align:left">Email Address</th></tr></thead><tbody><tr><td style="text-align:left"><a href="mailto:john.doe@example.com" target="_blank" rel="noopener noreferrer" class="">john.doe@example.com</a></td></tr><tr><td style="text-align:left"><a href="mailto:jane.s@beta.co" target="_blank" rel="noopener noreferrer" class="">jane.s@beta.co</a></td></tr></tbody></table>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="data-cleaning-and-standardization">Data Cleaning and Standardization<a href="https://boardflare.com/posts/2025/applications-ai-spreadsheets/#data-cleaning-and-standardization" class="hash-link" aria-label="Direct link to Data Cleaning and Standardization" title="Direct link to Data Cleaning and Standardization" translate="no">​</a></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 class=""><strong>Input Data:</strong></li>
</ul>
<table><thead><tr><th style="text-align:left">Raw Address</th></tr></thead><tbody><tr><td style="text-align:left">123 main st., anytown, ca 90210</td></tr><tr><td style="text-align:left">456 Oak Avenue, Springfield IL</td></tr><tr><td style="text-align:left">789 elm rd apt 2b new york ny</td></tr></tbody></table>
<ul>
<li class=""><strong>AI Application (<code>AI_FORMAT</code>):</strong> <code>=AI_FORMAT(A2, "Standard US Address format: Street, City, ST ZIP")</code></li>
<li class=""><strong>Output:</strong></li>
</ul>
<table><thead><tr><th style="text-align:left">Standardized Address</th></tr></thead><tbody><tr><td style="text-align:left">123 Main St, Anytown, CA 90210</td></tr><tr><td style="text-align:left">456 Oak Ave, Springfield, IL 62704</td></tr><tr><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 class=""><strong>Input Data:</strong></li>
</ul>
<table><thead><tr><th style="text-align:left">Raw Name</th></tr></thead><tbody><tr><td style="text-align:left">john SMITH</td></tr><tr><td style="text-align:left">mary-anne jones</td></tr><tr><td style="text-align:left">dr. peter pan</td></tr></tbody></table>
<ul>
<li class=""><strong>AI Application (<code>AI_FORMAT</code>):</strong> <code>=AI_FORMAT(A2, "Proper Name Capitalization")</code></li>
<li class=""><strong>Output:</strong></li>
</ul>
<table><thead><tr><th style="text-align:left">Cleaned Name</th></tr></thead><tbody><tr><td style="text-align:left">John Smith</td></tr><tr><td style="text-align:left">Mary-Anne Jones</td></tr><tr><td style="text-align:left">Dr. Peter Pan</td></tr></tbody></table>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="content-creation--brainstorming">Content Creation &amp; Brainstorming<a href="https://boardflare.com/posts/2025/applications-ai-spreadsheets/#content-creation--brainstorming" class="hash-link" aria-label="Direct link to Content Creation &amp; Brainstorming" title="Direct link to Content Creation &amp; Brainstorming" translate="no">​</a></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 class=""><strong>Input Data:</strong></li>
</ul>
<table><thead><tr><th style="text-align:left">Topic</th></tr></thead><tbody><tr><td style="text-align:left">Sustainable Urban Gardening</td></tr><tr><td style="text-align:left">Productivity Hacks for Teams</td></tr><tr><td style="text-align:left">Introduction to Quantum Computing</td></tr></tbody></table>
<ul>
<li class=""><strong>AI Application (<code>AI_LIST</code>):</strong> <code>=AI_LIST("Generate 5 blog post titles about "&amp;A2)</code></li>
<li class=""><strong>Output (Example for Row 1):</strong></li>
</ul>
<table><thead><tr><th style="text-align:left">Generated Titles</th></tr></thead><tbody><tr><td style="text-align:left">5 Easy Steps to Start Your Urban Garden Sustainably</td></tr><tr><td style="text-align:left">Balcony Bounty: Sustainable Gardening in Small Spaces</td></tr><tr><td style="text-align:left">The Future is Green: Why Cities Need Sustainable Gardens</td></tr><tr><td style="text-align:left">Reduce Your Footprint: Composting Tips for Urban Gardeners</td></tr><tr><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 class=""><strong>Input Data:</strong></li>
</ul>
<table><thead><tr><th style="text-align:left">Notes</th></tr></thead><tbody><tr><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 class=""><strong>AI Application (<code>AI_TABLE</code>):</strong> <code>=AI_TABLE(A2, "Action Item, Owner, Due Date")</code></li>
<li class=""><strong>Output:</strong></li>
</ul>
<table><thead><tr><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><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><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>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="pattern-recognition-and-data-augmentation">Pattern Recognition and Data Augmentation<a href="https://boardflare.com/posts/2025/applications-ai-spreadsheets/#pattern-recognition-and-data-augmentation" class="hash-link" aria-label="Direct link to Pattern Recognition and Data Augmentation" title="Direct link to Pattern Recognition and Data Augmentation" translate="no">​</a></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 class=""><strong>Input Data &amp; Goal:</strong> Fill in the 'Category' based on the 'Product SKU' pattern.</li>
</ul>
<table><thead><tr><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><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><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><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><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><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><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 class=""><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 class=""><strong>Output:</strong></li>
</ul>
<table><thead><tr><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><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><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><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><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><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><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 class=""><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>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="combining-ai-functions-for-complex-workflows">Combining AI Functions for Complex Workflows<a href="https://boardflare.com/posts/2025/applications-ai-spreadsheets/#combining-ai-functions-for-complex-workflows" class="hash-link" aria-label="Direct link to Combining AI Functions for Complex Workflows" title="Direct link to Combining AI Functions for Complex Workflows" translate="no">​</a></h2>
<p>The true power emerges when combining these functions. Imagine analyzing product feedback:</p>
<ol>
<li class=""><strong>Paste Raw Feedback:</strong> Place raw customer feedback text into Column A.</li>
<li class=""><strong>Extract Product Name (<code>AI_EXTRACT</code>):</strong> In Column B, use <code>=AI_EXTRACT(A2, "the product name mentioned")</code>.</li>
<li class=""><strong>Analyze Sentiment (<code>AI_CHOICE</code>):</strong> In Column C, use <code>=AI_CHOICE(A2, "Positive, Negative, Neutral")</code>.</li>
<li class=""><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 class=""><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>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="tips-for-effective-use">Tips for Effective Use<a href="https://boardflare.com/posts/2025/applications-ai-spreadsheets/#tips-for-effective-use" class="hash-link" aria-label="Direct link to Tips for Effective Use" title="Direct link to Tips for Effective Use" translate="no">​</a></h2>
<ul>
<li class=""><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 class=""><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 class=""><strong>Start Small:</strong> Test AI functions on a subset of your data first to understand their behavior and refine your prompts.</li>
<li class=""><strong>Review Results:</strong> AI is powerful but not infallible. Always review the generated results for accuracy, especially for critical data.</li>
<li class=""><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 class=""><strong>Consult Documentation:</strong> For detailed usage, parameters, and more examples, see the linked documentation for each function in the table above.</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="conclusion">Conclusion<a href="https://boardflare.com/posts/2025/applications-ai-spreadsheets/#conclusion" class="hash-link" aria-label="Direct link to Conclusion" title="Direct link to Conclusion" translate="no">​</a></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 class="">Quickly extract insights from unstructured text.</li>
<li class="">Automate tedious data cleaning and formatting tasks.</li>
<li class="">Generate creative content and ideas efficiently.</li>
<li class="">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>]]></content:encoded>
            <category>Excel</category>
            <category>AI</category>
        </item>
        <item>
            <title><![CDATA[Python for Excel Code Editor]]></title>
            <link>https://boardflare.com/posts/2025/python-excel-code-editor/</link>
            <guid>https://boardflare.com/posts/2025/python-excel-code-editor/</guid>
            <pubDate>Sat, 18 Jan 2025 00:00:00 GMT</pubDate>
            <description><![CDATA[Introducing a major update to our Python for Excel add-in: a new Monaco-based code editor with syntax highlighting, function management, and integrated testing.]]></description>
            <content:encoded><![CDATA[<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>
<!-- -->
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="key-features">Key Features<a href="https://boardflare.com/posts/2025/python-excel-code-editor/#key-features" class="hash-link" aria-label="Direct link to Key Features" title="Direct link to Key Features" translate="no">​</a></h2>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="monaco-editor-integration">Monaco Editor Integration<a href="https://boardflare.com/posts/2025/python-excel-code-editor/#monaco-editor-integration" class="hash-link" aria-label="Direct link to Monaco Editor Integration" title="Direct link to Monaco Editor Integration" translate="no">​</a></h3>
<p>The add-in now includes the same editor (<a href="https://github.com/microsoft/monaco-editor" target="_blank" rel="noopener noreferrer" class="">Monaco</a>) used in VS Code, providing:</p>
<ul>
<li class="">Syntax highlighting for Python</li>
<li class="">Code completion and formatting</li>
<li class="">Error detection</li>
</ul>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="function-management">Function Management<a href="https://boardflare.com/posts/2025/python-excel-code-editor/#function-management" class="hash-link" aria-label="Direct link to Function Management" title="Direct link to Function Management" translate="no">​</a></h3>
<p>A new Functions tab lets you:</p>
<ul>
<li class="">View all Python functions in your workbook</li>
<li class="">Edit existing functions</li>
<li class="">Delete unused functions</li>
<li class="">Import functions from Jupyter notebooks</li>
</ul>
<p><img decoding="async" loading="lazy" alt="Functions Tab" src="https://boardflare.com/assets/images/functions-tab-ba067ce528cbd7b370ae0f4e1b9f218b.png" width="1393" height="1054" class="img_ev3q"></p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="testing-integration">Testing Integration<a href="https://boardflare.com/posts/2025/python-excel-code-editor/#testing-integration" class="hash-link" aria-label="Direct link to Testing Integration" title="Direct link to Testing Integration" translate="no">​</a></h3>
<p>Write test cases directly in your Python code:</p>
<div class="language-python codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-python codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">def</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">hello</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">first</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> last</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token triple-quoted-string string" style="color:#e3116c">""" Returns a greeting. """</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    greeting </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token string-interpolation string" style="color:#e3116c">f"Hello </span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">{</span><span class="token string-interpolation interpolation">first</span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">,</span><span class="token string-interpolation interpolation"> last</span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">}</span><span class="token string-interpolation string" style="color:#e3116c">!"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> greeting</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic"># Test cases for the function</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">test_cases </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token punctuation" style="color:#393A34">[</span><span class="token string" style="color:#e3116c">"Nancy"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"Morgan"</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token string" style="color:#e3116c">"Ming"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"Lee"</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">]</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic"># Excel usage: =HELLO("Nancy", "Morgan")</span><br></div></code></pre></div></div>
<p>Click "Test" to run your cases and see results in the Output tab.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="how-it-works">How It Works<a href="https://boardflare.com/posts/2025/python-excel-code-editor/#how-it-works" class="hash-link" aria-label="Direct link to How It Works" title="Direct link to How It Works" translate="no">​</a></h2>
<p>Creating a Python-powered LAMBDA function is now a two-step process:</p>
<ol>
<li class="">Write your Python function in the editor</li>
<li class="">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="language-python codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-python codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">def</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">inches_to_mm</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">inches</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token triple-quoted-string string" style="color:#e3116c">""" Converts inches to millimeters. """</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> inches </span><span class="token operator" style="color:#393A34">*</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">25.4</span><br></div></code></pre></div></div>
<p>Creates this LAMBDA in Excel:</p>
<div class="language-excel codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-excel codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">=LAMBDA(inches, BOARDFLARE.EXEC("workbook-settings:inches_to_mm", inches))</span><br></div></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="jupyter-notebook-integration">Jupyter Notebook Integration<a href="https://boardflare.com/posts/2025/python-excel-code-editor/#jupyter-notebook-integration" class="hash-link" aria-label="Direct link to Jupyter Notebook Integration" title="Direct link to Jupyter Notebook Integration" translate="no">​</a></h2>
<p>A particularly exciting feature is the ability to import functions from Jupyter notebooks. You can:</p>
<ul>
<li class="">Import from our example notebooks</li>
<li class="">Load notebooks from GitHub Gists</li>
<li class="">Use the notebooks as templates for your own functions</li>
</ul>
<p>This makes it easy to maintain a library of functions in notebooks and import them into Excel as needed.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="try-it-out">Try It Out<a href="https://boardflare.com/posts/2025/python-excel-code-editor/#try-it-out" class="hash-link" aria-label="Direct link to Try It Out" title="Direct link to Try It Out" translate="no">​</a></h2>
<p>To get started with the new code editor:</p>
<ol>
<li class="">Install the <a href="https://appsource.microsoft.com/en-us/product/office/WA200007447?tab=Overview" target="_blank" rel="noopener noreferrer" class="">Python for Excel add-in</a></li>
<li class="">Open the task pane and go to the Editor tab</li>
<li class="">Try writing a simple function or import one of our examples</li>
<li class="">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 class="" href="https://boardflare.com/apps/excel/python/">updated documentation</a>.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="whats-next">What's Next?<a href="https://boardflare.com/posts/2025/python-excel-code-editor/#whats-next" class="hash-link" aria-label="Direct link to What's Next?" title="Direct link to What's Next?" translate="no">​</a></h2>
<p>We're continuing to improve the editor experience. Coming soon:</p>
<ul>
<li class="">Support for optional arguments</li>
<li class="">More example notebooks</li>
<li class="">Enhanced type conversion options</li>
</ul>
<p>Let us know what features you'd like to see next!</p>]]></content:encoded>
            <category>Excel</category>
            <category>Python</category>
            <category>Office Add-ins</category>
        </item>
        <item>
            <title><![CDATA[Fuzzy Matching with Python in Excel]]></title>
            <link>https://boardflare.com/posts/2024/fuzzy-matching-python-excel/</link>
            <guid>https://boardflare.com/posts/2024/fuzzy-matching-python-excel/</guid>
            <pubDate>Mon, 04 Nov 2024 00:00:00 GMT</pubDate>
            <description><![CDATA[Perform approximate string matching in Excel using the NLTK library and Python, enabling powerful fuzzy search capabilities beyond exact matches.]]></description>
            <content:encoded><![CDATA[<p>Fuzzy matching is a technique used to find strings that are approximately equal, e.g. "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" target="_blank" rel="noopener noreferrer" class="">Python in Excel</a> using the <a href="https://github.com/nltk/nltk" target="_blank" rel="noopener noreferrer" class="">NLTK</a> library.</p>
<p>Our <a href="https://tools.boardflare.com/" target="_blank" rel="noopener noreferrer" class="">text_distance</a> function for fuzzy matching is similar to that used in our <a class="" href="https://boardflare.com/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 class="" href="https://boardflare.com/resources/tasks/nlp/fuzzy-match/">Fuzzy Match tutorial</a> with more details.</p>
<!-- -->
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="nltk-library">NLTK Library<a href="https://boardflare.com/posts/2024/fuzzy-matching-python-excel/#nltk-library" class="hash-link" aria-label="Direct link to NLTK Library" title="Direct link to NLTK Library" translate="no">​</a></h2>
<p>The <a href="https://www.nltk.org/" target="_blank" rel="noopener noreferrer" class="">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="language-python codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-python codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">from</span><span class="token plain"> nltk</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">metrics</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">distance </span><span class="token keyword" style="color:#00009f">import</span><span class="token plain"> edit_distance</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">string1 </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"apple"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">string2 </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"apples"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">distance </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> edit_distance</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">string1</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> string2</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">print</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">distance</span><span class="token punctuation" style="color:#393A34">)</span><br></div></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 class=""><strong>Jaccard Distance</strong>: Measures the similarity between two sets by comparing the intersection and union of the sets.</li>
<li class=""><strong>Levenshtein Distance</strong>: Calculates the minimum number of single-character edits required to change one word into the other.</li>
<li class=""><strong>Jaro Similarity</strong>: Measures the similarity between two strings by considering the number of matching characters and transpositions.</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="python-function">Python Function<a href="https://boardflare.com/posts/2024/fuzzy-matching-python-excel/#python-function" class="hash-link" aria-label="Direct link to Python Function" title="Direct link to Python Function" translate="no">​</a></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="language-python codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-python codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">import</span><span class="token plain"> nltk</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">import</span><span class="token plain"> pandas </span><span class="token keyword" style="color:#00009f">as</span><span class="token plain"> pd</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">from</span><span class="token plain"> nltk</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">metrics</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">distance </span><span class="token keyword" style="color:#00009f">import</span><span class="token plain"> edit_distance</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> jaccard_distance</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> jaro_similarity</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">from</span><span class="token plain"> nltk</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">util </span><span class="token keyword" style="color:#00009f">import</span><span class="token plain"> ngrams</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">def</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">nltk_distance</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">lookup_value</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> lookup_array_df</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> algorithm</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token triple-quoted-string string" style="color:#e3116c">"""</span><br></div><div class="token-line" style="color:#393A34"><span class="token triple-quoted-string string" style="color:#e3116c">    Calculate the similarity between a lookup_value and a lookup_array using various distance algorithms.</span><br></div><div class="token-line" style="color:#393A34"><span class="token triple-quoted-string string" style="display:inline-block;color:#e3116c"></span><br></div><div class="token-line" style="color:#393A34"><span class="token triple-quoted-string string" style="color:#e3116c">    Parameters:</span><br></div><div class="token-line" style="color:#393A34"><span class="token triple-quoted-string string" style="color:#e3116c">    lookup_value (str or pd.DataFrame): The string or DataFrame to search for.</span><br></div><div class="token-line" style="color:#393A34"><span class="token triple-quoted-string string" style="color:#e3116c">    lookup_array_df (pd.DataFrame): The DataFrame to search within.</span><br></div><div class="token-line" style="color:#393A34"><span class="token triple-quoted-string string" style="color:#e3116c">    algorithm (str): The algorithm to use for calculating similarity. Options are 'levenshtein', 'jaccard', and 'jaro'. Default is 'jaccard'.</span><br></div><div class="token-line" style="color:#393A34"><span class="token triple-quoted-string string" style="display:inline-block;color:#e3116c"></span><br></div><div class="token-line" style="color:#393A34"><span class="token triple-quoted-string string" style="color:#e3116c">    Returns:</span><br></div><div class="token-line" style="color:#393A34"><span class="token triple-quoted-string string" style="color:#e3116c">    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><br></div><div class="token-line" style="color:#393A34"><span class="token triple-quoted-string string" style="color:#e3116c">    """</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic"># Define a dictionary to map algorithm names to functions</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    algo_funcs </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token string" style="color:#e3116c">'levenshtein'</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">lambda</span><span class="token plain"> x</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> y</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">1</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">-</span><span class="token plain"> edit_distance</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">x</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> y</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">/</span><span class="token plain"> </span><span class="token builtin">max</span><span class="token punctuation" style="color:#393A34">(</span><span class="token builtin">len</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">x</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token builtin">len</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">y</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token string" style="color:#e3116c">'jaccard'</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">lambda</span><span class="token plain"> x</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> y</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">1</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">-</span><span class="token plain"> jaccard_distance</span><span class="token punctuation" style="color:#393A34">(</span><span class="token builtin">set</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">ngrams</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">x</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">2</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token builtin">set</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">ngrams</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">y</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">2</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token string" style="color:#e3116c">'jaro'</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> jaro_similarity</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic"># Get the algorithm function from the dictionary</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    algo_func </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> algo_funcs</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">get</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">algorithm</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">if</span><span class="token plain"> algo_func </span><span class="token keyword" style="color:#00009f">is</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">None</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">raise</span><span class="token plain"> ValueError</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string-interpolation string" style="color:#e3116c">f"Unsupported algorithm: </span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">{</span><span class="token string-interpolation interpolation">algorithm</span><span class="token string-interpolation interpolation punctuation" style="color:#393A34">}</span><span class="token string-interpolation string" style="color:#e3116c">"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic"># Flatten the DataFrame to a list</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    lookup_array </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> lookup_array_df</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">values</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">flatten</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">tolist</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic"># Check if lookup_value is a DataFrame</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">if</span><span class="token plain"> </span><span class="token builtin">isinstance</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">lookup_value</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> pd</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">DataFrame</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        lookup_value_list </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> lookup_value</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">values</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">flatten</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">tolist</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">else</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        lookup_value_list </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain">lookup_value</span><span class="token punctuation" style="color:#393A34">]</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    results </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token punctuation" style="color:#393A34">]</span><span class="token plain"> </span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">for</span><span class="token plain"> lookup_value_item </span><span class="token keyword" style="color:#00009f">in</span><span class="token plain"> lookup_value_list</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token comment" style="color:#999988;font-style:italic"># Calculate similarity scores and round to 2 decimal places</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        scores </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">index </span><span class="token operator" style="color:#393A34">+</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">1</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token builtin">round</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">algo_func</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">lookup_value_item</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> item</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">2</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">for</span><span class="token plain"> index</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> item </span><span class="token keyword" style="color:#00009f">in</span><span class="token plain"> </span><span class="token builtin">enumerate</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">lookup_array</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">]</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token comment" style="color:#999988;font-style:italic"># Sort based on scores in descending order</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        scores</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">sort</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">key</span><span class="token operator" style="color:#393A34">=</span><span class="token keyword" style="color:#00009f">lambda</span><span class="token plain"> x</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> x</span><span class="token punctuation" style="color:#393A34">[</span><span class="token number" style="color:#36acaa">1</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> reverse</span><span class="token operator" style="color:#393A34">=</span><span class="token boolean" style="color:#36acaa">True</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token comment" style="color:#999988;font-style:italic"># Append the top index and score to results as a list</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        results</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">append</span><span class="token punctuation" style="color:#393A34">(</span><span class="token builtin">list</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">scores</span><span class="token punctuation" style="color:#393A34">[</span><span class="token number" style="color:#36acaa">0</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic"># results is 2D list, e.g. [[1, 0.75], [2, 0.85]]</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> results</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">nltk_distance</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">arg1</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> arg2</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> arg3</span><span class="token punctuation" style="color:#393A34">)</span><br></div></code></pre></div></div>
<p>The <code>nltk_distance</code> function takes three arguments:</p>
<ul>
<li class=""><code>lookup_value</code>: The string or DataFrame to search for, e.g. "apple" or <code>pd.DataFrame(["apple", "banana"])</code>.</li>
<li class=""><code>lookup_array_df</code>: The DataFrame to search within, e.g. <code>pd.DataFrame(["apples", "bananas", "cherries"])</code>.</li>
<li class=""><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>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="use-in-excel">Use in Excel<a href="https://boardflare.com/posts/2024/fuzzy-matching-python-excel/#use-in-excel" class="hash-link" aria-label="Direct link to Use in Excel" title="Direct link to Use in Excel" translate="no">​</a></h2>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="excel-py">EXCEL PY()<a href="https://boardflare.com/posts/2024/fuzzy-matching-python-excel/#excel-py" class="hash-link" aria-label="Direct link to EXCEL PY()" title="Direct link to EXCEL PY()" translate="no">​</a></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="language-python codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-python codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token operator" style="color:#393A34">=</span><span class="token plain">PY</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">arg1 </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> xl</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"A6:A10"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic"># lookup_value</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">arg2 </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> xl</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"B6:B27"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic"># lookup_array_df</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">arg3 </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> xl</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"C6"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic"># algorithm</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">def</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">nltk_distance</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">lookup_value</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> lookup_array_df</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> algorithm</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic"># ... function code omitted for brevity ...</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> results</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">nltk_distance</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">arg1</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> arg2</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> arg3</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">)</span><br></div></code></pre></div></div>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="boardflarerunpy">BOARDFLARE.RUNPY()<a href="https://boardflare.com/posts/2024/fuzzy-matching-python-excel/#boardflarerunpy" class="hash-link" aria-label="Direct link to BOARDFLARE.RUNPY()" title="Direct link to BOARDFLARE.RUNPY()" translate="no">​</a></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>
<div class="language-excel codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-excel codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">=BOARDFLARE.RUNPY(A1, A6:A10, B6:B27, C6)</span><br></div></code></pre></div></div>
<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>
<div class="language-excel codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-excel codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">=BOARDFLARE.RUNPY("text/fuzzy-match/nltk_distance.ipynb", A6:A10, B6:B27, C6)</span><br></div></code></pre></div></div>
<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>
<div class="language-excel codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-excel codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">=LAMBDA(lookup_value, lookup_array, [similarity_threshold], [algorithm],</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    LET(</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        threshold, IF(ISOMITTED(similarity_threshold), 0.7, similarity_threshold),</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        algo, IF(ISOMITTED(algorithm), "jaccard", algorithm),</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        result, BOARDFLARE.RUNPY("text/fuzzy-match/nltk_distance.ipynb", lookup_value, lookup_array, algo),</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        index, INDEX(result, 1),</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        score, INDEX(result, 2),</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        IF(score &gt;= threshold, index, "No match")</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    )</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">)</span><br></div></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="conclusion">Conclusion<a href="https://boardflare.com/posts/2024/fuzzy-matching-python-excel/#conclusion" class="hash-link" aria-label="Direct link to Conclusion" title="Direct link to Conclusion" translate="no">​</a></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>]]></content:encoded>
            <category>Excel</category>
            <category>Python</category>
        </item>
        <item>
            <title><![CDATA[Azure Sentiment Analysis in Excel]]></title>
            <link>https://boardflare.com/posts/2024/azure-sentiment-analysis/</link>
            <guid>https://boardflare.com/posts/2024/azure-sentiment-analysis/</guid>
            <pubDate>Fri, 01 Nov 2024 00:00:00 GMT</pubDate>
            <description><![CDATA[Integrate Azure AI Language service with Excel to perform advanced aspect-based sentiment analysis on customer reviews and text data.]]></description>
            <content:encoded><![CDATA[<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>
<!-- -->
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="background">Background<a href="https://boardflare.com/posts/2024/azure-sentiment-analysis/#background" class="hash-link" aria-label="Direct link to Background" title="Direct link to Background" translate="no">​</a></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" target="_blank" rel="noopener noreferrer" class="">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" target="_blank" rel="noopener noreferrer" class="">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><thead><tr><th>Review</th><th>"Food" Aspect</th><th>"Service" Aspect</th></tr></thead><tbody><tr><td>"The pizza was amazing but our waitress seemed uninterested"</td><td>pizza</td><td>waitress</td></tr><tr><td>"Delicious pasta, though service was slow tonight"</td><td>pasta</td><td>service</td></tr><tr><td>"The cuisine is outstanding but the staff was rude"</td><td>cuisine</td><td>staff</td></tr><tr><td>"Bland menu items and the waiter forgot our order"</td><td>menu items</td><td>waiter</td></tr><tr><td>"Great appetizers but long wait times for seating"</td><td>appetizers</td><td>wait times</td></tr><tr><td>"Fresh ingredients, friendly servers made our night"</td><td>ingredients</td><td>servers</td></tr><tr><td>"Tasty dishes but poor customer service experience"</td><td>dishes</td><td>customer service</td></tr><tr><td>"Mediocre food quality and inattentive waitstaff"</td><td>food quality</td><td>waitstaff</td></tr><tr><td>"Excellent menu selection, prompt table service"</td><td>menu selection</td><td>table service</td></tr><tr><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" target="_blank" rel="noopener noreferrer" class="">semantic similarity</a>, typically into clusters of related words.  This is beyond the scope of this article.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="python-function">Python Function<a href="https://boardflare.com/posts/2024/azure-sentiment-analysis/#python-function" class="hash-link" aria-label="Direct link to Python Function" title="Direct link to Python Function" translate="no">​</a></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="language-python codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-python codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">from</span><span class="token plain"> azure</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">ai</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">textanalytics </span><span class="token keyword" style="color:#00009f">import</span><span class="token plain"> TextAnalyticsClient</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">from</span><span class="token plain"> azure</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">core</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">credentials </span><span class="token keyword" style="color:#00009f">import</span><span class="token plain"> AzureKeyCredential</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">def</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">azure_sentiment</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">documents</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> language_key</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> language_endpoint</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic"># Check if documents is a string, list, or DataFrame</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">if</span><span class="token plain"> </span><span class="token builtin">isinstance</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">documents</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token builtin">str</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        documents </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain">documents</span><span class="token punctuation" style="color:#393A34">]</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">elif</span><span class="token plain"> </span><span class="token builtin">isinstance</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">documents</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> pd</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">DataFrame</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        documents </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> documents</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">values</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">flatten</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">tolist</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain">  </span><span class="token comment" style="color:#999988;font-style:italic"># Convert df to list</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic"># Authenticate the client using your key and endpoint </span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    ta_credential </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> AzureKeyCredential</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">language_key</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    client </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> TextAnalyticsClient</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            endpoint</span><span class="token operator" style="color:#393A34">=</span><span class="token plain">language_endpoint</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            credential</span><span class="token operator" style="color:#393A34">=</span><span class="token plain">ta_credential</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    result </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> client</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">analyze_sentiment</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">documents</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> show_opinion_mining</span><span class="token operator" style="color:#393A34">=</span><span class="token boolean" style="color:#36acaa">True</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    doc_result </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain">doc </span><span class="token keyword" style="color:#00009f">for</span><span class="token plain"> doc </span><span class="token keyword" style="color:#00009f">in</span><span class="token plain"> result </span><span class="token keyword" style="color:#00009f">if</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">not</span><span class="token plain"> doc</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">is_error</span><span class="token punctuation" style="color:#393A34">]</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    data </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token punctuation" style="color:#393A34">]</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">for</span><span class="token plain"> idx</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> document </span><span class="token keyword" style="color:#00009f">in</span><span class="token plain"> </span><span class="token builtin">enumerate</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">doc_result</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">for</span><span class="token plain"> sentence </span><span class="token keyword" style="color:#00009f">in</span><span class="token plain"> document</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">sentences</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token keyword" style="color:#00009f">for</span><span class="token plain"> mined_opinion </span><span class="token keyword" style="color:#00009f">in</span><span class="token plain"> sentence</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">mined_opinions</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">                target </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> mined_opinion</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">target</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">                </span><span class="token keyword" style="color:#00009f">for</span><span class="token plain"> assessment </span><span class="token keyword" style="color:#00009f">in</span><span class="token plain"> mined_opinion</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">assessments</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">                    data</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">append</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">                        idx </span><span class="token operator" style="color:#393A34">+</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">1</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain">  </span><span class="token comment" style="color:#999988;font-style:italic"># 1-based index</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">                        document</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">sentiment</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">                        document</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">confidence_scores</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">positive</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">                        document</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">confidence_scores</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">neutral</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">                        document</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">confidence_scores</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">negative</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">                        sentence</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">text</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">                        sentence</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">sentiment</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">                        sentence</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">confidence_scores</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">positive</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">                        sentence</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">confidence_scores</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">neutral</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">                        sentence</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">confidence_scores</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">negative</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">                        target</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">text</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">                        target</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">sentiment</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">                        target</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">confidence_scores</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">positive</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">                        target</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">confidence_scores</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">negative</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">                        assessment</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">text</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">                        assessment</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">sentiment</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">                        assessment</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">confidence_scores</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">positive</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">                        assessment</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">confidence_scores</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">negative</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">                    </span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> data</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">azure_sentiment</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">arg1</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> arg2</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> arg3</span><span class="token punctuation" style="color:#393A34">)</span><br></div></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="output">Output<a href="https://boardflare.com/posts/2024/azure-sentiment-analysis/#output" class="hash-link" aria-label="Direct link to Output" title="Direct link to Output" translate="no">​</a></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>
<!-- -->
<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>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="excel-integration">Excel Integration<a href="https://boardflare.com/posts/2024/azure-sentiment-analysis/#excel-integration" class="hash-link" aria-label="Direct link to Excel Integration" title="Direct link to Excel Integration" translate="no">​</a></h2>
<p>To run this function from Excel we need to use the <code>BOARDFLARE.RUNPY</code> function which is available in the <a class="" href="https://boardflare.com/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>
<div class="language-excel codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-excel codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">=BOARDFLARE.RUNPY("text/sentiment-analysis/azure_sentiment.ipynb", A1:A10, "your-azure-key", "your-azure-endpoint")</span><br></div></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="results">Results<a href="https://boardflare.com/posts/2024/azure-sentiment-analysis/#results" class="hash-link" aria-label="Direct link to Results" title="Direct link to Results" translate="no">​</a></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><thead><tr><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><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><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><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><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><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><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><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><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><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><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><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><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><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><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><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><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><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><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><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><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>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="conclusion">Conclusion<a href="https://boardflare.com/posts/2024/azure-sentiment-analysis/#conclusion" class="hash-link" aria-label="Direct link to Conclusion" title="Direct link to Conclusion" translate="no">​</a></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>]]></content:encoded>
            <category>Excel</category>
            <category>AI</category>
            <category>Azure</category>
        </item>
        <item>
            <title><![CDATA[Python in Excel Functions]]></title>
            <link>https://boardflare.com/posts/2024/align-with-python-excel/</link>
            <guid>https://boardflare.com/posts/2024/align-with-python-excel/</guid>
            <pubDate>Tue, 22 Oct 2024 00:00:00 GMT</pubDate>
            <description><![CDATA[Learn about the new BOARDFLARE.RUNPY function and how we've aligned our API with Microsoft's Python in Excel for better code compatibility.]]></description>
            <content:encoded><![CDATA[<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" target="_blank" rel="noopener noreferrer" class="">Python in Excel</a> so that the same code could be used in both with minimal modification.</p>
<!-- -->
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="-boardflarerunpy-function">🆕 BOARDFLARE.RUNPY function<a href="https://boardflare.com/posts/2024/align-with-python-excel/#-boardflarerunpy-function" class="hash-link" aria-label="Direct link to 🆕 BOARDFLARE.RUNPY function" title="Direct link to 🆕 BOARDFLARE.RUNPY function" translate="no">​</a></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>
<div class="language-python codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-python codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token comment" style="color:#999988;font-style:italic"># Using BOARDFLARE.RUNPY</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">def</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">add</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">a</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> b</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> a </span><span class="token operator" style="color:#393A34">+</span><span class="token plain"> b</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line theme-code-block-highlighted-line" style="color:#393A34"><span class="token plain">add</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">arg1</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain">arg2</span><span class="token punctuation" style="color:#393A34">)</span><br></div></code></pre></div></div>
<p>Assuming the code above is in cell <code>C2</code>, the arguments <code>arg1</code> and <code>arg2</code> are passed to the <code>BOARDFLARE.RUNPY</code> function as follows:</p>
<div class="language-excel codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-excel codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">=BOARDFLARE.RUNPY(C2, A2, B2)</span><br></div></code></pre></div></div>
<p>With Python in Excel, the same code would be written as follows:</p>
<div class="language-python codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-python codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token comment" style="color:#999988;font-style:italic"># Using Excel's PY</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">def</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">add</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">a</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> b</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> a </span><span class="token operator" style="color:#393A34">+</span><span class="token plain"> b</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line theme-code-block-highlighted-line" style="color:#393A34"><span class="token plain">add</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">xl</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"A2"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain">xl</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"B2"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><br></div></code></pre></div></div>
<p>Here the <code>xl</code> function is used to reference the Excel cells <code>A2</code> and <code>B2</code> 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 <code>BOARDFLARE.RUNPY</code> can.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="functions-collection">Functions collection<a href="https://boardflare.com/posts/2024/align-with-python-excel/#functions-collection" class="hash-link" aria-label="Direct link to Functions collection" title="Direct link to Functions collection" translate="no">​</a></h2>
<p>We're just getting started on building out a collection of ready-to-use Python <a href="https://tools.boardflare.com/" target="_blank" rel="noopener noreferrer" class="">functions</a> that can also be used as a starting point for building more complex functions.</p>
<p>For example, we've built a <a href="https://tools.boardflare.com/" target="_blank" rel="noopener noreferrer" class="">text_distance</a> function for fuzzy matching that is similar to that used in our <a class="" href="https://boardflare.com/apps/excel/fuzzy-match/">Fuzzy Match</a> app, but supports many more algorithms and can be readily modified to your specific needs.  Here's the code:</p>
<div class="language-python codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-python codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">import</span><span class="token plain"> textdistance</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">import</span><span class="token plain"> pandas </span><span class="token keyword" style="color:#00009f">as</span><span class="token plain"> pd</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">def</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">text_distance</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">needle</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> haystack_df</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> algorithm</span><span class="token operator" style="color:#393A34">=</span><span class="token string" style="color:#e3116c">'jaccard'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic"># Get the algorithm function from textdistance</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    algo_func </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token builtin">getattr</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">textdistance</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> algorithm</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic"># Flatten the DataFrame to a list</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    haystack </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> haystack_df</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">values</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">flatten</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">tolist</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic"># Check if needle is a DataFrame</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">if</span><span class="token plain"> </span><span class="token builtin">isinstance</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">needle</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> pd</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">DataFrame</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        needle_list </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> needle</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">values</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">flatten</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">tolist</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">else</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        needle_list </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain">needle</span><span class="token punctuation" style="color:#393A34">]</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    results </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token punctuation" style="color:#393A34">]</span><span class="token plain"> </span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">for</span><span class="token plain"> needle_item </span><span class="token keyword" style="color:#00009f">in</span><span class="token plain"> needle_list</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token comment" style="color:#999988;font-style:italic"># Calculate similarity scores with normalization and round to 2 decimal places</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token comment" style="color:#999988;font-style:italic"># Adjust index to be 1-based</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        scores </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">index </span><span class="token operator" style="color:#393A34">+</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">1</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token builtin">round</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">algo_func</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">normalized_similarity</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">needle_item</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> item</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">2</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">for</span><span class="token plain"> index</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> item </span><span class="token keyword" style="color:#00009f">in</span><span class="token plain"> </span><span class="token builtin">enumerate</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">haystack</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">]</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token comment" style="color:#999988;font-style:italic"># Sort based on scores in descending order</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        scores</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">sort</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">key</span><span class="token operator" style="color:#393A34">=</span><span class="token keyword" style="color:#00009f">lambda</span><span class="token plain"> x</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> x</span><span class="token punctuation" style="color:#393A34">[</span><span class="token number" style="color:#36acaa">1</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> reverse</span><span class="token operator" style="color:#393A34">=</span><span class="token boolean" style="color:#36acaa">True</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token comment" style="color:#999988;font-style:italic"># Append the top index and score to results as a list</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        results</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">append</span><span class="token punctuation" style="color:#393A34">(</span><span class="token builtin">list</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">scores</span><span class="token punctuation" style="color:#393A34">[</span><span class="token number" style="color:#36acaa">0</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic"># results is 2D list, e.g. [[1, 0.75], [2, 0.85]]</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> results</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">text_distance</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">arg1</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> arg2</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> arg3</span><span class="token punctuation" style="color:#393A34">)</span><br></div></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="lambda-functions-using-python">LAMBDA functions using Python<a href="https://boardflare.com/posts/2024/align-with-python-excel/#lambda-functions-using-python" class="hash-link" aria-label="Direct link to LAMBDA functions using Python" title="Direct link to LAMBDA functions using Python" translate="no">​</a></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>
<div class="language-excel codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-excel codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">=LAMBDA(lookup_value, lookup_array, [similarity_threshold], [algorithm],</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    LET(</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        threshold, IF(ISOMITTED(similarity_threshold), 0.7, similarity_threshold),</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        algo, IF(ISOMITTED(algorithm), "jaccard", algorithm),</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        result, BOARDFLARE.RUNPY("text/fuzzy/text_distance.ipynb", lookup_value, lookup_array, algo),</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        index, INDEX(result, 1),</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        score, INDEX(result, 2),</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        IF(score &gt;= threshold, index, "No match")</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    )</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">)</span><br></div></code></pre></div></div>]]></content:encoded>
            <category>Excel</category>
            <category>Python</category>
        </item>
        <item>
            <title><![CDATA[Python in Excel Review]]></title>
            <link>https://boardflare.com/posts/2024/python-in-excel/</link>
            <guid>https://boardflare.com/posts/2024/python-in-excel/</guid>
            <pubDate>Mon, 16 Sep 2024 00:00:00 GMT</pubDate>
            <description><![CDATA[An in-depth review of Microsoft's native Python in Excel feature, exploring its strengths, weaknesses, and available alternatives like Boardflare.]]></description>
            <content:encoded><![CDATA[<p>Microsoft's <a href="https://techcommunity.microsoft.com/t5/excel-blog/python-in-excel-available-now/ba-p/4240212" target="_blank" rel="noopener noreferrer" class="">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" target="_blank" rel="noopener noreferrer" class="">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" target="_blank" rel="noopener noreferrer" class="">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>
<!-- -->
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="strengths">Strengths<a href="https://boardflare.com/posts/2024/python-in-excel/#strengths" class="hash-link" aria-label="Direct link to Strengths" title="Direct link to Strengths" translate="no">​</a></h2>
<ul>
<li class="">
<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. <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 class="">
<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 class="">
<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 class="">
<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>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="potential-weaknesses">Potential Weaknesses<a href="https://boardflare.com/posts/2024/python-in-excel/#potential-weaknesses" class="hash-link" aria-label="Direct link to Potential Weaknesses" title="Direct link to Potential Weaknesses" translate="no">​</a></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 class="">
<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 class="">
<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 class="">
<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. <code>=LAMBDA(x, PY(x + 2))</code>, this does not work.</p>
</li>
<li class="">
<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 class="">
<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 class="">
<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" target="_blank" rel="noopener noreferrer" class="">post by xlwings</a> on these and some other potential weaknesses.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="alternatives">Alternatives<a href="https://boardflare.com/posts/2024/python-in-excel/#alternatives" class="hash-link" aria-label="Direct link to Alternatives" title="Direct link to Alternatives" translate="no">​</a></h2>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="pyxll">PyXLL<a href="https://boardflare.com/posts/2024/python-in-excel/#pyxll" class="hash-link" aria-label="Direct link to PyXLL" title="Direct link to PyXLL" translate="no">​</a></h3>
<p><a href="https://www.pyxll.com/index.html" target="_blank" rel="noopener noreferrer" class="">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>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="xlwings">xlwings<a href="https://boardflare.com/posts/2024/python-in-excel/#xlwings" class="hash-link" aria-label="Direct link to xlwings" title="Direct link to xlwings" translate="no">​</a></h3>
<p><a href="https://www.xlwings.org/" target="_blank" rel="noopener noreferrer" class="">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/" target="_blank" rel="noopener noreferrer" class="">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/" target="_blank" rel="noopener noreferrer" class="">Streamlit</a> or <a href="https://www.gradio.app/" target="_blank" rel="noopener noreferrer" class="">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>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="anaconda-code">Anaconda Code<a href="https://boardflare.com/posts/2024/python-in-excel/#anaconda-code" class="hash-link" aria-label="Direct link to Anaconda Code" title="Direct link to Anaconda Code" translate="no">​</a></h3>
<p><a href="https://www.anaconda.com/" target="_blank" rel="noopener noreferrer" class="">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" target="_blank" rel="noopener noreferrer" class="">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" target="_blank" rel="noopener noreferrer" class="">Anaconda Code</a> was added to the toolbox, which enabled users to run Python code locally in Excel using <a href="https://pyscript.net/" target="_blank" rel="noopener noreferrer" class="">PyScript</a>, which in turn uses <a href="https://pyodide.org/en/stable/" target="_blank" rel="noopener noreferrer" class="">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>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="python-for-excel">Python for Excel<a href="https://boardflare.com/posts/2024/python-in-excel/#python-for-excel" class="hash-link" aria-label="Direct link to Python for Excel" title="Direct link to Python for Excel" translate="no">​</a></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/" target="_blank" rel="noopener noreferrer" class="">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>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="conclusion">Conclusion<a href="https://boardflare.com/posts/2024/python-in-excel/#conclusion" class="hash-link" aria-label="Direct link to Conclusion" title="Direct link to Conclusion" translate="no">​</a></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>]]></content:encoded>
            <category>Excel</category>
            <category>Python</category>
        </item>
        <item>
            <title><![CDATA[Excel TRANSLATE Function]]></title>
            <link>https://boardflare.com/posts/2024/translate-excel/</link>
            <guid>https://boardflare.com/posts/2024/translate-excel/</guid>
            <pubDate>Thu, 27 Jun 2024 00:00:00 GMT</pubDate>
            <description><![CDATA[Overview of the new native TRANSLATE and DETECTLANGUAGE functions in Excel and how they compare to alternative solutions.]]></description>
            <content:encoded><![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" target="_blank" rel="noopener noreferrer" class="">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" target="_blank" rel="noopener noreferrer" class="">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>
<!-- -->
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="functions">Functions<a href="https://boardflare.com/posts/2024/translate-excel/#functions" class="hash-link" aria-label="Direct link to Functions" title="Direct link to Functions" translate="no">​</a></h2>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="translate">TRANSLATE<a href="https://boardflare.com/posts/2024/translate-excel/#translate" class="hash-link" aria-label="Direct link to TRANSLATE" title="Direct link to TRANSLATE" translate="no">​</a></h3>
<p>The <a href="https://support.microsoft.com/en-us/office/translate-function-d34f71c7-2ffe-409a-9a63-5eb5e91aa3dd" target="_blank" rel="noopener noreferrer" class="">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 class=""><strong>text</strong>: The text to translate, either in quotation marks or as a cell reference.</li>
<li class=""><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 class=""><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" target="_blank" rel="noopener noreferrer" class="">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>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="detectlanguage">DETECTLANGUAGE<a href="https://boardflare.com/posts/2024/translate-excel/#detectlanguage" class="hash-link" aria-label="Direct link to DETECTLANGUAGE" title="Direct link to DETECTLANGUAGE" translate="no">​</a></h3>
<p>The <a href="https://support.microsoft.com/en-us/office/detectlanguage-function-0748e285-1912-4d24-b735-57d18142fa3b" target="_blank" rel="noopener noreferrer" class="">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 class=""><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" target="_blank" rel="noopener noreferrer" class="">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>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="alternatives">Alternatives<a href="https://boardflare.com/posts/2024/translate-excel/#alternatives" class="hash-link" aria-label="Direct link to Alternatives" title="Direct link to Alternatives" translate="no">​</a></h2>
<p>The TRANSLATE function is similar to the <a class="" href="https://boardflare.com/posts/2024/googletranslate-excel/">GOOGLETRANSLATE function</a> in Google Sheets and the <a class="" href="https://boardflare.com/apps/excel/translate/">Translate for Excel</a> function provided by BoardFlare.</p>
<p>The main advantages of Boardflare's <a class="" href="https://boardflare.com/apps/excel/translate/">Translate for Excel</a> are as follows:</p>
<ul>
<li class="">no throttling or quotas on usage.</li>
<li class="">your data stays in Excel and is not shared.</li>
</ul>]]></content:encoded>
            <category>Excel</category>
            <category>AI</category>
        </item>
        <item>
            <title><![CDATA[GOOGLETRANSLATE for Excel]]></title>
            <link>https://boardflare.com/posts/2024/googletranslate-excel/</link>
            <guid>https://boardflare.com/posts/2024/googletranslate-excel/</guid>
            <pubDate>Wed, 29 May 2024 00:00:00 GMT</pubDate>
            <description><![CDATA[Bring Google Sheets' translation capabilities to Excel with our local machine learning implementation that ensures data privacy.]]></description>
            <content:encoded><![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>
<!-- -->
<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" target="_blank" rel="noopener noreferrer" class="">TRANSLATE function</a> for Excel.  See <a class="" href="https://boardflare.com/posts/2024/translate-excel/">this post</a>.</p>
</blockquote>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="googletranslate">GOOGLETRANSLATE<a href="https://boardflare.com/posts/2024/googletranslate-excel/#googletranslate" class="hash-link" aria-label="Direct link to GOOGLETRANSLATE" title="Direct link to GOOGLETRANSLATE" translate="no">​</a></h2>
<p><a href="https://support.google.com/docs/answer/3093331?hl=en" target="_blank" rel="noopener noreferrer" class="">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>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="translate-for-excel">Translate for Excel<a href="https://boardflare.com/posts/2024/googletranslate-excel/#translate-for-excel" class="hash-link" aria-label="Direct link to Translate for Excel" title="Direct link to Translate for Excel" translate="no">​</a></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>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="key-features">Key Features<a href="https://boardflare.com/posts/2024/googletranslate-excel/#key-features" class="hash-link" aria-label="Direct link to Key Features" title="Direct link to Key Features" translate="no">​</a></h2>
<p>Translate for Excel offers several key features:</p>
<ul>
<li class=""><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 class=""><strong>Unlimited free use</strong>: There are no usage limits or fees.</li>
<li class=""><strong>Local operation</strong>: The function runs on your computer, so your data remains secure.</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="how-to-use-translate-for-excel">How to Use Translate for Excel<a href="https://boardflare.com/posts/2024/googletranslate-excel/#how-to-use-translate-for-excel" class="hash-link" aria-label="Direct link to How to Use Translate for Excel" title="Direct link to How to Use Translate for Excel" translate="no">​</a></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>
<div class="language-excel codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-excel codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">=BOARDFLARE.TRANSLATE(text, source_language, target_language)</span><br></div></code></pre></div></div>
<p>For example, to translate a cell A1 from Spanish to English, you would use:</p>
<div class="language-excel codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-excel codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">=BOARDFLARE.TRANSLATE(A1, "es", "en"    )</span><br></div></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="installation">Installation<a href="https://boardflare.com/posts/2024/googletranslate-excel/#installation" class="hash-link" aria-label="Direct link to Installation" title="Direct link to Installation" translate="no">​</a></h2>
<p>You can install Translate for Excel from the Microsoft AppSource store or directly from Excel.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="conclusion">Conclusion<a href="https://boardflare.com/posts/2024/googletranslate-excel/#conclusion" class="hash-link" aria-label="Direct link to Conclusion" title="Direct link to Conclusion" translate="no">​</a></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>]]></content:encoded>
            <category>Excel</category>
            <category>Google Sheets</category>
        </item>
        <item>
            <title><![CDATA[Creating a Web Worker with Google Apps Script]]></title>
            <link>https://boardflare.com/posts/2024/apps-script-web-workers/</link>
            <guid>https://boardflare.com/posts/2024/apps-script-web-workers/</guid>
            <pubDate>Thu, 18 Apr 2024 00:00:00 GMT</pubDate>
            <description><![CDATA[A guide on implementing background processing in Google Apps Script using the inline web worker pattern to keep your extension's UI responsive.]]></description>
            <content:encoded><![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>
<!-- -->
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="background">Background<a href="https://boardflare.com/posts/2024/apps-script-web-workers/#background" class="hash-link" aria-label="Direct link to Background" title="Direct link to Background" translate="no">​</a></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" target="_blank" rel="noopener noreferrer" class="">web worker</a> so the UI can remain responsive (e.g. to report on progress, cancel the operation, etc.) and also to enable multi-threaded processing.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="problem">Problem<a href="https://boardflare.com/posts/2024/apps-script-web-workers/#problem" class="hash-link" aria-label="Direct link to Problem" title="Direct link to Problem" translate="no">​</a></h2>
<p>Google Apps Script doesn't support serving a worker script directly from a file.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="solution">Solution<a href="https://boardflare.com/posts/2024/apps-script-web-workers/#solution" class="hash-link" aria-label="Direct link to Solution" title="Direct link to Solution" translate="no">​</a></h2>
<p>We'll use the <a href="https://web.dev/articles/workers-basics#inline_workers" target="_blank" rel="noopener noreferrer" class="">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. <code>worker.html</code>, with no html tags as shown below.</p>
<div class="language-html codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-html codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">self.onmessage = function(e) {</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  console.log('Message received from main script');</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  var workerResult = 'Result: ' + (e.data[0] * e.data[1]);</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  console.log('Posting message back to main script');</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  self.postMessage(workerResult);</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">}</span><br></div></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" target="_blank" rel="noopener noreferrer" class="">module worker</a>, which we need for the ESM-only library we are using in the worker.</p>
<div class="language-html codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-html codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token doctype punctuation" style="color:#393A34;font-style:italic">&lt;!</span><span class="token doctype doctype-tag" style="color:#999988;font-style:italic">DOCTYPE</span><span class="token doctype" style="color:#999988;font-style:italic"> </span><span class="token doctype name" style="color:#999988;font-style:italic">html</span><span class="token doctype punctuation" style="color:#393A34;font-style:italic">&gt;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token tag punctuation" style="color:#393A34">&lt;</span><span class="token tag" style="color:#00009f">html</span><span class="token tag punctuation" style="color:#393A34">&gt;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token tag punctuation" style="color:#393A34">&lt;</span><span class="token tag" style="color:#00009f">head</span><span class="token tag punctuation" style="color:#393A34">&gt;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token tag punctuation" style="color:#393A34">&lt;</span><span class="token tag" style="color:#00009f">base</span><span class="token tag" style="color:#00009f"> </span><span class="token tag attr-name" style="color:#00a4db">target</span><span class="token tag attr-value punctuation attr-equals" style="color:#393A34">=</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag attr-value" style="color:#e3116c">_top</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag punctuation" style="color:#393A34">&gt;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token tag punctuation" style="color:#393A34">&lt;/</span><span class="token tag" style="color:#00009f">head</span><span class="token tag punctuation" style="color:#393A34">&gt;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token tag punctuation" style="color:#393A34">&lt;</span><span class="token tag" style="color:#00009f">body</span><span class="token tag punctuation" style="color:#393A34">&gt;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token tag punctuation" style="color:#393A34">&lt;</span><span class="token tag" style="color:#00009f">script</span><span class="token tag" style="color:#00009f"> </span><span class="token tag attr-name" style="color:#00a4db">type</span><span class="token tag attr-value punctuation attr-equals" style="color:#393A34">=</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag attr-value" style="color:#e3116c">module</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag punctuation" style="color:#393A34">&gt;</span><span class="token script language-javascript"></span><br></div><div class="token-line" style="color:#393A34"><span class="token script language-javascript">    </span><span class="token script language-javascript keyword" style="color:#00009f">var</span><span class="token script language-javascript"> workerScript </span><span class="token script language-javascript operator" style="color:#393A34">=</span><span class="token script language-javascript"> </span><span class="token script language-javascript template-string template-punctuation string" style="color:#e3116c">`</span><span class="token script language-javascript template-string string" style="color:#e3116c">&lt;?!= HtmlService.createTemplateFromFile('worker').evaluate().getContent() ?&gt;</span><span class="token script language-javascript template-string template-punctuation string" style="color:#e3116c">`</span><span class="token script language-javascript"></span><br></div><div class="token-line" style="color:#393A34"><span class="token script language-javascript">    </span><span class="token script language-javascript keyword" style="color:#00009f">var</span><span class="token script language-javascript"> blob </span><span class="token script language-javascript operator" style="color:#393A34">=</span><span class="token script language-javascript"> </span><span class="token script language-javascript keyword" style="color:#00009f">new</span><span class="token script language-javascript"> </span><span class="token script language-javascript class-name">Blob</span><span class="token script language-javascript punctuation" style="color:#393A34">(</span><span class="token script language-javascript punctuation" style="color:#393A34">[</span><span class="token script language-javascript">workerScript</span><span class="token script language-javascript punctuation" style="color:#393A34">]</span><span class="token script language-javascript punctuation" style="color:#393A34">,</span><span class="token script language-javascript"> </span><span class="token script language-javascript punctuation" style="color:#393A34">{</span><span class="token script language-javascript literal-property property" style="color:#36acaa">type</span><span class="token script language-javascript operator" style="color:#393A34">:</span><span class="token script language-javascript"> </span><span class="token script language-javascript string" style="color:#e3116c">'application/javascript'</span><span class="token script language-javascript punctuation" style="color:#393A34">}</span><span class="token script language-javascript punctuation" style="color:#393A34">)</span><span class="token script language-javascript punctuation" style="color:#393A34">;</span><span class="token script language-javascript"></span><br></div><div class="token-line" style="color:#393A34"><span class="token script language-javascript">    </span><span class="token script language-javascript keyword" style="color:#00009f">var</span><span class="token script language-javascript"> workerUrl </span><span class="token script language-javascript operator" style="color:#393A34">=</span><span class="token script language-javascript"> </span><span class="token script language-javascript constant" style="color:#36acaa">URL</span><span class="token script language-javascript punctuation" style="color:#393A34">.</span><span class="token script language-javascript method function property-access" style="color:#d73a49">createObjectURL</span><span class="token script language-javascript punctuation" style="color:#393A34">(</span><span class="token script language-javascript">blob</span><span class="token script language-javascript punctuation" style="color:#393A34">)</span><span class="token script language-javascript punctuation" style="color:#393A34">;</span><span class="token script language-javascript"></span><br></div><div class="token-line" style="color:#393A34"><span class="token script language-javascript">    </span><span class="token script language-javascript keyword" style="color:#00009f">var</span><span class="token script language-javascript"> worker </span><span class="token script language-javascript operator" style="color:#393A34">=</span><span class="token script language-javascript"> </span><span class="token script language-javascript keyword" style="color:#00009f">new</span><span class="token script language-javascript"> </span><span class="token script language-javascript class-name">Worker</span><span class="token script language-javascript punctuation" style="color:#393A34">(</span><span class="token script language-javascript">workerUrl</span><span class="token script language-javascript punctuation" style="color:#393A34">,</span><span class="token script language-javascript"> </span><span class="token script language-javascript punctuation" style="color:#393A34">{</span><span class="token script language-javascript literal-property property" style="color:#36acaa">type</span><span class="token script language-javascript operator" style="color:#393A34">:</span><span class="token script language-javascript"> </span><span class="token script language-javascript string" style="color:#e3116c">'module'</span><span class="token script language-javascript punctuation" style="color:#393A34">}</span><span class="token script language-javascript punctuation" style="color:#393A34">)</span><span class="token script language-javascript punctuation" style="color:#393A34">;</span><span class="token script language-javascript"></span><br></div><div class="token-line" style="color:#393A34"><span class="token script language-javascript">    worker</span><span class="token script language-javascript punctuation" style="color:#393A34">.</span><span class="token script language-javascript method-variable function-variable method function property-access" style="color:#d73a49">onmessage</span><span class="token script language-javascript"> </span><span class="token script language-javascript operator" style="color:#393A34">=</span><span class="token script language-javascript"> </span><span class="token script language-javascript keyword" style="color:#00009f">function</span><span class="token script language-javascript punctuation" style="color:#393A34">(</span><span class="token script language-javascript parameter">e</span><span class="token script language-javascript punctuation" style="color:#393A34">)</span><span class="token script language-javascript"> </span><span class="token script language-javascript punctuation" style="color:#393A34">{</span><span class="token script language-javascript"></span><br></div><div class="token-line" style="color:#393A34"><span class="token script language-javascript">      </span><span class="token script language-javascript console class-name">console</span><span class="token script language-javascript punctuation" style="color:#393A34">.</span><span class="token script language-javascript method function property-access" style="color:#d73a49">log</span><span class="token script language-javascript punctuation" style="color:#393A34">(</span><span class="token script language-javascript">e</span><span class="token script language-javascript punctuation" style="color:#393A34">.</span><span class="token script language-javascript property-access">data</span><span class="token script language-javascript punctuation" style="color:#393A34">)</span><span class="token script language-javascript punctuation" style="color:#393A34">;</span><span class="token script language-javascript"></span><br></div><div class="token-line" style="color:#393A34"><span class="token script language-javascript">    </span><span class="token script language-javascript punctuation" style="color:#393A34">}</span><span class="token script language-javascript punctuation" style="color:#393A34">;</span><span class="token script language-javascript"></span><br></div><div class="token-line" style="color:#393A34"><span class="token script language-javascript">    worker</span><span class="token script language-javascript punctuation" style="color:#393A34">.</span><span class="token script language-javascript method function property-access" style="color:#d73a49">postMessage</span><span class="token script language-javascript punctuation" style="color:#393A34">(</span><span class="token script language-javascript string" style="color:#e3116c">'Start processing data'</span><span class="token script language-javascript punctuation" style="color:#393A34">)</span><span class="token script language-javascript punctuation" style="color:#393A34">;</span><span class="token script language-javascript"></span><br></div><div class="token-line" style="color:#393A34"><span class="token script language-javascript">    </span><span class="token tag punctuation" style="color:#393A34">&lt;/</span><span class="token tag" style="color:#00009f">script</span><span class="token tag punctuation" style="color:#393A34">&gt;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token tag punctuation" style="color:#393A34">&lt;/</span><span class="token tag" style="color:#00009f">body</span><span class="token tag punctuation" style="color:#393A34">&gt;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token tag punctuation" style="color:#393A34">&lt;/</span><span class="token tag" style="color:#00009f">html</span><span class="token tag punctuation" style="color:#393A34">&gt;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div></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>]]></content:encoded>
            <category>Google Sheets</category>
            <category>Office Add-ins</category>
        </item>
    </channel>
</rss>