Vai al contenuto

CRM033 - Motore formule campi calcolati

Panoramica

CRM033 e' il sottoprogramma che gestisce i campi calcolati con formula nel modulo CRM. Permette di definire formule matematiche che calcolano il valore di un'informazione sulla scheda nominativo a partire dai valori di altre informazioni numeriche della stessa scheda.

Le formule vengono editate tramite una DLL esterna (AreaCalc.dll) che fornisce un editor visuale, e i risultati vengono calcolati dalla stessa DLL.

Sorgente: cbl/crm033.cbl (805 righe) Tipo: subroutine (mmsubw.cpy) Autore: Andrea Parmeggiani - Eurosystem


Interfaccia (utilcrm033.cpy)

CALL "CRM033" USING stringhe util-crm033
Campo Tipo Descrizione
crm033-ope x(20) Operazione da eseguire
crm033-informazione Posizione info sulla scheda nominativo
- crm033-tcl x(03) Tipo scheda
- crm033-pag 9(02) Pagina
- crm033-prog 9(04) Progressivo
crm033-nom 9(08) Codice nominativo
crm033-esito x(01) Esito: S=successo, N=errore
crm033-msg x(200) Messaggio di errore
crm033-risultato x(30) Risultato stringa (formattato)
crm033-h-win comp-n Handle finestra (per DLL editor)
crm033-risultato-n s9(12)v999999 Risultato numerico
crm033-estrai-dati x(01) S=da file, N=da linkage
crm033-dati Array info/valore per calcolo da linkage
- crm033-dati-pnt 9(04) Numero elementi
- crm033-d-inf 9(04) Codice informazione
- crm033-d-val s9(12)v999999 Valore informazione
filler x(482) Riservato

Costante: k-max-info-formula — numero massimo di coppie info/valore passabili da linkage.


Operazioni

GESTIONE

Apre l'editor visuale di formula per l'informazione specificata.

Flusso:

  1. Validazione: legge CRMSKINF per verificare che l'informazione esista sulla scheda
  2. Font: ottiene il font corrente tramite W$FONT (wfont-describe-font) per passarlo alla DLL
  3. Composizione parametri: costruisce una stringa multi-riga con terminatore ## (poi sostituito con low-value):
  4. S=1000 — dimensione output
  5. E=<formula attuale> — formula corrente letta da CRMINFFR
  6. F=<nome font>,<size> — font dell'interfaccia
  7. X<n>=<descrizione> — un parametro per ogni informazione numerica non calcolata della scheda, dove n e' il codice info e la descrizione viene da CRMINFOR.ipt-des
  8. Scan parametri disponibili: scorre CRMSKINF dalla pagina 1 (la pagina 0 contiene info fisse non utilizzabili). Per ogni informazione:
  9. Legge CRMINFOR per verificare tipo e flag
  10. Esclude le info non numeriche (ipt-tip <> k-inf-tip-numero)
  11. Esclude le info gia' calcolate (ipt-fl-calc = "C") — non si possono nidificare formule
  12. Chiamata DLL: ShowAreaCalcFormA passando handle finestra, parametri e buffer risultato
  13. Parsing risultato (se esito = 0): scorre la stringa risultato carattere per carattere estraendo i codici info racchiusi tra [ e ] (es. [13] → info 13). Accumula le cifre fino alla parentesi chiusa per gestire codici multi-cifra. Duplicati ignorati (controlla tab-info prima di aggiungere).
  14. Aggiornamento DB:
  15. Scrive/aggiorna CRMINFFR con la formula restituita dalla DLL
  16. Cancella tutti i record CRMINFFC per l'informazione
  17. Riscrive un record CRMINFFC per ogni info referenziata dalla formula
  18. Scarico DLL al termine

VISUALIZZA

Identico a GESTIONE ma chiama ShowAreaCalcReadonlyFormA — l'editor e' in sola lettura. Non salva nulla.

CALCOLA

Calcola il valore della formula per un nominativo specifico.

Flusso:

  1. Validazione: verifica informazione su CRMSKINF e che crm033-nom > 0
  2. Lettura info: legge CRMINFOR per ottenere ipt-lun-dec (decimali) e ipt-lun (lunghezza totale) — servono per la formattazione del risultato
  3. Lettura formula: legge CRMINFFR — se non esiste, errore (formula non definita)
  4. Composizione parametri:
  5. S=1000 e E=<formula>
  6. Per ogni info referenziata: X<n>=<valore> (con valore formattato punto decimale)
  7. Estrazione valori — due modalita':
  8. Da file (crm033-estrai-dati = "S" o crm033-dati-pnt = 0): scorre CRMINFFC per trovare le info referenziate, per ciascuna legge CRMANANF (k03, chiave: specie=variabile + inf + cod nominativo) e prende nnf-dato-num
  9. Da linkage (crm033-estrai-dati = "N" e crm033-dati-pnt > 0): usa direttamente la tabella crm033-dati passata dal chiamante
  10. Formattazione valori: ogni valore viene convertito con COGU20W operazione "PreparaAcc" e la virgola sostituita con il punto (formato internazionale per la DLL)
  11. Chiamata DLL: GetAreaCalcValueA con parametri e buffer risultato (non richiede handle finestra)
  12. Elaborazione risultato (esito = 0):
  13. Sostituisce low-value con spazi e . con , (formato italiano)
  14. Se risultato = "INF" (divisione per zero) → imposta risultato numerico = 0
  15. Altrimenti converte con NUMVAL in numerico
  16. Arrotondamento: COGU20W "Arrotonda" con u20-n-dec = decimali info, u20-n-int = lunghezza - decimali, u20-fl-segno = "T" (troncamento)
  17. Formattazione: COGU20W "PreparaAcc" con stessi parametri → risultato stringa in crm033-risultato

Nota: dopo CALCOLA la DLL resta caricata in memoria per efficienza. Il chiamante deve invocare SCARICA-DLL quando ha finito tutti i calcoli.

CANCELLA

Elimina formula e dipendenze per un'informazione.

  1. Scorre e cancella tutti i record CRMINFFC per l'informazione
  2. Cancella il record CRMINFFR

SCARICA-DLL

Scarica AreaCalc.dll dalla memoria. Va chiamato dopo una serie di operazioni CALCOLA.


DLL AreaCalc

Funzione Uso Parametri
ShowAreaCalcFormA Editor formula handle finestra (by value), parametri (by ref), risultato (by ref)
ShowAreaCalcReadonlyFormA Editor read-only handle finestra (by value), parametri (by ref), risultato (by ref)
GetAreaCalcValueA Calcolo parametri (by ref), risultato (by ref)

Caricamento: AreaCalc.dll@__stdcall tramite framework ucalldll.cpy / calldll.cpy

Codici ritorno:

Codice Significato
0 Successo
1 Errore DLL (messaggio in tm-risultato)
2 DLL non trovata
3 Annullato dall'utente (solo editor)
altro Errore imprevisto

Formato parametri

Stringa multi-riga terminata da low-value (separatore interno ## sostituito prima della chiamata):

S=1000
E=[13]+[14]*2
F=Arial,10
X13=Peso
X14=Quantita'
  • S=: dimensione massima output (fisso 1000)
  • E=: espressione formula (le info sono referenziate come [n])
  • F=: font nome,dimensione (solo per editor)
  • Xn=: in GESTIONE/VISUALIZZA → descrizione info; in CALCOLA → valore numerico

Formato risultato (editor)

La DLL restituisce una stringa con la formula aggiornata. I riferimenti alle informazioni sono nel formato [n] dove n e' il codice informazione.

Formato risultato (calcolo)

Stringa con il valore numerico calcolato (punto come separatore decimale). Caso speciale: "INF" per divisione per zero.


Limiti e costanti

Costante Valore Descrizione
k-len-formula 3000 Lunghezza massima formula (caratteri)
k-max-ti-pnt 500 Massimo info referenziabili in una formula
k-max-info-formula (da cpy) Massimo coppie info/valore da linkage
k-inf-tip-numero (da costanti-clipot) Tipo info "numerico"

Tabelle utilizzate

Tabella Chiave Ruolo
CRMINFFR informazione (tcl+pag+prog) Formula (ifr-formula, fino a 5000 char)
CRMINFFC informazione + inf Dipendenze formula (quali info referenzia)
CRMSKINF informazione (tcl+pag+prog) Schema info sulla scheda (validazione)
CRMINFOR ipt-num Definizione informazione (tipo, lunghezza, decimali, fl-calc)
CRMANANF specie+inf+cod (k03) Dati nominativo (nnf-dato-num)
FEURTAB (cogfiles) Tabella configurazione generale

Integrazioni

Programma Contesto
CRM015 Configurazione schede CRM — F5 apre CRM033 in modalita' GESTIONE per definire la formula
CRM030 Gestione nominativi — visualizza il valore calcolato sulla scheda
CRMS06 Operazioni su informazioni scheda — chiama CRM033 "CALCOLA" per ricalcolare i campi calcolati quando un dato cambia

Flusso tipico: definizione formula

  1. L'utente apre CRM015 (configurazione informazioni scheda)
  2. Posiziona il cursore su un'informazione numerica
  3. Preme F5 → CRM015 chiama CRM033 con operazione "GESTIONE"
  4. Si apre l'editor visuale AreaCalc con le info disponibili
  5. L'utente compone la formula (es. [13] + [14] * 2)
  6. Al salvataggio, CRM033 aggiorna CRMINFFR e CRMINFFC
  7. L'informazione viene marcata con ipt-fl-calc = "C" su CRMINFOR

Flusso tipico: calcolo

  1. CRM030 o CRMS06 rileva che un valore e' stato modificato
  2. Chiama CRM033 con operazione "CALCOLA", passando codice nominativo e informazione
  3. CRM033 legge la formula, estrae i valori (da file o linkage) e calcola
  4. Il risultato formattato torna in crm033-risultato / crm033-risultato-n
  5. Il chiamante chiama "SCARICA-DLL" quando ha finito tutti i ricalcoli

Copybook

File Contenuto
utilcrm033.cpy Linkage section — interfaccia
crm033.select SELECT file
crm033.fd File descriptors
crm033.wrk Working-storage
crm033.decla Declaratives
crm033.prc Procedure I/O file
costanti-clipot.cpy Costanti CRM (k-inf-tip-numero, k-inf-variabile)
k-tipi-cogtabel.cpy Tipi tabella generica
k-personal.cpy Costanti personalizzazioni
ucalldll.cpy Framework caricamento DLL (working)
calldll.cpy Framework caricamento DLL (procedure)
utilu20.cpy Interfaccia COGU20W (arrotondamento/formattazione)

Note implementative

  • La DLL usa la convenzione __stdcall, caricata dinamicamente tramite il framework ucalldll/calldll
  • Durante GESTIONE/VISUALIZZA si imposta CODE-CASE = 0 prima della chiamata e si ripristina dopo (la DLL richiede case sensitivity)
  • In CALCOLA, i valori numerici vengono convertiti in formato con punto decimale (inspect replacing "," by ".") prima di passarli alla DLL, poi il risultato viene riconvertito in formato italiano (virgola decimale)
  • Il caso INF (infinity, tipicamente divisione per zero) viene gestito restituendo 0 sia come numerico che come stringa
  • Le formule non possono essere nidificate: un campo calcolato (ipt-fl-calc = "C") non appare tra i parametri disponibili dell'editor
  • La DLL resta caricata in memoria dopo CALCOLA per ottimizzare il caso di calcoli multipli consecutivi; il chiamante e' responsabile di invocare SCARICA-DLL
  • Il parsing dei riferimenti [n] nella formula gestisce codici info da 1 a 4 cifre (accumulo cifra per cifra fino a ])
  • La configurazione da CLIPOT.CNF (sezione commentata nel sorgente) non e' attiva — possibile estensione futura per info-id assoluto