
La segunda parte de la trilogía de lenguaje y plataforma lsFusion. La primera parte se puede encontrar
aquí .
Se centrará en la lógica de las representaciones, es decir, en todo lo relacionado con la combinación de datos y mostrarlos al usuario u otros sistemas de información.
Está claro que muchos pueden no estar tan interesados en mirar la presentación del luchador, y les gustaría ver una pelea real, si es posible con sangre (y lo será, ya que la discusión de los artículos anteriores ayudó a comprender mejor los lugares desprotegidos de competidores potenciales y dónde vencerla) . Pero hay dos cosas a considerar:
a) este es Habr. Es decir, un recurso técnico, no les gustan las bellas imágenes y los lemas publicitarios aquí; para decir algo, necesita detalles sobre cómo va a lograr esto.
b) es un mercado para el desarrollo de sistemas de información, y es muy similar al mercado de productos para perder peso. Aquí, todos dicen que tenemos un rápido y fácil. Pero cuando se trata de detalles, en los que, como saben, el diablo miente, o los CRUD más simples se usan como ejemplos o recurren a varios trucos: muestran algunos fragmentos de código y ocultan la parte principal con las palabras "no importa". "," Hecho en un par de minutos "y todo eso.
En realidad, es por eso que teníamos dos opciones: comenzar con los beneficios y los riesgos de obtener reproches por mentiras de marketing, o comenzar con una descripción técnica y las preguntas "¿por qué necesitamos un idioma más?". Teóricamente, por supuesto, todo esto podría hacerse en un artículo, pero tal artículo sería difícil no solo de leer, sino incluso de desplazarse. En consecuencia, elegimos la segunda opción, aunque si todavía es importante que alguien conozca las razones de la apariencia y las ventajas del idioma en este momento (y no en futuros artículos), bienvenido al
sitio . Consta de solo tres páginas: qué, cómo y por qué no, y, en mi opinión, proporciona suficiente información para responder a todas estas preguntas. Además, también puede probar la plataforma en
línea allí , incluso para asegurarse de que no haya "piano en los arbustos", y el código de los ejemplos en este artículo es realmente todo el código necesario para ejecutar la aplicación.
Pero suficientes digresiones líricas, volvemos a la
presentación de la descripción del
luchador de la lógica de las representaciones.
Al igual que la lógica de dominio (primer artículo), todos los conceptos de lógica de presentación en lsFusion forman una pila:

y es en el orden de esta pila que hablaré sobre ellos.
Formas
Un formulario es el concepto más importante (y de hecho prácticamente el único) en la lógica de presentación, que es responsable de todo, tanto de la interacción del usuario como de la impresión, exportación e importación de datos.
El formulario se puede dividir lógicamente en dos partes:
- La estructura del formulario determina qué datos muestra el formulario.
- La presentación del formulario determina cómo muestra estos datos.
Estructura de la forma
Comenzamos, naturalmente, con la estructura de la forma.
Los objetos
Al crear un formulario, primero debe determinar qué objetos mostrará. Vale la pena señalar que puede haber una ligera confusión en la terminología entre los objetos del formulario y los objetos que se muestran en estos objetos de formulario. Por lo tanto, en el futuro, si esto no es obvio por el contexto, utilizaremos los términos "objetos de formulario" (para el primer caso) y "objetos en la base de datos" (para el segundo).
Para cada objeto de formulario, debe establecer su clase. Esta clase puede ser primitiva (incorporada) u objeto (personalizada).
De acuerdo con el orden de agregar objetos al formulario, se forma una lista ordenada de objetos. En consecuencia, el último objeto para un determinado conjunto de objetos se llamará un objeto de este conjunto con el número de serie máximo en esta lista (es decir, el más reciente).
Cada objeto en el formulario en un momento dado tiene un valor actual. Su cambio ocurre dependiendo de la presentación, ya sea como resultado de las acciones correspondientes del usuario en la presentación interactiva, o "virtualmente" en el proceso de lectura de datos en una representación estática.
Propiedades y acciones
Después de definir los objetos en el formulario, puede agregar propiedades y acciones, sustituyendo los objetos descritos anteriormente por ellos como entrada a los argumentos.
Tenga en cuenta que agregar acciones solo es relevante para la presentación interactiva; se ignoran en los informes y las exportaciones. Además, dado que el comportamiento de las propiedades y acciones desde el punto de vista de su visualización en el formulario es exactamente el mismo, en el futuro utilizaremos solo el término propiedad (para acciones, el comportamiento es exactamente el mismo).
Objeto de visualización
Cada propiedad se muestra exactamente en un objeto en el formulario (lo llamaremos el objeto de visualización de esta propiedad). Por defecto, el objeto de visualización es un objeto, este último para el conjunto de objetos que se pasan a la entrada de esta propiedad. Por ejemplo, si tenemos una forma de saldos actuales con dos objetos: un almacén y mercancías, y tres propiedades, nombres del almacén y mercancías y el saldo de mercancías en el almacén:
Luego, para el nombre del almacén, el objeto de visualización será s (almacén), y para el nombre de las mercancías y el saldo, i (mercancías).
Sin embargo, si es necesario, el desarrollador puede especificar el objeto de visualización explícitamente (es decir, en una vista interactiva, mostrar la propiedad con el resto en la tabla de almacenes, no productos).
Filtros y clasificación
Para cada formulario, el desarrollador puede establecer filtros y órdenes que limitarán la lista de objetos disponibles para ver / seleccionar en el formulario, así como el orden en que se muestran.
Para establecer un filtro, debe especificar una propiedad que se utilizará como criterio de filtro. El filtro se aplicará a la tabla de ese objeto, que es el último para el conjunto de objetos pasados a la entrada de esta propiedad (es decir, de manera similar a la definición del objeto de visualización de la propiedad). En este caso, solo se mostrarán aquellos conjuntos de objetos (series) para los que los valores de propiedad no son NULL. Por ejemplo, si agregamos el filtro currentBalance (s, i) OR isActive (i) al formulario anterior:
Captura de pantalla del formulario al mostrar productos, solo se mostrarán los productos que están en la balanza o marcados como activos.
Los tipos se definen como una lista de propiedades en el formulario en el que se deben mostrar los objetos de orden. De lo contrario, todo es similar a los filtros.
Grupos de objetos
La plataforma también tiene la capacidad de combinar objetos en un
grupo de objetos . En este caso, el "producto cartesiano" de estos objetos se mostrará en las tablas / listas (es decir, para dos objetos, todos pares, tres objetos, triples, etc.).
Captura de pantalla del formulario En consecuencia, en casi todas partes, tanto antes como después, en lugar de objetos individuales del formulario, puede usar grupos de objetos.
En realidad, esto es lo que se hizo en la documentación: el término más general "grupo de objetos" se usa en todas partes, pero para no complicar las cosas en este artículo (y los grupos de objetos que consisten en varios objetos se usan con mucha menos frecuencia), se decidió olvidar y contar sobre grupos de objetos, que un grupo de objetos siempre consiste exactamente en un objeto y, en consecuencia, use el término "objeto" en todas partes en lugar del más complejo "grupo de objetos" y "conjunto de objetos".
Grupos de propiedades
Las propiedades en el formulario, como los objetos, también se pueden combinar en grupos, que, a su vez, se utilizan en las representaciones interactivas (diseño predeterminado) y jerárquicas del formulario (un poco más adelante sobre ellas). De forma predeterminada, el enlace de una propiedad a un grupo es global (es decir, se establece para una propiedad para todos los formularios a la vez), sin embargo, si es necesario, para formularios individuales, este enlace se puede redefinir.
Objetos de columna
Por defecto, una propiedad se muestra exactamente una vez en su objeto de visualización. En este caso, como los valores de los objetos que no sean el objeto de visualización de esta propiedad (los llamamos superiores), se utilizan sus valores actuales. Sin embargo, la plataforma también tiene la capacidad de mostrar una propiedad varias veces para que los valores de algunos objetos superiores no sean utilizados por sus valores actuales, sino todos los objetos en la base de datos que sean adecuados para los filtros. Con este mapeo de propiedades, se forma una especie de "matriz" - (objeto de visualización) x (objetos superiores). Por consiguiente, para crear una matriz de este tipo, al agregar una propiedad al formulario, es necesario indicar qué objetos superiores se deben usar para crear columnas (llamaremos a estos objetos objetos en columnas).
Captura de pantalla del formulario Entonces, con lo que muestra el formulario, más o menos resuelto, pasemos a cómo puede hacer esto.
Envíos de formularios
Hay tres presentaciones de formularios:

Ver capturas de pantallaInteractivo:

Impreso:

Estructurado:

- Interactivo Una vista con la que el usuario puede interactuar es cambiar los datos y los objetos actuales activando varios eventos. En realidad, esta representación generalmente se llama forma.
- Impreso Por lo general, se denomina informe: cargar todos los datos del formulario y presentarlo en forma gráfica. Incluso con la posibilidad de imprimirlos (de donde obtuvo su nombre).
- Estructurado: representación del formulario en varios formatos estructurados (JSON, XML, DBF, etc.). Normalmente se usa para una mayor integración con otros sistemas.
Las representaciones interactivas e impresas son gráficas, es decir, muestran los datos recibidos en un espacio bidimensional: papel o la pantalla del dispositivo. En consecuencia, cada una de estas representaciones tiene un diseño que, dependiendo de la representación particular, se puede establecer utilizando los mecanismos apropiados (sobre ellos un poco más adelante).
La presentación impresa y estructurada es estática, es decir, leen todos los datos en el momento en que se abre el formulario (a diferencia del interactivo, que lee los datos según sea necesario).
La descripción de las actuaciones comenzará, quizás, con lo más difícil: la presentación interactiva.
Presentación interactiva
En una vista interactiva, los objetos de formulario se muestran en forma de tabla. Las filas en esta tabla corresponden a los objetos en la base de datos que satisfacen los filtros especificados, las columnas, a su vez, corresponden a las propiedades.
Sin embargo, si es necesario, la propiedad puede mostrarse no como una columna de tabla, es decir, para todas sus filas, sino como un campo separado en el formulario, es decir, solo para el valor actual del objeto de formulario. Por ejemplo:
Captura de pantalla del formulario El cambio del valor actual de un objeto de formulario se produce como resultado de que un usuario cambie la fila actual de la tabla o como resultado de una acción creada utilizando un operador de búsqueda especial (SEEK).
Tenga en cuenta que la forma en que se muestra una propiedad en un panel o tabla, como regla, no se establece para cada propiedad por separado, sino como un todo para un objeto de formulario. En consecuencia, si el objeto de formulario se marca como PANEL, todas sus propiedades se muestran en el panel (es decir, para el valor actual), de lo contrario (de forma predeterminada) todas sus propiedades se muestran en la tabla. Las propiedades sin parámetros y acciones predeterminadas se muestran en el panel.
Todas las tablas en la vista interactiva son dinámicas de manera predeterminada, es decir, solo se lee un número limitado de objetos en la base de datos y el resto se lee a medida que cambia el objeto actual en la tabla. El número de objetos mostrados en este caso puede determinarse automáticamente en función de la altura de la parte visible de la tabla, o el desarrollador puede establecerlo explícitamente al crear el formulario.
Además, el formulario en la presentación interactiva es completamente reactivo, es decir, actualiza automáticamente todos los datos en el formulario cuando cambia cualquier dato que los afecte (como Reaccionar, solo en el caso general). Además, todo esto no se realiza mediante un recálculo completo (como en el mismo React), sino de forma incremental, además, en el servidor SQL.
En general, es divertido cuando, al comparar con otras tecnologías, intentas incluir los tres requisitos principales en la tarea, las personas a menudo miran con ojos redondos, como si se les pidiera lanzar a una persona al espacio. Aunque el incumplimiento del segundo requisito por parte de cualquier usuario normal se clasificará como un error, y el primer y tercer requisito es que el formulario desarrollado funcionará normalmente cuando aparezca al menos una pequeña cantidad de datos en la base de datos (varias decenas de miles de registros, por ejemplo).
La presentación interactiva es compatible tanto en modo cliente web (es decir, aplicaciones web en un navegador) como en modo cliente de escritorio (aplicaciones Java). El cliente de escritorio, como cualquier cliente nativo, tiene una capacidad de respuesta ligeramente mejor de la interfaz, pero lo más importante, le permite trabajar con equipos y realizar otras operaciones que no están disponibles en el navegador (principalmente debido a problemas de seguridad).
Árboles de objetos
Además de las tablas, la plataforma también le permite organizar la visualización de objetos en forma de árboles, tanto planos ("anidados" en otras tablas) como recursivos (por ejemplo, objetos "anidados" en la base de datos).
Los árboles planos, de hecho, son una generalización de tablas, cuando varias tablas se "combinan" en una tabla a la vez:
Captura de pantalla del formulario Este es un mecanismo relativamente complejo y rara vez se usa en la práctica, por lo que no nos detendremos en detalle.
Pero los árboles recursivos, por el contrario, se usan con bastante frecuencia (por ejemplo, para implementar clasificadores). Para mostrar un objeto de formulario en la forma de dicho árbol, es necesario establecer un filtro adicional para él, una propiedad cuyo valor para los objetos inferiores debe ser igual al objeto superior. Inicialmente, el objeto superior se considera NULL.
Captura de pantalla del formulario Gestión de formularios de usuario
Para garantizar una mejor ergonomía del sistema (incluso no crear formularios para todos), los propios usuarios pueden realizar parte de las operaciones para configurar la presentación interactiva del formulario. Por ejemplo, tales operaciones son:
- configuración de tablas (columnas visibles, orden, fuentes, etc.),
- creando filtros y tipos personalizados,
- agrupando datos por valores de columna,
- imprima una tabla y cárguela en Excel.
Además, el desarrollador puede crear los llamados grupos de filtros, que el usuario puede activar / desactivar de forma independiente. Por ejemplo:
Estas no son todas las posibilidades para que el usuario personalice el sistema, pero volveremos a las otras posibilidades en el tercer artículo, ya que la mayoría de ellas aún no tienen una relación directa con la lógica de presentación.
Tenga en cuenta que la funcionalidad descrita anteriormente se refiere más probablemente a la funcionalidad de las plataformas ERP, que ya es completamente discordante con el título del artículo. Por otro lado, como se menciona en el primer artículo, en el futuro, el lenguaje / plataforma pretende reemplazar, incluida esta clase de plataformas, por lo que sería un error no mencionar estas características en absoluto.
Operadores de objetos
Uno de los escenarios más comunes de trabajar con un formulario es agregar / eliminar un objeto, así como editarlo en un nuevo formulario. Para implementar tales escenarios, la plataforma tiene un conjunto predefinido de operadores que le permiten crear las acciones necesarias en una palabra directamente en el operador de creación de formularios:
- NUEVO: crear un objeto
- EDITAR - editar un objeto
- NEWEDIT - crear y editar un objeto
- BORRAR - eliminar un objeto
Además, dado que a menudo es necesario realizar estas acciones en una nueva sesión (si necesita separar las acciones de creación de objetos de las acciones en la forma en que se crean estos objetos), la plataforma admite el azúcar sintáctico correspondiente: las opciones NEWSESSION y NESTEDSESSION, que funcionan de manera similar a los operadores del mismo nombre crear acciones, pero, al igual que los propios operadores que trabajan con objetos, no requieren que el desarrollador cree y nombre nuevas acciones. Por ejemplo:
Por defecto, al editar un objeto, se llama al formulario de edición, que se genera automáticamente para la clase del objeto de formulario pasado. Sin embargo, a menudo es necesario redefinir este formulario (por ejemplo, agregar información adicional, cambiar el diseño, etc.) Para hacer esto, es suficiente crear el formulario de edición necesario e indicar que es el formulario predeterminado para editar objetos de una clase dada:
Del mismo modo, las formas para seleccionar objetos de una clase dada se redefinen.
Diseño de la forma
Como con la mayoría de las GUI existentes, el diseño de una presentación interactiva de un formulario es una jerarquía cuyos nodos son componentes. Los componentes, a su vez, pueden ser:
- contenedores: componentes que contienen otros componentes.
- componentes básicos: representaciones gráficas de elementos básicos: tablas, paneles de propiedades, grupos de filtros, etc.
El mecanismo para organizar los componentes dentro de los contenedores esencialmente repite
el diseño de caja flexible CSS (y se implementa en el cliente web con él), por lo que no nos detendremos en este mecanismo con gran detalle.
Tenga en cuenta que el diseño del formulario generalmente no se crea desde cero (ya que es bastante laborioso). Por lo general, un diseño de formulario se crea automáticamente en función de la estructura del formulario, y luego el desarrollador solo lo modifica un poco: por ejemplo, agrega un nuevo contenedor y le transfiere los componentes existentes:
Ejemplo de diseño de formulario predeterminadoLa jerarquía de contenedores y componentes en el diseño predeterminado se verá así:

Captura de pantalla del formulario Diseño de formulario 2.0 (Reaccionar)
Si observa las representaciones interactivas de los formularios en las capturas de pantalla anteriores (o, por ejemplo, en una demostración en línea), puede ver que el diseño actual del formulario en la interfaz de usuario es, digamos, bastante ascético. Esto, por supuesto, nunca ha sido un problema particular para los sistemas de información, donde los principales usuarios son empleados o socios de la empresa propietaria de estos sistemas de información. Además, a pesar del ascetismo, el mecanismo de diseño de formularios actual le permite implementar casos muy difíciles, por ejemplo, POS:
Captura de pantalla del formulario Pero si se trata de, por ejemplo, SaaS B2B, o incluso B2C (por ejemplo, algunos servicios bancarios por Internet), entonces inmediatamente comienzan a aparecer preguntas sobre cómo hacer que el diseño sea más ergonómico.
En la etapa actual, para resolver este problema,
se ha desarrollado una
biblioteca javascript especial, cuya tarea principal es crear y actualizar un objeto js especial que contenga datos de formulario. En consecuencia, este objeto se puede usar como estado para el componente Reaccionar y, por lo tanto, crear cualquier diseño y cualquier interactividad adicional de la forma que se está desarrollando. Por ejemplo:
Reaccionar formulario de ejemplo (en codesandbox)O un ejemplo más complejo: con listas desplegables y utilizando la API REST (o más bien Sin estado) para esto:
Ejemplo de formulario de reacción con listas desplegables (en codesandbox)Es cierto que el problema con este enfoque es que los formularios de los ejemplos anteriores no se integrarán en la interfaz de la plataforma general ni en el flujo de control general de las acciones. Por lo tanto, una de las tareas más inmediatas en el desarrollo de la plataforma es la traducción del mecanismo de diseño de formularios al esquema utilizado en el diseño del informe (presentación impresa):
- La plataforma genera automáticamente un diseño de reacción basado en la estructura del formulario como en el ejemplo anterior.
- Si es necesario, el desarrollador puede guardarlo y editarlo como quiera. En consecuencia, la plataforma utilizará este diseño editado al abrir el formulario.
Además, este enfoque permitirá generar formularios React Native y, por lo tanto, permitirá crear aplicaciones móviles nativas. Aunque este problema (con aplicaciones móviles nativas) aún no hemos resuelto muy profundamente.
Es cierto que observamos que el antiguo mecanismo de diseño también será compatible, ya que, para las mismas aplicaciones comerciales, cumple perfectamente su función.
Eventos de formulario
Los eventos de formulario son el segundo mecanismo clave después de los eventos de dominio, que es responsable de determinar cuándo realizar acciones.
La plataforma tiene un conjunto completo de varios eventos de formulario que surgen como resultado de ciertas acciones del usuario, pero en este artículo consideraremos solo uno, el más utilizado: el evento CHANGE. Este evento ocurre cuando el usuario inició una llamada de acción / cambio de propiedad, por ejemplo, presionando cualquier tecla que no sea del sistema en el teclado, estando en el campo de la propiedad que se está cambiando o haciendo clic en este campo con el mouse.
En cuanto a los eventos del área temática, para los eventos del formulario, puede especificar el procesamiento, la acción que se realizará cuando ocurra el evento especificado. Tenga en cuenta que la mayoría de los eventos de formulario ya tienen un procesamiento predeterminado que implementa el comportamiento más esperado por el usuario (por ejemplo, con el evento CHANGE mencionado anteriormente, solicite la entrada del usuario y cambie la propiedad al valor ingresado). Sin embargo, en la práctica, a veces surgen situaciones cuando para algún evento de formulario es necesario especificar algún procesamiento específico, por ejemplo:
, – , ( , , , paste , ). . .
, , , , , , , , INPUT.
, , , , , , . Por ejemplo:
, , :
, INPUT – . (ASK):
(DIALOG) , , , , .
.
, . , , . , «» . , A B, A B, A A, B (A, B) B, A B ( «» ).
, , :
Por ejemplo:

, , , , .
LGPL – JasperReports.
, JasperReports , . , :
- «» ( , O1, O2, O3,… On, O2 – O1, O3 – O2 ..) ;
- , .
«» , SUBREPORT ( , -):

:
JasperReports (, lsFusion). , . , JasperSoft Studio.
, lsFusion- IDEA, Eclipse, ( Eclipse JasperReports ). IDEA , language injection, jrxml-, , , , , , . , , Eclipse GrammarKit autocomplete (, ), stub-, lazy chameleon- ( ), , . .
() :
- (XML, JSON) – , () -.
- (DBF, CSV, XLS) – - . parent, «» -.
, (- ), , , ( ). . , .
– XML, JSON. , , JSON ( XML ).
/ JSON , : JSON-, – , – . :
JSON/ , / :
, / :
JSON ::= { JSON , / } JSON , / ::= JSON 1 | JSON 1 | JSON 1 JSON 2 | JSON 2 | JSON 2 ... JSON M | JSON M | JSON M JSON ::= " " : JSON ::= " " : { JSON , / } JSON ::= " " : [ { JSON , / 1 }, { JSON , / 2 }, ... { JSON , / N }, ]
:
Resultado { "s": [ { "date": "21.02.19", "sd": [ { "money": { "item": " 3", "quantity": 1, "price": 5, "index": 1 } } ], "stock": " 2", "customer": " 2" }, { "date": "15.03.19", "sd": [ { "money": { "item": " 1", "quantity": 1, "price": 5, "index": 1 } }, { "money": { "item": " 2", "quantity": 1, "price": 10, "index": 2 } }, { "money": { "item": " 3", "quantity": 1, "price": 15, "index": 3 } }, { "money": { "item": " 4", "quantity": 1, "price": 20, "index": 4 } }, { "money": { "item": "Milk", "quantity": 1, "price": 50, "index": 5 } } ], "stock": " 1", "customer": " 3" }, { "date": "04.03.19", "sd": [ { "money": { "item": " 1", "quantity": 2, "price": 4, "index": 1 } }, { "money": { "item": " 2", "quantity": 3, "price": 4, "index": 2 } }, { "money": { "item": " 1", "quantity": 2, "price": 5, "index": 3 } } ], "stock": " 1", "customer": " 2" }, { "date": "04.03.19", "sd": [ { "money": { "item": " 1", "quantity": 3, "price": 1, "index": 1 } }, { "money": { "item": " 2", "quantity": 2, "price": 1, "index": 2 } } ], "stock": " 1", "customer": " 2" }, { "date": "14.03.19", "sd": [ { "money": { "item": " 2", "quantity": 1, "price": 2, "index": 1 } } ], "stock": " 1", "customer": " 2" }, { "date": "17.04.19", "sd": [ { "money": { "item": " 2", "quantity": 5, "price": 6, "index": 1 } }, { "money": { "item": " 1", "quantity": 2, "price": 6, "index": 2 } } ], "stock": " 1", "customer": " 1" }, { "date": "21.02.19", "sd": [ { "money": { "item": " 3", "quantity": 1, "price": 22, "index": 1 } } ], "stock": " 2", "customer": " 1" }, { "date": "21.02.19", "sd": [ { "money": { "item": " 3", "quantity": 1, "price": 22, "index": 1 } } ], "stock": " 2", "customer": " 1" }, { "date": "20.02.19", "sd": [ { "money": { "item": " 3", "quantity": 1, "price": 22, "index": 1 } } ], "stock": " 2", "customer": " 1" } ] }
, JSON JSON-. , , IDE JSON , – JSON. , ( , , JSON- ), . / JSON .
, :
, , , ( ). , , , / :
, SELECT SQL. , , , ( , ).
, , , – .
, , , :
– ( ) . .
(SHOW, DIALOG)
:
- (WAIT) – , , , , .
- (NOWAIT) – .
.
, :
- (FLOAT) – .
- (DOCKED) – System.forms.
, – .
, , (DIALOG). (, , ), , , .
, , (INPUT), ( ), , , ( ), , , ( ).
(PRINT)
( ) , JasperReports : DOC, DOCX, XLS, XLSX, PDF, HTML, RTF , JasperReports. , , , , ( , ).
, - (PREVIEW), , / . , , .
(EXPORT, IMPORT)
, , , : XML, JSON, DBF, CSV, XLS, XLSX. .
, , , – . () , () , .
– , , « », :
- .
- ( , , , , , TRUE f(a) = b – f(a) b)
TRUE ( , , 0 , .., , , ).
, , . , , , . . ( ), .
- , ( ). , , ( ). .
. , — .
– , . , , . , , .

.

100x100 . , , . , «» . , ( ). , . , .
. , - , , .
:
- , – , , .
- – forms, log, status, root, toolbar, tree, (, root, , )
, – , , , , , ERP-. , , « », : ? ? ? , -, lsFusion language-based ( SQL ABAP), library-based ( Java 1C) / . , , – domain-specific , . -, , , , . : , , , . , , , ( ).
. – , :
, :
- . «» : , , / . , , , , , , .
- . control flow . , – .
- SQL ( ORM). , , , .
Conclusión
, , (, , , , tutorial, , , ). , , ( ) «», , lsFusion.
, , – . , . , , « . .», , ( - ).
. : « ». , . , , lsFusion SQL-. , , , – , - , . , SQL- (
). , . , , ( , ), , , . «?», « ...?» «?».
UPD:
.