La interfaz de cada aplicación moderna de una forma u otra contiene listas de objetos. Al trabajar con ellos, el usuario a menudo necesita el mismo tipo de acciones como ordenar, filtrar, exportar, etc. La implementación de estas operaciones a menudo se complica por el hecho de que las listas pueden ser "dinámicas". En este caso, los datos se leerán según sea necesario no solo del servidor al cliente, sino también del servidor de la base de datos al servidor de aplicaciones.
En la plataforma
lsFusion abierta y gratuita
, todas las listas son dinámicas por defecto y se agregan a cualquier forma en unas pocas líneas de código. En este artículo, le contaré algunos detalles técnicos de su implementación, así como las características de la interfaz que se proporcionan automáticamente al usuario cuando trabaja con cualquier lista en cualquier forma.
Creación
Las listas en el formulario en lsFusion se agregan mediante la declaración
OBJETOS :
Se agregará una tabla al formulario, en la que todos los objetos de la clase
Item estarán contenidos en las filas. Puede agregar varios objetos a una sola lista. Por ejemplo
En este caso, la tabla mostrará todos los pares posibles de objetos de las clases
Artículo y
Stock .
Las columnas se agregan a la lista con la declaración de
PROPIEDADES :
En la tabla se pueden agregar como detalles simples del objeto, así como cualquier expresión con agrupaciones, particiones, recursiones, etc.
Por defecto, la lista mostrará todos los objetos en la base de datos. Para limitarlos, puede usar la
declaración FILTROS :
En la condición de filtro, puede usar cualquier expresión que dependa de cualquier objeto en el formulario.
La navegación
Cuando el usuario abre el formulario, la plataforma determina automáticamente el número de registros visibles según el tamaño de la tabla. Para simplificar la presentación, suponemos que hay 50 de esos registros. En cada momento, la plataforma almacenará 150 registros en el cliente y en el servidor. En este caso, el objeto activo actual debe estar en el medio de esta "ventana": del registro 50 al 99. Puede haber menos entradas si el objeto actual está al principio o al final de la lista.
Si necesita activar un registro específico cuando abre el formulario, se realizan dos solicitudes al servidor de la base de datos, cada una de las cuales lee 75 registros en cada lado del registro deseado. Luego se pega una lista general de sus resultados. En el caso de que necesite inicializar la lista desde el principio o el final, se realiza una solicitud de 100 registros y el primer o el último registro recibido se activa. Lo mismo sucede si el usuario presiona CTRL + INICIO o CTRL + FIN en la lista para ir al principio o al final de la lista.
Tan pronto como el usuario realiza una grabación activa fuera del centro de la ventana actual (antes del 50 o después del 99), la plataforma lee registros adicionales para que el registro actual esté en el "centro" de la nueva ventana.
La peculiaridad de una implementación de lista tan dinámica es que el objeto actual no puede estar fuera del centro de la ventana. Por lo tanto, al desplazarse por la lista, el objeto actual se mueve automáticamente al área visible.
La lectura de datos en una lista siempre ocurre en dos consultas. La primera consulta lee solo las claves de los registros necesarios en la tabla temporal. La segunda consulta lee los valores de todas las columnas para las claves ya leídas. Esto se hace porque las columnas pueden contener expresiones que se pueden compilar en subconsultas u otras construcciones SQL complejas. En este caso, la plataforma en sí empuja estas claves a subconsultas para que el cálculo de los valores de estas columnas no pase por toda la base de datos, sino solo de acuerdo con las claves necesarias. Esto crea una ligera sobrecarga, ya que se realizan dos consultas en lugar de una, pero protege contra el "ingreso" accidental en un plan de servidor de base de datos ineficiente.
Filtrado
Las entradas en la lista del formulario se pueden filtrar según las siguientes opciones:
- Indicación en el código de selección continua utilizando la instrucción FILTERS:La expresión puede depender de cualquier otro objeto actualmente seleccionado en el formulario. Por ejemplo, si hay una tabla o un árbol con un almacén en el formulario, en la expresión de la lista de productos puede consultar el almacén actual para filtrar solo los productos que están en la balanza.
- Indicación en el código de selección, que el usuario puede aplicar según sea necesario utilizando la instrucción FILTERGROUP :
Se agregará una lista desplegable al formulario (o una casilla de verificación si hay un filtro en el grupo), con el cual el usuario puede seleccionar uno de los filtros que necesita aplicar.

- Filtrado personalizado manual realizado por el usuario en la interfaz:

Si la columna de la lista no es editable, al ingresar caracteres, el filtro para esta columna se activará automáticamente, lo que se puede restablecer presionando la tecla ESC.
La plataforma misma monitorea los cambios en cualquier condición que pueda afectar el filtro actual (cambio de objetos dependientes, acciones del usuario, etc.). Cuando se detectan dichos cambios, la lista se actualiza automáticamente sin cambiar el objeto seleccionado actualmente. Para hacer esto, se realizan dos solicitudes, 75 entradas en cada dirección desde la actual, así como durante la inicialización del formulario.
Clasificación
Por defecto, las entradas en las listas están ordenadas en orden ascendente de los identificadores internos de los objetos. Estos identificadores se generan automáticamente en orden ascendente al crear objetos (al mismo tiempo, son globalmente únicos dentro de todas las clases), y los índices siempre se construyen sobre ellos.
La clasificación en la lista se puede cambiar de la siguiente manera:
- Al indicar en el código las columnas por las cuales se realiza la clasificación a través de la instrucción ORDER :
- Al hacer doble clic en el encabezado de la columna por el usuario (si mantiene presionada la tecla CTRL se agregará la clasificación "anidada").

Dependiendo de la clasificación actual, al leer las claves de registro, las expresiones de columna correspondientes se agregarán al bloque ORDER BY de la solicitud. Al mismo tiempo, el identificador único de los objetos siempre se agrega a la clasificación para garantizar que las claves de todos los registros sean únicas.
Una expresión de la forma: column1> value1 OR (column1 = value1 AND column2> value2) OR (column1 = value1 AND column2 = value2 AND key> value) se agregará a la cláusula WHERE de la solicitud. Además, al leer las claves, se agregará a la solicitud la instrucción LIMIT con el número requerido de registros legibles. Al leer los registros "arriba", el orden en ORDER BY y la expresión WHERE se "voltearán" en consecuencia para leer los registros en la dirección opuesta.
Cabe señalar que la complejidad de realizar estas consultas será relativamente pequeña si hay un índice apropiado (ya que el índice será el kilometraje comenzando desde la tecla actual hacia arriba o hacia abajo solo para un número dado de registros). Por lo tanto, para acelerar el trabajo con la lista dinámica al ordenar por columnas columna1, columna2, se recomienda crear el siguiente índice:
Si la clasificación se basa en la columna calculada, se puede almacenar permanentemente, como se describe en este
artículo , y luego se puede construir un índice sobre ella.
Una de las características de dicha implementación es la falta de una barra de desplazamiento "honesta". Al leer registros, solo se lee el número necesario de ellos. Una solicitud para obtener el número total de filas en la lista a través de COUNT (*) con el filtro deseado puede conducir a una ejecución completa en la tabla o índice, lo que afectará negativamente el rendimiento. El mismo problema ocurrirá al leer registros a través de la construcción OFFSET. Además, debe tenerse en cuenta que al navegar por una lista, el número de entradas en él puede ser modificado por otros usuarios haciendo nuevos cambios.
Edición
Sorprendentemente, en algunas plataformas comerciales incluso no pudieron darse cuenta de la capacidad de editar en listas dinámicas. La principal dificultad para implementar este mecanismo es que solo la ventana visible se almacena en el servidor y el cliente, y se pueden hacer cambios en toda la lista.
No hay un mecanismo específico en lsFusion que implemente la edición de listas directamente. Esta funcionalidad se implementa como parte del mecanismo de sesión general.
Todos los cambios realizados en la sesión de cambio actual se almacenan en tablas temporales. Cuando el usuario edita algo en el formulario (incluido el valor en una de las entradas), los nuevos valores se escriben en tablas temporales con las claves apropiadas. Luego, cuando la segunda consulta (después de recibir las claves) lee los valores de las columnas, la UNIÓN con las tablas temporales correspondientes con cambios simplemente se agrega a la consulta.
Al guardar la sesión de cambio, se ejecuta una consulta, que en una transacción escribe todos los valores de las tablas temporales en la base de datos.
Ajuste grupal
Muy a menudo, el usuario necesita cambiar el valor de la columna para todos los objetos seleccionados en la lista a la vez. Para hacer esto, hay un botón especial en la barra de herramientas de cada lista (con la tecla de acceso rápido F12). Cuando se presiona, se activa el modo de edición de celda normal, pero los cambios no se aplican al registro actual, sino a todos los seleccionados.
Este mecanismo le permite editar rápidamente una gran cantidad de objetos según los criterios especificados:
Además de durante la edición normal, los cambios no se guardan inmediatamente en la base de datos, sino que se registran en tablas temporales. Luego, el usuario deberá hacer clic en el botón
Guardar para escribirlos en la base de datos. La desventaja de este enfoque puede ser que el usuario cambia accidentalmente los datos adicionales. Pero aquí, como dicen, el principio funciona: "con gran poder viene una gran responsabilidad".
Resumen de la lista
En cualquier lista, el usuario tiene la oportunidad de averiguar el número de registros o la cantidad de una determinada columna en la selección actual. Para hacer esto, el usuario debe hacer clic en los botones apropiados en la barra de herramientas de una lista específica:
Para obtener estos datos, se generará automáticamente una solicitud con la expresión COUNT (*) o SUM, en la que se agregará la expresión de selección actual. Con esta función, puede obtener rápidamente totales de listas sin recurrir a generar informes.
En la versión de escritorio del cliente, también es posible calcular la suma de las celdas seleccionadas por analogía con Excel:
Copiar / Pegar
En la versión de escritorio, el usuario tiene la oportunidad de marcar ciertas celdas, presionar CTRL + C y pegar sus valores en el portapapeles:
Del mismo modo, puede pegar la tabla desde el portapapeles en cualquier lista editable en cualquier forma:
Tal oportunidad es a menudo una alternativa al desarrollo de importaciones especializadas.
Ajuste de la mesa
En cualquier lista, puede cambiar algunos de sus parámetros:
Puede cambiar la composición de las columnas, sus tamaños, encabezados, máscaras, etc. Puede guardar la configuración de la tabla tanto para el usuario actual como para todos los usuarios (si el usuario actual tiene los derechos necesarios).
Tenga en cuenta la opción Tamaño de página. Al usarlo, puede cambiar el tamaño de la "ventana" que se describe al principio del artículo. Por ejemplo, en lugar de 50 entradas automáticas, puede especificar un valor mayor. Luego, se descargará una mayor cantidad de datos al cliente y al servidor, pero las solicitudes se producirán con menos frecuencia. Establecer el valor de este parámetro en 0 lo hará normal desde cualquier lista dinámica, es decir, todas las entradas de la lista siempre se leerán. El tamaño de la ventana también se puede especificar directamente en el código utilizando el parámetro
pageSize de la instrucción
DESIGN .
Exportar a Excel
Para cualquier lista, es posible cargar todos sus registros en Excel. Para hacer esto, simplemente haga clic en el siguiente botón:
Esto tiene en cuenta las selecciones actuales, las clasificaciones, así como solo las columnas visibles especificadas en la configuración de la tabla.
Pivotante
Por defecto, cualquier lista se muestra como una tabla. Pero existe la posibilidad de cambiarlo a un modo de visualización especial en el que el usuario puede crear varios informes y diagramas:
Con un pequeño número de entradas en la lista, los datos se procesarán directamente en el cliente. Tan pronto como la cantidad de datos exceda un cierto umbral, las consultas de base de datos generadas automáticamente en el servidor se utilizarán para agrupar los datos.
Alternativa
Surge una pregunta razonable. Cómo resolver el problema de editar listas dinámicas en plataformas donde esta característica no es compatible. Muy a menudo, hacen una lista simple, obligando al usuario a limitar el número de entradas mediante algunas selecciones (por ejemplo, especificar filtros por categoría, proveedor u otros directorios relacionados).
Sin embargo, este enfoque tiene un problema grave. Incluso con las selecciones establecidas, no hay garantía de que no haya un número significativo de registros en la muestra. Es imposible calcular de antemano el número de valores obtenidos, ya que a menudo la complejidad de dicha operación es directamente comparable a la complejidad de obtener todos los datos. En consecuencia, en algunos casos se agregará una gran cantidad de entradas a la lista, lo que conducirá a un gran consumo de recursos en el servidor o cliente, así como a una disminución significativa en el rendimiento.
Conclusión
Implementar una lista dinámica en el desarrollo moderno no es la tarea más trivial, ya que tanto el cliente como el servidor están involucrados. Existen bastantes bibliotecas de código abierto con una licencia abierta en el mundo que le permiten implementar esta funcionalidad de manera rápida y conveniente.
En la plataforma lsFusion abierta y gratuita, las listas dinámicas se crean en varias líneas de código y brindan al usuario una gran cantidad de oportunidades para trabajar con ellas. En combinación con la capacidad de editar dichas listas, la plataforma le permite trabajar rápidamente con documentos en cientos de miles de líneas, organizar trabajos convenientes para
seleccionar registros en documentos, realizar cambios grupales en directorios y mucho más.
El uso de listas dinámicas puede reducir significativamente el consumo de tiempo de procesador y memoria en el servidor y el cliente al trabajar con un conjunto limitado de datos, así como reducir la carga en el canal de comunicación entre el servidor y el cliente. Debido a esta alta eficiencia, cinco de las ocho
cadenas minoristas más
grandes llevan a cabo sus principales actividades operativas en
soluciones basadas en la plataforma lsFusion en Bielorrusia.