This repository provides a collection of high-performance, thread-safe User Defined Functions (UDFs) for Microsoft Excel, developed using Excel-DNA. These functions are designed to enhance Excel's capabilities, offering advanced features for power users and developers.
Author: Nicolas Pepin Date: 2025-06 Version: 3.1.1 Licensing: MIT
- Overview
- Available Functions
- Integration with eSharper
- C# Version Compatibility
- Building and Deployment
- License
- Appendix A: Excel-DNA Technical Overview
The UDFs in this collection are implemented in C# and can be integrated into Excel through the Excel-DNA framework. They are particularly useful for tasks that require:
- Advanced data manipulation.
- Enhanced control over Excel's calculation settings.
- Improved worksheet function capabilities.
-
VEXCELDNA()
- Returns the current version of the UDF collection
- Usage:
=VEXCELDNA() - Returns: String with the version number
-
SETTARGETVERSION(version)
- Sets the target version for backward compatibility
- Usage:
=SETTARGETVERSION("2.0.0") - Returns: Confirmation string with the previous and current target version
-
GETTARGETVERSION()
- Gets the current target version for backward compatibility
- Usage:
=GETTARGETVERSION() - Returns: String with the current target version
-
RECALCALL()
- Triggers a full recalculation of the workbook
- Usage:
=RECALCALL() - Returns:
"TRUE"on success
-
GETITERATIONSTATUS()
- Returns Excel's iterative calculation settings
- Usage:
=GETITERATIONSTATUS() - Returns: String with status (ON/OFF), max iterations, and max change
-
SETITERATION(IterationOn, [maxIterations], [maxChange])
- Configures Excel's iterative calculation settings
- Usage:
=SETITERATION(TRUE, 100, 0.001) - Returns: Confirmation string with current settings
-
ISVISIBLE([cachingTime])
- Checks if a cell is visible (not hidden by rows/columns)
- Usage:
=ISVISIBLE(10)(10 second cache duration) - Returns:
"TRUE"if visible,"FALSE"if hidden
-
DESCRIBE(cell_reference)
- Returns a description of the cell's content type
- Usage:
=DESCRIBE(A1) - Returns: String describing the value type
-
INJECTVALUE(cell_reference, value)
- Injects a value into a cell (stateful operation)
- Usage:
=INJECTVALUE(B2, "Test Value") - Returns: The injected value
-
FINDPOS(text, substring, instance)
- Finds positions of substrings (case-insensitive)
- Usage:
=FINDPOS("Hello World", "o", 1) - Returns: Position number or error if not found
-
PUTOBJECT(name, value, [force], [debug])
- Stores an object in temporary storage
- Usage:
=PUTOBJECT("temp1", A1:A10, TRUE) - Returns: The stored object
-
GETOBJECT(name, [debug])
- Retrieves an object from temporary storage
- Usage:
=GETOBJECT("temp1") - Returns: The stored object or error
-
PURGEOBJECTS()
- Clears all objects from temporary storage
- Usage:
=PURGEOBJECTS() - Returns:
"TRUE"on success
-
TRUESPLIT(input_array, delimiter)
- Splits strings into dynamic arrays
- Usage:
=TRUESPLIT(A1:A3, ",") - Returns: 2D array of split components
-
ISMEMBEROF(array1, array2)
- Checks for common elements between arrays
- Usage:
=ISMEMBEROF(A1:A10, B1:B20) - Returns:
TRUEif any match found
-
GETTHREADS()
- Returns Excel's current thread count for calculations
- Usage:
=GETTHREADS() - Returns: Integer thread count
-
SETTHREADS(threadCount)
- Configures Excel's calculation thread count
- Usage:
=SETTHREADS(4)(Use 4 threads)
=SETTHREADS(0)(Use all processors) - Returns: Actual thread count set
-
HASHARRAY(input_array, [hashLength])
- Computes a consistent hash value for an array of values
- Usage:
=HASHARRAY(A1:A10, 8) - Returns: Hash string (default length 8, range 4–32)
-
ISLOCALIP(ipAddress_string)
- Checks if an IP address is a local IP (private or loopback)
- Usage:
=ISLOCALIP(ipAddress_string) - Returns:
TRUEif local IP,FALSEotherwise or#N/Aif invalid input
To simplify the management and usage of these UDFs within Excel 365, this project leverages the eSharper Excel add-in container.
These UDFs use features from C# 10. Attempting to use syntax from later C# versions may cause compilation errors.
Compatibility Notes:
- Excel-DNA supports .NET Framework 4.5.2+ and .NET 6+/8.
- eSharper relies on the .NET version available within Excel, potentially limiting newer features.
Requirements:
- Visual Studio 2022+
- .NET Framework 4.7.2 SDK or .NET 6.0 SDK
- Excel-DNA NuGet package
Steps:
- Clone the repository.
- Open in Visual Studio.
- Build to generate
.xll. - Load
.xllin Excel via Add-ins menu.
MIT License. See LICENSE file.
ExcelDNA is a powerful library that allows developers to create high-performance Excel add-ins using .NET languages (like C# or VB.NET). Here's a technical breakdown of how it works:
ExcelDNA bridges Excel's native C API (the Excel XLL SDK) with the .NET runtime. It does this by:
-
Compiling .NET code into an XLL: An XLL is a DLL specifically designed for Excel. ExcelDNA generates a thin native XLL stub that loads the .NET runtime and hosts your managed code.
-
Using Managed/Unmanaged Interop: The XLL acts as a bridge between Excel (unmanaged C/C++ world) and .NET (managed world) using P/Invoke and COM Interop.
-
ExcelDna.Integration.dll: Provides the core API for registering functions, handling callbacks, and marshaling data between Excel and .NET.
-
ExcelDna.Loader.dll: Manages the dynamic loading of .NET assemblies into Excel.
-
ExcelDnaPack: A tool that bundles custom .NET assemblies and dependencies into a single
.xllfile for deployment.
When Excel loads the XLL:
-
ExcelDNA scans your .NET assembly for methods marked with Excel-specific attributes (e.g.,
[ExcelFunction]). -
It generates Excel-compatible exports (via
xlAutoOpenandxlAddInManagerInfocallbacks). -
Wraps .NET methods in native XLL-compatible functions, handling type conversion between:
-
Excel
XLOPER/XLOPER12types ↔ .NET types (double, string, object[,], etc.). -
Excel arrays ↔ .NET
object[,]ordouble[,].
-
-
Arguments passed from Excel are converted into .NET types.
-
Return values from .NET are packed back into Excel-compatible structures.
-
ExcelDNA manages memory to prevent leaks (e.g., freeing temporary
XLOPERs).
-
Excel is single-threaded (STA), but ExcelDNA allows async functions via
[ExcelAsync]. -
Uses .NET Tasks to run computations in the background and return results later.
-
Implements Excel's RTD server interface for push-based real-time updates.
-
Managed .NET code can push data to Excel cells in real time.
-
If needed, ExcelDNA can expose .NET classes to Excel via COM (for UDFs or macros).
-
Supports customizing the Ribbon UI via Fluent UI XML.
-
Works with Visual Studio debugging (attach to Excel process).
-
Packaged as a single
.xllfile (no separate installer needed).
-
Minimal overhead (~native speed) due to direct XLL integration.
-
Avoids COM where possible for better performance.
-
Faster than VSTO (no COM overhead).
-
Lighter than VSTO (no need for a separate runtime).
-
More flexible than VBA (full .NET ecosystem access).
-
User enters
=MyNetFunction(A1)in Excel. -
Excel calls the XLL’s exported stub.
-
ExcelDNA marshals arguments to .NET.
-
Your
[ExcelFunction]method runs in .NET. -
Return value is marshaled back to Excel.
ExcelDNA essentially makes .NET a first-class citizen in Excel while maintaining high performance and compatibility.
ExcelDNA (for .NET) and Python integration in Excel serve different purposes and have distinct technical approaches. Here’s a detailed comparison:
| Aspect | ExcelDNA (.NET) | Python in Excel |
|---|---|---|
| Integration Level | Deep XLL integration (native Excel C API) | Officially supported by Microsoft (via PyXLL, xlwings, or built-in Python in Excel) |
| Performance | Near-native (minimal overhead) | Slower (Python interpreter + marshaling) |
| Language | C#, F#, VB.NET | Python |
| Deployment | Single .xll file |
Requires Python runtime, dependencies |
| Concurrency | Supports async via [ExcelAsync] |
Limited (Python's GIL can bottleneck multithreading) |
| Real-Time Data | RTD support (push updates) | Possible with PyXLL/xlwings, but slower |
| Debugging | Easy (attach to Excel process) | Requires IDE setup (e.g., VS Code, PyCharm) |
| Feature | ExcelDNA | Python in Excel |
|---|---|---|
| User-Defined Functions (UDFs) | Yes (high performance) | Yes (slower, but flexible) |
| Macros & Automation | Yes (via [ExcelMacro]) |
Yes (xlwings, COM) |
| Data Processing | Fast (direct .NET arrays) | Slower (Pandas/NumPy marshaling) |
| Machine Learning | ML.NET, TensorFlow.NET | Full scikit-learn/TensorFlow/PyTorch |
| Excel UI Control | Custom Ribbon, WinForms/WPF | Limited (depends on tool) |
| Cross-Platform | Windows-only | Works on Mac (xlwings) |
Pros:
-
Blazing fast (native XLL performance).
-
Direct access to Excel’s C API (low-level control).
-
Strong typing (C#/F# reduces runtime errors).
-
Easy deployment (single
.xllfile). -
Full .NET ecosystem (e.g., parallel computing, databases).
Cons:
-
Windows-only (no macOS support).
-
Requires .NET knowledge.
-
Only works with desktop version of Excel.
-
Less popular for data science than Python.
Pros:
-
Built-in Python in Excel (Microsoft 365): No add-ins needed.
-
Huge ecosystem (Pandas, NumPy, scikit-learn, etc.).
-
Better for prototyping (Jupyter-like workflows).
-
Cross-platform (xlwings works on Mac).
Cons:
-
Slower (Python interpreter + data marshaling).
-
Dependency hell (conda/pip environments).
-
Limited real-time performance (no RTD in pure Python).
-
Debugging is harder (external IDE needed).
-
Use ExcelDNA if:
-
You need maximum performance (financial models, real-time data).
-
You’re already using .NET/C#.
-
You need deep Excel integration (custom UI, RTD, async).
-
-
Use Python in Excel if:
-
You’re doing data science/ML (Pandas, scikit-learn).
-
You prefer quick prototyping (Jupyter-style).
-
You need cross-platform support (Mac + Windows).
-
-
Microsoft’s built-in Python in Excel (2023+):
-
Runs Python in the cloud (not locally).
-
Seamless grid integration (no add-ins).
-
Still early (limited libraries, no local execution).
-
-
Alternatives:
-
PyXLL: Commercial, high-performance Python XLL.
-
xlwings: Free, but COM-based (slower).
-
-
ExcelDNA = Speed + Control (best for .NET devs).
-
Python in Excel = Flexibility + Ecosystem (best for data scientists).
You do not need the eSharper add-in to use these Excel-DNA functions. They can be deployed as standard Excel add-ins using the following steps:
-
Visual Studio (recommended) or a text editor
-
.NET Framework 4.7.2 or later (for compatibility with most versions of Excel)
-
Excel (2010 or newer recommended)
Create a file named MyAddIn.dna with the following content:
<DnaLibrary Name="MyExcelFunctions" RuntimeVersion="v4.0">
<ExternalLibrary Path="MyFunctions.dll" />
</DnaLibrary>-
MyFunctions.dllis the compiled output of your.cscode (see next step). -
RuntimeVersionmust match the .NET version used for compiling the DLL.
Compile your C# file into a class library (.dll). You can do this using:
-
Visual Studio (File > New > Project > Class Library)
-
Or with the command line:
csc /target:library /out:MyFunctions.dll Custom-Excel-DNA-UDFs.csDownload the latest Excel-DNA binaries and place the following in your project folder:
-
ExcelDna.Integration.dll -
ExcelDna.Loader.dll -
ExcelDna.xll(rename this toMyAddIn.xllfor clarity)
To link everything together, you should have:
MyAddIn.dna
MyFunctions.dll
MyAddIn.xll (copied/renamed from ExcelDna.xll)Optional: Use the Excel-DNA Pack utility to bundle the .xll, .dll, and .dna into a single file:
ExcelDnaPack.exe MyAddIn.dnaThis will create MyAddIn-packed.xll.
-
Open Excel.
-
Go to
File > Options > Add-Ins. -
At the bottom, select Manage: Excel Add-ins, and click Go....
-
Click Browse, find your
.xllor*-packed.xllfile, and open it. -
The UDFs will now be available as native Excel functions.
-
Excel-DNA add-ins are fully portable and do not require administrator installation.
-
You can distribute the
.xllor.xll + .dllpair to other users. -
No COM registration is needed.
-
You can sign your
.dllfor macro security compliance.
Excel-DNA is powerful and flexible, making it ideal for deploying managed-code add-ins without the overhead and complexity of COM registration or VSTO.