Files
Marius Mutu d64124386c skills: 9 skill-uri de agent ROA (COMUN\skills) + legare si rutare
- leaga_skills.ps1: expune skill-urile in ~/.claude/skills prin symlink (citit si de Claude Code, si de opencode), fara copiere
- rutare zona->skill in reguli_lucru pct. 7, README, AGENTS.md; skill-ul devine proprietarul procedurii, docurile raman referinta conditionata
- rec_skills.md: decizia, inventarul si cum se adauga un skill nou
2026-09-16 11:54:37 +03:00

4.3 KiB

name, description
name description
roa-vfp-go-recno Prinde capcana `GO <recno>` in Visual FoxPro 9 cand numarul de inregistrare a fost capturat mai devreme sau primit ca parametru - cursorul s-a schimbat intre timp, iar `GO` fie da "Record is out of range", fie aseaza pointerul pe alt rand, tacit, fara eroare. Foloseste-l OBLIGATORIU cand vezi `GO` pe o variabila de recno (`lnRecno = Recno()`, `GO tnRecNo`, `Recno(alias)` refolosit), cand exista un `SELECT-SQL` sau requery intre captura si pozitionare, sau cand auzi "s-a pozitionat pe alt rand", "dupa requery sare altundeva", "recno capturat", "GO pe Recno()", "nu s-a dus pe inregistrarea ceruta", "record is out of range", "GO-ul nu nimereste". Nu repara cu `IF BETWEEN(...)` si nu te multumi cu "nu a dat eroare" - inlocuieste cu repozitionare pe cheie unica (`LOCATE`/`SEEK`) sau impacheteaza `GO` in `TRY/CATCH`.

GO pe Recno() capturat - repozitionare sigura

GO <n> e pozitionare absoluta pe numarul curent de ordine al cursorului. Daca n a fost capturat inainte de un SELECT-SQL, APPEND, DELETE, PACK sau orice requery, n nu mai desemneaza acelasi rand. De multe ori nu primesti eroare, doar alt rand.

Cand se foloseste

Opreste-te si aplica regula cand:

  • vezi GO <variabila> sau GO (expresie) unde expresia e un recno pastrat (lnRecno = Recno(), Recno(alias), RECNO());
  • o rutina primeste un recno ca parametru (LPARAMETERS tnRecNo) si face GO tnRecNo;
  • intre capturarea recno-ului si GO exista un SELECT ... FROM sau orice requery pe acelasi cursor;
  • auzi "s-a pozitionat pe alt rand", "dupa requery sare altundeva", "recno capturat", "nu s-a dus pe inregistrarea ceruta", "record is out of range".

GO TOP / GO BOTTOM nu poarta recno, dar se re-evalueaza si ele dupa requery.

Regula

Nu folosi GO pe un recno capturat anterior sau primit ca parametru. Repozitioneaza prin cheia unica de rand (ex. doc_key), care nu depinde de ordinea cursorului.

WRONG - recno capturat, apoi requery, apoi GO:

lnRecno = Recno("facturi")
SELECT SUM(valoare) FROM facturi WHERE ... INTO CURSOR tmp
GO lnRecno                      && sursa a ramas pe EOF -> "Record is out of range" sau alt rand

RIGHT - cheie unica, refacuta dupa requery:

lcKey = facturi.doc_key
SELECT SUM(valoare) FROM facturi WHERE ... INTO CURSOR tmp
SELECT facturi
LOCATE FOR doc_key = lcKey      && sau SEEK( lcKey, "facturi", "tag_doc_key" )
IF NOT FOUND()
	GO TOP                      && randul a disparut intre timp - decizie explicita
ENDIF

Daca nu exista cheie si ramai la recno (rar), impacheteaza-l: TRY / GO tnRecNo / CATCH / GO TOP / ENDTRY.

Capcane

  • SELECT-SQL ... FROM cursor lasa pointerul sursei pe EOF (Reccount()+1); GO pe un recno capturat inainte de SELECT da "Record is out of range" - pointerul nu revine singur.
  • Recno() fara alias se citeste pe aliasul selectat; un SELECT intre timp intoarce alt numar. Captureaza cu alias explicit, inainte de requery.
  • Randurile pot disparea intre timp (DELETE + PACK, filtru schimbat, SET ORDER); un LOCATE care intoarce .F. e informatie reala - trateaz-o explicit.
  • GO in afara [1, Reccount()] da eroare; in interior NU da niciodata. "A mers" nu inseamna "s-a dus corect"; fara assert pe cheie nu ai dovada.
  • Nu repara cu IF BETWEEN(tnRecNo, 1, Reccount()) - trece, dar poate cadea pe alt rand. Doar re-LOCATE pe cheie rezolva.
  • SEEK cere tag-ul/ordinea potrivita; dupa un SET ORDER gresit rateaza tacit. Verifica ORDER() sau foloseste LOCATE.

Criterii de acceptare si dovada

Fara dovada da/nu nu raporta ca rezolvat; "nu a dat eroare" nu e dovada.

  1. Dupa fiecare requery, assert pe cheia randului curent (ASSERT doc_key == lcKey, sau log daca difera). Recno-ul nu e dovada, cheia e.
  2. Test headless pe scenariul real: captureaza cheia, forteaza un requery pe acelasi cursor, repozitioneaza, apoi verifica doc_key si campurile randului asteptat.
  3. Caz limita: randul capturat dispare intre timp -> rutina cade pe GO TOP sau pe calea decisa, fara eroare, cu log.
  4. Regresii: zero GO <variabila_recno> ramase in modul (grep -rn "GO " <module>).

Referinta (doar la nevoie)

  • COMUN\docs\conventie_go_recno.md - nota de conventie (EOF dupa SELECT-SQL, varianta TRY/CATCH).