Lógica y Eventos
FlowFilters
Dificultad: 7/10Un FlowFilter (Filtro de Flujo) es el "mejor amigo pero independiente" de un FlowField. El FlowFilter es un campo especial de tu tabla, pero es como un campo "fantasma": no guarda datos de verdad para almacenarlos permanentemente.
Ejemplo rápido
Un FlowFilter captura un rango de fechas y se lo pasa al FlowField para que filtre su cálculo:
// 1. El campo "fantasma" que atrapa la fecha del usuario
field(100; "Date Filter"; Date)
{
FieldClass = FlowFilter;
}
// 2. El FlowField que usa ese filtro en su fórmula
field(101; "Ventas Netas"; Decimal)
{
FieldClass = FlowField;
CalcFormula = sum("Sales Invoice Line".Amount
where ("Sell-to Customer No." = field("No."),
"Posting Date" = field("Date Filter"))); // FlowFilter inyectado aquí
}
¿Qué son?
Son campos de la tabla que sirven únicamente para recibir parámetros y filtros dinámicos desde la pantalla del usuario con el propósito de dárselos a un FlowField para que la fórmula cambie según la situación y "fluya" a través de él.
A diferencia de un campo normal que almacena valores en una base de datos, un FlowFilter es un campo transitorio cuya única función es capturar criterios de filtrado para inyectarlos en la lógica de cálculo de los FlowFields.
Naturaleza y comportamiento técnico
- No persistencia: Los valores que un usuario introduce en un FlowFilter no se guardan en el registro. Solo existen mientras dura la sesión o la vista actual.
- Uso estructural: Se definen en la tabla con
FieldClass = FlowFilter, lo que permite que aparezcan en la interfaz de usuario como filtros de página y sean accesibles desde código AL medianteSetRangeoSetFilter. - Puente de cálculo: Actúan como un "cable de conexión" entre la interfaz y el motor de cálculo. Permiten que una misma fórmula devuelva resultados distintos según el contexto de filtrado (por fecha, por almacén, por proyecto...).
¿Cómo modifican el resultado de un FlowField?
Imagina que tienes un FlowField que es "Deuda Total". Cuando entras a ver al Cliente, te
dice "Nos debe 5.000€". Bien, usando la directiva Sum(...) en AL.
Pero ¿qué pasa si el contable quiere saber: "¿Cuánto nos empezó a deber este mes específico (Enero)"?
Para esto, el programador diseña un FlowFilter de tipo fecha llamado "Date Filter". En
el código AL del FlowField "Deuda Total", le dice a la fórmula:
Sum(Facturas donde "Fecha Emisión" = mi FlowFilter).
Así, el usuario, al ver la ficha del cliente en pantalla, le pone un filtro de fecha (Enero 1..Enero 31). El FlowFilter "atrapa" ese rango, se lo pasa al FlowField, y en décimas de segundo la "Suma" que valía 5.000€ baja mágicamente a 800€, calculando únicamente los registros pertenecientes a enero.
Tipos y escenarios comunes
| Tipo de FlowFilter | Uso habitual |
|---|---|
| Date Filter (Periodo) | El más extendido. Permite análisis temporales sin duplicar datos. |
| Global Dimensions | Filtra resultados financieros por departamentos o centros de coste. |
| Location Filter | Filtra existencias de inventario por un almacén concreto. |
1. Definición en la tabla
El FlowFilter se declara como un campo más, pero con FieldClass = FlowFilter. No ocupa
espacio en SQL, es solo una "ventana" de filtrado:
field(100; "Date Filter"; Date)
{
FieldClass = FlowFilter;
Caption = 'Rango de Fecha de Análisis';
}
2. Inyección en la fórmula del FlowField
El FlowFilter solo cobra sentido cuando se menciona dentro de la propiedad where de un
FlowField. El FlowField de ventas usará el valor actual del "Date Filter":
field(101; "Ventas Netas"; Decimal)
{
FieldClass = FlowField;
CalcFormula = sum("Sales Invoice Line".Amount
where ("Sell-to Customer No." = field("No."),
"Posting Date" = field("Date Filter"))); // FlowFilter inyectado aquí
}
3. Aplicación desde código AL
Los FlowFilters también se pueden aplicar desde código usando SetRange, lo que permite
comparativas dinámicas. Los filtros se deben aplicar antes de llamar a
CalcFields:
procedure ComparativaVentas(CustomerNo: Code[20])
var
Cust : Record Customer;
VentasEnero : Decimal;
VentasFebrero: Decimal;
begin
Cust.Get(CustomerNo);
// Filtramos para Enero
Cust.SetRange("Date Filter", 20240101D, 20240131D);
Cust.CalcFields("Ventas Netas");
VentasEnero := Cust."Ventas Netas";
// Cambiamos el FlowFilter para Febrero
Cust.SetRange("Date Filter", 20240201D, 20240229D);
Cust.CalcFields("Ventas Netas");
VentasFebrero := Cust."Ventas Netas";
Message('Comparativa: Enero (%1) vs Febrero (%2)', VentasEnero, VentasFebrero);
end;
⚠️ Aviso importante
Los filtros con SetRange se deben poner antes de
CalcFields. Si los pones después, ya no tienen efecto porque BC ya ha calculado el
valor sin el filtro.
💡 Tips
- Un FlowFilter nunca almacena datos en la base de datos. Solo existe durante la sesión activa.
- Solo tiene sentido si está referenciado dentro de la cláusula
wherede al menos un FlowField. - Permiten que una misma fórmula devuelva resultados radicalmente distintos según el contexto de filtrado, sin duplicar campos ni tablas.
- El uso más habitual es el Date Filter para análisis por periodo: mes, trimestre, año fiscal...