diff --git a/docs/excel/excel-data-types-add-properties-to-basic-cell-values.md b/docs/excel/excel-data-types-add-properties-to-basic-cell-values.md new file mode 100644 index 000000000..86bc9dc12 --- /dev/null +++ b/docs/excel/excel-data-types-add-properties-to-basic-cell-values.md @@ -0,0 +1,218 @@ +--- +title: Add properties to basic cell values +description: Add properties to basic cell values. +ms.topic: how-to #Required; leave this attribute/value as-is +ms.date: 04/14/2025 +ms.localizationpriority: medium +--- + +# Add properties to basic cell values + +Add properties to basic cell values in Excel to associate additional information with the values. Similar to entity values, you can add properties to the **string**, **double**, and **Boolean** basic types. Each property is a key/value pair. The following example shows the number 104.67 (double) that represents a bill with added fields named **Drinks**, **Food**, **Tax**, and **Tip**. + +:::image type="content" source="../images/data-type-basic-fields.png" alt-text="Screen shot of the drinks, food, tax, and tip fields shown for the selected cell value."::: + +If the user chooses to show the data type card, they'll see the values for the fields. + +:::image type="content" source="../images/data-type-basic-data-type-card.png" alt-text="Data type card showing values for drinks, food, tax, and tip properties"::: + +Cell value properties can also be used in formulas. + +:::image type="content" source="../images/data-type-basic-dot-syntax.png" alt-text="Show user typing 'a1.' and Excel showing a menu with drinks, food, tax, and tip options."::: + +## Create a cell value with properties + +To create a cell value and add properties to it, use `valuesAsJson` to assign properties. The following code sample shows how to create a new number in cell **A1**. It adds the **Food**, **Drinks**, and additional properties describing a bill in a restaurant. It assigns a JSON description of the properties to `Range.valuesAsJson`. + +```javascript +async function createNumberProperties() { + await Excel.run(async (context) => { + const sheet = context.workbook.worksheets.getActiveWorksheet(); + const range = sheet.getRange("A1"); + range.valuesAsJson = [ + [ + { + type: Excel.CellValueType.double, + basicType: Excel.RangeValueType.double, + basicValue: 104.67, + properties: { + Food: { + type: Excel.CellValueType.string, + basicType: Excel.RangeValueType.string, + basicValue: "Sandwich and fries" + }, + Drinks: { + type: Excel.CellValueType.string, + basicType: Excel.RangeValueType.string, + basicValue: "Soda" + }, + Tax: { + type: Excel.CellValueType.double, + basicType: Excel.RangeValueType.double, + basicValue: 5.5 + }, + Tip: { + type: Excel.CellValueType.double, + basicType: Excel.RangeValueType.double, + basicValue: 21 + } + } + } + ] + ]; + await context.sync(); + }); +} +``` + +> [!NOTE] +> Some cell values change based on a user's locale. The `valuesAsJsonLocal` property offers localization support and is available on all the same objects as `valuesAsJson`. + +## Add properties to an existing value + +To add properties to an existing value, first get the value from the cell using `valuesAsJson` , then add a properties JSON object to it. The following example shows how to get the number value from cell **A1** and assign a property named **Precision** to it. Note that you should check the type of the value to ensure it is a **string**, **double**, or **Boolean** basic type. + +```javascript +async function addPropertyToNumber() { + await Excel.run(async (context) => { + let sheet = context.workbook.worksheets.getActiveWorksheet(); + let range = sheet.getRange("A1"); + range.load("valuesAsJson"); + await context.sync(); + let cellValue = range.valuesAsJson[0][0] as any; + + // Only apply this property to a double. + if (cellValue.basicType === "Double") { + cellValue.properties = { + Precision: { + type: Excel.CellValueType.double, + basicValue: 4 + } + }; + range.valuesAsJson = [[cellValue]]; + await context.sync(); + } + }); +} +``` + +## Differences from entity values + +Adding properties to **string**, **Boolean**, and **double** basic types is similar to adding properties to entity values. However there are differences. + +- Basic types have a non-error fallback so that calculations can operate on them. For example, consider the formula **=SUM(A1:A3)** where **A1** is **1** (a double with properties), **A2** is **2**, and **A3** is **3**. The sum will return the correct result of **6**. The formula would not work if **A1** was an entity value. +- When the value of a basic type is used in a calculation, the properties are discarded. In the previous example of **=SUM(A1:A3)** where A1 is a double with properties, the result of **6** will not have any properties. +- If no icon is specified for a basic type, the cell does not show any icon. If an entity value does not specify an icon, it will still show a default icon in the cell value. + +## Formatted number values + +You can apply number formatting to values of type **CellValueType.double**. Use the **numberFormat** property in the JSON schema to specify a number format. The following code sample shows the complete schema of a number value formatted as currency. The formatted number value in the code sample displays as **$24.00** in the Excel UI. + +```javascript +// This is an example of the complete JSON of a formatted number value with a property. +// In this case, the number is formatted as currency. +async function createCurrencyValue() { + await Excel.run(async (context) => { + const sheet = context.workbook.worksheets.getActiveWorksheet(); + const range = sheet.getRange("A1"); + range.valuesAsJson = [ + [ + { + type: Excel.CellValueType.double, + basicType: Excel.RangeValueType.double, + basicValue: 24, + numberFormat: "$0.00", + properties: { + Name: { + type: Excel.CellValueType.string, + basicValue: "dollar" + } + } + } + ] + ]; + await context.sync(); + }); +} +``` + +The number formatting is considered the default format. If the user, or other code, applies formatting to a cell containing a formatted number, the applied format will override the number’s format. + +## Card layout + +Cell values with properties have a default data type card that the user can view. You can provide a custom card layout to use instead of the default card layout to improve the user experience when viewing properties. To do this, add the **layouts** property to the JSON description. + +For more information, see [Use cards with cell value data types](excel-data-types-entity-card.md). + +## Nested data types + +You can nest data types in a cell value, such as additional entity values, as well as **strings**, **doubles**, and **Booleans**. The following code sample shows how to create a cell value that represents the charge status on a computer battery. It contains a nested entity value that describes the computer properties for power consumption and charging status. The computer entity value also contains a nested string value that describes the computer’s power plan. + +```javascript +async function createNumberWithNestedEntity() { + await Excel.run(async (context) => { + const sheet = context.workbook.worksheets.getActiveWorksheet(); + const range = sheet.getRange("A1"); + range.valuesAsJson = [ + [ + { + type: Excel.CellValueType.double, + basicType: Excel.RangeValueType.double, + layouts: { + compact: { + icon: "Battery10" + } + }, + basicValue: 0.7, + numberFormat: "00%", + properties: { + Computer: { + type: Excel.CellValueType.entity, + text: "Laptop", + properties: { + "Power Consumption": { + type: Excel.CellValueType.double, + basicType: Excel.RangeValueType.double, + basicValue: 0.25, + numberFormat: "00%", + layouts: { + compact: { + icon: "Power" + } + }, + properties: { + plan: { + type: Excel.CellValueType.string, + basicType: Excel.RangeValueType.string, + basicValue: "Balanced" + } + } + }, + Charging: { + type: Excel.CellValueType.boolean, + basicType: Excel.RangeValueType.boolean, + basicValue: true + } + } + } + } + } + ] + ]; + await context.sync(); + }); +} +``` + +The following image shows the number value and the data type card for the nested laptop entity. + +:::image type="content" source="../images/data-type-basic-nested-entities.png" alt-text="Cell value in Excel showing battery charge at 70% and the data type card showing the nested laptop entity with charging and power consuption property values."::: + +## Compatibility + +On previous versions of Excel that do not support the data types feature, users will see a warning of **Unavailable Data Type**. The value will still show in the cell and function as expected with formulas and other Excel features. If the value is a formatted number, calculations use the **basicValue** in place of the formatted number. +On Excel versions older than Office 2016, the value will be shown in the cell with no error and will be indistinguishable from a basic value. + +## Related content + +- [Excel JavaScript API data types core concepts](excel-data-types-concepts.md) diff --git a/docs/excel/excel-data-types-concepts.md b/docs/excel/excel-data-types-concepts.md index 28fd32302..61f4c12f6 100644 --- a/docs/excel/excel-data-types-concepts.md +++ b/docs/excel/excel-data-types-concepts.md @@ -1,7 +1,7 @@ --- title: Excel JavaScript API data types core concepts description: Learn the core concepts for using Excel data types in your Office Add-in. -ms.date: 10/14/2022 +ms.date: 04/14/2025 ms.topic: overview ms.custom: scenarios:getting-started ms.localizationpriority: high @@ -37,8 +37,10 @@ The `valuesAsJson` property returns a [CellValue](/javascript/api/excel/excel.ce - [EmptyCellValue](/javascript/api/excel/excel.emptycellvalue) - [EntityCellValue](/javascript/api/excel/excel.entitycellvalue) - [ErrorCellValue](/javascript/api/excel/excel.errorcellvalue) -- [FormattedNumberCellValue](/javascript/api/excel/excel.formattednumbercellvalue) +- [ExternalCodeServiceObjectCellValue](/javascript/api/excel/excel.externalcodeserviceobjectcellvalue) +- [FunctionCellValue](/javascript/api/excel/excel.functioncellvalue) - [LinkedEntityCellValue](/javascript/api/excel/excel.linkedentitycellvalue) +- [LocalImageCellValue](/javascript/api/excel/excel.localimagecellvalue) - [ReferenceCellValue](/javascript/api/excel/excel.referencecellvalue) - [StringCellValue](/javascript/api/excel/excel.stringcellvalue) - [ValueTypeNotAvailableCellValue](/javascript/api/excel/excel.valuetypenotavailablecellvalue) @@ -58,23 +60,33 @@ The following sections show JSON code samples for the formatted number value, en ## Formatted number values -The [FormattedNumberCellValue](/javascript/api/excel/excel.formattednumbercellvalue) object enables Excel add-ins to define a `numberFormat` property for a value. Once assigned, this number format travels through calculations with the value and can be returned by functions. +The [DoubleCellCellValue](/javascript/api/excel/excel.doublecellvalue) object enables Excel add-ins to define a `numberFormat` property for a value. Once assigned, this number format travels through calculations with the value and can be returned by functions. The following JSON code sample shows the complete schema of a formatted number value. The `myDate` formatted number value in the code sample displays as **1/16/1990** in the Excel UI. If the minimum compatibility requirements for the data types feature aren't met, calculations use the `basicValue` in place of the formatted number. ```TypeScript // This is an example of the complete JSON of a formatted number value. // In this case, the number is formatted as a date. -const myDate: Excel.FormattedNumberCellValue = { - type: Excel.CellValueType.formattedNumber, +const myDate: Excel.DoubleCellValue = { + type: Excel.CellValueType.double, basicValue: 32889.0, basicType: Excel.RangeValueType.double, // A read-only property. Used as a fallback in incompatible scenarios. numberFormat: "m/d/yyyy" }; ``` +The number formatting is considered the default format. If the user, or other code, applies formatting to a cell containing a formatted number, the applied format will override the number’s format. + Begin experimenting with formatted number values by opening [Script Lab](../overview/explore-with-script-lab.md) and checking out the [Data types: Formatted numbers](https://github.com/OfficeDev/office-js-snippets/blob/prod/samples/excel/20-data-types/data-types-formatted-number.yaml) snippet in our **Samples** library. +## Basic cell values + +Add properties to basic cell values in Excel to associate additional information with the values. Similar to entity values, you can add properties to the **string**, **double**, and **Boolean** basic types. Each property is a key/value pair. The following example shows the number 104.67 (double) that represents a bill with added fields named **Drinks**, **Food**, **Tax**, and **Tip**. + +:::image type="content" source="../images/data-type-basic-fields.png" alt-text="Screen shot of the drinks, food, tax, and tip fields shown for the selected cell value."::: + +For more information, see [Add properties to basic cell values](excel-data-types-add-properties-to-basic-cell-values.md). + ## Entity values An entity value is a container for data types, similar to an object in object-oriented programming. Entities also support arrays as properties of an entity value. The [EntityCellValue](/javascript/api/excel/excel.entitycellvalue) object allows add-ins to define properties such as `type`, `text`, and `properties`. The `properties` property enables the entity value to define and contain additional data types. @@ -102,13 +114,18 @@ const myEntity: Excel.EntityCellValue = { }; ``` -Entity values also offer a `layouts` property that creates a card for the entity. The card displays as a modal window in the Excel UI and can display additional information contained within the entity value, beyond what's visible in the cell. To learn more, see [Use cards with entity value data types](excel-data-types-entity-card.md). - To explore entity data types, start by going to [Script Lab](../overview/explore-with-script-lab.md) in Excel and opening the [Data types: Create entity cards from data in a table](https://github.com/OfficeDev/office-js-snippets/blob/prod/samples/excel/20-data-types/data-types-entity-values.yaml) snippet in our **Samples** library. The [Data types: Entity values with references](https://github.com/OfficeDev/office-js-snippets/blob/prod/samples/excel/20-data-types/data-types-references.yaml) and [Data types: Entity value attribution properties](https://github.com/OfficeDev/office-js-snippets/blob/prod/samples/excel/20-data-types/data-types-entity-attribution.yaml) snippets offer a deeper look at entity features. -### Linked entities +### Linked entity cell values + +Linked entity cell values, or [LinkedEntityCellValue](/javascript/api/excel/excel.linkedentitycellvalue) objects, integrated data types from external data sources and can display the data as an entity card. They enable you to scale your data types to represent large data sets without downloading all the data into the workbook. The [Stocks and Geography data domains](https://support.microsoft.com/office/excel-data-types-stocks-and-geography-61a33056-9935-484f-8ac8-f1a89e210877) available via the Excel UI provide linked entity cell values. + +Linked entity cell values are linked to an external data source. They provide the following advantages over regular entity values: + +- Linked entity cell values can nest, and nested linked entity cell values are not retrieved until referenced, either by the user, or by the worksheet. This helps reduce file size and improve workbook performance. +- Excel uses a cache to allow different cells to reference the same linked entity cell value seamlessly. This also improves workbook performance. -Linked entity values, or [LinkedEntityCellValue](/javascript/api/excel/excel.linkedentitycellvalue) objects, are a type of entity value. These objects integrate data provided by an external service and can display this data as an [entity card](excel-data-types-entity-card.md), like regular entity values. The [Stocks and Geography data types](https://support.microsoft.com/office/excel-data-types-stocks-and-geography-61a33056-9935-484f-8ac8-f1a89e210877) available via the Excel UI are linked entity values. +For more information, see [Create linked entity cell values](excel-data-types-linked-entity-cell-values.md). ## Web image values @@ -164,6 +181,8 @@ Use the [Create and explore data types in Excel](https://github.com/OfficeDev/Of ## See also - [Overview of data types in Excel add-ins](excel-data-types-overview.md) +- [Create linked entity cell values](excel-data-types-linked-entity-cell-values.md) +- [Add properties to basic cell values](excel-data-types-add-properties-to-basic-cell-values.md) - [Use cards with entity value data types](excel-data-types-entity-card.md) - [Create and explore data types in Excel](https://github.com/OfficeDev/Office-Add-in-samples/tree/main/Samples/excel-data-types-explorer) - [Custom functions and data types](custom-functions-data-types-concepts.md) diff --git a/docs/excel/excel-data-types-entity-card.md b/docs/excel/excel-data-types-entity-card.md index b813b37e4..5abb2ecb8 100644 --- a/docs/excel/excel-data-types-entity-card.md +++ b/docs/excel/excel-data-types-entity-card.md @@ -1,18 +1,22 @@ --- -title: Excel JavaScript API data types entity value card -description: Learn how to use entity value cards with data types in your Excel add-in. -ms.date: 01/22/2025 +title: Use cards for cell values using the Excel JavaScript API +description: Learn how to create cards for cell value data types in your Excel add-in. +ms.date: 04/14/2025 ms.localizationpriority: medium --- -# Use cards with entity value data types +# Use cards with cell value data types -This article describes how to use the [Excel JavaScript API](../reference/overview/excel-add-ins-reference-overview.md) to create card modal windows in the Excel UI with entity value data types. These cards can display additional information contained within an entity value, beyond what's already visible in a cell, such as related images, product category information, and data attributions. +You can specify card modal windows in the Excel UI for various cell value data types. Cards can display additional information beyond what's already visible in a cell, such as related images, product category information, and data attributions. > [!NOTE] -> This article expands on information described in the [Excel data types core concepts](excel-data-types-concepts.md) article. We recommend reading that article before learning about entity cards. +> This article expands on information described in the [Excel data types core concepts](excel-data-types-concepts.md) article. We recommend reading that article before learning about cards for cell values. -An entity value, or [EntityCellValue](/javascript/api/excel/excel.entitycellvalue), is a container for data types and similar to an object in object-oriented programming. This article shows how to use entity value card properties, layout options, and data attribution functionality to create entity values that display as cards. +Cards are supported for the following cell value types. + +- [EntityCellValue](/javascript/api/excel/excel.entitycellvalue) +- [LinkedEntityCellValue](/javascript/api/excel/excel.linkedentitycellvalue) +- **string**, **double**, and **Boolean** basic types The following screenshot shows an example of an open entity value card, in this case for the **Chef Anton's Gumbo Mix** product from a list of grocery store products. @@ -20,7 +24,7 @@ The following screenshot shows an example of an open entity value card, in this ## Card properties -The entity value [`properties`](/javascript/api/excel/excel.entitycellvalue#excel-excel-entitycellvalue-properties-member) property allows you to set customized information about your data types. The `properties` key accepts nested data types. Each nested property, or data type, must have a `type` and `basicValue` setting. +Use [`properties`](/javascript/api/excel/excel.entitycellvalue#excel-excel-entitycellvalue-properties-member) to specify all custom information about your data types. The `properties` key supports nested data types. Each nested property, or data type, must have a `type` and `basicValue` setting. > [!IMPORTANT] > The nested `properties` data types are used in combination with the [Card layout](#card-layout) values described in the subsequent article section. After defining a nested data type in `properties`, it must be assigned in the `layouts` property to display on the card. @@ -52,7 +56,7 @@ const entity: Excel.EntityCellValue = { basicValue: product.quantityPerUnit || "" }, "Unit Price": { - type: Excel.CellValueType.formattedNumber, + type: Excel.CellValueType.double, basicValue: product.unitPrice, numberFormat: "$* #,##0.00" }, @@ -71,39 +75,16 @@ The following screenshot shows an entity value card that uses the preceding code :::image type="content" source="../images/excel-data-types-entity-card-properties-gumbo.png" alt-text="An entity value data type with the card layout window displayed. The card shows the product name, product ID, quantity per unit, and unit price information."::: -### Property metadata - -Entity properties have an optional `propertyMetadata` field that uses the [`CellValuePropertyMetadata`](/javascript/api/excel/excel.cellvaluepropertymetadata) object and offers the properties `attribution`, `excludeFrom`, and `sublabel`. The following code snippet shows how to add a `sublabel` to the `"Unit Price"` property from the preceding code snippet. In this case, the sublabel identifies the currency type. - -> [!NOTE] -> The `propertyMetadata` field is only available on data types that are nested within entity properties. - -```TypeScript -// This code snippet is an excerpt from the `properties` field of the -// preceding `EntityCellValue` snippet. "Unit Price" is a property of -// an entity value. - "Unit Price": { - type: Excel.CellValueType.formattedNumber, - basicValue: product.unitPrice, - numberFormat: "$* #,##0.00", - propertyMetadata: { - sublabel: "USD" - } - }, -``` - -The following screenshot shows an entity value card that uses the preceding code snippet, displaying the property metadata `sublabel` of **USD** next to the **Unit Price** property. - -:::image type="content" source="../images/excel-data-types-entity-card-property-metadata.png" alt-text="The sublabel USD next to the Unit Price."::: - ## Card layout -The entity value [`layouts`](/javascript/api/excel/excel.entitycellvalue#excel-excel-entitycellvalue-layouts-member) property defines the appearance of the entity. Use `layouts` to specify attributes such as an entity icon, card title, image for a card, and the number of sections to display. +Cell values have a default data type card that the user can view. Specify a custom card layout to improve the user experience when viewing properties. The [`layouts`](/javascript/api/excel/excel.entitycellvalue#excel-excel-entitycellvalue-layouts-member) property defines the structure and appearance of the card. Use `layouts` to specify attributes such as an icon, card title, image for a card, and the number of sections to display. > [!IMPORTANT] > The nested `layouts` values are used in combination with the [Card properties](#card-properties) data types described in the preceding article section. A nested data type must be defined in `properties` before it can be assigned in `layouts` to display on the card. -The `layouts` property contains two direct subproperties, `compact` and `card`. The `card` property specifies the appearance of a card when the entity card is open. The `compact` property only defines the icon for an entity, and this icon only displays when the card is in its compact, or unopened state. See the [`EntityCompactLayoutIcons`](/javascript/api/excel/excel.entitycompactlayouticons) enum for a full list of available icons. The next code snippet shows how to display the `shoppingBag` icon. +The `layouts` property contains two direct subproperties, `compact` and `card`. The `card` property specifies the appearance of a card when the card is open. The `compact` property is optional and defines the icon for a value. The icon is shown in the cell value if it's provided. It can also be shown in the card if it's referenced as a subproperty. + +See the [`EntityCompactLayoutIcons`](/javascript/api/excel/excel.entitycompactlayouticons) enum for a full list of available icons. The next code snippet shows how to display the `shoppingBag` icon. Within the `card` property, use the [`CardLayoutStandardProperties`](/javascript/api/excel/excel.cardlayoutstandardproperties) object to define the components of the card like `title`, `subTitle`, and `sections`. @@ -166,38 +147,114 @@ The following screenshot shows an entity value card that uses the preceding code > > There is a known issue with nested icons in Excel on Mac. In that environment, nested icons will always display as the `generic` icon, regardless of which icon is selected with the `EntityCompactLayoutIcons` enum. -## Card data attribution - -Entity value cards can display a data attribution to give credit to the provider of the information in the entity card. The entity value [`provider`](/javascript/api/excel/excel.entitycellvalue#excel-excel-entitycellvalue-provider-member) property uses the [`CellValueProviderAttributes`](/javascript/api/excel/excel.cellvalueproviderattributes) object, which defines the `description`, `logoSourceAddress`, and `logoTargetAddress` values. - -The data provider property displays an image in the lower left corner of the entity card. It uses the `logoSourceAddress` to specify a source URL for the image. The `logoTargetAddress` value defines the URL destination if the logo image is selected. The `description` value displays as a tooltip when hovering over the logo. The `description` value also displays as a plain text fallback if the `logoSourceAddress` is not defined or if the source address for the image is broken. +### Property metadata -The JSON in the following code snippet shows an entity value that uses the `provider` property to specify a data provider attribution for the entity. +Entity properties have an optional `propertyMetadata` field that uses the [`CellValuePropertyMetadata`](/javascript/api/excel/excel.cellvaluepropertymetadata) object and offers the properties `attribution`, `excludeFrom`, and `sublabel`. The following code snippet shows how to add a `sublabel` to the `"Unit Price"` property from the preceding code snippet. In this case, the sublabel identifies the currency type. > [!NOTE] -> To experiment with this code snippet in a complete sample, open [Script Lab](../overview/explore-with-script-lab.md) in Excel and select [Data types: Entity value attribution properties](https://github.com/OfficeDev/office-js-snippets/blob/prod/samples/excel/20-data-types/data-types-entity-attribution.yaml) in our **Samples** library. +> The `propertyMetadata` field is only available on data types that are nested within entity properties. ```TypeScript -const entity: Excel.EntityCellValue = { - type: Excel.CellValueType.entity, - text: productName, - properties: { - // Enter property settings here. - }, - layouts: { - // Enter layout settings here. - }, - provider: { - description: product.providerName, // Name of the data provider. Displays as a tooltip when hovering over the logo. Also displays as a fallback if the source address for the image is broken. - logoSourceAddress: product.sourceAddress, // Source URL of the logo to display. - logoTargetAddress: product.targetAddress // Destination URL that the logo navigates to when selected. - } -}; +// This code snippet is an excerpt from the `properties` field of the +// preceding `EntityCellValue` snippet. "Unit Price" is a property of +// an entity value. + "Unit Price": { + type: Excel.CellValueType.double, + basicValue: product.unitPrice, + numberFormat: "$* #,##0.00", + propertyMetadata: { + sublabel: "USD" + } + }, +``` + +## Attribution + +Add attribution for information that comes from third parties to indicate the source and any license information. Use [Excel.CellValueAttributionAttributes](/javascript/api/excel/excel.cellvalueattributionattributes) to add attribution to a cell value. The following code example shows how to add attribution for usage of information about the planet Mars from Wikipedia. + +```javascript +async function createPlanet() { + await Excel.run(async (context) => { + const sheet = context.workbook.worksheets.getActiveWorksheet(); + const range = sheet.getRange("A1"); + const attributionObject: Excel.CellValueAttributionAttributes = { + licenseAddress: "https://en.wikipedia.org/wiki/Wikipedia:Wikipedia_is_free_content", + licenseText: "Free usage information", + sourceAddress: "https://en.wikipedia.org/wiki/Mars", + sourceText: "Wikipedia" + }; + + range.valuesAsJson = [ + [ + { + type: Excel.CellValueType.double, + basicType: Excel.RangeValueType.double, + basicValue: 6779, //kilometers (radius) + properties: { + Name: { + type: Excel.CellValueType.string, + basicType: Excel.RangeValueType.string, + basicValue: "Mars", + propertyMetadata: { + sublabel: "Planetary Body", + attribution: [attributionObject] + } + } + } + } + ] + ]; + await context.sync(); + }); +} + +``` + +The following image shows how the attribution is displayed in the data type card for the user. + +:::image type="content" source="../images/data-type-basic-card-attribution.png" alt-text="Data type card showing attribution for Wikipedia."::: + +## Provider information + +You can add information about your add-in, or service, that is the source for the information in the data type card. Use [Excel.CellValueProviderAttributes](/javascript/api/excel/excel.cellvalueproviderattributes) to add your provider information. The following code sample shows how to add provider information for Contoso generic search as the source of search data for the cell value. + +```javascript +async function createSearchEntry() { + await Excel.run(async (context) => { + const sheet = context.workbook.worksheets.getActiveWorksheet(); + const range = sheet.getRange("A1"); + + range.valuesAsJson = [ + [ + { + type: Excel.CellValueType.string, + basicType: Excel.RangeValueType.string, + basicValue: "cell function - Microsoft support", + properties: { + "Search Keywords": { + type: Excel.CellValueType.string, + basicType: Excel.RangeValueType.string, + basicValue: "Cell Values" + } + }, + provider: { + description: "Contoso generic search", + //Ignacio javier igjav, Public domain, via Wikimedia Commons + logoSourceAddress: "https://upload.wikimedia.org/wikipedia/commons/f/f9/Lupa.png", + logoTargetAddress: "https://contoso.com" + } + } + ] + ]; + + await context.sync(); + }); +} ``` -The following screenshot shows an entity value card that uses the preceding code snippet. The screenshot shows the data provider attribution in the lower left corner. In this instance, the data provider is Microsoft and the Microsoft logo is displayed. +The following image shows how the provider information appears as the logo in the data type card for the user. -:::image type="content" source="../images/excel-data-types-entity-card-attribution.png" alt-text="An entity value data type with the card layout window displayed. The card shows the data provider attribution in the lower left corner."::: +:::image type="content" source="../images/data-type-basic-provider-information.png" alt-text="Data type card showing the search logo for Contoso generic search."::: ## Next steps @@ -208,4 +265,4 @@ Try out the [Create and explore data types in Excel](https://github.com/OfficeDe - [Overview of data types in Excel add-ins](excel-data-types-overview.md) - [Excel data types core concepts](excel-data-types-concepts.md) - [Create and explore data types in Excel](https://github.com/OfficeDev/Office-Add-in-samples/tree/main/Samples/excel-data-types-explorer) -- [Excel JavaScript API reference](../reference/overview/excel-add-ins-reference-overview.md) \ No newline at end of file +- [Excel JavaScript API reference](../reference/overview/excel-add-ins-reference-overview.md) diff --git a/docs/excel/excel-data-types-linked-entity-cell-values.md b/docs/excel/excel-data-types-linked-entity-cell-values.md new file mode 100644 index 000000000..61e2fc93e --- /dev/null +++ b/docs/excel/excel-data-types-linked-entity-cell-values.md @@ -0,0 +1,539 @@ +--- +title: Create linked entity cell values +description: Create linked entity cell values to represent large data sets in Excel. +ms.topic: how-to +ms.date: 03/31/2025 +ms.localizationpriority: medium +--- + +# Create linked entity cell values + +Linked entity cell values integrate data types from external data sources and can display the data as an entity card, like [regular entity values](excel-data-types-entity-card.md). They enable you to scale your data types to represent large data sets without downloading all the data into the workbook. The [Stocks and Geography data domains](https://support.microsoft.com/office/excel-data-types-stocks-and-geography-61a33056-9935-484f-8ac8-f1a89e210877) available via the Excel UI provide linked entity cell values. This article explains how to create your own data provider in an Excel add-in to provide custom values for end users. + +Linked entity cell values are linked to an external data source. They provide the following advantages over regular entity values. + +- Linked entity cell values can nest, and nested linked entity cell values are not retrieved until referenced; either by the user, or by the worksheet. This helps reduce file size and improve workbook performance. +- Excel uses a cache to allow different cells to reference the same linked entity cell value seamlessly. This also improves workbook performance. + +This article expands on information described in the following articles. We recommend reading the following articles before learning how to build your own linked entity cell values. + +- [Excel data types: Stocks and geography](https://support.microsoft.com/office/excel-data-types-stocks-and-geography-61a33056-9935-484f-8ac8-f1a89e210877) +- [Overview of data types in Excel add-ins](excel-data-types-overview.md) +- [Excel JavaScript API data types entity value card](excel-data-types-entity-card.md). + +## Key concepts + +Linked entity cell values provide the user with data linked from an external data source. The user can view them as an entity value card. + +:::image type="content" source="../images/excel-geography-linked-data-type-seattle.png" alt-text="Screen shot of an entity value data card for the Seattle Geography linked data type in the worksheet."::: + +Like regular entity values, linked entity cell values can be referenced in formulas. + +:::image type="content" source="../images/excel-geography-seattle-dot-syntax.png" alt-text="Screen shot of using dot notation in a formula using =D6. To display fields for Seattle Geography data type."::: + +## Definitions + +The following definitions are fundamental to understanding how to implement your own linked entity cell values. + +- **Data provider** - The data provider is recognized by Excel as the source of data for one or more registered linked entity data domains. +- **Linked entity data domain** – A linked entity data domain describes an entity such as one you might find in a database. Some examples are employees, organizations, or cars. +- **Linked entity cell value** – An instance created from a data domain. An example is an employee value for Joe. It can be displayed as an entity value card. +- **Linked entity load service function** – A TypeScript or JavaScript custom function you implement in your add-in. It handles requests from Excel to get linked entity cell values for the workbook. + +## How your add-in provides linked entity cell values + +The following diagram shows the steps that occur when your add-in is loaded and then inserts a new linked entity cell value into a cell. + +:::image type="content" source="../images/excel-data-types-linked-entity-workflow.png" alt-text="Diagram showing five steps for add-in to register data domains and handle requests from Excel to get properties from a linked entity cell value."::: + +1. Excel loads your add-in, and your add-in registers all of the linked entity data domains that it supports. Each registration includes the id of a linked entity load service function which is called later by Excel to request property values for the linked entity cell value from the linked entity data domain. In this example, one data domain named Products is registered. +1. Excel tracks each registered linked entity data domain in a linked entity data domain collection. This enables Excel to call your linked entity load service function when data is needed for a linked entity cell value. +1. Your add-in inserts a new linked entity cell value into the worksheet. In this example a new linked entity cell value is created for the product **Chai**. This would typically occur from the user choosing a button on your add-in that results in creating one or more linked entity cell values. When you create new linked entity cell values, they only contain an initial text string that is displayed in the cell. Excel calls your linked entity load service function to get the remaining property values. Your add-in can also create linked entity cell values from custom functions. +1. Excel calls the linked entity load service function that you registered in step 1. This occurs every time you create a new linked entity cell value, or if a data refresh occurs. Excel calls your linked entity load service function to get all of the property values. +1. The linked entity load service function returns an up-to-date linked entity cell value ([Excel.LinkedEntityCellValue](/javascript/api/excel/excel.linkedentitycellvalue)) for the linked entity ID ([Excel.LinkedEntityId](/javascript/api/excel/excel.linkedentityid)) requested by Excel. Typically, your linked entity load service function queries an external data source to get the values and create the linked entity cell value. In this example the values for **product ID**, **category**, **quantity**, and **price** are returned. + +> [!NOTE] +> If Excel needs multiple linked entity cell values, the linked entity IDs are passed as a batch to your linked entity load service function. The linked entity load service then returns a batch result of all values. + +The following sections provide additional details about the previous definitions. + +### Data provider + +Your add-in is the data provider and is recognized by Excel as the source of data for one or more registered data domains. Your add-in exposes one or more data provider functions that return data for linked entity cell values. The data provider is identified by a text string ([LinkedEntityDataDomainCreateOptions.dataprovider](/javascript/api/excel/excel.linkedentitydatadomaincreateoptions)) such as **Contoso** or the name of your add-in. The name must be unique within your add-in. + +### Linked entity data domains + +The data provider (your add-in) registers one or more data domains. A data domain describes an entity to Excel. For example, a data provider can provide the **products** and **categories** data domains. The domains must be registered with Excel so that it can work with those domains to retrieve and display linked entity cell values and perform calculations. + +A data domain describes to Excel the following attributes: + +- The name of the data provider it is associated with. +- A domain id to uniquely identify it, such as **products**. +- A display name for the user, such as **Products**. +- A linked entity load service function to call when Excel needs a linked entity cell value. +- A specified refresh mode and interval describing how often it refreshes. + +An example of a linked entity data domain is the **Geography** data domain in Excel that provides linked entity cell values for cities. + +### Linked entity cell value + +A linked entity cell value is an instance created from a data domain. An example is a value for Seattle, from the [Geography data domain](https://support.microsoft.com/en-us/office/excel-data-types-stocks-and-geography-61a33056-9935-484f-8ac8-f1a89e210877). It displays an entity value card like regular entity cell values. + +:::image type="content" source="../images/excel-geography-linked-data-type-seattle.png" alt-text="Screen shot of an entity value data card for the Seattle Geography linked data type in the worksheet."::: + +Since linked entity cell values are linked to the data domain, they can be refreshed. Also, nested linked entity cell values are not retrieved unless the user requests them (such as viewing the entity card). And nested entity cell values aren’t saved with the worksheet unless they are referenced from the worksheet (such as a formula). This reduces file size and improves performance. + +### Linked entity load service function + +Each data domain requires a function that Excel can call when it needs linked entity cell values. Your add-in provides the service as a JavaScript or TypeScript function tagged with **@linkedEntityLoadService**. It's recommended to create just one load service function for best performance. Excel will send all requests for linked entity cell values as a batch to the load service function. + +## Create a data provider with data domains + +The following sections of this article show how to write TypeScript code to implement an Excel add-in that is a data provider for **Contoso**. It provides two data domains named **Products** and **Categories**. + +### Register the data domains + +Let’s look at the code to register new domains named **Products** and **Categories**. The data provider name is **Contoso**. When the add-in loads, it first registers the data domains with Excel. + +Use the [Excel.LinkedEntityDataDomainCreateOptions](/javascript/api/excel/excel.linkedentitydatadomaincreateoptions) type to describe the options you want, including which function to use as the linked entity load service. Then add the domain to the [Workbook.linkedEntityDataDomains](/javascript/api/excel/excel.workbook#excel-excel-workbook-linkedentitydatadomains-member) collection. It's recommended to register domains when you [Initialize your Office Add-in](../develop/initialize-add-in.md). +The following code shows how to register the **Products** and **Categories** data domains. + +```javascript +Office.onReady(async () => { + await Excel.run(async (context) => { + const productsDomain: Excel.LinkedEntityDataDomainCreateOptions = { + dataProvider: "Contoso", + id: "products", + name: "Products", + // Id of the custom function that will be called on demand by Excel to resolve/refresh linked entity + // cell values of this data domain. + loadFunctionId: "CONTOSOLOADSERVICEID", + // periodicRefreshInterval is only required when supportedRefreshModes contains "Periodic". + periodicRefreshInterval: 300, + // Manual refresh mode is always supported, even if unspecified. + supportedRefreshModes: [ + Excel.LinkedEntityDataDomainRefreshMode.periodic, + Excel.LinkedEntityDataDomainRefreshMode.onLoad + ] + }; + + const categoriesDomain: Excel.LinkedEntityDataDomainCreateOptions = { + dataProvider: "Contoso", + id: "categories", + name: "Categories", + loadFunctionId: "CONTOSOLAODSERVICEID", + periodicRefreshInterval: 300, + supportedRefreshModes: [ + Excel.LinkedEntityDataDomainRefreshMode.periodic, + Excel.LinkedEntityDataDomainRefreshMode.onLoad + ] + }; + + // Register the data domains by adding them to the collection. + context.workbook.linkedEntityDataDomains.add(productsDomain); + context.workbook.linkedEntityDataDomains.add(categoriesDomain); + + await context.sync(); + }); +}); +``` + +## Insert a linked entity cell value + +There are two ways to insert a linked entity cell value into a cell on a worksheet. + +- Create a command button on the ribbon or a button in your task pane. When the user selects the button your code inserts a linked entity cell value. +- Create a custom function that returns a linked entity cell value. + +The following code example shows how to insert a new linked entity cell value into the selected cell. This code can be called from a command button on the ribbon, or a button in the task pane. Notes about the following code: + +- You must specify a `serviceId` of `268436224` for any linked entity cell values you return. This informs Excel that the linked entity cell value is associated with an Excel add-in. +- You must specify a `culture`. Excel will pass it to your linked entity load service function so that you can maintain the original culture when the workbook is opened in a different culture. +- The `text` property is displayed to the user in the cell while the linked entity data value is updated. This prevents the user seeing a blank cell while the update is completed. + +```javascript +export async function insertProduct() { + await Excel.run(async (context) => { + const productLinkedEntity: Excel.LinkedEntityCellValue = { + type: Excel.CellValueType.linkedEntity, + id: { + entityId: "chai", + domainId: "products", + serviceId: 268436224, + culture: "en-US", + }, + text: "Chai", + }; + context.workbook.getActiveCell().valuesAsJson = [[productLinkedEntity]]; + await context.sync(); + }); +} +``` + +The following code sample shows how to insert a linked entity cell value by using a custom function. A user could get a linked entity cell value by entering `=CONTOSO.GETPRODUCTBYID("productid")` into any cell. The notes for the previous code sample also apply to this one. + +```javascript +/** + * Custom function that shows how to insert a `LinkedEntityCellValue`. + * @customfunction + * @param {string} productID Unique id of the product. + * @return {Promise} `LinkedEntityCellValue` for the requested product, if found. + */ +async function getProductById(productID: string): Promise { + const product = getProduct(productID); + if (product === null) { + throw new CustomFunctions.Error(CustomFunctions.ErrorCode.notAvailable, "Invalid productID"); + } + const productLinkedEntity: Excel.LinkedEntityCellValue = { + type: Excel.CellValueType.linkedEntity, + id: { + entityId: product.productID, + domainId: "products", + serviceId: 268436224, + culture: "en-US", + }, + text: product.productName + }; + + return productLinkedEntity; +} +``` + +## Implement the linked entity load service function + +The add-in must provide a linked entity load service function to handle requests from Excel when property values are needed for any linked entity cell values. The function is identified with the `@linkedEntityLoadService` JSDoc tag. + +The following code example shows how to create a function that handles data requests from Excel for the **Products** and **Categories** data domains. Notes on the following code: + +- It uses helper functions to create the linked entity cell values. That code is shown later. +- If an error occurs it throws a `CustomFunctions.ErrorCode.notAvailable` error. This displays `#CONNECT!` in the cell that the user sees. + +```javascript +// Linked entity data domain constants +const productsDomainId = "products"; +const categoriesDomainId = "categories"; + +// Linked entity cell value constants +const addinDomainServiceId = 268436224; +const defaultCulture = "en-US"; + +/** + * Custom function which acts as the "service" or the data provider for a `LinkedEntityDataDomain`, that is + * called on demand by Excel to resolve/refresh `LinkedEntityCellValue`s of that `LinkedEntityDataDomain`. + * @customfunction + * @linkedEntityLoadService + * @param {any} request Request to resolve/refresh `LinkedEntityCellValue` objects. + * @return {Promise} Resolved/Refreshed `LinkedEntityCellValue` objects that were requested in the passed-in request. + */ +async function productLinkedEntityService(linkedEntityId: any): Promise { + const notAvailableError = new CustomFunctions.Error(CustomFunctions.ErrorCode.notAvailable); + console.log(`Fetching linked entities from request: ${request} ...`); + + try { + // Parse the request that was passed-in by Excel. + const parsedRequest: Excel.LinkedEntityLoadServiceRequest = JSON.parse(request); + const requestResult: Excel.LinkedEntityLoadServiceResult = { entities: [] }; + + // Identify the domainId of the request and call the corresponding function to create + // linked entity cell values for that linked entity data domain. + for (const { entityId } of parsedRequest.entities) { + var linkedEntityResult = null; + switch (parsedRequest.domainId) { + case productsDomainId: { + linkedEntityResult = makeProductLinkedEntity(entityId); + break; + } + + case categoriesDomainId: { + linkedEntityResult = makeCategoryLinkedEntity(entityId); + break; + } + + default: + throw notAvailableError; + } + + if (!linkedEntityResult) { + // Throw an error to signify to Excel that resolution/refresh of the requested linkedEntityId failed. + throw notAvailableError; + } + + requestResult.entities.push(linkedEntityResult); + } + + return requestResult; + } catch (error) { + console.error(error); + throw notAvailableError; + } +} +``` + +The following code sample shows the helper function to create a product linked entity cell value. This function is called by the previous code `productLinkedEntityService` to create a linked entity for a specific product ID. Notes on the following code: + +- It uses the same settings as the previous `insertProduct` example for the `type`, `id`, and `text` properties. +- It includes additional properties specific to the **Products** data domain, such as `Product name` and `Unit price`. +- It creates a deferred nested linked entity for the product's category. The properties for the category are not requested until they are needed. + +```javascript +/** Helper function to create linked entity from product properties. */ +function makeProductLinkedEntity(productID: string): any { + // Search the product data in the data source for a matching product ID. + const product = getProduct(productID); + if (product === null) { + // Return null if no matching product is found. + return null; + } + + const productLinkedEntity: Excel.LinkedEntityCellValue = { + type: "LinkedEntity", + text: product.productName, + id: { + entityId: product.productID, + domainId: productsDomainId, + serviceId: addinDomainServiceId, + culture: defaultCulture + }, + properties: { + "Product ID": { + type: "String", + basicValue: product.productID + }, + "Product Name": { + type: "String", + basicValue: product.productName + }, + "Quantity Per Unit": { + type: "String", + basicValue: product.quantityPerUnit + }, + // Add Unit Price as a formatted number. + "Unit Price": { + type: "FormattedNumber", + basicValue: product.unitPrice, + numberFormat: "$* #,##0.00" + }, + Discontinued: { + type: "Boolean", + basicValue: product.discontinued + } + }, + layouts: { + compact: { + icon: "ShoppingBag" + }, + card: { + title: { property: "Product Name" }, + sections: [ + { + layout: "List", + properties: ["Product ID"] + }, + { + layout: "List", + title: "Quantity and price", + collapsible: true, + collapsed: false, + properties: ["Quantity Per Unit", "Unit Price"] + }, + { + layout: "List", + title: "Additional information", + collapsed: true, + properties: ["Discontinued", "LastRefreshedTime"] + } + ] + } + } + }; + + }; + + // Add image property to the linked entity and then add it to the card layout. + if (product.productImage) { + productLinkedEntity.properties["Image"] = { + type: "WebImage", + address: product.productImage + }; + productLinkedEntity.layouts.card.mainImage = { property: "Image" }; + } + + // Add a deferred nested linked entity for the product category. + const category = getCategory(product.categoryID.toString()); + if (category) { + productLinkedEntity.properties["Category"] = { + type: "LinkedEntity", + text: category.categoryName, + id: { + entityId: category.categoryID.toString(), + domainId: categoriesDomainId, + serviceId: addinDomainServiceId, + culture: defaultCulture + } + }; + + // Add nested product category to the card layout. + productLinkedEntity.layouts.card.sections[0].properties.push("Category"); + } + + return productLinkedEntity; +} +``` + +The following code sample shows the helper function to create a category linked entity cell value. This function is called by the previous code `productLinkedEntityService` to create a linked entity for a specific category ID. + +```javascript +/** Helper function to create linked entity from category properties. */ +function makeCategoryLinkedEntity(categoryID: string): any { + // Search the sample JSON category data for a matching category ID. + const category = getCategory(categoryID); + if (category === null) { + // Return null if no matching category is found. + return null; + } + + const categoryLinkedEntity: Excel.LinkedEntityCellValue = { + type: "LinkedEntity", + text: category.categoryName, + id: { + entityId: category.categoryID, + domainId: categoriesDomainId, + serviceId: addinDomainServiceId, + culture: defaultCulture + }, + properties: { + "Category ID": { + type: "String", + basicValue: category.categoryID, + propertyMetadata: { + // Exclude the category ID property from the card view and auto complete. + excludeFrom: { + cardView: true, + autoComplete: true + } + } + }, + "Category Name": { + type: "String", + basicValue: category.categoryName + }, + Description: { + type: "String", + basicValue: category.description + } + }, + layouts: { + compact: { + icon: "Branch" + } + } + }; + + return categoryLinkedEntity; +} +``` + +## Data refresh options + +When you register a data domain, the user can refresh it manually at any time (such as choosing **Refresh All** from the **Data** tab.). There are three refresh modes you can specify for your data domain. + +- `manual`: The data is refreshed only when the user chooses to refresh. This is the default mode. Manual refresh can always be performed by the user, even when the refresh mode is set to `onLoad` or `periodic`. +- `onLoad`: The data is refreshed when the add-in is loaded. After the add-in loads, data is only refreshed manually by the user. If you want to refresh data when the workbook is opened, configure your add-in to load on document open. For more information, see [Run code in your Office Add-in when the document opens](../develop/run-code-on-document-open.md). +- `periodic`: The data is refreshed when the workbook is opened, and then continuously updated after a specified interval of time. For example you could specify that the data domain refreshes every 300 seconds (which is the minimum value). + +The following code example shows how to configure a data domain to refresh on load, and then continue to refresh every 300 seconds. + +```javascript +const productsDomain: Excel.LinkedEntityDataDomainCreateOptions = { + dataProvider: domainDataProvider, + id: "products", + name: "Products", + // Id of the custom function that will be called on demand by Excel to resolve/refresh linked entity + // cell values of this data domain. + loadFunctionId: domainLoadFunctionId, + // periodicRefreshInterval is only required when supportedRefreshModes contains "Periodic". + periodicRefreshInterval: 300, + // Manual refresh mode is always supported, even if unspecified. + supportedRefreshModes: [ + Excel.LinkedEntityDataDomainRefreshMode.periodic, + Excel.LinkedEntityDataDomainRefreshMode.onLoad + ] +}; +``` + +You can also programmatically request a refresh on a linked entity data domain by using either of the following methods. + +- `LinkedEntityDataDomain.refresh()` - Refreshes all `LinkedEntityCellValue` objects of the linked entity data domain. +- `LinkedEntityDataDomainCollection.refreshAll()` - Refreshes all `LinkedEntityCellValue` objects of all linked entity data domains in the collection. + +The refresh methods request a refresh which occurs asynchronously. To determine the results of the refresh, listen for the `onRefreshCompleted` event. The following code sample shows an example of listening for the `onRefreshCompleted` event. + +```javascript + await Excel.run(async (context) => { + const dataDomains = context.workbook.linkedEntityDataDomains; + dataDomains.onRefreshCompleted.add(onLinkedEntityDomainRefreshed); + + await context.sync(); +}); + +async function onLinkedEntityDomainRefreshed (eventArgs: Excel.LinkedEntityDataDomainRefreshCompletedEventArgs): Promise { + console.log("Linked entity domain refreshed: " + eventArgs.id); + console.log("Refresh status: " + eventArgs.refreshed); + console.log("Refresh error: " + eventArgs.errors); + return null; +} +``` + +## Error handling in linked entity load service + +When Excel calls your add-in to get data for a linked entity cell value, it's possible an error can occur. If Excel is unable to connect to your add-in at all (such as when it is not loaded) it will display `#CONNECT!` to the user. + +If your linked entity load service function encounters an error, it should throw an error. The error will cause Excel to show `#CONNECT!` to the user. + +The following code shows how to handle an error in a linked entity load service function. + +```javascript +async function productLinkedEntityService(request: any): Promise { + const notAvailableError = new CustomFunctions.Error(CustomFunctions.ErrorCode.notAvailable); + try { + // Create an return a new linked entity cell value. + let linkedEntityResult = ... + ... + if (!linkedEntityResult) { + // Throw an error to signify to Excel that resolution/refresh of the requested linkedEntityId failed. + throw notAvailableError; + } + ... + } catch (error) { + console.error(error); + throw notAvailableError; + } +} +``` + +## Debugging the linked entity load service + +Most add-in functionality for linked entity data types can be debugged using the guidance in [Overview of debugging Office Add-ins](../testing/debug-add-ins-overview.md). However, the linked entity load service function can be implemented in a shared runtime, or a JavaScript-only runtime (also know as a custom function runtime.) If you choose to implement the function in a JavaScript-only runtime, use the debugging guidance in JavaScript-only runtime for [Custom functions debugging in a non-shared runtime](custom-functions-debugging.md). + +The linked entity load service function uses the custom function architecture, regardless of which runtime you use. However, there are significant differences from regular custom functions. +Differences: + +- They will not appear to end users for usage in formulas. +- They do not support the JSDoc tags `@streaming` or `@volatile`. + +Similarities: + +- They use [Custom functions naming and localization](custom-functions-naming.md). +- They use the same error handling approach. + +## Behavior in Excel 2019 and earlier + +If someone opens a worksheet with linked entity cell values on an older version of Excel that doesn’t support linked entity cell values, Excel will show the cell values as errors. This is the designed behavior. This is also why you set the `basicType` to `Error` and the `basicValue` to `#VALUE!` every time you insert or update a linked entity cell value. This is the error that Excel will fall back to on older versions. + +## Best practices + +- Register linked entity data domains in the initialization code `Office.OnReady`, so that the user will have immediate functionality such as refreshing the linked entity cell values. +- After publishing your add-in, don’t change the linked entity data domain ids. Consistent ids across logically the same objects will help with performance. +- Always provide the `text` property when creating a new linked entity cell value. This value is displayed while Excel calls your data provider function to get the remaining property values. Otherwise the user will see a blank cell until the data is retrieved. + +don't use exclamation marks in product names. diff --git a/docs/images/data-type-basic-card-attribution.png b/docs/images/data-type-basic-card-attribution.png new file mode 100644 index 000000000..5865a6c08 Binary files /dev/null and b/docs/images/data-type-basic-card-attribution.png differ diff --git a/docs/images/data-type-basic-card-layout.png b/docs/images/data-type-basic-card-layout.png new file mode 100644 index 000000000..525032f9a Binary files /dev/null and b/docs/images/data-type-basic-card-layout.png differ diff --git a/docs/images/data-type-basic-data-type-card.png b/docs/images/data-type-basic-data-type-card.png new file mode 100644 index 000000000..83f921f5a Binary files /dev/null and b/docs/images/data-type-basic-data-type-card.png differ diff --git a/docs/images/data-type-basic-dot-syntax.png b/docs/images/data-type-basic-dot-syntax.png new file mode 100644 index 000000000..9cacb4861 Binary files /dev/null and b/docs/images/data-type-basic-dot-syntax.png differ diff --git a/docs/images/data-type-basic-fields.png b/docs/images/data-type-basic-fields.png new file mode 100644 index 000000000..6c34f2d25 Binary files /dev/null and b/docs/images/data-type-basic-fields.png differ diff --git a/docs/images/data-type-basic-nested-entities.png b/docs/images/data-type-basic-nested-entities.png new file mode 100644 index 000000000..25123c58c Binary files /dev/null and b/docs/images/data-type-basic-nested-entities.png differ diff --git a/docs/images/data-type-basic-provider-information.png b/docs/images/data-type-basic-provider-information.png new file mode 100644 index 000000000..ea5544045 Binary files /dev/null and b/docs/images/data-type-basic-provider-information.png differ diff --git a/docs/images/excel-data-types-linked-entity-workflow.png b/docs/images/excel-data-types-linked-entity-workflow.png new file mode 100644 index 000000000..e2c3064b5 Binary files /dev/null and b/docs/images/excel-data-types-linked-entity-workflow.png differ diff --git a/docs/images/excel-geography-linked-data-type-seattle.png b/docs/images/excel-geography-linked-data-type-seattle.png new file mode 100644 index 000000000..39e481121 Binary files /dev/null and b/docs/images/excel-geography-linked-data-type-seattle.png differ diff --git a/docs/images/excel-geography-seattle-dot-syntax.png b/docs/images/excel-geography-seattle-dot-syntax.png new file mode 100644 index 000000000..fbf1d01a1 Binary files /dev/null and b/docs/images/excel-geography-seattle-dot-syntax.png differ diff --git a/docs/images/get-app-cmdlet-providername.png b/docs/images/get-app-cmdlet-providername.png index fbb25a5b7..bff22c6af 100644 Binary files a/docs/images/get-app-cmdlet-providername.png and b/docs/images/get-app-cmdlet-providername.png differ diff --git a/docs/toc.yml b/docs/toc.yml index 29f1b37c3..fc9f01a7e 100644 --- a/docs/toc.yml +++ b/docs/toc.yml @@ -490,9 +490,15 @@ items: - name: Concepts href: excel/excel-data-types-concepts.md displayName: Excel - - name: Entity value cards + - name: Property values on basic types + href: excel/excel-data-types-add-properties-to-basic-cell-values.md + displayName: Excel + - name: Cards for cell value types href: excel/excel-data-types-entity-card.md displayName: Excel + - name: Linked Entity values + href: excel/excel-data-types-linked-entity-cell-values.md + displayName: Excel - name: Data validation href: excel/excel-add-ins-data-validation.md displayName: Excel