# Totaluri pe grup: variabile de raport (standard ROA) In rapoartele ROA totalurile se calculeaza **in raport**, cu variabile de raport resetate pe grup - nu se precalculeaza in cursor. Randurile numerice: `EXPR = transform(camp, get_mask(14, gnpa))` (masca cu SPATIU, ca rapoartele existente). ## Reteta (dovedita pe `Rapoarte\pvcasare_mf.frx`, 24.09.2026, beh 90, 2 randuri/PV) Variabila = inregistrare `OBJTYPE=18` in .frx (creata de Marius in IDE, Report > Variables): | camp | valoare | sens | |---|---|---| | `NAME` | `tot_valoare` | numele variabilei | | `EXPR` | `valoare` | expresia NUMERICA acumulata (camp brut, nu `transform`) | | `TOTALTYPE` | `2` Sum / `1` Count | Calculate | | `RESETTOTAL` | `6` | reset la grupul 1 (= nr. grup + 5); `1` = sfarsit raport, `2` = pagina | | `TAG` | `0` | valoarea initiala | | `PENRED` | `0` | (asa o scrie IDE-ul) | Afisarea in Group Footer: camp `OBJTYPE=8` cu `EXPR = transform(tot_valoare, get_mask(14,gnpa))`, **`TOTALTYPE=0`** (variabila deja acumuleaza). **Nr. crt. pe grup**: variabila Count (`TOTALTYPE=1`, `RESETTOTAL=6`, `EXPR=id_mf`), afisata cu `alltrim(str(nrcrt_pv))`. **NU `recno()`**: cursorul se parcurge pe index (`SET ORDER`), deci `recno()` e ordinea fizica (a dat 5,3 / 4,1 in loc de 1,2 / 1,2) si nici nu se reseteaza pe grup. ## Capcane - **Nume de variabila = nume de camp din cursor**: campul castiga (rezolvarea VFP a numelor necalificate), deci raportul afiseaza campul, nu variabila. Scoate campul din cursor sau da-i variabilei alt nume. - **Creare programatica**: `APPEND BLANK` + `REPLACE` pe campuri alese de mana a dat **Fatal error C0000005** la `REPORT FORM` (r4, `verify80b.prg`). Ce merge: copiaza o variabila facuta in IDE (`LOCATE FOR objtype=18` + `SCATTER MEMO NAME lo` + modifici `name/expr/totaltype` + `APPEND BLANK` + `GATHER MEMO NAME lo`) - randat OK. Daca raportul nu are inca o variabila, cere-o facuta in IDE sau copiaz-o din `COMUN\Rapoarte\factura.frx`. - `EXPR = transform(camp, ...)` + `TOTALTYPE=2` pe campul de afisare -> `****` (motorul nu suma string-uri). Suma se face pe variabila numerica, `transform` doar la afisare. - `PICTURE` e un **sir literal de format**, nu expresie: `PICTURE = "get_mask(14,gnpa)"` tipareste textul. Nu pune masca in PICTURE. - Test obligatoriu cu **cel putin 2 randuri pe grup** si randuri inserate fizic in afara ordinii indexului - un singur rand pe grup nu dovedeste nici suma, nici resetul, nici nr. crt. ## Masca numerica `get_mask` `get_mask` real (`COMUN\programe\oproceduri_comune.prg:1719`; `proceduri_comune.prg:1090`) construieste masca cu **SPATIU**: `transform(3000, "99 999 999 999 999.99")` => `"3 000.00"`. `SET SEPARATOR` nu schimba asta. **Stub-ul din harness trebuie sa intoarca masca reala** (cu spatiu); un stub cu virgula (runda 2) a facut preview-ul sa arate virgule - adica preview-ul minte. Definiti `FUNCTION get_mask` identic cu cel real (vezi sablonul din SKILL.md, la Scripturi).