ene 8

Búsquedas en 3 plano

Escribo este artículo, para aclarar aún más, si es que se puede, lo que ha descrito bastante bien nuestro amigo Fran Varona en este hilo del foro: Cargar lista Vs. Búsqueda

Una discusión que ha dado muchos quebraderos de cabeza y que por fin se desvela.

Para cada tabla, tenemos una búsqueda, en la que aprovechamos para usar varios indices y así, no tener que definir múltiples búsquedas:

Y en esa búsqueda hemos definido unas variables y unos componentes de búsqueda, para realizar búsquedas complejas.

Si os habéis fijado bien en vBase, veréis que en cada una de las opciones del menú, tenemos un formulario con un alternador, y desde un manejador de evento BUS, se llama a la búsqueda mediante el manejador de objetos:

En el evento, creamos un Manejador de objetos para llamar a la búsqueda y le pasamos los valores a las variables locales, antes de Disparar el objeto. Así, la búsqueda retorna una lista de registros con aquellos que cumplen las condiciones establecidas por las variables.

Tal y como se indica en el foro, las búsquedas siempre se ejecutan en 3º plano, pero esta afirmación solo es válida en aquellos casos en que las búsqueda se realiza por un solo índice, ya que cuando intervienen varios índices para obtener un resultado, las operaciones de Añadir, Cruzar y Quitar se realizan en 1º plano. Esto significa que el rendimiento baja considerablemente en la medida en la que aumenta el número de registros de la tabla en cuestión.

La solución a este problema, es sencilla, crear un proceso para llamar a la búsqueda:

El proceso debe cumplir unas reglas básicas:

  1. El proceso, como destino, debe ser de tipo Lista y para la misma tabla que la búsqueda a ejecutar.
  2. Tener las mismas variables definidas que la búsqueda a ejecutar, y para mayor sencillez, llamamos a las variables exactamente igual que en la búsqueda, de echo, podemos copiarlas.
  3. Creamos un manejador de objetos para llamar a la búsqueda, le pasamos todas las variables, y al finalizar retornamos la lista a la salida.

Ahora ya solo tenemos que crear el manejador de evento en el formulario principal, para llamar al proceso en 3º plano (en vez de a la búsqueda), asegurándonos así, de que esta vez si, la búsqueda se ejecutará en 3º plano y las operaciones de Añadir, Cruzar y Quitar, también.

Pero en este mismo hilo del foro se extiende la pregunta sobre la optimización de este tema, cuando además debemos usar búsquedas con formulario, pero este tema, lo dejare como ejercicio para otra ocasión, aunque la idea ya esta en el aire.

¿Tengo que repetirlo?

Pues vale, lo repito:

Antes de ejecutar el manejador de objetos que dispara el proceso en 3º plano, debemos pedir el formulario para introducir los valores por el usuario, y luego, pasar esos valores al proceso.

PDF Printer    Enviar artculo en formato PDF   
comments: 1 »
sep 5

¿Función o proceso?

En Velneo V7, como en la mayoría de los lenguajes y herramientas de programación, hay problemas que podemos resolverlos de distintas formas y obtener el mismo resultado.

La diferencia no esta en el resultado en si, que de un modo u otro será el mismo, la verdadera diferencia está en usar el método óptimo para llegar a ese resultado.

Y es aqui, donde se nos plantea la siguiente duda, en multitud de ocasiones, para solucionar un problema, podemos usar una “Función” o un “Proceso”.

A fin de cuentas, una “Función” es muy similar a un “Proceso” en muchos aspectos, aunque también tienen algunas diferencias

La función:

  • Permite hasta 10 parámetros de entrada, aunque esa barrera ya la habiamos superado cuando se publicó este articulo: Parámetros en funciones de V7
  • Tiene un parámetro de salida, aunque también habiamos solucionado este problema encadenando los valores (en el mismo artículo).
  • La función no tiene una tabla de origen, y tampoco destino.

El proceso:

  • Podemos usar tantos parámetros como necesitemos, eso si, usando el manejador de objetos para poder pasar y recibir parámetros.
  • Podemos obtener varios valores de retorno.
  • No es necesario indicar todos los parámetros en la llamada, solo aquellos que sean realmente necesarios.
  • El proceso puede ser: sin origen, o con origen y destino en una misma tabla (de tipo ficha o lista) dependiendo de donde lo vayamos a llamar.

Veamos ahora un ejemplo real que podriamos usar para solucionar un problema común:

La función:

El proceso:

Como podemos observar, las dos imagenes representan lo mismo:

Pasamos como parámetros de entrada los campos #ALM (almacén) y #ART (artículo), y comprobamos si existe el registro en la tabla de “Stock”, y si no existe, lo creamos. Al finalizar retornamos el #ID del registro creado (esto no es necesario pero se ha incluido para ver el retorno de valores).

Ademas, la definición es practicamente igual:

  • Las mismas variables en el panel de subobjetos
  • Las mismas instrucciones en el editor central
  • Y el mismo origen, en el panel de propiedades, aunque en el caso del proceso, esto puede cambiar.

Hemos visto como se definen las funciones y los procesos, pero como sería la llamada para ejecutarlos, porque aqui es donde realmente se diferencian:

En el caso de la función, la llamada es asi:

Necesitamos una variable a la cual asignamos el resultado que retorna la función, y despues, llamamos a la función pasandole todos los parámetros que necesita.

En el caso del proceso, la llamada mediante el manejador de objetos es asi:

La llamada mediante el manejador de objetos es un poco más compleja, ya que hay que definir el objeto en el manejador, luego asignar los valores a las variables con SET, después, ejecutar el proceso y, en último lugar, recoger los valores retornados con GET.

A la vista de los ejemplos, podemos ver que el uso de uno u otro método es aconsejable en los siguientes casos:

  • La función es obligatoria cuando necesitemos hacer uso de ella desde un contenido inicial.
  • El proceso es recomendable cuando necesitemos muchos parámetros o vayamos a retornar varios valores.
  • El proceso es obligatorio si queremos ejecutar en 3º plano.
  • El proceso es recomendable cuando los parámetros de entrada no sean obligatorios

Gracias por la visita y hasta pronto.

PDF Download    Enviar artculo en formato PDF   
comments: 6 »
jun 19

Oferta en funciones: 3 x 1

Estamos de oferta señoras y señores, …

vamos, que me las quitan de las manos, …

Ya solo me quedan 3, lleveselas y pague solo una.

Antes de comprar una oferta, deberiamos saber los que compramos, ¿no?

¿Qué es una función?

En la programación tradicional, en los lenguajes de 3 generación, una función es una porción de código que se separa del resto con el fin de abstraer la programación y evitar usar el mismo código de forma repetitiva. Es decir, si tengo que usar el mismo código en diferentes partes de una aplicación, creamos una función y llamamos a esa función cada vez que la necesitemos.

En Velneo V7, como en el resto de herramientas, tenemos 2 tipos de funciones:

  1. Funciones predefinidas, que son las que incluye la propia herramienta para las tareas más básicas:
    • round()
    • len()
    • choose()
    • currentDate()
    • etc…
  2. Funciones definidas por el usuario, que son aquellas que podemos definir nosotros mediante porciones de código o comandos de instrucción (igual que el usado en los procesos)
    • FUN_USER(param1,param2)

Y en este artículo nos centraremos en las funciones definidas por el usuario y debemos tener claras algunas consideraciones:

  • Las funciones hacen uso de los parámetros y podemos definir funciones que tengan hasta un máximo de 10 parámetros, aunque también podemos definir funciones que no necesitan ningún parámetro
  • El código de una función es el mismo que el usado en los procesos, y en algunos casos, seremos nosotros mismos, los que tengamos que decidir si realizamos una determinada tarea mediante una función o un proceso, ¿qué es mejor?
  • La función retorna un único valor, como resultado de ejecutar el código de la misma.

Ahora que ya hemos aclarado para que sirve una función y como debemos usarla, vamos a plantear el problema, o mejor dicho, los problemas que se nos presentan:

  1. Resulta que, con la salida de la versión 7.10 de Velneo V7, y la posibilidad de crear fórmulas y procesos JavaScript, he caido en la cuenta de que me falta algo, ¿dónde estan las funciones JavaScript?, tenemos fórmulas, tenemos procesos, pero no tenemos funciones.
    • El caso, es que despues de comentarlo con soporte, y de llegar a la conclusión de que no hay una solución clara a este problema que parece ser bastante complejo, y no tendrá solución viable a corto plazo, se me ocurre la siguiente solución, en la que afortunadamente, coindidimos con la respuesta de soporte:
    • No podemos crear funciones en JavaScript, pero hay que ser positivo y ver lo que si podemos hacer. Podemos crear un proceso JavaScript y llamar al proceso desde una función. No es la solución ideal, pero ¡es una solución!.
  2. Luego, de esta pequeña charla, cai en la cuenta de que podiamos llevar esta solución un poco mas alla, y de paso, solucionar el 2º problema. ¡No podemos ejecutar funciones en 3º plano!
    • ¿Cómo que no?, si ya hemos visto, que podemos llamar al proceso desde una función, esta misma solución nos vale para ejecutar las funciones en 3º plano. Para esto, solo hay que crear la función, y del mismo modo, llamamos a un proceso mediante el Manejador de objetos y disparamos el proceso en 3º plano. ¡Otro problema solucionado!
  3. Pero no acaba ahi la cosa, ya que uno de los problemas principales, para el cual se requeria el uso de funciones JavaScript, era poder usarlas desde contenidos iniciales en las fómulas de los campos.
    • Asi que, despues de lo dicho anteriormente, ya deberiais saber la solución. ¡Si!, crear una función que llame a un proceso en V7 o JavaScript, eso ahora da igual. Lo que importa es que con esta solución, en realidad, lo que hacemos es conseguir ejecutar procesos en los contenidos iniciales, que por definición, tampoco es posible. Te lo repito: “Si necesitas ejecutar un proceso desde un contenido inicial, ¡ya es posible!”

De esta forma, y con una única solución, estamos resolviendo 3 problemas que se nos pueden presentar con frecuencia.

Si necesitas ayuda para cualquier proyecto, seguro que podremos llegar a algún acuerdo. Aqui estan mis datos de contacto:

http://www.ascsl.com/about/

PDF    Enviar artculo en formato PDF   
comments: 2 »
jun 13

¡Estreno! próximamente …

Estamos de oferta señoras y señores, …

vamos, que me las quitan de las manos, …

sólo me quedan 3,

lleveselas y pague solo una.

¡¡¡tatatachan!!!

PDF Creator    Enviar artculo en formato PDF   
comments: Comentarios desactivados en ¡Estreno! próximamente …
oct 10

¡Las variables globales son prescindibles?

¿Pregunta? o ¡Afirmación!, he ahí la cuestión …

Asi es, otra de tantas decisiones que hay que tomar, y que YO mismo, como muchos otros, sobre todo de los que aprendimos con versiones anteriores de Velneo, hemos usado (y abusado) de ellas.

V7 es otra cosa, y a veces, nos empeñamos en decir que algo no funciona cuando en realidad somos nosotros los que hacemos un mal uso, o uso incorrecto de los elementos que tenemos a nuestar disposición, y uno de ellos es la Variable global.

Y ya puestos, el título del post incita a cuestionar si el uso de las Variables globales es recomendable o no. Y cada uno tendrá su propia respuesta y estara en la certeza de que sus aplicaciones son las mejores que hay y que todo lo que hace lo hace bien, igual que yo, por supuesto. No estaba criticando a nadie, yo me incluyo en ese paquete.

Pero es bueno reconocer cuando uno se equivoca, porque ello nos permite mejorar y poner los medios para evitar esa y otras equivocaciones similares en el futuro.

La respuesta a esa Pregunta/Afirmación es, por mi parte, una rotunda ¡AFIRMACIÓN!, que voy a escenificar con un sencillo ejemplo, que me temo, somos muchos los que hemos abusado de el (aunque solo puedo confirmar mi experiencia).

Tenemos una variable global “$BC_EJERCICIO@proyecto.dat” y como era costumbre adquirida, al cambiar a V7, esa costumbre paso a ser “un vicio”, y lejos de preguntarnos si era la forma correcta de hacerlo, la usamos y nos autoconvencimos de que debia ser asi.

Tenemos una Búsqueda de la tabla “Facturas”, que es, multiejercico, para este ejemplo, y en la búsqueda usamos un Índice por el campo #BC_EJERCICIO (Ejercicio) para mostrar unicamente las facturas del ejercicio actual.

A la búsqueda le incluimos un componente por el Índice “BC_EJERCICIO”, correposdiente al campo #BC_EJERCICIO, con resolución de la “Parte izquierda” y en el contenido, le indicamos directamente la Variable global: $BC_EJERCICIO@proyecto.dat


Y como realizamos el ejemplo:

Desde un proceso o evento, asignamos el valor a la variable global, lanzamos la búsqueda y retornamos la lista a la salida.

Hasta aqui todo es correcto, y el ejemplo debe funcionar bien.

Pero, …. ¿se puede mejorar el ejemplo?

Pues claro que se puede, piensa en ello y mañana tendremos la solución …

PDF Creator    Enviar artculo en formato PDF   
comments: 1 »
dic 20

Soluciones sencillas para optimizar el rendimiento.

Nuestro amigo sat.sbinario plantea el siguiente problema en el foro de V7

Preocupación con el rendimiento con número de registros elevado y optimización

en el que expone lo siguiente:

Hola a todos:

La situación es esta. Tabla con 40 campos (2 de ellos singular de plural por índice), unos 10 índices y 180000 registros.

He notado que el rendimiento de la aplicación cuando se trabaja con esta tabla decae notablemente. Por ejemplo, una rejilla que muestra todos los registros (resultado de una búsqueda), “se ve” en pantalla mientras la carga cómo va refrescando los datos, en especial los resueltos a través de los punteros singular de plural. Además cuando utilizas algún localizador asociado a la tabla, tienes tiempos de espera notables, que incluso provocan la rotura del vClient si no eres suficientemente paciente.

Esto nunca me había pasado en v6, así que lanzo varias preguntas.

¿Se debe a los punteros singular de plural? ¿A los componentes visuales? ¿Qué aspectos intervienen en estos tiempos de espera? ¿Optimización? ¿Alguna experiencia con número de registros elevados?

Un saludo y gracias.

Y despues de varias respuestas en el mismo hilo del foro se llega a la conclusion de que el problema esta en los “Punteros singular de plural”. Y la verdad, considero que es un problema muy puntual, para casos especiales.

Como ya sabeis, yo suelo protestar mucho donde otros no protestan, pero como me gusta llevar la contraria a todos, 😀 , donde los demas se quejan, yo busco soluciones,  asi que analicemos el planteamiento y veremos la solución:

Planteamiento:

  1. La tabla tiene “muchos campos”
  2. La tabla tiene varios “punteros singular de plural por indice”
  3. La tabla tiene 180000 registros, pero podria tener más.

Problema:

Ya hemos identificado que el problema son los “punteros singular de plural por indice”

Solución:

A la vista de estos parametros tenemos varias soluciones posibles:

  1. El problema son los “Punteros” pues una solución sencilla es “Quitar los punteros”, 😀 , creo que es la más fácil, la mas sencilla de implementar y la que mejor soluciona el problema. Ahhhhhhhhh, vale, ¡que no se puede hacer eso!, :( , pues vamos a buscar otra solución.
  2. En el foro se aporta una solución que también es valida, dejar los punteros en la tabla, pero quitarlos de la rejilla. Es una buena solución, pero que pasa si necesito mostrar columnas a través de los punteros y no puedo eliminarlos, esta solución tampoco es valida.
  3. Olvidemos el problema principal, que parecen ser los “Punteros” y centremonos en el resto de parámetros de la ecuación. Haber, para que necesito mostrar 180000 registros, acaso tengo que memorizarlos, :( , ¿necesito verlos todos? si falta uno, o faltan 1000 registros, ¿te vas a dar cuenta?. Pues ahi tienes la solución, prepara un paginador y muestra los registros de 100 en 100 o de 5000 en 5000 y veras como la velocidad aumenta considerablemente. Ademas, antes de mostrar cantidades indecentes de información, deberiamos pensar todos en el ahorro economico (si, economico), porque vamos a utilizar las aplicaciones con moviles, y las compañias van a cobrar por volumenes de transmisión de datos, y de esta forma, además, matamos 2 pajaros de un tiro (ahorramos dinero a nuestros clientes, beneficiandoles a ellos, y reducimos su factura de consumo telefónico, perjudicando al operador de telefonia).

Piensa en verde, porque ahorrar es sano, sobre todo para el bolsillo, … y en estos tiempos que corren, más.

Y ahora me direis algunos, … ¿y como se hace un paginador en V7? … vale, vale, lo preparo y otro dia os lo cuento. 😉

Create PDF    Enviar artculo en formato PDF   
comments: 5 »
dic 21

¿Que es la abstracción?

Posted in analisis, optimización

Vamos a analizar una de las piezas fundamentales de cualquier aplicación de gestión, las Entidades, y lo vamos a hacer mostrando varios diseños y observando los detalles en cada uno de ellos.

En el siguiente ejemplo, vemos una estructura básica de entidades, que cualquiera hemos creado en los inicios,

Esque tablas básicas sin abstracción

En esta estructura, vemos como tenemos 3 tablas para las entidades: clientes, proveedores y agentes comerciales.

  • La tabla de Agentes es maestra de clientes, de esta forma, un agente puede tener varios clientes en su cartera, pero cada cliente solo puede pertenecer a un agente, y solo a uno.
  • La tabla de Clientes tambien es maestra y a su vez, historica de agentes.
  • Y la tabla de Proveedores es maestra

Las 3 tablas tienen enlaces a Formas juridicas, Formas de pago y Divisas, asi un proveedor puede tener una Forma de pago asignada por defecto, una forma juridica y un tipo de moneda. Y esto mismo es aplicable a Clientes y también a Agentes.

Y bién, si tanto se parecen las tres tablas, que tienen los mismos enlaces a tablas maestras, ¿porque no creamos una tabla común llamada Entidades?

Si hay una respuesta afirmativa a ésta pregunta, eso es la “abstracción”, en definitiva, es sacar la esencia del esquema sin perder funcionalidad en el trayecto.

Y si analizamos lo dicho anteriormente,

Un cliente, es una persona fisica o juridica

Tiene un domicilio fiscal,

tiene una Forma de pago,

trabaja con una moneda determinada

Un proveedor, tambien es una persona fisica o jurídica

y también tiene un domicilio fiscal,

y tiene una Forma de pago,

y trabaja con una moneda determinada

Y un agente, pues lo mismo.

Si todos son tan parecidos en tantos aspectos, porque no crear una única tabla Entidades donde reunirlos a todos. ¡Pues SI, es posible! Y fijate si es posible, que aquí te dejo el esquema,

Esquema de tablas básicas con abstracción

Pero, ¿hay diferencias?

¡Pues claro que hay diferencias!, en la ficha del cliente acumulamos normalmente las ventas realizadas, y en el proveedor las compras, y en el agente el total de ventas y las comisiones

Y ¿como podemos solucionar esto?

Pues muy facilmente, solo tendremos que crear los campos apropiados en la tabla entidades, Total-Ventas, Total-Compras, Total-Comisiones.

Pero si una entidad es cliente, ¿para que queremos los campos de Total-Compras, y Total-Comisiones en su ficha?

Pues en este caso, esos campos no se utilizarian, y su contenido sería “0”.

Y si estan todos juntos, ¿como puedo mostrar únicamente los clientes? y que los proveedores y los agentes no se vean.

Pues aquí tenemos otro inconveniente, pero también tiene solución. Usaremos campos booleanos para definir si una entidad es cliente, es proveedor o es agente o también puede ser varias cosas a la vez, y tendremos que duplicar indices por codigo, nombre, etc. y quizá tengamos que duplicar mas cosas, pero no tenemos otra opción. Si queremos abstraer las tres tablas en una sola, la tabla resultante va ser mas compleja de manejar que las 3 tablas anteriores por separado.

Y es en este punto dónde debemos reflexionar sobre el tema, y valorar las ventajas de tener una tabla única, o tener 3 tablas separadas. Porque a medida que abstraemos cualquier ocpión del programa, se hace mas dificil de mantener.

Además, ya hemos dicho que hay muchos campos que serán comunes a todas las entidades, como, Nombre, Dirección, C.Postal, Poblacion, Telefonos, etc. pero tendremos muchos mas campos que solo serán utiles cuando la entidad sea cliente, y otros solo para proveedores y otros solo para agentes.

El problema no es el espacio que este archivo va a ocupar en el disco, pues ahora no hay problemas de capacidad. El problema puede estar en el tratamiento de esos datos a la hora de realizar cambios en la estructura de la tabla (simplemente tendremos que tener mas precaución), ya que cualquier cambio en Clientes, puede afectar también a proveedores y a agentes si no tenemos cuidado.

A todo esto debemos añadir que si los datos estan en tablas separadas, no se mezclaran los datos, pero si una empresa es cliente y proveedor al mismo tiempo, tendras que duplicar sus fichas. Pero te aseguras que no se van a mezclar datos y las tablas son mas sencillas.

Si acabas de iniciarte en la herramienta, demasiada abstracción quizá no sea buena idea.

Después de leer esto, tú eres el único que debes tomar ésta decisión,

¡Abstracción! O ¡sencillez!

Create PDF    Enviar artculo en formato PDF   
comments: 5 »