Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Excel] (Custom Functions) Add new Get started article #4852

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
112 changes: 112 additions & 0 deletions docs/excel/custom-functions-get-started.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
---
description: Get started with Excel custom functions for Office Add-ins.
title: Get started with custom functions in Excel
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
title: Get started with custom functions in Excel
title: Best practices for custom functions in Excel

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you recommend changing the title throughout (the H1 in the article, the TOC name), or only here?

ms.date: 10/18/2024
ms.topic: overview
ms.custom: scenarios:getting-started
ms.localizationpriority: medium
---

# Get started with custom functions in Excel

This article includes tips, best practices, and Office Add-ins ecosystem information for new custom functions add-in developers.

The following diagram illustrates the interaction between a custom function and the two main components involved in custom function add-ins, Excel and external services.

:::image type="content" source="../images/custom-functions-add-in-components.png" alt-text="The custom functions add-in communicates with both Excel and an external service, but Excel and the external service don't communicate directly with each other.":::

**Excel** allows you to integrate your own custom functions into the application and run them like built-in functions.

The **custom functions add-in** defines the logic for your functions and how they interact with Excel and Office JavaScript APIs. To learn how to create a custom functions add-in, see the [custom functions tutorial](../tutorials/excel-tutorial-create-custom-functions.md).

An **external service** is optional. It can give your add-in capabilities like importing data from outside the workbook. The custom functions add-in specifies how external data is incorporated into the workbook. To learn more, see [Receive and handle data with custom functions](custom-functions-web-reqs.md).

To develop a custom functions add-in with high performance, it’s important to ensure that these three components operate in harmony.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know that this sentence is informative. Delete?


## Optimize custom functions recalculation efficiency

In general, custom functions recalculation follows the established pattern of [recalculation in Excel](/office/client-developer/excel/excel-recalculation). When recalculation is triggered, Excel enters a three-stage process: construct a dependency tree, construct a calculation chain, and then recalculate the cells. To optimize recalculation efficiency in your add-in, consider the level of nesting within your custom functions, the Excel calculation mode, and the limitations of volatile functions.

### Nesting in custom functions

A custom function can accept another custom function as an argument, ensuring that any dependent values are updated during recalculation. The recalculation of the outer custom function depends on the result of the nested function, leading to increased time consumption with each additional nested function. Minimize the number of nested levels in your custom functions to improve recalculation efficiency. The following code snippets demonstrate two approaches that produce similar outputs. **Option 1** is more likely to reduce the nested levels for end users when adding values in the workbook compared to **Option 2**.

#### Option 1: Less nesting

```js
/**
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How does this nest another custom function? I can call this with Add(1,2,3) (no custom functions).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@grangeryy Can you answer David's question here?

* Returns the sum of input numbers.
* @customfunction
*/
function Add(args: number[]): number {
let total = 0;
args.forEach(value => {
total += value;
});

return total;
}
```

#### Option 2: More nesting
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If this is the "bad" example, might be better to start with this, explain why it causes extra calc, and then show the better example. right now it looks like you can use either option equally well.


```js
/**
* Returns the sum of two numbers.
* @customfunction
*/
function Add(arg1: number, arg2: number): number {
return arg1 + arg2;
}
```

### Excel calculation mode

Excel has three calculation modes: Automatic, Automatic Except Tables, and Manual. For a description of these calculation modes, see [Excel Recalculation](/office/client-developer/excel/excel-recalculation). The most frequently used calculation mode for custom functions add-ins is manual calculation mode. Set the calculation mode for your add-in with the [Excel.CalculationMode enum](/javascript/api/excel/excel.calculationmode) based on your scenario. Note that automatic calculation mode may trigger recalculation often and reduce the efficiency of your add-in.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might make a clearer call to action here if the goal is to make your custom functions more efficient by reading the article. Perhaps the goal is to "Refer to the article and determine which calculation mode will work best for your custom function design..."


### Volatile function limitations

Custom functions allow you to create your own volatile functions, similar to the `NOW` and `TODAY` functions in Excel. During recalculation, Excel evaluates cells that contain volatile functions and all of their dependent cells. As a result, using many volatile functions may make recalculation slow. Volatile functions should be used sparingly to optimize your custom functions add-in. For additional information, see [Volatile and Non-Volatile Functions](/office/client-developer/excel/excel-recalculation#volatile-and-non-volatile-functions).

## Design approaches to improve efficiency

Custom functions add-ins allow for flexible designs, which means that different add-in designs can produce the same output for your end users.

### Multiple results

You can return multiple results from your custom function with multiple functions or with one function.

To return multiple results with one function, use a dynamic array. This is usually the recommended approach because dynamic arrays only require updating a single cell to trigger recalculation for all results. To learn more about dynamic arrays in custom functions, see [Return multiple results from your custom function](custom-functions-dynamic-arrays.md).

Another way to return multiple results is to use multiple functions and return a single result for each function. A benefit of using multiple functions is that your end user can decide precisely which formula they want to update and then only trigger recalculation for that formula.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might be good to show example like in the spec. Also point out the tradeoff of how one function for multiple results is less efficient across a larger dataset. Especially if relying on an external service.


### Complex data structures
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm unclear on how the subsections here related to complex data structures. They look like they apply to basic data types as well.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My thinking is that all Excel data types are a "complex data structure" from the perspective of custom functions, and the goal of this section is the communicate that data types offer a way for custom functions to handle complex data structures.


[Data types](custom-functions-data-types-concepts.md) are the best way to handle complex data structures in custom functions add-ins. Data types support [Excel errors](custom-functions-errors.md) and [formatted number values](custom-functions-data-types-concepts.md#output-a-formatted-number-value). Data types also allow for designing [entity value cards](excel-data-types-entity-card.md), extending Excel data beyond the 2-dimensional grid.

## Improve the user experience of remote data calls

Custom functions can fetch data from remote locations beyond the workbook, such as the web or a server. For more information about fetching remote data, see [Receive and handle data with custom functions](custom-functions-web-reqs.md). To maintain efficiency when making remote data calls, consider batching external calls, minimizing roundtrip duration for each call, and including messages in your add-in to communicate delays to your end user.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would be good to use the term "external service" to tie in with the graphic at the beginning and connect the dots here.


### Batch custom function remote calls

If your custom functions call a remote service, use a batching pattern to reduce the number of network calls to the remote service. To learn more, see [Batching custom function calls for a remote service](custom-functions-batching.md).

### Minimize roundtrip duration

Remote service connections can have a large impact on custom function performance. To reduce this impact, use these strategies:

- Server-heavy processing should be handled efficiently in the remote server to shorten the end-to-end latency for a custom function. For example, have parallel computing designed on the server. If your service is deployed on Azure, consider optimization using [high-performance computing on Azure](/azure/architecture/topics/high-performance-computing).
- Reduce the number of service calls by optimizing the add-in flow. For example, only send necessary calls to a remote service.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would image we could have another section about using a cache for repeat CF calls, or common calls. Check with Phoebe.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@grangeryy Can you take a look at David's suggestion here?


### Improve user-perceived performance through add-in UX

If a delay while calling a remote service is inevitable, consider providing messages through the add-in task pane to explain the delay to your end users. This information helps manage their expectations. The following image shows an example.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would mention that they will see the "busy" text in the cell while processing, so it's not like you should always think to use the task pane. But if you fell you must might be good to point out a pattern here of how it works. You need CF runtime, set the TP image on CF entry, then turn off the TP image on CF exit. Plus the task pane has to keep track if multiple CF long processes are running (which could get complicated).


:::image type="content" source="../images/custom-functions-delay-example.png" alt-text="The delay message says 'It may take some time as we are getting the data ready for you'.":::

## See also

- [Receive and handle data with custom functions](custom-functions-web-reqs.md)
- [Batching custom function calls for a remote service](custom-functions-batching.md)
- [Custom functions tutorial](../tutorials/excel-tutorial-create-custom-functions.md)
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/images/custom-functions-delay-example.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 4 additions & 1 deletion docs/toc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -566,7 +566,7 @@ items:
items:
- name: Overview
href: excel/custom-functions-overview.md
displayName: Excel, Custom Functions
displayName: Excel, Custom Functions
- name: Tutorials
items:
- name: Build your first custom functions add-in
Expand All @@ -578,6 +578,9 @@ items:
- name: Share custom function data with the task pane
href: tutorials/share-data-and-events-between-custom-functions-and-the-task-pane-tutorial.md
displayName: Excel, Custom Functions
- name: Get started
href: excel/custom-functions-get-started.md
displayName: Excel, Custom Functions
- name: Naming and localization
href: excel/custom-functions-naming.md
displayName: Excel, Custom Functions
Expand Down