Dynamically Retrieving a View ID by View Name and Table Name in Dynamics 365

 This article demonstrates how to dynamically retrieve the ID of a custom view based on its name and the target table (entity) in Dynamics 365. This technique is useful when you need to apply a custom view for lookups or other scenarios where a filtered set of records is required.

Overview

Dynamics 365 stores system views in the savedquery entity and personal views in the userquery entity. To dynamically retrieve a view's ID:

  1. Build a FetchXML Query: Retrieve records from savedquery (or fallback to userquery) filtering by the view's name.
  2. Filter by Table Name: Use the returnedtypecode attribute to ensure the view is associated with the desired entity.
  3. Return the View ID: If a matching view is found, return its ID wrapped in curly braces.

This approach allows you to programmatically use custom views in your JavaScript code without hardcoding the view ID.

Code Example

Below is the JavaScript function getViewIdByName, which retrieves the view ID based on the provided view name and table name:

/**
 * Retrieves the view id for a given view name and table name from the savedquery or userquery entity using FetchXML.
 *
 * @param {string} viewName - The name of the view to retrieve (e.g., "Active Drivers").
 * @param {string} tableName - The logical name of the entity for which the view is defined (e.g., "systemuser").
 * @returns {Promise<string>} - A promise that resolves with the view id in curly braces.
 *
 * Usage: Call this function with the view name and table name.
 */
function getViewIdByName(viewName, tableName)
{
    return new Promise(function(resolve, reject)
    {
        var fetchXml = [
            "<fetch version='1.0' output-format='xml-platform' mapping='logical' distinct='false'>",
            "  <entity name='savedquery'>",
            "    <attribute name='savedqueryid' />",
            "    <attribute name='returnedtypecode' />",
            "    <filter>",
            "      <condition attribute='name' operator='eq' value='" + viewName + "' />",
            "    </filter>",
            "  </entity>",
            "</fetch>"
        ].join("");
        Xrm.WebApi.retrieveMultipleRecords("savedquery", "?fetchXml=" + encodeURIComponent(fetchXml)).then(
            function(result)
            {
                var records = result.entities || result.value;
                if (records && records.length > 0)
                {
                    var filtered = records.filter(function(item)
                    {
                        return item.returnedtypecode && item.returnedtypecode.toLowerCase() === tableName.toLowerCase();
                    });
                    if (filtered.length > 0)
                    {
                        var viewId = filtered[0].savedqueryid;
                        resolve("{" + viewId + "}");
                        return;
                    }
                }
                // Fallback: query personal views in the userquery entity.
                var userQuery = [
                    "<fetch version='1.0' output-format='xml-platform' mapping='logical' distinct='false'>",
                    "  <entity name='userquery'>",
                    "    <attribute name='userqueryid' />",
                    "    <attribute name='returnedtypecode' />",
                    "    <filter>",
                    "      <condition attribute='name' operator='eq' value='" + viewName + "' />",
                    "    </filter>",
                    "  </entity>",
                    "</fetch>"
                ].join("");
                Xrm.WebApi.retrieveMultipleRecords("userquery", "?fetchXml=" + encodeURIComponent(userQuery)).then(
                    function(result2)
                    {
                        var records2 = result2.entities || result2.value;
                        if (records2 && records2.length > 0)
                        {
                            var filtered2 = records2.filter(function(item)
                            {
                                return item.returnedtypecode && item.returnedtypecode.toLowerCase() === tableName.toLowerCase();
                            });
                            if (filtered2.length > 0)
                            {
                                var viewId = filtered2[0].userqueryid;
                                resolve("{" + viewId + "}");
                                return;
                            }
                        }
                        reject("View not found: " + viewName);
                    },
                    function(error2)
                    {
                        reject(error2.message);
                    }
                );
            },
            function(error)
            {
                reject(error.message);
            }
        );
    });
}


How It Works

  1. FetchXML Query Construction:
    The function constructs a FetchXML query to retrieve the savedqueryid and returnedtypecode for records in the savedquery entity where the view name matches the input.

  2. Filtering by Table Name:
    The results are filtered using the returnedtypecode attribute to ensure that the view is defined for the specified table (e.g., "systemuser").

  3. Fallback to Personal Views:
    If no matching view is found in savedquery, the function builds a similar FetchXML query for the userquery entity to check for personal views.

  4. Promise Resolution:
    The function resolves with the view ID (wrapped in curly braces) if a matching view is found, otherwise, it rejects with an error message.

Conclusion

By using this generalized function, you can dynamically retrieve view IDs by specifying both the view name and the target table. This approach provides flexibility for various lookup and filtering scenarios in Dynamics 365, allowing you to adapt your customizations without hardcoding view IDs.

Feel free to integrate and adapt this code to suit your specific Dynamics 365 customization needs. Happy coding!

No comments:

Post a Comment