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 nombreClientese entiende solo;txt xobliga 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 computanevita un error futuro. - Elige el tipo de script (
TipoScriptE):Terminalpara los eventos del formulario,Algoritmopara cálculos,PlantillaDeImpresionpara documentos yFuncionAPIpara 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 = 5Condiciones 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
elseoelseif, o lógica anidada.
if v.totalPedido > v.umbralDescuento
v.descuento = 5
v.avisoCliente = 'Descuento por volumen aplicado'
else
v.descuento = 0
endEscribe 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 = '' ? salirLas 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.DataListLoadAddFilterrecorta la consulta antes de traer datos. Unifdentro del recorrido trae toda la sección y descarta filas ya cargadas. - Pagina. El tercer parámetro de
F.DataListLoades cuántos resultados llegan. Pide 200 si vas a usar 200. - No cargues listados dentro de un recorrido. Un
F.DataListLoaddentro de un bloqueF.ProcessDataList_Inies 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_CountoF.Aggregate_Averagecompila 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 conen. - 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ímite | Qué implica al escribir |
|---|---|
| Sin recursión | Un script no puede llamarse a sí mismo, ni directamente ni por una cadena de F.ExecuteScript. |
| Sin funciones propias | Todas las funciones son las del espacio F.. Para reutilizar lógica, sepárala en otro script. |
| Línea a línea | No hay expresiones multilínea: cada instrucción completa en su línea. |
Sin try | No hay manejo de excepciones. Protege las operaciones delicadas con comprobaciones previas. |
| Ejecución síncrona | Las instrucciones se ejecutan una tras otra; un paso lento retrasa todo lo que viene después. |
| Sin distinción de mayúsculas | F.Round y f.round son la misma función. Usa la grafía de la referencia para poder buscarla. |
| Palabras clave bilingües | if 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.