Compartir por


Personalice los registros subyacentes cuadrícula en los pronósticos

Como desarrollador, utilice esta documentación de referencia para obtener más información sobre los eventos y el objeto de contexto para personalizar los registros subyacentes cuadrícula en su pronóstico. Puede utilizar el objeto de contexto para realizar personalizaciones como hacer que todo el cuadrícula o campos específicos sean de solo lectura, deshabilitar campos, mostrar notificaciones de error, etc.

Requisitos de licencia y rol

Tipo de requisito Debe tener
Licencia Dynamics 365 Sales Premium o Dynamics 365 Sales Enterprise
Más información: Precios de Dynamics 365 Sales
Roles de seguridad Personalizador del sistema
Más información: Roles de seguridad predefinidos para Sales

Nota

El objeto de contexto de previsión al que se hace referencia en este tema es diferente del contexto de ejecución de Microsoft Dataverse. El objeto de contexto de pronóstico es específico para el pronóstico y admite las configuraciones avanzadas para los registros subyacentes cuadrícula.

Eventos para la cuadrícula de registros subyacente

Se admiten los siguientes eventos en previsión:

Los siguientes escenarios de muestra se crean en función de los controladores de eventos admitidos:

Evento OnRowLoad

El evento OnRowLoad se activa para cada registro subyacente cargado en la cuadrícula. El objeto de contexto que se pasa al controlador de eventos OnRowLoad contiene API que son específicas del registro subyacente.

Los siguientes son los escenarios de muestra que puede realizar utilizando el controlador OnRowLoad:

Nota

Para configurar el pronóstico, los registros subyacentes de diferentes entidades se visualizan seleccionando el atributo Groupby en los registros subyacentes cuadrícula. Para manejar la lógica basada en estas entidades, consulte los ejemplos Siempre habilite solo algunos campos según la entidad y Deshabilitar la edición de campos según la lógica y la entidad.

Evento OnChange

El evento se activa cuando se actualiza el valor de una celda en los registros subyacentes cuadrícula y la celda queda fuera de foco. OnChange

Nota

  • Para los registros subyacentes cuadrícula, cualquier cambio de campo afectará a los controladores de eventos Gatillo OnChange y OnSave , si existen.
  • El guardado no se activará si un campo se configura con notificaciones de error mediante el uso de la API del cliente en el controlador OnChange. Para notificaciones relacionadas con las API de previsión del cliente, vaya a la API setNotification en context.getFormContext().data.entity.attributes.getByName("Nombre del atributo").controls.get(0).
  • No hay asignación entre atributos para el controlador OnChange, y cualquier cambio de campo activará el controlador OnChange con el parámetro de objeto de contexto. Para identificar el atributo que activó el controlador, utilice la función getIsDirty en el objeto de atributo. Más información: context.getFormContext().data.entity.attributes.getByName("Nombre del atributo")

El siguiente es un escenario de ejemplo que puede realizar utilizando el controlador OnChange:

Evento OnSave

El evento se activa cuando se cambia un valor en una celda de los registros subyacentes cuadrícula y la celda está fuera de foco. OnSave Sin embargo, si el controlador OnChange existe para la misma configuración de previsión, el controlador OnSave se invoca después del controlador OnChange.

El controlador OnSave se invoca antes de guardar el campo.

Nota

El siguiente es un escenario de ejemplo que puede realizar utilizando el controlador OnSave:

Objeto de contexto para controladores de eventos en los registros subyacentes cuadrícula

El objeto de contexto contiene un conjunto de API para realizar operaciones específicas a un registro subyacente en una previsión. Este objeto de contexto se pasa como parámetro a los controladores de eventos en la vista de registros subyacentes cuadrícula.

Se admiten las siguientes API:

Método context.getFormContext

Devuelve una referencia a un registro en los registros subyacentes cuadrícula.

context.getFormContext().data.entity

Esto devuelve un objeto de entidad y tiene los siguientes métodos:

método Tipo devuelto Descripción
getEntityName() String Devuelve una cadena que representa el nombre lógico de la entidad para el registro.
getId() String Devuelve una cadena que representa el valor de GUID del registro.
attributes List Devuelve una lista de atributos relacionados con la vista y una entidad que se carga como parte de los registros subyacentes cuadrícula. Puede realizar las siguientes operaciones:
- context.getFormContext().data.entity.attributes.forEach
- context.getFormContext().data.entity.attributes.getByName(arg)
- context.getFormContext().data.entity.attributes.get(index)

context.getFormContext().data.entity.attributes.getByName("Nombre del atributo")

Esto devuelve un objeto de atributo y tiene los siguientes métodos:

método Tipo devuelto Descripción
getName() String Devuelve una cadena que representa el nombre lógico del atributo.
getValue() -- Recupera el valor de los datos de un atributo.
getIsDirty() Booleana Devuelve un valor booleano que indica si hay cambios no guardados en el valor del atributo.
controls List Devuelve una lista de controles para cada objeto de atributo.
Nota : La longitud de la lista de objetos controls es siempre 1, y get(0) se puede utilizar directamente.

context.getFormContext().data.entity.attributes.getByName("Nombre del atributo").controls.get(0)

Esto devuelve una asignación de objeto de control al atributo y tiene los siguientes métodos:

método Tipo devuelto Descripción
getDisabled() Booleana Devuelve si el control está deshabilitado.
setDisabled(bool) -- Establece el valor deshabilitado (verdadero o falso) al control.
setNotification(message: string, uniqueId?: string) Booleana Muestra un mensaje de error para el control para indicar que los datos no son válidos. Cuando se usa este método, aparece un icono de cruz rojo junto al control dentro de la celda. Al pasar el cursor sobre el icono de error, se mostrará el mensaje proporcionado. Al seleccionar el icono de error, se volverá a cargar la fila y se desharán los cambios. uniqueId se usa para borrar este mensaje cuando se usa el método clearNotification.
clearNotification(uniqueId?: string) Booleana Elimina un mensaje que ya se muestra para un control. Si no se proporciona una identificación única, se eliminan todas las notificaciones para ese control.

Nota

Recomendamos que los nombres de las funciones en el archivo JavaScript deben coincidir con los nombres de eventos y deben aceptar el parámetro del objeto de contexto.

Ejemplo 1:

Creemos un código JavaScript para hacer que todos los campos en los registros subyacentes cuadrícula sean DE SOLO LECTURA. Además, llamaremos a la función OnRowLoad para cada fila cuando la cuadrícula se carga y se guarda correctamente.

function OnRowLoad(executionContext) {
    // Iterating through all attributes and disabling it.
    executionContext.getFormContext().data.entity.attributes.forEach(
        attribute => {
            attribute.controls.get(0).setDisabled(true);
        }
    )
}

Ejemplo 2:

Vamos crear un código JavaScript para deshabilitar todos los campos excepto algunos para solo la entidad Oportunidad. Además, llamaremos a la función OnRowLoad para cada fila cuando la cuadrícula se carga y se guarda correctamente.

function OnRowLoad(executionContext) {

    // Get the logical name of the loaded entity as part of underlying records grid.
    var entityName = executionContext.getFormContext().data.entity.getEntityName();

    if (entityName === "opportunity") {

        // Defining the attributes list from opportunity that has to be enabled if loaded as part of view.
        var OPTY_ENABLE_ATTRS_LIST = ["name", "msdyn_forecastcategory", "actualvalue", "actualclosedate", "estimatedvalue", "estimatedclosedate"];

        executionContext.getFormContext().data.entity.attributes.forEach(
            attribute => {
                // Disabling all attributes other than OPTY_ENABLE_ATTRS_LIST
                if (!OPTY_ENABLE_ATTRS_LIST.includes(attribute.getName())) {
                    attribute.controls.get(0).setDisabled(true);
                }
            }
        )        
    }
}

Ejemplo 3:

Vamos a crear un código JavaScript para manejar diferentes entidades para la configuración de previsión cargada.

Para una entidad de Oportunidad, el script deshabilitará lo siguiente:

  • Columna nombre
  • actualRevenue y actualCloseData si el valor forecastCategory es el mejor caso, enviado, enviado o en canalización.
  • estimatedRevenue y estimatedCloseDate si el valor forecastCategory se gana o se pierde.

De manera similar, el script deshabilitará la columna de nombre para la entidad Cuenta y deshabilitará todas las columnas para otras entidades.

Además, llamaremos a la función OnRowLoad para cada fila cuando la cuadrícula se carga y se guarda correctamente.


function OnRowLoad(executionContext) {
		 
    // Get the logical name of the loaded entity as part of underlying records grid.
    var entityName = executionContext.getFormContext().data.entity.getEntityName();
    
    // If loaded logical name of entity in underlying records grid is opportunity.
    if (entityName === "opportunity") {
        
       var allAttrs = executionContext.getFormContext().data.entity.attributes;

       // Disable column name for all records if exists in the view.
       var nameAttr = allAttrs.getByName("name");
       if (nameAttr) {
           nameAttr.controls.get(0).setDisabled(true);
       }

       var fcatAttr = allAttrs.getByName("msdyn_forecastcategory");
       if (fcatAttr) {
           // Disable actualRevenue, actualCloseDate for forecastcategory Bestcase, committed, omitted, or pipeline.
           if (fcatAttr.getValue() <= 100000004 && fcatAttr.getValue() >= 100000001) {
                   var actualRevenueAttr = allAttrs.getByName("actualvalue");
                   var actualCloseDateAttr = allAttrs.getByName("actualclosedate");
                   if (actualRevenueAttr) actualRevenueAttr.controls.get(0).setDisabled(true);
                   if (actualCloseDateAttr) actualCloseDateAttr.controls.get(0).setDisabled(true);
           }
           // Disable estimatedRevenue, estimatedCloseDate for forecastCategory won or lost.
           else if (fcatAttr.getValue() == 100000005 || fcatAttr.getValue() == 100000006) {
                   var estimatedRevenueAttr = allAttrs.getByName("estimatedvalue");
                   var estimatedCloseDateAttr = allAttrs.getByName("estimatedclosedate");
                   if (estimatedRevenueAttr) estimatedRevenueAttr.controls.get(0).setDisabled(true);
                   if (estimatedCloseDateAttr) estimatedCloseDateAttr.controls.get(0).setDisabled(true);
           }
       }
   } 
   
   // Else disable name column, if loaded logical name of entity is Account.
   else if (entityName === "account"){
       var attrNameObj = executionContext.getFormContext().data.entity.attributes.getByName("name");
       if (attrNameObj) {
               attrNameObj.controls.get(0).setDisabled(true);
       }
   } 
   
   // For all other entities
   else {
       executionContext.getFormContext().data.entity.attributes.forEach(
           attribute => {
               attribute.controls.get(0).setDisabled(true);
           }
       )
   }
}

Ejemplo 4:

Vamos a crear un archivo JavaScript de validación que bloqueará el guardado y mostrará una notificación de error en la columna de ingresos estimados cuando el valor sea inferior a 10. Además, eliminaremos la notificación de error y permitiremos guardar cuando el valor de la columna de ingresos estimados se corrija para que sea mayor o igual a 10. Aquí, la función OnChange se invoca cuando se actualiza el valor de cualquier campo en los registros subyacentes cuadrícula de un pronóstico.


// OnChange function is invoked when any field's value is updated on the underlying records grid of the forecast
function OnChange(executionContext) {

    let entity = executionContext.getFormContext().data.entity;

    // Verify the logical name of the entity and load as part of the underlying records grid.
    if (entity.getEntityName() === "opportunity") {

        // Verify estimated revenue value
        let estValAttr = entity.attributes.get("estimatedvalue");

        // Verify if this attribute exists within the grid view and changed
        if(estValAttr && estValAttr.getIsDirty()) 
        {
            if(estValAttr.getValue() < 10){

                // This will show an error icon next to the estimated revenue field. On hovering over the icon, the below provided message is displayed.
                // Any save attempts are blocked by the system until all notifications are cleared from the columns.
                estValAttr.controls.get(0).setNotification("Estimated revenue cannot be less than 10");
            }
            else{
                // Clearing notifications to save.
                estValAttr.controls.get(0).clearNotification();
            }
        }
    }
}

context.getWebApiContext()

Esto devuelve un objeto webApiContext y tiene los siguientes métodos:

método Descripción
retrieveRecord(entityLogicalName, id, options)
then (successCallback, errorCallback);
Recupera un registro de entidad. Más información: retrieveRecord (referencia de API de cliente)
updateRecord(entityLogicalName, id, data)
then(successCallback, errorCallback);
Actualiza un registro de entidad. Más información: updateRecord (referencia de la API del cliente)
createRecord(entityLogicalName, data)
then(successCallback, errorCallback);
Crea un registro de entidad. Más información: createRecord (referencia de la API del cliente)
deleteRecord(entityLogicalName, id)
then(successCallback, errorCallback);
Elimina un registro de entidad. Más información: deleteRecord (referencia de la API del cliente)

context.getEventArgs().preventDefault()

El método preventDefault() está disponible solo dentro del evento OnSave. Llamar a este método dentro de OnSave evita que se lleve a cabo el evento de guardado.

Ejemplo:

Vamos a crear JavaScript de muestra para abrir la cuadrícula de oportunidades, bloquear el evento de guardado automático y abrir una ventana de alerta si el valor de ingresos estimado es inferior a 10. Además, permitiremos el evento de guardado automático si el valor de ingresos estimado es mayor o igual a 10.

// OnSave function will be invoked whenever grid attempts to save changes made to any field. 
function OnSave(executionContext){

    let entity = executionContext.getFormContext().data.entity;

    // Verify the logical name of the entity and load as part of the underlying records grid.
    if (entity.getEntityName() === "opportunity") {

        // Verify estimated revenue value
        var estValAttr = entity.attributes.get("estimatedvalue");

        if(estValAttr && estValAttr.getIsDirty() && estValAttr.getValue() < 10){

            // This call will prevent the save event from proceeding
            executionContext.getEventArgs().preventDefault(); 
            alert("Estimated revenue cannot be less than 10");

        }
    }
}

Personalizar registros subyacentes cuadrícula