Buenas prácticas de DinaScript

Nombres, comentarios, condiciones, comprobaciones previas, carga de listados y diseño de algoritmos para scripts legibles que no penalicen al guardar.

Cómo escribir DinaScript legible y rápido: nombres, condiciones, comprobaciones, carga de datos y diseño de algoritmos. La referencia de cada función está en Funciones.

Nombres y comentarios

  • El nombre de la variable cuenta qué contiene. txt nombreCliente se entiende solo; txt x obliga a leer el resto del script.
  • El comentario @ cuenta por qué. Documenta la regla de negocio, no lo que ya dice la línea: @ los pedidos anulados no computan evita un error futuro.
  • Elige el tipo de script (TipoScriptE): Terminal para los eventos del formulario, Algoritmo para cálculos, PlantillaDeImpresion para documentos y FuncionAPI para lógica de servidor. Ver Scripts.
  • Un script, una responsabilidad. Si crece, sepáralo en scripts pequeños y encadénalos con F.ExecuteScript.
@ Los pedidos de más de 3.000 euros llevan descuento por volumen
num umbralDescuento = 3000
¿v.totalPedido > v.umbralDescuento ? v.descuento = 5

Condiciones legibles

El if en línea ¿condición ? acción y el bloque if hacen lo mismo; la diferencia es cuánto cabe dentro.

  • En línea cuando hay una condición y una sola acción.
  • Bloque cuando hay varias acciones, ramas else o elseif, o lógica anidada.
if v.totalPedido > v.umbralDescuento
    v.descuento = 5
    v.avisoCliente = 'Descuento por volumen aplicado'
else
    v.descuento = 0
end

Escribe las condiciones en positivo y compara con valores con nombre (v.umbralDescuento), no con números sueltos repartidos por el script.

Comprueba antes de operar

DinaScript no tiene try: si una operación falla a mitad de script, el error no se puede capturar. Comprueba antes con un if, sobre todo los valores que vienen del usuario o de campos vacíos.

@ Comprueba antes de usar: no hay manejo de errores después
¿F.IsEmpty_Text(v.emailCliente) = 1 ? v.error = 'Falta el email del cliente'
¿C.ReferenciaCliente = '' ? salir

Las funciones IsEmpty_* e IsNotEmpty_* existen para Text, Time, Date y DateTime. Están en Lógica y comparación.

Carga solo lo necesario

Cada listado que cargas es una consulta a la base de datos. Pide solo las filas que necesitas.

  • Filtra en la carga, no en el bucle. Un F.DataListLoadAddFilter recorta la consulta antes de traer datos. Un if dentro del recorrido trae toda la sección y descarta filas ya cargadas.
  • Pagina. El tercer parámetro de F.DataListLoad es cuántos resultados llegan. Pide 200 si vas a usar 200.
  • No cargues listados dentro de un recorrido. Un F.DataListLoad dentro de un bloque F.ProcessDataList_Ini es una consulta a la base de datos por cada fila. Si necesitas cruzar datos, casi siempre lo resuelve un informe con las columnas ya cruzadas o un algoritmo.
  • Guarda en variable lo que leas varias veces. Leer un campo o llamar a la misma función en cada vuelta repite trabajo.
  • Calcula los totales con algoritmos. Para sumar, contar o promediar registros no recorras un listado: un algoritmo con F.Aggregate_Sum, F.Aggregate_Count o F.Aggregate_Average compila a SQL y calcula en la base de datos.
@ El filtro viaja en la consulta: llegan solo las compras del periodo
F.DataListLoad(S.Sections.ComprasGastos.ID, 1, 200)
F.DataListLoadAddFilter(S.Sections.ComprasGastos.ID, S.Fields.ComprasGastos.FechaContable.ID, '>=', v.Fecha_Desde)
F.DataListLoadAddFilter(S.Sections.ComprasGastos.ID, S.Fields.ComprasGastos.FechaContable.ID, '<=', v.Fecha_Hasta)

Algoritmos: el tipo más simple que cubra el cálculo

Cada tipo de algoritmo opera sobre un alcance distinto, y el coste crece con el alcance:

  • Lineal (Lineal): los datos de la propia ficha, sin consultar ninguna otra. El de menor coste; la primera opción para campos calculados.
  • Relacionado (Compuesto): resume las fichas de otra sección que corresponden a cada una de las suyas, como la factura que suma sus líneas. Cada cruce encarece la consulta.
  • Búsqueda (Compatibilidad): devuelve la lista de fichas que cumplen una condición, para filtrar un informe o usarla con en.
  • Dato (Dato): agregado de una sección, para paneles e informes.
  • Calculadora (Calculo): ninguna ficha; combina constantes, funciones y preguntas.

Filtra pronto: el prefiltrado y los filtrados de izquierda y derecha reducen las filas antes de agregar. Filtrar después de traer todas las filas ejecuta la consulta completa para quedarse con unas pocas.

Recálculo y cadenas

Un campo calculado se recalcula cuando se guarda o borra un registro de la sección origen, cuando un administrador lanza un recálculo masivo, cuando lo dispara una tarea programada o cuando cambia otro algoritmo del que depende. El servidor ordena la ejecución por dependencias y rechaza los ciclos: un algoritmo no puede depender, directa o indirectamente, de su propio resultado.

Un algoritmo lento asociado a un campo calculado se ejecuta en cada guardado de la sección origen. Si guardar se vuelve lento, acorta la cadena o acota con filtros.

Límites del lenguaje

LímiteQué implica al escribir
Sin recursiónUn script no puede llamarse a sí mismo, ni directamente ni por una cadena de F.ExecuteScript.
Sin funciones propiasTodas las funciones son las del espacio F.. Para reutilizar lógica, sepárala en otro script.
Línea a líneaNo hay expresiones multilínea: cada instrucción completa en su línea.
Sin tryNo hay manejo de excepciones. Protege las operaciones delicadas con comprobaciones previas.
Ejecución síncronaLas instrucciones se ejecutan una tras otra; un paso lento retrasa todo lo que viene después.
Sin distinción de mayúsculasF.Round y f.round son la misma función. Usa la grafía de la referencia para poder buscarla.
Palabras clave bilingüesif y si valen igual, y end, end if y endif también. Elige una forma y no las mezcles en el mismo script.

Siguiente: Funciones. Recetas reales: Recetas de scripts.

En esta página