Esta es la decimoquinta entrega de la serie sobre utilidades para Business Central. En esta ocasión presento un conjunto de funciones que permiten abrir un diálogo de selección de campos de cualquier tabla de forma completamente dinámica. Muy útil cuando desarrollas configuraciones avanzadas donde el usuario debe elegir qué campo de una tabla quiere usar.
¡Vamos manos a la obra! 🗂️
📋 Selector rápido de campos activos: SelectFieldEnable
procedure SelectFieldEnable(TableNo: Integer) ReturnValue: Integer
var
Fields: Record field;
begin
ReturnValue := this.SelectField(TableNo, '', '', Format(Fields.Class::Normal), true, false, '<>Removed');
end;
¿Qué hace?
Abre el diálogo de selección de campos para la tabla indicada, mostrando únicamente los campos activos, normales (no de clave primaria) y no obsoletos. Es la versión más simple y la que usarás en la mayoría de casos.
Devuelve el número del campo seleccionado, o 0 si el usuario cancela.
📋 Selector con filtro de tipo: SelectFieldEnable_FilterType
procedure SelectFieldEnable_FilterType(TableNo: Integer; FilterType: Text) ReturnValue: Integer
var
Fields: Record field;
begin
ReturnValue := this.SelectField(TableNo, FilterType, '', Format(Fields.Class::Normal), true, false, '<>Removed');
end;
¿Qué hace?
Igual que SelectFieldEnable pero permite filtrar por tipo de campo. Por ejemplo, puedes limitar la selección únicamente a campos de tipo Code, Integer o Decimal.
Ejemplo de uso:
var
Utils: Codeunit Utils;
FieldNo: Integer;
begin
// Solo muestra campos de tipo Code
FieldNo := Utils.SelectFieldEnable_FilterType(Database::Customer, 'Code');
end;
📋 Selector con filtro de número: SelectFieldEnable_FilterNo
procedure SelectFieldEnable_FilterNo(TableNo: Integer; FilterNo: Text) ReturnValue: Integer
var
Fields: Record field;
begin
ReturnValue := this.SelectField(TableNo, '', FilterNo, Format(Fields.Class::Normal), true, false, '<>Removed');
end;
¿Qué hace?
Permite filtrar por un rango de números de campo. Por ejemplo, mostrar solo campos entre el 1 y el 100, o excluir los campos de extensión con números altos.
⚙️ Selector completo y configurable: SelectField
procedure SelectField(TableNo: Integer; FilterType: Text; FilterNo: Text; FilterClass: Text; Enable: Boolean; IsPartOfPrimaryKey: Boolean; FilterObsoleteReason: Text) ReturnValue: Integer
var
Fields: Record field;
begin
Clear(ReturnValue);
if TableNo = 0 then
exit;
Fields.Reset();
Fields.SetRange(TableNo, TableNo);
Fields.SetRange(Enabled, Enable);
Fields.SetRange(IsPartOfPrimaryKey, IsPartOfPrimaryKey);
if FilterNo <> '' then
Fields.SetFilter("No.", FilterNo);
if FilterObsoleteReason <> '' then
Fields.SetFilter(ObsoleteReason, FilterObsoleteReason);
if FilterType <> '' then
Fields.SetFilter(Type, FilterType);
if FilterClass <> '' then
Fields.SetFilter(Class, FilterClass);
ReturnValue := this.SelectField(Fields);
end;
procedure SelectField(var Fields: Record Field) ReturnValue: Integer
var
FieldSelection: Codeunit "Field Selection";
begin
Clear(ReturnValue);
if FieldSelection.Open(Fields) then
ReturnValue := Fields."No.";
end;
¿Qué hace?
Esta es la función base que utilizan todas las anteriores. Acepta todos los filtros como parámetros y construye el Record Field filtrado antes de abrir el diálogo estándar Field Selection. También existe una sobrecarga que acepta directamente un Record Field ya filtrado externamente, dando el máximo control al desarrollador.
Parámetros de la versión completa:
TableNo: ID de la tabla sobre la que mostrar campos.FilterType: Filtro por tipo de campo (vacío = sin filtro).FilterNo: Filtro por número de campo (vacío = sin filtro).FilterClass: Filtro por clase del campo (Normal, FlowField, FlowFilter).Enable: Sitrue, solo muestra campos activos.IsPartOfPrimaryKey: Sifalse, excluye los campos de clave primaria.FilterObsoleteReason: Filtro sobre la razón de obsolescencia (p.ej.<>Removed).
💡 Aplicaciones prácticas
- Configuraciones avanzadas donde el usuario elige qué campo de una tabla usar como clave o filtro.
- Herramientas de mapeo dinámico (ej: mapear campos de una tabla externa a campos de BC).
- Asistentes de configuración donde el usuario define reglas sobre campos concretos.
- Desarrollo de extensiones genéricas que trabajan con cualquier tabla sin hardcodear campos.
Conclusión
En esta decimoquinta entrega de la serie Utils, muestro cómo abrir un diálogo de selección de campos de cualquier tabla de forma dinámica y configurable. Las funciones van desde la más sencilla (SelectFieldEnable) hasta la más parametrizable (SelectField completo), cubriendo la mayoría de escenarios que se presentan en desarrollos avanzados.
Para seguir todos los posts de esta serie, puedes encontrarlos bajo la etiqueta #UtilsBc.
Si quieres ver el código completo, está en GitHub.
¡Nos vemos en la próxima!