O eroare în calcularea soldurilor în sistemul de stocare și corectarea software-ului acestuia folosind exemplul unui raport universal. O eroare în calcularea soldurilor în sistemul de stocare și corectarea software-ului acestuia folosind exemplul unui raport universal Aveți o întrebare, aveți nevoie de ajutor de la un consultant

41
Am făcut recent un raport cu un număr nedefinit de coloane. Nu am vrut să schimb codul, așa că am decis să o fac pe sistemul de control al accesului. Nu a fost nicio problemă cu aceasta, a fost necesar să se extindă rezultatul pe un aspect arbitrar (propriul antet +... 27
Chiar dacă studenții CDS întâlnesc acest lucru în prima sau a doua zi, ar trebui să fie în secțiunea Întrebări frecvente. Un exemplu simplu de ieșire programatică a unui raport pe un aspect, folosind setările implicite. 18
//Obțineți diagrama de la... 10
La generarea rapoartelor asupra sistemului de control al accesului, implicit toate grupările sunt extinse, dar uneori este necesar să afișați un raport cu grupările restrânse imediat după generare! Acest cod din modulul de raport vă permite să restrângeți... 9
Pe această filă puteți specifica ce conexiuni se fac între două sau mai multe seturi de date, în funcție de ce parametri și condiții..png 1. „Sursa conexiunii” - indică primul set de date, de la...

Ceea ce este necesar la elaborarea rapoartelor este ca pentru un utilizator cu drepturi limitate, raportul să fie generat complet fără drepturi de verificare! Mai ales dacă RLS este configurat Există mai multe moduri de a face acest lucru: 1. Instalați...

Nu știu câți oameni au întâmpinat deja eroarea de a calcula soldurile inițiale și finale pe grupări. Personal, am fost „norocos”, de mai multe ori. Motivul, după cum am putut să aflu, constă în setările incorecte ale câmpurilor de date ACS, de a căror importanță mulți programatori începători (și nu atât de începători) nu sunt încă pe deplin conștienți.

Dacă nu ați mai întâlnit această problemă până acum, atunci pentru a înțelege mai bine esența ei, vă sugerez să o reproduceți singur folosind un raport universal (bazat pe metadate). Lansăm raportul, selectăm orice registru de acumulare nevid cu solduri și cifra de afaceri, activăm caseta de selectare „Înregistrări detaliate” în setările raportului (), indicăm unele grupări și adăugăm Recorder-ul în câmpurile de ieșire. Voila - soldurile de deschidere și de închidere sunt însumate pentru fiecare grupare. Rezultatul este un raport cu numere absolut incorecte, care nu poate fi afișat utilizatorilor.

Pentru a rezolva această problemă, este necesar să completați corect setările de câmp ale setului de date ACS - în special, câmpul „Rol”, care este de o importanță cheie.

SOLUȚIE interactivă ( nu este potrivit pentru raportul universal):

Deschideți diagrama de prezentare a datelor pentru raportul dvs. și priviți setările câmpului setului de date.

Pentru câmpurile soldurilor inițiale și finale pentru fiecare resursă, trebuie să completați rolul: selectați grupul de roluri „Restau” și în el specificați valoarea „Sold de început” sau respectiv „Sold final”. Asa de ( ) acest lucru se face în constructorul ACS.

În mod similar, trebuie să atribuiți rolul „Dimensiune” tuturor dimensiunilor din setul dvs. de date.

Dar acest lucru nu este suficient pentru ca rapoartele să funcționeze corect. Pentru a calcula corect câmpurile reziduale, trebuie să cunoașteți perioada fiecărei mișcări pentru a le plasa în ordinea cronologică corectă. Dacă sursa de date inițială nu are un câmp de perioadă, trebuie să îl adăugați acolo. Dacă câmpul perioadă există deja în setul de date, acesta trebuie specificat cu rolul „Perioadă” și numărul perioadei corespunzător (puteți citi mai multe despre numerotarea perioadei în ajutor).

Astfel de setări ale câmpurilor de date ACS fac în majoritatea cazurilor posibilă realizarea unui calcul corect al soldurilor prin grupare atunci când cu setările implicite sunt calculate incorect.

SOLUȚIE software (folosind exemplul Raportului de metadate universale):

Acum să vedem cum să remediați aceeași eroare în Raportul de metadate universale. Raportul universal diferă de majoritatea celorlalte rapoarte prin aceea că schema de prezentare a datelor de acolo este generată în întregime programatic, deci trebuie să configurați și rolurile pentru câmpurile de date ACS în mod programatic.

Pentru roluri soldurile de început și de sfârșit pentru fiecare resursă Cel mai simplu mod este să nu reinventezi roata (totul a fost deja scris înaintea noastră) și să folosești procedura standard Completați DataSetFieldRemainder() de la modulul general StandardReports. Acolo treceți câmpul setului de date și numele resursei ca parametri și, ca rezultat, un câmp rămas cu un rol completat corect este creat în setul de date.

În mod similar, atunci când creați câmpuri de set de date pentru dimensiuni, trebuie să le atribuiți rolul Dimensiune. Codul va fi cam așa:

NewDimension = TypicalReports.AddDataSetField(DataCompositionSchema.DataSets, Dimension.Name, Dimension.Synonym); NewDimension.Role.Dimension = Adevărat;

Manipulările cu câmpurile de resurse și dimensiuni descrise mai sus sunt necesare, dar nu suficiente pentru a rezolva problema - principala problemă a raportului universal este lipsa numerotării perioadelor. Câmpurile perioadei sunt prezente în setul de date, dar rolurile lor nu sunt completate.

Câmpurile de perioadă sunt adăugate raportului prin procedura modulului general StandardReports.AddPeriodFieldsToDataSet(), care este apelată din procedura modulului obiect AddDataSetFields(). Din păcate, această procedură nu atribuie numere de perioade.

În plus, câmpurile „Număr de linie” și „Registrar” nu sunt adăugate programatic nicăieri în raport. Mi s-a părut ciudat, pentru că... sunt prezente în setul de date final.

După cum sa dovedit, câmpurile „Număr de linie” și „Registrar”(Recorder) este adăugat automat de platformă în sine atunci când generatorul de setări este inițializat. Mai mult, platforma nu completează rolurile pentru câmpurile pe care le creează și nu este posibil să le completeze programatic, ceea ce creează probleme atunci când se lucrează în continuare cu ele. Dar dacă creați aceste câmpuri „manual” și le atribuiți programatic rolurile corecte, atunci platforma nu mai încearcă să le creeze din nou.

Vă ofer mai jos o rețetă care m-a ajutat să rezolv aproape complet această problemă a platformei și Raportul Universal Metadate:

Iată acest fragment de cod al modulului obiect:

// Adăugați câmpuri de perioadă Dacă TableName = "RemainsAndTurnover" SAU TableName = "Turnover" Then TypicalReports.AddPeriodFieldsToDataSet(DataCompositionScheme.DataSets); endIf; trebuie înlocuite cu următoarele: // Adăugați câmpuri de perioadă Dacă TableName = "RemainsAndTurnover" SAU TableName = "Turnover" Then PeriodList = TypicalReports.AddPeriodFieldsToDataSet(DataCompositionScheme.DataSets); //Completați câmpurile de serviciu și introduceți manual perioadele, deoarece platforma nu le completează Field = TypicalReports.AddDataSetField(DataCompositionSchema.DataSets, "RowNumber", "RowNumber"); Field.Role.PeriodNumber = 1; Câmp = TypicalReports.AddDataSetField(DataCompositionSchema.DataSets, „Registrator”, „Registrar”); Field.Role.PeriodNumber = 2; сч = 3; Pentru fiecare FieldPeriod din lista de perioade Ciclul FieldPeriod.Value.Role.PeriodNumber = count; Dacă număr > 3, atunci FieldPeriod.Value.Role.PeriodType = DataCompositionPeriodType.Additional; endIf; sch = sch+1; EndCycle; endIf;

Am reușit să găsesc o limitare asociată cu această soluție. Pentru calculul corect al începutului. si con. soldurilor, este necesar ca atunci când se utilizează orice detalii ale unui document de înregistrare într-un raport, registratorul însuși trebuie să fie selectat. În caz contrar, raportul universal după astfel de modificări nu mai provoacă alergii în rândul utilizatorilor.

UPDATE: Mi s-a spus în comentarii că un articol pe această temă a fost odată publicat pe discul ITS. Din păcate, acest articol a trecut pe lângă mine, dar m-a putut ajuta doar parțial în rezolvarea problemelor cu raportul universal. Din păcate, problemele platformei cu câmpurile de servicii ACS, cum ar fi „Recorder”, nici nu sunt descrise acolo.

În orice caz, sper că articolul meu îi va ajuta pe toți cei care au probleme similare. Am petrecut mult timp cautand aceasta solutie...

O altă greșeală comună la crearea rapoartelor privind sistemul de control al accesului pentru întreprinderea 1C este că soldurile inițiale și finale din tabelele virtuale ale registrelor de acumulare sunt calculate incorect. De exemplu, să creăm un raport simplu care va afișa soldurile și mișcările în registrul GoodsInWarehouses. Cererea lui va arăta astfel:

De asemenea, vom crea setări simple pentru variante:

Ca urmare, obținem următorul raport:

Ai o întrebare sau ai nevoie de ajutor de la un consultant?

Deoarece Nu am indicat nicăieri începutul și sfârșitul perioadei; raportul ar trebui să arate date de la începutul menținerii bazei de date. Dar în grupele noastre de depozite și articole există solduri de deschidere diferite de zero. Este ușor de înțeles că datele sunt afișate incorect, deoarece... Nu ar trebui să existe solduri la începutul întreținerii bazei de date. Deși cererea în sine este corectă.

Cert este că ACS are propriul său mecanism de calculare a soldurilor. Pentru funcționarea sa corectă, este necesar să se determine fără ambiguitate locația înregistratoarelor pe axa timpului. În acest caz, numai legătura este prezentă în selecție, astfel încât sistemul de layout nu poate face acest lucru. Pentru a evita acest comportament al sistemului de control acces, trebuie să selectați câmpul PeriodSecond din cerere. În acest caz, sistemul va calcula corect soldurile:

Vă rugăm să rețineți că câmpurile cu rolul „Perioadă” au o casetă de selectare „Suplimentar”. Și dacă din anumite motive este eliminat din câmpul PeriodSecond, raportul va reveni la versiunea incorectă. Pentru a calcula corect soldurile, trebuie fie să aveți bifată caseta „Adițional” în rol, fie prezența câmpului în câmpurile de raport selectate la nivel de variantă.

O zi bună, dragi cititori ai blogului! Ultima dată am atins deja un subiect care vorbea despre utilizarea funcției. Și astăzi în primul din această serie de articole, vom afla pentru ce sunt folosite rolurile câmpurilor de compoziție a datelor?și luați în considerare, de asemenea, exemple de ocupare a acestor roluri.

Rolul câmpului ACS indică ce este acest domeniu. Fiecare rol de câmp poate conține proprietățile sale. De exemplu, are o valoare numerică și conține numărul perioadei dacă câmpul este punct. Dacă valoarea proprietății „Perioad” este 0 (zero), aceasta înseamnă că acest câmp nu este o perioadă. Sau proprietatea „Dimensiune” – conține o indicație că câmpul este o dimensiune. Dacă câmpul este o dimensiune, atunci aceste informații sunt utilizate la calcularea totalurilor pentru câmpurile de sold.

Pentru fiecare câmp din schema de compunere a datelor, puteți specifica un rol. Roluri afectează corectitudinea calculelor soldului. În special, soldul inițial și final conform unor tabel. Dacă în interogare este selectat tabelul virtual „Solduri și cifre de afaceri”, atunci soldurile inițiale și finale sunt calculate folosind un algoritm complex, mai ales dacă folosim spread-uri suplimentare pe perioadă.

Dar dacă în interogări toate acestea funcționează corect, pe baza unui set de câmpuri de ieșire, atunci în compoziția datelor lucrurile stau oarecum mai rău. La urma urmei, nu știm ce câmpuri va selecta de fapt utilizatorul. Totul va depinde de setările versiunii sale de raport, pe care le poate schimba oricând. Prin urmare, sistemul de compunere a datelor are propriul mecanism de calculare a soldurilor de deschidere și de închidere pentru un anumit set de date, iar rolurile sunt utilizate în consecință. Să-l deschidem și să vedem că poți seta roluri pentru fiecare câmp.

Să adăugăm un set de date de interogare. Pentru a face acest lucru, trebuie să activăm elementul rădăcină „Query Builder”. Să trecem la tabelul virtual „Solduri și cifre de afaceri” din registrul de acumulare. Ce vedem?

După cum puteți vedea din ilustrația de mai sus, vedem că pentru unele câmpuri rolul a fost ocupat. Acest lucru s-a întâmplat deoarece avem setat indicatorul de completare automată. Dar acest lucru nu este întotdeauna posibil, așa că uneori trebuie să introduceți rolul manual. Să ne uităm la câteva exemple.

Să presupunem că într-o interogare folosim, de exemplu, operatorul de limbaj de interogare „SELECT”. Să descriem următoarea condiție:

SELECTARE CÂND Product RemainingRemainingsAndTurnover.Nomenclature = Value(Directory.Nomenclature.EmptyLink) THEN Value(Directory.Nomenclature.Sampon) ELSE Product RemainingRemainingAndTurnover.Nomenclature END

Această intrare înseamnă că dacă elementul corespunde unei legături goale (ne referim la directorul de valori ale funcției „Nomenclatură”, link gol), atunci valoarea elementului predefinit va fi returnată. Să presupunem că în configurația noastră există un astfel de element predefinit și se numește „Șampon”. În caz contrar, returnăm valoarea articolului în sine. Obținem următoarele:

După cum puteți vedea, rolul nu a fost completat pentru câmpul „Nomenclatură”. Dar după cum puteți vedea în imagine, în realitate nu avem un rol introdus pentru câmpul „Field1”, iar în acest caz restul nu va fi calculat corect.

Există și alte exemple în care rolul nu poate fi atribuit independent. De exemplu, aceasta este utilizarea lui , adică un anumit tabel de valori este furnizat ca intrare, să zicem, încărcat dintr-o altă bază de date, iar soldurile trebuie calculate din aceasta. În acest caz, trebuie să ne atribuim noi înșine roluri. Vom vedea cum se face acest lucru în.

La finalul articolului vreau să vă recomand unul gratuit de la Anatoly Sotnikov. Acesta este un curs de la un programator experimentat. Vă va arăta separat cum să creați rapoarte în sistemul de control al accesului. Trebuie doar să ascultați cu atenție și să vă amintiți! Veți primi răspunsuri la următoarele întrebări:
  • Cum se creează un raport simplu de listă?
  • Pentru ce sunt coloanele Câmp, Cale și Titlu din fila „Câmpuri”?
  • Care sunt limitările pentru câmpurile de aspect?
  • Cum se configurează corect rolurile?
  • Care sunt rolurile câmpurilor de aspect?
  • Unde pot găsi fila de compoziție a datelor într-o interogare?
  • Cum se configurează parametrii în sistemul de control acces?
  • Devine și mai interesant...
Poate că nu ar trebui să încerci să navighezi singur pe internet în căutarea informațiilor necesare? În plus, totul este gata de utilizare. Doar începeți! Toate detaliile despre ceea ce este în lecțiile video gratuite

Ceea ce este necesar la elaborarea rapoartelor este ca pentru un utilizator cu drepturi limitate, raportul să fie generat complet fără drepturi de verificare! Mai ales dacă RLS este configurat Există mai multe moduri de a face acest lucru: 1. Instalați...

Nu știu câți oameni au întâmpinat deja eroarea de a calcula soldurile inițiale și finale pe grupări. Personal, am fost „norocos”, de mai multe ori. Motivul, după cum am putut să aflu, constă în setările incorecte ale câmpurilor de date ACS, de a căror importanță mulți programatori începători (și nu atât de începători) nu sunt încă pe deplin conștienți.

Dacă nu ați mai întâlnit această problemă până acum, atunci pentru a înțelege mai bine esența ei, vă sugerez să o reproduceți singur folosind un raport universal (bazat pe metadate). Lansăm raportul, selectăm orice registru de acumulare nevid cu solduri și cifra de afaceri, activăm caseta de selectare „Înregistrări detaliate” în setările raportului (), indicăm unele grupări și adăugăm Recorder-ul în câmpurile de ieșire. Voila - soldurile de deschidere și de închidere sunt însumate pentru fiecare grupare. Rezultatul este un raport cu numere absolut incorecte, care nu poate fi afișat utilizatorilor.

Pentru a rezolva această problemă, este necesar să completați corect setările de câmp ale setului de date ACS - în special, câmpul „Rol”, care este de o importanță cheie.

SOLUȚIE interactivă ( nu este potrivit pentru raportul universal):

Deschideți diagrama de prezentare a datelor pentru raportul dvs. și priviți setările câmpului setului de date.

Pentru câmpurile soldurilor inițiale și finale pentru fiecare resursă, trebuie să completați rolul: selectați grupul de roluri „Restau” și în el specificați valoarea „Sold de început” sau respectiv „Sold final”. Asa de ( ) acest lucru se face în constructorul ACS.

În mod similar, trebuie să atribuiți rolul „Dimensiune” tuturor dimensiunilor din setul dvs. de date.

Dar acest lucru nu este suficient pentru ca rapoartele să funcționeze corect. Pentru a calcula corect câmpurile reziduale, trebuie să cunoașteți perioada fiecărei mișcări pentru a le plasa în ordinea cronologică corectă. Dacă sursa de date inițială nu are un câmp de perioadă, trebuie să îl adăugați acolo. Dacă câmpul perioadă există deja în setul de date, acesta trebuie specificat cu rolul „Perioadă” și numărul perioadei corespunzător (puteți citi mai multe despre numerotarea perioadei în ajutor).

Astfel de setări ale câmpurilor de date ACS fac în majoritatea cazurilor posibilă realizarea unui calcul corect al soldurilor prin grupare atunci când cu setările implicite sunt calculate incorect.

SOLUȚIE software (folosind exemplul Raportului de metadate universale):

Acum să vedem cum să remediați aceeași eroare în Raportul de metadate universale. Raportul universal diferă de majoritatea celorlalte rapoarte prin aceea că schema de prezentare a datelor de acolo este generată în întregime programatic, deci trebuie să configurați și rolurile pentru câmpurile de date ACS în mod programatic.

Pentru roluri soldurile de început și de sfârșit pentru fiecare resursă Cel mai simplu mod este să nu reinventezi roata (totul a fost deja scris înaintea noastră) și să folosești procedura standard Completați DataSetFieldRemainder() de la modulul general StandardReports. Acolo treceți câmpul setului de date și numele resursei ca parametri și, ca rezultat, un câmp rămas cu un rol completat corect este creat în setul de date.

În mod similar, atunci când creați câmpuri de set de date pentru dimensiuni, trebuie să le atribuiți rolul Dimensiune. Codul va fi cam așa:

NewDimension = TypicalReports.AddDataSetField(DataCompositionSchema.DataSets, Dimension.Name, Dimension.Synonym); NewDimension.Role.Dimension = Adevărat;

Manipulările cu câmpurile de resurse și dimensiuni descrise mai sus sunt necesare, dar nu suficiente pentru a rezolva problema - principala problemă a raportului universal este lipsa numerotării perioadelor. Câmpurile perioadei sunt prezente în setul de date, dar rolurile lor nu sunt completate.

Câmpurile de perioadă sunt adăugate raportului prin procedura modulului general StandardReports.AddPeriodFieldsToDataSet(), care este apelată din procedura modulului obiect AddDataSetFields(). Din păcate, această procedură nu atribuie numere de perioade.

În plus, câmpurile „Număr de linie” și „Registrar” nu sunt adăugate programatic nicăieri în raport. Mi s-a părut ciudat, pentru că... sunt prezente în setul de date final.

După cum sa dovedit, câmpurile „Număr de linie” și „Registrar”(Recorder) este adăugat automat de platformă în sine atunci când generatorul de setări este inițializat. Mai mult, platforma nu completează rolurile pentru câmpurile pe care le creează și nu este posibil să le completeze programatic, ceea ce creează probleme atunci când se lucrează în continuare cu ele. Dar dacă creați aceste câmpuri „manual” și le atribuiți programatic rolurile corecte, atunci platforma nu mai încearcă să le creeze din nou.

Vă ofer mai jos o rețetă care m-a ajutat să rezolv aproape complet această problemă a platformei și Raportul Universal Metadate:

Iată acest fragment de cod al modulului obiect:

// Adăugați câmpuri de perioadă Dacă TableName = "RemainsAndTurnover" SAU TableName = "Turnover" Then TypicalReports.AddPeriodFieldsToDataSet(DataCompositionScheme.DataSets); endIf; trebuie înlocuite cu următoarele: // Adăugați câmpuri de perioadă Dacă TableName = "RemainsAndTurnover" SAU TableName = "Turnover" Then PeriodList = TypicalReports.AddPeriodFieldsToDataSet(DataCompositionScheme.DataSets); //Completați câmpurile de serviciu și introduceți manual perioadele, deoarece platforma nu le completează Field = TypicalReports.AddDataSetField(DataCompositionSchema.DataSets, "RowNumber", "RowNumber"); Field.Role.PeriodNumber = 1; Câmp = TypicalReports.AddDataSetField(DataCompositionSchema.DataSets, „Registrator”, „Registrar”); Field.Role.PeriodNumber = 2; сч = 3; Pentru fiecare FieldPeriod din lista de perioade Ciclul FieldPeriod.Value.Role.PeriodNumber = count; Dacă număr > 3, atunci FieldPeriod.Value.Role.PeriodType = DataCompositionPeriodType.Additional; endIf; sch = sch+1; EndCycle; endIf;

Am reușit să găsesc o limitare asociată cu această soluție. Pentru calculul corect al începutului. si con. soldurilor, este necesar ca atunci când se utilizează orice detalii ale unui document de înregistrare într-un raport, registratorul însuși trebuie să fie selectat. În caz contrar, raportul universal după astfel de modificări nu mai provoacă alergii în rândul utilizatorilor.

UPDATE: Mi s-a spus în comentarii că un articol pe această temă a fost odată publicat pe discul ITS. Din păcate, acest articol a trecut pe lângă mine, dar m-a putut ajuta doar parțial în rezolvarea problemelor cu raportul universal. Din păcate, problemele platformei cu câmpurile de servicii ACS, cum ar fi „Recorder”, nici nu sunt descrise acolo.

În orice caz, sper că articolul meu îi va ajuta pe toți cei care au probleme similare. Am petrecut mult timp cautand aceasta solutie...