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:
- Haga una cuadrícula de solo lectura deshabilitando todos los campos.
- Habilitar siempre solo algunos campos según la entidad.
- Deshabilitar la edición de campos según la lógica y la entidad.
- Mostrar una notificación de error basada en el valor.
- Bloquee el guardado automático en función del valor estimado utilizando preventDefault y abra un evento de ventana.
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
:
- Haga una cuadrícula de solo lectura deshabilitando todos los campos.
- Habilitar siempre solo algunos campos según la entidad.
- Deshabilitar la edición de campos según la lógica y la entidad.
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
yOnSave
, 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 APIsetNotification
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 controladorOnChange
con el parámetro de objeto de contexto. Para identificar el atributo que activó el controlador, utilice la funcióngetIsDirty
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
- Para los registros subyacentes cuadrícula, cualquier cambio de campo afectará a los controladores de eventos Gatillo
OnChange
yOnSave
, 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
OnSave
. Para notificaciones relacionadas con las API de previsión del cliente, vaya a la APIsetNotification
en context.getFormContext().data.entity.attributes.getByName("Nombre del atributo").controls.get(0). - No hay asignación entre atributos para el controlador
OnSave
, y cualquier cambio de campo activará el controladorOnSave
con el parámetro de objeto de contexto. Para identificar el atributo que activó el controlador, utilice la funcióngetIsDirty
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 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.
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);
}
)
}
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
yactualCloseData
si el valorforecastCategory
es el mejor caso, enviado, enviado o en canalización. -
estimatedRevenue
yestimatedCloseDate
si el valorforecastCategory
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);
}
)
}
}
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.
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");
}
}
}