sync SVN r18202

This commit is contained in:
2026-09-24 23:07:59 +03:00
parent c8aac857a3
commit e13b0e928e
17 changed files with 730 additions and 2 deletions

View File

@@ -21,6 +21,7 @@ atingi zona X, citeste fisierul Y"). Restul se deschid doar la declansator.
| **VFP** | |
| `cautare_vcx_vct.md` | cauti cod in `.vcx`/`.scx`/`.frx`/`.mnx` -> skill `roa-vfp-text-edit` |
| `flux-editare-vfp-text.md` | editezi `.vc2`/`.sc2` + write-back; invariantele si `*p:`/`*m:` -> skill `roa-vfp-text-edit` |
| `creare-editare-rapoarte-frx.md` | creezi/editezi un raport `.frx`/`.frt` sau verifici unul nou (structura DBF, band-uri, grupare, totaluri) -> skill `roa-vfp-frx-report` |
| `conventie_encoding_cp1252.md` | fisierul editat are diacritice (cp1250, nu cp1252) -> skill `roa-vfp-text-edit` |
| `inventar-comun.md` | inainte de cod nou: exista deja o functie/clasa comuna? |
| `conventie_ux_formulare.md` | adaugi/rearanjezi controale pe formular |

View File

@@ -1,6 +1,6 @@
# rec_skills - skill-uri de agent pentru suita ROA
Data: 2026-09-16. Status: aplicat (10 skill-uri create, rutare + backstop puse in docs).
Data: 2026-09-16. Status: aplicat (11 skill-uri create, rutare + backstop puse in docs).
## Decizie
@@ -25,6 +25,7 @@ Data: 2026-09-16. Status: aplicat (10 skill-uri create, rutare + backstop puse i
|---|---|
| `roa-vfp-text-edit` | editare `.vcx/.scx` pe text (`.vc2/.sc2`), cautare in binare, encoding cp1250, write-back |
| `roa-vfp-headless-test` | rulare/depanare teste VFP headless, harness UI + screenshots |
| `roa-vfp-frx-report` | creezi/editezi/verifici un raport `.frx`/`.frt` (layout, benzi, grupare, totaluri, preview) |
| `roa-git-svn-commit` | commit / `svn update` / `roa_sync` in COMUN |
| `roa-oracle-migration` | scriere + publicare scripturi de migrare, re-export pachet PL/SQL |
| `roa-oracle-diagnostic` | update ROA blocat la client, tablespace/disc plin |
@@ -47,7 +48,7 @@ Data: 2026-09-16. Status: aplicat (10 skill-uri create, rutare + backstop puse i
## Verificari la data aplicarii
- 10/10 skill-uri: ASCII pur, fara BOM, `name` = folder, descriere <= 1024, exact 1 bullet sub
- 11/11 skill-uri: ASCII pur, fara BOM, `name` = folder, descriere <= 1024, exact 1 bullet sub
`## Referinta (doar la nevoie)`.
- 0 rute reziduale zona -> doc in `CLAUDE.md`, `AGENTS.md`, `reguli_lucru.md`, `README.md`.
- `leaga_skills.ps1`: 4 create apoi idempotent (0 create, 9 ok); director real cu acelasi nume

View File

@@ -0,0 +1,95 @@
# Rapoarte VFP (.frx/.frt): citire, creare, verificare
Un `.frx` este un DBF cu 75 de campuri fixe (identice la toate rapoartele) + memo-ul `.frt`.
`goExport.export2frx(cursor, "nume", ...)` il lanseaza; `getRepPath` (oexport.prg) cauta
`nume.frx` in `SET PATH` (`Rapoarte\`) sau in `USERREPORTS\<schema>\USR_nume.frx`. Cursorul
selectat inainte de `Report Form` este sursa expresiilor din raport.
## Campuri cheie
- `OBJTYPE`: 1=raport (OBJCODE=53), 9=banda, 5=eticheta, 8=expresie/camp, 6=linie,
7=dreptunghi (OBJCODE=4), 18=variabila de raport, 25=dataenvironment.
- `OBJCODE` pe `OBJTYPE=9`: 0=Title, 1=Page Header, 2=Column Header, 3=Group Header,
4=Detail, 5=Group Footer, 6=Column Footer, 7=Page Footer, 8=Summary.
- `EXPR`: textul (intre ghilimele) la etichete, expresia la campuri, **expresia de grupare la
banda OBJCODE=3**. `PAGEBREAK=".T."` pe OBJCODE=3 => pagina noua per grup.
- `FONTFACE`/`FONTSIZE`/`FONTSTYLE` (1=bold); obiectele au `MODE=1`.
- Aliniere: la **etichete** (OBJTYPE=5) `PICTURE` = `""` stanga, `"@I"` centrat, `"@J"` dreapta;
la **campuri** (OBJTYPE=8) `OFFSET` = 0 stanga, 1 dreapta, 2 centrat.
- Numere: `EXPR = transform(camp, get_mask(14, gnpa))` (ca rapoartele existente).
`_PAGENO`, `goFirma.Antet`, `get_mask` sunt disponibile la randare.
## Asocierea obiect -> banda (capcana centrala)
VFP NU asociaza obiectele dupa ordinea inregistrarilor si NU foloseste VPOS relativ la banda.
`VPOS` este **absolut pe pagina**, iar banda fiecarui obiect se determina cu intervalele
calculate de `FFC\_FRXCursor.vcx`: fiecarei benzi i se adauga un **separator de 2083.333 FRU**:
```
band_START = suma(inaltimilor benzilor precedente) + 2083.333 * (numarul de benzi precedente + 1)
band_STOP = band_START + HEIGHT
```
Obiectul apartine primei benzi cu `band_START <= VPOS <= band_STOP` si se deseneaza la `VPOS`
absolut. Deci, ca sa pui un obiect intr-o banda, calculeaza `VPOS = band_START + offset` (vezi
exemplu mai jos). Verificarea exacta: ruleaza `_FRXCursor` si citeste `BANDS.START/STOP` +
`OBJECTS.BANDLABEL` (vezi scriptul de mai jos).
**Capcana: continutul benzii Group Header nu se randeaza** (nici cu `PAGEBREAK` pe ea, nici fara;
obiectele sunt asociate corect dar nu apar). Solutia care merge: pune continutul per-grup
(antet, tabel document, texte, cap de tabel) in **Page Header**, cu `VPOS` in intervalul benzii
Page Header, si lasa banda Group Header **goala (HEIGHT=0) doar cu `PAGEBREAK=.T.`** ca sa
declanseze pagina noua per grup. Campurile de grup (`nrdoc` etc.) se evalueaza corect in Page
Header, pentru ca pagina noua incepe cu primul rand al grupului.
## Crearea unui raport nou programatic (fara IDE)
`COPY STRUCTURE` NU e suficient: produce un `.frx` pe care motorul il raporteaza "is invalid"
(lipseste formatul de raport). Corect:
1. `COPY FILE <model>.frx TO <nou>.frx` si `COPY FILE <model>.frt TO <nou>.frt` (pastreaza
antetul/memo-ul exact).
2. `USE <nou>.frx EXCLUSIVE` apoi `ZAP`.
3. `APPEND BLANK` + `REPLACE` campurile, per obiect (incepe cu un `FUNCTION addrec` cu valorile
implicite, suprascrie per tip).
4. Benzile: `HEIGHT` si `OBJCODE`; Title/PageFooter pot avea HEIGHT=0.
Exemplu de calcul VPOS pentru benzi Title(0), PageHeader(24000), GroupHeader(0), Detail(1800),
GroupFooter(15000), PageFooter(0): `PH_START=2083.333`, `GH_START=28166.666`,
`DETAIL_START=30250`, `GF_START=34133.333`. Obiectele din Page Header: `VPOS=2083.333+offset`.
## Rulare headless (obligatoriu .FXP)
`vfp9.exe -A "<script.prg>"` deschide des editorul si nu scrie log (proces viu, log gol).
Corect: precompileaza intai (`COMUN\utile\Teste\_precompile.ps1 -Prg <script.prg>`), apoi
`vfp9.exe -A "<script.FXP>"` (fara `-T`). Prima linie: `SET SAFETY OFF`. Pune
`ON ERROR DO ... WITH ERROR(), MESSAGE(), PROGRAM(), LINENO()` care scrie in log si `QUIT`,
altfel orice eroare deschide un dialog nativ si blocheaza pana la timeout.
## Verificarea ca raportul e valid si arata corect
- Validitate: `FoxBin2Prg.EXE "<raport>.frx" "" "" "" 1 0 1` trebuie sa produca `.fr2`.
- Continut: `SELECT <cursor>` + `REPORT FORM <raport> TO FILE <txt> ASCII NOCONSOLE` si cauta in
`<txt>` antetul, coloanele, totalurile (`TO FILE` fara `ASCII` scrie binar).
- Aspect: `REPORT FORM <raport> PREVIEW NOWAIT`, apoi muta fereastra copil "Print Preview"
(MoveWindow) ca sa nu acopere pagina si fa screenshot pe fereastra copil cu titlul raportului
(`PrintWindow`). Fara mutarea barei, jumatatea de sus a paginii e mascata de umbra ei.
## Capcane
- **`COPY STRUCTURE` da un `.frx` invalid**; foloseste `COPY FILE` + `ZAP` (punctul de mai sus).
- **Continutul benzii Group Header nu se randeaza**; muta-l in Page Header (punctul de mai sus).
- `LOCAL laFields` + `AFIELDS(laFields, ...)` da eroarea 232 "not an array"; declara
`LOCAL ARRAY laFields[1,1]`.
- Fara `ON ERROR ... QUIT`, o eroare intr-un script headless deschide un dialog nativ si pare
"agatat" (proces viu, CPU ~0, log gol).
- `vfp9.exe -A "<script>"` pe `.prg` (nu `.FXP`) deschide editorul; ruleaza `.FXP`.
- Diacriticele se scriu ca octeti cp1250 (in `.prg` le construiesti cu `CHR()`), nu cu Edit/Write.
Setul de caractere se declara pe fiecare obiect text/camp prin `DOUBLE=.T.` + `RESOID=238`
(Central European); pentru rapoarte fara diacritice, `RESOID=0` si texte ASCII.
- Fundal pe un cap de tabel: `FILLRED/GREEN/BLUE` + `FILLPAT=1` **si `MODE=0`** - la `MODE=1`
(transparent) fundalul nu se deseneaza.
- Cursorul referit de raport trebuie sa fie cel selectat la `Report Form`; altfel expresiile dau
"Variable not found".
- `VFP 9` nu face word-wrap la etichete: liniile lungi se taie la latime; pune `CHR(13)` explicit
in textul etichetei (intre ghilimele) pentru linii multiple.

View File

@@ -23,6 +23,7 @@ opreste lane-urile celuilalt si le poate muta directorul de lucru (verificat 15.
|---|---|
| ROAFACTURARE | 4096 |
| ROACONT | 4196 |
| ROAIMOB | 4296 |
Proiect nou: urmatorul port liber din tabel (+100), trecut aici inainte de pornire. In API trimite si `?directory=<radacina proiectului>`.
| Actiune | Apel |

View File

@@ -28,6 +28,19 @@ cand primesti un mesaj nou, il aplici imediat; are prioritate fata de sarcina in
date sau istoric.
- Fisierele `.sql` pentru `SCRIPTURI_CLAR` se scriu cu CRLF.
## Rulare VFP (obligatoriu)
- Orice rulare vfp9 (test, randare raport, compilare) trece prin watchdog, niciodata vfp9.exe direct:
`powershell -File COMUN\utile\Teste\watchdog_vfp.ps1 -Script <prg> -TimeoutSec 120 -AutoDismiss -OutDir <dir>`.
Tu nu vezi ecranul: dialogurile modale (erori VFP, MessageBox, "Fatal error") blocheaza procesul
fara sa apara in log. Watchdog-ul le captureaza (PNG + text) si le inchide.
- Rularea nu s-a terminat sau logul e gol: CITESTI intai captura PNG si dump-ul text din `-OutDir`,
apoi decizi. Nu relua aceeasi comanda fara sa stii ce dialog a blocat-o.
- `Fatal error: Exception code=C0000005` = crash VFP (acces invalid la memorie), nu eroare de logica;
linia e in "Called from". Nu repeta instructiunea: izoleaz-o intr-un script minim si schimba
abordarea (tipic: `.frx` deschis cu `USE` si apoi `REPORT FORM` pe el, `_FRXCursor`, obiect distrus).
Noteaza cazul in raport, la capcane.
- La final si dupa fiecare blocaj: niciun `vfp9` pornit de tine ramas viu (opresti doar PID-urile tale).
## Raport (obligatoriu, pe disc)
Scrii `docs\raport_<lane>.md` (numele lane-ului il primesti in sarcina), scurt:
1. Facut: fisier:linie pentru fiecare modificare.

View File

@@ -118,6 +118,7 @@
ce se intoarce si modelul de lucru (backlog de story-uri mici): `orchestrare-subagenti.md`.
7. Conventii obligatorii, de citit cand atingi zona respectiva:
- editezi `.vc2`/`.sc2` sau `.prg` cu diacritice -> skill roa-vfp-text-edit (el detine procedura; criteriile lui blocheaza "gata");
- creezi sau editezi un raport `.frx`/`.frt` (structura DBF, band-uri, grupare, totaluri, preview) -> skill roa-vfp-frx-report (el detine procedura; criteriile lui blocheaza "gata");
- adaugi o PROPRIETATE sau o METODA noua intr-o clasa `.vc2`/`.sc2` -> skill roa-vfp-text-edit (membrul nou si `*p:`/`*m:` sunt in procedura lui; criteriile lui blocheaza "gata");
- adaugi/rearanjezi controale pe formulare sau coloane in grid -> `conventie_ux_formulare.md`;
- grid needitabil pe formular cu 2+ grid-uri -> `capcana_grid_controlsource.md`;