Documentación de Velneo
29
29
  • Introducción
  • Velneo
    • Requerimientos de Velneo
    • Notas de la versión
    • Funcionalidades comunes a los componentes de Velneo
      • Instalación
      • Conexión con Velneo vServer
      • Cambiar el estilo de visualización
      • Ver u ocultar barras de herramientas
      • Mensajería interna entre usuarios
      • Soporte de alta resolución (HighDPI)
      • Carpetas de trabajo de los componentes de Velneo
      • Numeración de versiones de Velneo
      • Certificado de firma digital para componentes de Windows
    • Tipos de archivo generados por Velneo
    • Velneo Web
      • Plataformas y navegadores compatibles
      • Acceso a recursos del sistema
      • Siempre https
      • Funcionamiento de vatp por websocket
      • CORS para llamadas xmlhttprequest
  • Velneo vDevelop
    • ¿Qué es Velneo vDevelop?
    • Interfaz de Velneo vDevelop
      • Menú Soluciones
      • Menú Proyectos
      • Menú Objetos
      • Menú Scripts
      • Menú Edición
      • Menú Ver
      • Menú Componentes
      • Menú Ayuda
    • Lista de teclas aceleradoras de Velneo vDevelop
    • Soluciones y proyectos
    • Control y edición de proyectos
    • Herencia
    • Inspectores
    • Proyectos objetos y editores
      • Proyecto de datos
      • Proyecto de aplicación
        • Crear CSS para aplicar a objetos en edición
      • Objeto
      • Objetos de proyecto de datos
        • Indice complejo
        • Tabla
          • Actualización
          • Campo
          • Enlace
          • Indice
          • Plural
          • Traspaso de campo
          • Trigger
        • Tabla estática
        • Variable
      • Objetos de proyecto de aplicación
        • Acción
        • Alternador de lista
        • Arbol visor de tablas
        • Bloc de formularios
        • Casillero
        • Cesta
        • ComboView
        • Control SVG
        • Dispositivo serie
        • Formulario
          • Controles de visualización
            • Texto estático
            • Nombre de campo
            • Visor HTML
            • Dibujo
            • Imagen SVG
            • Caja de grupo
            • Menú arbolado
            • Barra de progreso
            • Reloj
            • Manómetro
            • Termómetro
          • Controles de edición
            • Caja de texto
            • Caja de texto enriquecido
            • Data catcher edit
            • Edición alfabética
            • Edición fecha
            • Edición fecha/hora
            • Edición fórmula
            • Edición hora
            • Edición numérica
            • Edición senda fichero
            • Edición senda directorio
            • Objeto dibujo
          • Controles de entrada
            • Botón
            • Botón de check
            • Botón de radio
            • Calendario
            • ComboBox
            • Deslizador
            • Dial
            • ListBox
            • Rueda
          • Contenedores
            • Área de scroll
            • Caja de formularios
            • Pila de formularios
            • Separador de formularios
            • Splitter
            • Vista de datos
          • Layout
          • Tree widget
          • Controles SVG
          • Extensión de ficha
        • Formulario QML
        • Gráfico
        • Imagen SVG
        • Impresora lógica
        • Informe
          • Editor de informes
          • Agrupamiento
          • Sección
          • Cálculo
        • Informe personalizable
          • Diseñando un informe personalizable básico
          • Diseño avanzado
          • Diseñando un informe personalizable
          • Añadiendo orígenes de datos
          • Añadiendo elementos al informe
          • Características avanzadas
          • Etiquetas
          • Asistente de scripts
          • Impresión de gráficos
          • Opciones html
        • ListView
        • Lista QML
        • Localizador
        • Marco
        • Menú
        • Multivista
        • Protocolo TCP-IP
        • Reemplazo
        • Rejilla
          • Propiedades de columna de rejilla
        • Rejilla avanzada
          • Propiedades de columna de rejilla avanzada
        • Toolbar
        • ViewFlow
        • Sub-objetos de vistas de datos
          • Conexión de evento
          • Drop
          • Inserción
          • Manejador de evento
      • Objetos comunes a proyecto de datos y de aplicación
        • Búsqueda
        • Cola
        • Constante
        • Dibujo
        • Esquema de tablas
        • Fichero adjunto
        • Función
        • Librería externa
        • Lupa
        • Proceso
          • Indice de comandos de instrucción de proceso
          • Comandos de base de datos
            • API
            • Bases de datos externas
            • Búsquedas
            • Campos (grupo de comandos)
            • Cestas
            • Fichas
            • Fichas seleccionadas
            • Listas
            • Tablas
            • Tubos
          • Básicos
            • Controles de flujo
            • Debug
            • Ejecución
            • Salida/retornos
            • Scripts (grupo de comandos)
            • Transacciones (comandos)
            • Variables
          • Comunicación
            • Internet
            • Protocolo TCP
            • Puerto serie
            • SDV
          • Interfaz
            • Acciones (comandos)
            • Control
              • Ejemplo de CSS
            • Diálogos
            • Formularios - comandos
            • Localizadores
            • Objeto - grupo de comandos
            • Ventana principal
            • Vista de datos - comandos
          • Sistema
            • Comandos de Sistema
            • Configuración
            • Directorios
            • Ficheros
        • Tubo de ficha
        • Tubo de lista
        • Variable local
      • Editores
        • Asistente de fórmulas
          • Operadores
          • Funciones estándar
            • Funciones API
            • Funciones básicas
            • Funciones de cadenas
              • Expresiones regulares
            • Funciones científicas
            • Funciones de Cliente-servidor
            • Funciones de color
            • Funciones de códigos
            • Funciones de directorios
            • Funciones de fechas
            • Funciones de ficha en curso
            • Funciones de horas
            • Funciones JSON
            • Funciones de Internet
            • Funciones de juegos de caracteres
              • Codecs
            • Funciones numéricas
            • Funciones de sistema
            • Funciones de tiempo
            • Funciones trigonométricas
          • Funciones de dll
          • Funciones de proceso
          • Funciones de campo
          • Campos
          • Constantes
          • Variables globales
          • Variables locales
          • Variables del sistema
          • Verificador de fórmulas
          • Conversión automática de datos
          • Introducción de datos literales
          • Secuencias de escape en cadenas de caracteres
          • Composición de sendas en fórmulas
          • Operar con datos de tipo fecha, hora y tiempo
        • Editor de imágenes
        • Selector de fuentes
    • Scripts
      • Lenguajes
        • JavaScript
          • Procesos JavaScript
          • Fórmulas JavaScript
          • Clases
            • Funciones globales
            • Objetos
            • VAbstractBrowser
            • VAbstractDataView
            • VAbstractListDataView
            • VAdvandedGridListDataView
            • VAlternatorListDataView
            • VApp
            • VBoundFieldComboBox
            • VBoundFieldEdit
            • VBoundFieldEditBrowser
            • VBoundFieldListBox
            • VByteArray
            • VCheckBox
            • VClipboard
            • VClockWidget
            • VComboBox
            • VComboListDataView
            • VCoverFlowListDataView
            • VCWebView
            • VDataCatcherEdit
            • VDataCatcherEditBrowser
            • VDataView
            • VDataViewDialog
            • VDateEdit
            • VDateEditBrowser
            • VDateTimeEdit
            • VDateTimeEditBrowser
            • VDial
            • VDir
            • VExtension
            • VFile
            • VFileInfo
            • VFilePathEditBrowser
            • VFinder
            • VFont
            • VFormBlockListDataView
            • VFormDataView
            • VFormulaEditBrowser
            • VGaugeWidget
            • VGridListDataView
            • VGroupBox
            • VImage
            • VImageEdit
            • VImageWidget
            • VInstancesList
            • VInstance
            • VInstances
            • VItemRegisterPattern
            • VLabel
            • VLineEdit
            • VLineEditBrowser
            • VListBox
            • VListDataView
            • VLogin
            • VMainWindow
            • VMdiView
            • VMimeData
            • VMultiDataView
            • VNumberSpinBox
            • VNumberSpinBoxBrowser
            • VObjectInfo
            • VObjectInstance
            • VProcess
            • VProgressBar
            • VProjectInfo
            • VPushButton
            • VQmlFormDataView
            • VQmlListDataView
            • VQmlListModel
            • VQuery
            • VRadioButton
            • VRegister
            • VRegisterList
            • VReportListDataView
            • VRequest
            • VResponse
            • VRoot
            • VScreen
            • VScrollArea
            • VServerAdmin
            • VSettings
            • VSlider
            • VSlotListDataView
            • VSolutionInfo
            • VSplitter
            • VSqlDatabase
            • VSSLCertificate
            • VSSLInfo
            • VSSLSessionCipher
            • VStackedWidget
            • VSvgButton
            • VSvgSlideSwitch
            • VSvgToggleSwitch
            • VSvgWidget
            • VSysInfo
            • VTableInfo
            • VTabWidget
            • VTextEdit
            • VTextFIle
            • VThermometerWidget
            • VThumbWheel
            • VTimeEdit
            • VTimeEditBrowser
            • VToolBox
            • VTreeItem
            • VTreeItemRegister
            • VTreeListDataView
            • VTreeMenu
            • VTreeMultiTableListDataView
            • VTreeWidget
            • VUser
            • VUserGroup
            • VUserGroupList
            • VUserList
            • VXmlReader
            • VXmlWriter
            • Widget
            • XMLHttpRequest
        • QML
          • Tipos QML
          • Funciones específicas de QML
    • Depuración
      • Depuración de procesos de Velneo
      • Depuración de procesos JavaScript
      • Monitor de vClient
    • Extensiones de Velneo vDevelop
    • Acceso directo a una solución desde vDevelop
    • Buenas prácticas
      • Buenas prácticas de organización
        • Proyectos
        • Organización de carpetas
        • Proyecto de datos
        • Proyecto de aplicación
      • Buenas prácticas de codificación
        • Identificadores
        • Teclas aceleradoras
        • Documenta
        • Diseña los formularios como si no existiesen los layouts
      • Buenas prácticas de rendimiento
        • Arquitectura
          • Listas de registros
          • Lista de resultados de una búsqueda
          • Las cestas
          • Las variables globales
          • La caché de fichas
          • Programa en cloud
        • Formularios
          • Condiciones de visible y activo
          • Carga de subformularios en pestaña, caja o pila
        • Base de datos
          • Campos
          • Indices
          • Actualizaciones
          • Eventos de tabla o triggers
          • Variables globales y constantes
          • Tablas en memoria vs tablas en disco
          • Optimizar migraciones de datos
          • Búsquedas en el servidor ¿Cuándo y Cómo?
          • Campos fórmula vs campos en disco
          • Indices condicionados vs búsquedas complejas
          • ¿Cuándo usar tablas de extensión?
          • Indices de trozos y palabras
          • ¿Cuándo usar cada tipo de campo alfa?
        • Procesos y funciones y eventos
          • 1º, 2º, 3º y 4º plano ¿Cuándo usar cada uno?
          • Bloqueo blando vs bloqueo duro
          • Pasar información del cliente al servidor
          • ¿Cómo optimizar transacciones grandes?
          • ¿Cómo gestionar las transacciones?
          • Grabaciones optimizadas para el usuario
        • Carga de registros en objetos de lista
          • Rejillas
            • Campos punteros a singular
            • Totales
            • Condiciones de activo, visible y color en columna
            • Campos de tipo objeto
        • Conoce los límites
      • Imágenes
      • Buenas prácticas para el desarrollo en equipo
    • Análisis de bases de datos para aplicaciones de Velneo
      • Un centro de enseñanza
      • Facturas de un cliente
      • Repartos de obras de teatro
      • Galería de arte
      • Gestión de un colegio
      • Instalación de lunas para vehículos
      • Libros y autores
      • Tienda de discos
      • Últimos pedidos de un proveedor
      • Existencias por almacén y precios por cliente
      • Generación de tickets para un quiosco
      • Navegación por facturas
  • Velneo vDevelop Web
  • Velneo vAdmin
    • ¿Qué es Velneo vAdmin?
    • Gestión de usuarios
    • Gestión de aplicaciones
      • Soluciones
      • Instancias
      • Disco
    • Monitorización
      • Lista de comandos
    • Tareas
    • Acceso directo
    • Velneo vAdmin Web
  • Velneo vClient
    • ¿Qué es Velneo vClient?
    • Movilidad
    • Funcionalidades de Velneo vClient
      • Accesos directos y VRL
      • Cambiar idioma
      • Panel de procesos en 2º plano
      • Manejo de rejillas
        • Submenú de filtros
      • Uso de la rejilla avanzada
      • Manejo de cestas
      • Refrescos
      • Caché local
      • Edición de campos enlazados a maestro
      • Edición de campos de tipo fecha
      • Capturar imagen desde una cámara
      • Asignar impresoras lógicas
      • Actualización automática
      • Personalización de la ventana de conexión de Velneo vClient
      • Instalador personalizado de Velneo vClient
      • Ordenación de listas
  • Velneo vServer
    • ¿Qué es Velneo vServer?
    • Instalación y configuración
      • Activación de la licencia
      • Línea de comandos de Velneo vServer
      • Parámetros configurables de Velneo vServer
      • Estructura de directorios
    • Iniciar y detener Velneo vServer
    • Funcionalidades
      • Protocolo VATP
      • Protocolo VATPS
      • Multi-hilo
      • Integridad referencial
      • Refrescos terciarios
      • Sistema transaccional
      • Sistema de bloqueos
      • Tecnología bigkey
      • Hilo de control
    • Mensajes de log de sistema
    • vPacker
  • Velneo vInstallBuilder
    • ¿Qué es Velneo vInstallBuilder?
    • Configurar una instalación
    • Probar una instalación
    • Crear el instalable
    • Accesos directos
  • Velneo vModApache
    • ¿Qué es Velneo vModApache?
    • Instalación y configuración
    • Nomenclatura de objetos en urls
    • Uso de ficheros adjuntos
    • Caché local de Velneo vModApache
  • Velneo vDataClient
    • ¿Qué es Velneo vDataClient?
    • Iniciar Velneo vDataClient
    • Interfaz de Velneo vDataClient
    • Procesos
    • Utilidades
    • Acceso directo a una instancia de datos
  • Velneo vTranslator
    • ¿Qué es Velneo vTranslator?
    • Importación y exportación basada en XLIFF
    • Acceso directo a una solución
  • Velneo ODBC Driver
    • ¿Qué es velneo ODBC Driver?
    • Referencia de comandos SQL
  • Velneo vVersion
    • ¿Qué es Velneo vVersion?
  • Velneo vERP
    • ¿Qué es Velneo vERP?
    • Manual del programador
    • Documentación de la ApiRest
    • Novedades de la versión
  • Velneo vTutor
    • ¿Qué es vTutor?
    • Tutores de objetos básicos
      • Tutor de árboles visores de tablas arboladas
      • Tutor de búsquedas
      • Tutor de cestas
      • Tutor de formularios
      • Tutor de informes
      • Tutor de localizador básico
      • Tutor de marcos
      • Tutor de rejillas
      • Tutor de rejillas avanzadas
    • Tutores de objetos avanzados
      • Tutor de alternadores de lista
      • Tutor de comboview
      • Tutor de drag and drop
      • Tutor de eventos
      • Tutor de tablas de extensión y extensiones de ficha
      • Tutor de grabación de fichas
      • Tutor de gráficos
      • Tutor de impresión de informes
      • Tutor de lupas
      • Tutor de protocolo TCP/IP
      • Tutor de reemplazo
    • Tutores de controles
      • Tutor de botones de menú
      • Tutor de controles SVG
      • Tutor de edición numérica
      • Tutor de visor html dinámico
      • Tutor de vistas de datos de lista
    • Tutores de procesos y manejadores de evento avanzados
      • Tutor de cambio de marco
      • Tutor de comandos de interfaz y acciones
      • Tutor de importación y exportación de ficheros ASCII
      • Tutor de portapapeles
      • Tutor de procesos
      • Tutor de SDV
    • Tutores de scripts
      • QML: hola mundo
      • QML: tutor básico
      • QML: tutor de vistas
      • Tutor de XMLHttpRequest (webServices)
  • Velneo cloud
    • ¿Qué es Velneo Cloud?
    • Panel de control vServer cloud
      • URC
      • vServer
      • Apache
      • SFTP
      • Usuarios
    • Copias de seguridad
    • Velneo cloud API
      • Uso de Velneo cloud API
    • Explorador de archivos cloud sFTP
    • TCP en Velneo cloud
    • Velneo vModApache en cloud
    • SLA
    • Hora de los servidores en el cloud de Velneo
    • ¿Qué puedo hacer si tengo una incidencia en mi servidor cloud?
Con tecnología de GitBook
En esta página
  • Procesos
  • Aplica el criterio de responsabilidad única
  • Separa interfaz de proceso
  • Evita la complejidad ciclomática
  • Las verificaciones primero
  • ¿Cuándo es mejor un proceso que una función?
  • ¿Cuándo debo usar el comando ejecutar proceso?
  • ¿Cuándo debo usar el comando disparar objeto con un proceso?
  • Funciones
  • Acorta código
  • Ten en cuenta el número limitado de parámetros
  • Documenta los parámetros en el inicio de la función
  • Usa buenas descripciones en las variables locales que sean parámetros
  • Ten en cuenta que en 1º plano genera una transacción independiente
  • ¿Cuándo es mejor una función que un proceso?
  • Conexiones de evento
  • Evita el uso de la conexión pérdida de foco
  • Value changed es una buena opción
  • Mejor usar "Ratón: botón soltado" que "Ratón: botón pulsado"
  • Incompatibilidad entre "Ítem: simple clic" e "Ítem: doble clic"
  • Onclose solo está disponible en el objeto marco en uso
  • Controlar el cierre de un formulario en cuadro de diálogo
  • Controlar el cierre de un formulario en vista
  • Manejadores de evento
  • Las variables locales son compartidas entre los manejadores
  • Las cestas locales son compartidas entre los manejadores
  • Aplica el criterio de responsabilidad única y evita código repetido
  • Más información

¿Te fue útil?

  1. Velneo vDevelop
  2. Buenas prácticas
  3. Buenas prácticas de rendimiento

Procesos y funciones y eventos

Procesos

Sin duda es el objeto más poderoso de Velneo a la hora de crear funcionalidad en nuestras aplicaciones. Tiene la capacidad de ejecutarse en cualquier plano, admite cualquier origen (ninguno, ficha o lista) y cualquier destino (ninguno, ficha o lista), puede recibir un número ilimitado de parámetros y además puede devolver cualquier valor de cualquier variable local declarada en el objeto como si se tratase de parámetros de retorno. Tanta potencia requiere control para no hacer un mal uso de los procesos.

Aplica el criterio de responsabilidad única

Cuando estamos desarrollando una funcionalidad es fácil caer en la tentación de escribir un proceso largo que contiene toda la funcionalidad. Sin embargo esa es un mala praxis. Cuando más largo es un proceso más complicado es de leer, entender y mantener. Por ese motivo es conveniente usar el criterio de responsabilidad única. En lugar de tener un mega proceso es mejor:

  • Crear un proceso principal que se encargue de llamar a otros procesos.

  • Cada uno de los procesos llamados debería realizar una único función. No debemos confundir función con cálculo, es decir un proceso puede calcular muchos valores pero siempre que se realicen sobre la misma información.

Tampoco debemos caer en el error opuesto, es decir, atomizar tanto nuestros procesos que al final tengamos un grupo de procesos encadenados difíciles de analizar y comprender. Por ejemplo, no es fácil de mantener un proceso A que llama a un proceso B que a su vez llama a los procesos C1 y C2 y cada uno de estos llamada otros procesos. Esta jerarquía de procesos hace complicado seguirlo y mantenerlos.

Por lo tanto nuestro objetivo debe ser siempre buscar el equilibrio entre responsabilidad única y evitar el exceso de atomización, para ellos podemos recurrir a combinaciones de procesos y funciones que faciliten la legibilidad del código.

Otro problema que plantea la aplicación de la responsabilidad única es la necesidad de pasar información de un proceso a otro, algo que se evita cuando todo está en el mismo proceso. En este punto volvemos a repetir la palabra equilibrio, es decir debemos aplicar el criterio de responsabilidad única cuando un proceso va a ser llamado por otros y es mejor tener pequeñas piezas de código que realizan funciones concretas con un bajo nivel jerárquico y sin complejidades a la hora de pasar información.

Separa interfaz de proceso

Uno de los aspectos más importantes a la hora de optimizar un proceso es separar la parte de interacción con el usuario a través de la interfaz de la aplicación de reglas de negocio, cálculos y otras operaciones transaccionales automáticas que no requieren interacción.

El problema de que todo esté junto es que nos imposibilita la ejecución de un proceso en 3º plano, perdiendo la posibilidad de optimizar la parte de aplicaciones de reglas de negocio, cálculos y otras operaciones transaccionales.

Por este motivo y aunque requiera algo más de programación siempre es conveniente tener separada en un proceso independiente la parte de interfaz. Un ejemplo de buena práctica podría ser el siguiente esquema de ejecución:

  • Un proceso LLAMADOR lanza la interfaz donde se pide la información al usuario.

  • El proceso LLAMADOR realiza las verificaciones oportunas avisando al usuario en caso de error.

  • Si todo es correcto lanza en 3º plano un proceso CALCULADOR que realiza las operaciones transaccionales.

  • Al finalizar el proceso CALCULADOR en 3º plano el proceso de interfaz recupera la información relevante como el estado final, errores en caso de que los haya, registros creados, etc.

  • El proceso LLAMADOR muestra al usuario el resultado final del proceso ejecutado.

En el ejemplo anterior solo hay 2 procesos LLAMADOR y CALCULADOR, el primero se encarga de la interacción con el usuario a través de la interfaz tanto antes como después de que finalice la transacción, mientras que el segundo proceso se ejecuta de forma optimizada en el servidor ya que no utiliza nada de interfaz.

Este mismo esquema podemos realizarlo de forma similar sustituyendo el proceso LLAMADOR por un formulario que realizar toda la parte de interfaz con manejadores de evento del formulario.

Evita la complejidad ciclomática

La complejidad ciclomática es una métrica del software que proporciona una medición cuantitativa de la complejidad lógica de un programa. Es una de las métricas de software de mayor aceptación, ya que ha sido concebida para ser independiente del lenguaje.

Traducido a lenguaje Velneo es un valor que se calcula en base a la cantidad de niveles que se establecen en un proceso.

Sin duda alguna cuando vemos un proceso así no es fácil saber que hace cada línea del proceso ya que cuando estamos en 1º, 2º o 3º nivel de jerarquía todavía podemos controlarlo, pero cuando los niveles siguen creciendo nos obliga a leer todo el código secuencialmente para saber bajo qué condiciones se ejecuta las líneas de ese nivel.

Los comandos if y los subprocesos que generar muchos comandos de instrucción nos añaden complejidad ciclomática a los procesos, por ese motivo debemos tratar de simplificarlos al máximo y en estos casos aplicar el criterio de responsabilidad única puede ser de gran ayuda, así como el uso de funciones que simplifican la lectura del código.

Las verificaciones primero

Cuando tenemos que hacer verificaciones para decidir si vamos o no a ejecutar un parte del código del proceso, siempre que sea posible aplica el criterio de las verificaciones primero y en caso de error finaliza el proceso.

El primero verifica y si no hay error aceptar el formulario:

¿Cuándo es mejor un proceso que una función?

Existen diferentes motivos por los que un proceso puede ser más conveniente que una función:

  • Cuando queremos ejecutar un código con un origen ficha o lista.

  • Cuando queremos recuperar una ficha o lista de retorno.

  • Si queremos que el código se puede ejecutar en un plano diferente al del código lanzador.

  • Cuando no queremos tener límite de parámetros.

  • Cuando queremos que el orden de los parámetros no influya.

  • Cuando queremos que existan parámetros opcionales independientemente de su posición.

  • Cuando queremos poder recuperar no un único valor de retorno sino todos los valores que sean necesarios.

  • Cuando queremos que el código quede integrado en la transacción en curso aunque estemos ejecutando en 1º plano.

¿Cuándo debo usar el comando ejecutar proceso?

El comando de instrucción es más limitado que disparar objeto, sin embargo cuenta con la ventaja de la sencillez.

  • Cuando ya estoy en el origen ficha o lista y no necesito pasarle parámetros.

  • Cuando necesito ejecutar el proceso en 2º plano.

¿Cuándo debo usar el comando disparar objeto con un proceso?

El comando disparar objeto requiere más líneas de código que ejecutar proceso sin embargo cuenta con ventajas funcionales que nos motivan a usarlo cuando:

  • Cuando quiero pasarle parámetros al proceso.

  • Cuando necesito recuperar parámetros o valores calculados en el proceso ejecutado.

Funciones

La función es un contenedor de código sin origen. Podríamos decir que una función es como un proceso sin origen, pero la gran diferencia es que mientras el proceso puede ser ejecutado desde una acción, otro proceso, función, manejador o trigger, la función se puede ejecutar en cualquier fórmula lo que le da una potencia de ejecución que no tiene el proceso. Una función puede ser ejecutada en cualquier ámbito de nuestra aplicación.

Acorta código

Uno de sus usos más interesantes es la posibilidad de evitar código repetido. Una función permite lanzar código pasándole parámetros para que ejecute una funcionalidad retornando un valor que podemos capturar para su reutilización.

Esto nos permite mover código repetido en un proceso, función, manejador de evento o evento de tabla a una función que será llamada desde diferentes puntos. La ventaja es que la llamada a una función se realiza con un única línea de código, en el siguiente ejemplo se ve la llamada a 2 funciones.

Sin embargo, ejecutar un proceso con paso de parámetros requiere varias líneas de proceso. En el siguiente ejemplo vemos la llamada a 2 procesos con los comandos de instrucción de manejador de objeto.

Ten en cuenta el número limitado de parámetros

Una de las limitaciones de las funciones es que admite un máximo de 10 parámetros. No es una gran limitación, pero debemos tenerla en cuenta a la hora de establecer la estrategia de paso de muchos parámetros a una función.

Tener una función con muchos parámetros no es cómodo, por lo que en la medida de los posible es mejor crear funciones con pocos parámetros.

Si tenemos que pasar más de 10 parámetros y no podemos hacerlo con un proceso tenemos 2 opciones, utilizar el 10º parámetros para pasar muchos valores o pasar un único parámetro con todos los valores. Esta segunda opción tiene la ventaja de que es más homogénea, es decir, no hay unos parámetros que se pasan directamente y otros agrupados sino que todos se pasan agrupados.

Ese parámetro con múltiples valores puede tener los valores aplicando un formato JSON o XML o CSV, por ejemplo. Una vez recibido el parámetro la función comienza descomponiendo dichos valores en las diferentes variables locales o en una variable global de tipo array.

Documenta los parámetros en el inicio de la función

Pensando siempre en la mantenibilidad del código y que cualquier desarrollador puede necesitar usar la función es importante describir correctamente los parámetros que recibe la función y el valor que devuelve.

Usa buenas descripciones en las variables locales que sean parámetros

Cuando usamos una función tras seleccionarla de la lista nos encontraremos que en el lugar donde tenemos que escribir los parámetros nos aparecerán unos textos correspondiente a las descripciones de las variables locales de la función. Es fundamental que esas descripciones sean lo más cortas posibles a la vez que cumplan la función de describir con precisión el dato que debemos pasar a la función. Si podemos utilizar una palabra es mejor que dos o más, pero lo más importante es que se describa bien el parámetro.

Ten en cuenta que en 1º plano genera una transacción independiente

Velneo tiene un sistema transaccional automático que se encarga de englobar en una única transacción todas las operaciones realizadas a partir de que ya exista una transacción abierta. Esto es totalmente aplicable a las funciones cuando se ejecutan en el servidor. Sin embargo, cuando una función transacciona y se ejecuta en 1º plano, su transacción no queda agrupada con la que ya estuviese en abierta en curso, sino que se crea una independiente.

Este funcionamiento debemos tenerlo en cuenta para evitar cuando sea preciso, cambiando en ese caso la función por un proceso o para forzarlo cuando nos interese cambiando un proceso por una función.

¿Cuándo es mejor una función que un proceso?

Existen diferentes motivos por los que una función es más conveniente que un proceso:

  • Cuando queremos lanzar código desde una fórmula debemos usar una función.

  • Si queremos que se puede ejecutar el código remotamente desde otro servidor a través de una función remota.

  • Cuando queremos reducir el código de llamada a una línea.

  • Cuando el código no tiene origen y necesitamos pasarle parámetros.

  • Cuando queremos que genere una transacción independiente al ejecutarlo en 1º plano.

Conexiones de evento

Una gran parte de la potencia y funcionalidad de la interfaz de una aplicación viene dada por el uso de señales que nos permiten lanzar código en un momento determinado de la aplicación. Las conexiones de evento son muy potentes, pero también debemos usarlas con precaución para no abusar de ellas y producir el efecto no deseado en nuestra interfaz.

Evita el uso de la conexión pérdida de foco

Aunque es una tendencia natural usar esta señal, no es la más recomendable ya que existen muchas formas de perder el foco, cambiar de control con tabulación, con intro, pulsar una opción del botón de menú del control, pulsar una tecla de función que activa un botón, cambiar de aplicación, etc.

El problema es que no siempre nos vamos a encontrar con que el funcionamiento es el esperado, aunque detrás del comportamientos siempre hay una explicación lógica. Por este motivo es necesario trabajar con esta señal con precaución. Funciona y funciona bien, pero hay mucha casuística que se debe tener en cuenta.

Por ejemplo al pulsar un botón del formulario utilizando una tecla aceleradora, aunque se ejecuta el botón nuestro control no pierde foco ya que así es el funcionamiento de las señales en Qt. Por este motivo en ocasiones no es suficiente con la señal de pérdida de foco, además hay que hacer controles adicionales al aceptar o cerrar el formulario.

Value changed es una buena opción

Lo que tenemos que tener presente es que si el cambio de valor del control se realiza mediante programación la señal no se disparará. Es decir, si el usuario cambia el valor manualmente si se dispara, pero si el cambio es realizado por un manejador de evento programado la señal no se va a disparar. Es fácil de gestionar, pero siempre que tengamos claro su funcionamiento.

Mejor usar "Ratón: botón soltado" que "Ratón: botón pulsado"

Incompatibilidad entre "Ítem: simple clic" e "Ítem: doble clic"

En las rejillas, por ejemplo, nos encontramos que podemos aplicar ambas señales, sin embargo debemos tener en cuenta que si declaramos las 2 señales nos vamos a encontrar con que al hacer simple clic se dispara la señal correspondiente, sin embargo hacer doble clic también se va a disparar la señal de simple clic, algo que puede no ser lo esperado, pero que debemos tenerlo en cuenta.

Onclose solo está disponible en el objeto marco en uso

Controlar el cierre de un formulario en cuadro de diálogo

Una vez que no hay botón cerrar en el título de la ventana podemos poner un botón "Cerrar" o "Cancelar" en el formulario con el que tendremos control absoluto sobre la acción del usuario.

Controlar el cierre de un formulario en vista

Cuando se dispara la señal podemos utilizar funciones del API de Velneo a través de JavaScript para saber que formulario es el que está activo y por lo tanto el que está tratando de cerrar el usuario.

Manejadores de evento

Los manejadores de evento tienen la ventaja de ser código “conectado” al objeto al que pertenece, de tal forma que un manejador de evento de un formulario tiene control sobre el registro editado y todos los controles de la interfaz, y un manejador de evento de una rejilla sobre la lista de registros y sus columnas.

Al estar conectado el manejador de evento es usado para aplicar funcionalidades de avanzadas de interfaz que no podríamos lograr con procesos o funciones.

Un manejador puede llamar a otro del mismo objeto salvo en el marco AUTOEXEC

Un comando usado habitualmente y que nos ayuda a tener código de responsabilidad única es “Interfaz: ejecutar manejador de evento”, este comando permite hacer llamadas de un manejador a otro teniendo siempre presente que comparten el registro o la lista de origen del objeto así como las variables locales y las cestas.

Sin embargo, hay una excepción, el marco AUTOEXEC aunque permite la creación de conexiones y manejadores de evento no permite que un manejador de evento llame a otro. En este caso particular tendremos que hacer uso de funciones o procesos para evitar código repetido.

Las variables locales son compartidas entre los manejadores

Una funcionalidad muy cómoda cuando trabajamos con los manejadores de objetos es que las variables locales declaradas en el objeto son compartidas por todos los manejadores, eso significa que podemos almacenar valores en variables locales para posteriormente utilizarlas en otro manejador. Esta funcionalidad es aplicable dentro del objeto, es decir a nivel de una tabla, un formulario, una rejilla, etc.

Debemos tener en cuenta que si un objeto está instanciado más de una vez, por ejemplo el usuario abre el formulario de dos clientes distintos, aunque el objeto es el mismo cada formulario tiene su propio ámbito de ejecución, y por lo tanto las variables de un formulario son comunes para todos sus manejadores, pero las variables locales de un formulario no son accesibles para los manejadores que están asociados al otro formulario.

Las cestas locales son compartidas entre los manejadores

Las cestas locales tienen un ámbito y una persistencia asociada a la ejecución del manejador que la crea, sin embargo sin un manejador de objeto crea una cesta local y llamamos desde ese manejador a otro manejador que utiliza un cesta con el mismo identificador, la cesta es compartida por ambos manejadores. Al finalizar la ejecución del manejador que creó la cesta el objeto será destruido de tal forma que al volver a lanzar el mismo manejador se creará una nueva cesta local.

Aplica el criterio de responsabilidad única y evita código repetido

Los manejadores de evento al igual que las otras piezas de código en Velneo permiten escribir todo el código que necesites, aunque no es recomendable hacer código largo ya que dificulta su legibilidad y mantenibilidad.

Gracias a la compartición del origen, variables y cestas, es muy sencillo evitar el código repetido en los manejadores de evento, ya que podemos hacer que un manejador llame a otro. Aplicando el mismo criterio podemos evitar que los manejadores hagan múltiples cosas, por ejemplo verificaciones, transacciones, cambiar el estado de la interfaz, etc. Es recomendable crear pequeños manejadores de evento con responsabilidad única que son llamados desde otros manejadores de evento.

Más información

Última actualización hace 3 años

¿Te fue útil?

Habitualmente es más recomendable usar la señal que la de pérdida de foco para detectar si se han realizado cambios en los datos de un control. Es una señal que nos garantiza detectar cuando el valor del campo ha cambiado tanto si es con una opción de localidad o alta de maestro a través del botón de menú del control, como si es por una acción del usuario con el teclado a escribir un nuevo valor o con el ratón al pulsar algún botón arriba o abajo o de selección de una lista en vista de datos.

Estas señales aunque parezcan similares tienen una gran diferencia. El se dispara cuando el usuario pulsa el botón, aunque pulse y no suelte el botón del ratón la señal se habrá disparado, sin embargo si antes de soltar el botón se desplaza fuera del botón la señal ya se habría disparado cuando el usuario realmente a cambiado de opinión al tratar de desplazar el ratón fuera del botón.

Por este motivo es más recomendable utilizar la señal que garantiza que el usuario pulsó y soltó el botón de ratón sobre el control. En el caso de controles de tipo botón ya existe una señal específica con el nombre “Botón pulsado”.

Cuando tratamos de controlar el cierre de la aplicación contamos con la señal disponible en el objeto que se esté usando. Esta señal nos permite cancelar su cierre con el comando de instrucción .

En el caso de los formularios en cuadro de diálogo aunque no disponemos de la señal podemos evitar su cierre quitando la barra de título de la ventana, o quitando el icono de cerrar ; opciones que podemos desactivar en la propiedad estilo del .

En el caso de que queramos controlar el cierre de un formulario abierto en vista, podemos controlarlo a través de la señal .

.

.

.

formulario
1º, 2º, 3º y 4º plano, ¿cuándo usar cada uno?
Bloqueo blando vs. bloqueo duro
Pasar información del cliente al servidor
¿Cómo optimizar transacciones grandes?
¿Cómo gestionar las transacciones?
Grabaciones optimizadas para el usuario
marco
set retorno proceso = NO
value changed
botón pulsado
botón soltado
Onclose
Vista cerrada