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:
- Validazione: legge
CRMSKINFper verificare che l'informazione esista sulla scheda - Font: ottiene il font corrente tramite
W$FONT(wfont-describe-font) per passarlo alla DLL - Composizione parametri: costruisce una stringa multi-riga con terminatore
##(poi sostituito con low-value): S=1000— dimensione outputE=<formula attuale>— formula corrente letta daCRMINFFRF=<nome font>,<size>— font dell'interfacciaX<n>=<descrizione>— un parametro per ogni informazione numerica non calcolata della scheda, dovene' il codice info e la descrizione viene daCRMINFOR.ipt-des- Scan parametri disponibili: scorre
CRMSKINFdalla pagina 1 (la pagina 0 contiene info fisse non utilizzabili). Per ogni informazione: - Legge
CRMINFORper verificare tipo e flag - Esclude le info non numeriche (
ipt-tip <> k-inf-tip-numero) - Esclude le info gia' calcolate (
ipt-fl-calc = "C") — non si possono nidificare formule - Chiamata DLL:
ShowAreaCalcFormApassando handle finestra, parametri e buffer risultato - 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 (controllatab-infoprima di aggiungere). - Aggiornamento DB:
- Scrive/aggiorna
CRMINFFRcon la formula restituita dalla DLL - Cancella tutti i record
CRMINFFCper l'informazione - Riscrive un record
CRMINFFCper ogni info referenziata dalla formula - 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:
- Validazione: verifica informazione su
CRMSKINFe checrm033-nom > 0 - Lettura info: legge
CRMINFORper ottenereipt-lun-dec(decimali) eipt-lun(lunghezza totale) — servono per la formattazione del risultato - Lettura formula: legge
CRMINFFR— se non esiste, errore (formula non definita) - Composizione parametri:
S=1000eE=<formula>- Per ogni info referenziata:
X<n>=<valore>(con valore formattato punto decimale) - Estrazione valori — due modalita':
- Da file (
crm033-estrai-dati = "S"ocrm033-dati-pnt = 0): scorreCRMINFFCper trovare le info referenziate, per ciascuna leggeCRMANANF(k03, chiave: specie=variabile + inf + cod nominativo) e prendennf-dato-num - Da linkage (
crm033-estrai-dati = "N"ecrm033-dati-pnt > 0): usa direttamente la tabellacrm033-datipassata dal chiamante - Formattazione valori: ogni valore viene convertito con
COGU20Woperazione "PreparaAcc" e la virgola sostituita con il punto (formato internazionale per la DLL) - Chiamata DLL:
GetAreaCalcValueAcon parametri e buffer risultato (non richiede handle finestra) - Elaborazione risultato (esito = 0):
- Sostituisce low-value con spazi e
.con,(formato italiano) - Se risultato =
"INF"(divisione per zero) → imposta risultato numerico = 0 - Altrimenti converte con
NUMVALin numerico - Arrotondamento:
COGU20W"Arrotonda" conu20-n-dec= decimali info,u20-n-int= lunghezza - decimali,u20-fl-segno = "T"(troncamento) - Formattazione:
COGU20W"PreparaAcc" con stessi parametri → risultato stringa incrm033-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.
- Scorre e cancella tutti i record
CRMINFFCper l'informazione - 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)
- X
n=: 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¶
- L'utente apre
CRM015(configurazione informazioni scheda) - Posiziona il cursore su un'informazione numerica
- Preme F5 → CRM015 chiama
CRM033con operazione "GESTIONE" - Si apre l'editor visuale AreaCalc con le info disponibili
- L'utente compone la formula (es.
[13] + [14] * 2) - Al salvataggio, CRM033 aggiorna
CRMINFFReCRMINFFC - L'informazione viene marcata con
ipt-fl-calc = "C"suCRMINFOR
Flusso tipico: calcolo¶
CRM030oCRMS06rileva che un valore e' stato modificato- Chiama
CRM033con operazione "CALCOLA", passando codice nominativo e informazione - CRM033 legge la formula, estrae i valori (da file o linkage) e calcola
- Il risultato formattato torna in
crm033-risultato/crm033-risultato-n - 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 frameworkucalldll/calldll - Durante GESTIONE/VISUALIZZA si imposta
CODE-CASE = 0prima 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