Totul despre tuning auto

Crearea și lucrul cu solicitări (pentru începători). Crearea și lucrul cu interogări (pentru începători) 1c tip de document într-o interogare

Klyuev V.V.

http://prof1c.kklab.ru

Creația șilucrul cu cereri. Cele mai simple operațiipentru incepatori(Aplicație regulată)

Bună ziua

Astăzi vreau să vă spun cum să începeți să lucrați cu interogări și să învățați (treptat, desigur) cum să lucrați cu interogări în 1C. Pentru cei familiarizați cu întrebările MS
SQL va fi, desigur, mult mai simplu.

Deci, să deschidem configuratorul și să creăm o nouă procesare externă.

După care vom primi o fereastră cu procesarea noastră. Să trecem direct la experimente cu privire la solicitări, pentru aceasta vom crea un formular nou în procesarea noastră - și pentru aceasta, în listă (câmp alb), selectați Formulare - și faceți clic pe (+) Adăugați, de acord cu toți parametrii de formular implicit propuși și faceți clic pe Terminat.

Așa că am creat un formular gol pentru tine, cu butoane și. În fereastra cu formular, selectați filele și treceți direct la scrierea codului care va fi executat când faceți clic pe butonul de executare. Pentru a face acest lucru, găsiți procedura ButtonExecutePress(Button)

si scrie urmatorul cod:

Procedura ButtonExecutePress(Button) Request = New Request() ; Cerere. Text = " SELECTAȚI | * | DIN| Document . Factură de plată către Cumpărător" ; Rezultat = Interogare. Executați (). Descărcați (); Sfârșitul procedurii

Să comentăm ce am scris aici. Am selectat toate documentele „Factură de plată către Cumpărător” împreună cu cererea. Aș dori să notez imediat că, în funcție de configurația în care experimentați, uitați-vă la compoziția documentelor din configurația dvs. și în locul „Facturii de plată către Cumpărător” pe care am indicat-o, înlocuiți orice obiect Document din lista de documente din configurația dvs., de preferință astfel încât documentele de acest tip să fie create în baza de informații, pentru a evita obținerea unui rezultat de interogare gol. De asemenea, vreau să remarc un punct important - dacă există prea multe astfel de documente, atunci executarea cererii poate dura ceva timp - datorită faptului că nu limităm cererea la condiții și selectăm toate câmpurile - care asteriscul ( *) spune-ne.

Cu cuvântul cheie „Selectați” ordonăm solicitarea noastră de a selecta toate câmpurile (*) (detalii document) din documentul „Factură de plată către Cumpărător”.

Important:
De asemenea, aș dori să remarc că atunci când scriu un limbaj de interogare, obiectele de configurare ar trebui să fie adresate la singular, nu la plural. In acest
caz, obiectul Documente din configurație (ramura Documente) - cererea conține un Document. De asemenea, la compoziția documentelor - ajungem prin punctul (.) - și denumirea documentului.

Primim rezultatul solicitării sub forma unui tabel de valori, după cum demonstrează metoda (parametrul) folosită - Încărcați, adică mai întâi am executat
cerere (Run), și abia apoi a încărcat rezultatul interogării în tabelul de valori, iar tabelul de valori se află în variabila Rezultat.

Apoi, ne salvăm procesarea într-un fișier, pentru a face acest lucru, faceți clic pe File->Save As și scrieți numele fișierului, pentru procesarea mea am setat numele „ExternalProcessing1Demo”, pentru a nu căuta procesarea mult timp, îl poți salva pe desktop, apoi va trebui să îl deschidem)).

Acum să învățăm câteva elemente de bază despre depanare. Pentru a face acest lucru, acum în câmpul de lângă textul Rezultat = ... faceți dublu clic pe butonul stâng al mouse-ului, astfel încât să apară un cerc roșu, ar trebui să obțineți ceva de genul următor:

Deci, acum am setat un punct de întrerupere pe linia cu rezultatul, acum să rulăm configurația pentru depanare apăsând tasta (F 5) sau butonul
pe bara de instrumente:

Acum, în modul 1C:Enterprise pe care l-am lansat, să deschidem fișierul nostru de procesare salvat->Deschide și găsim locul în care ați salvat fișierul de procesare, selectați-l și faceți clic pe Deschide. Faceți clic pe butonul „Run” în procesarea noastră. Dacă ați făcut totul corect, veți trece automat la modul configurator și veți vedea următoarele în locația în care a fost instalat punctul nostru de întrerupere:

Pe cercul nostru a apărut o săgeată - am trecut la execuția pas cu pas a codului nostru și apoi vom vedea cel mai interesant lucru. Dacă ați făcut totul corect, acum puteți obține rezultatul solicitării.

Pentru a vizualiza cererea, procedați în felul următor: În meniul de sus al configuratorului, găsiți meniul Depanare și selectați comanda Tableau.

O fereastră goală -> Tableau se va deschide în partea de jos a ferestrei configuratorului. Există linii goale în această fereastră. Faceți dublu clic pe linia evidențiată goală și scrieți cuvântul Rezultat. Ar trebui să obțineți următoarele:

Deci, în fereastra pe care am specificat-o, ar trebui să primim rezultatul executării codului nostru, și anume acum - variabila „Rezultat”, deoarece nu am executat încă această linie de cod - avem o valoare goală și tipul de date al variabilei este „Nedefinit”.

Să facem un pas - pentru a executa linia de cod specificată. Pentru a face acest lucru, apăsați tasta sau în meniul Debug->Step through... (F 10).

Și ce vedem în tabloul nostru:

Vedem cu tine - valoarea variabilei și tipul variabilei. Acum putem vizualiza și conținutul tabelului nostru de valori, pentru a face acest lucru, mutați cursorul mouse-ului în câmpul de rezultat, faceți clic dreapta și selectați „Afișați valoarea într-o fereastră separată”

Primim o fereastră cu documentele pe care le-am selectat, care se află în variabila Rezultat

A rezuma:

Ați învățat cum să creați o solicitare simplă și, de asemenea, ați luat parte la depanarea codului dvs. și chiar v-ați uitat la rezultatul solicitării noastre în configurator.

Am decis să-mi aduc contribuția și să descriu acele trăsături ale limbajului care nu au fost discutate în articolele de mai sus. Articolul se adresează dezvoltatorilor începători.

1. Design „IZ”.

Pentru a obține date din baza de date nu este deloc necesară utilizarea construcției „FROM”.
Exemplu: Trebuie să selectăm toate informațiile despre bănci din directorul băncilor.
Cerere:

SELECT Director.Bănci.*

Selectează toate câmpurile din directorul Bănci. Și este similar cu cererea:

SELECT Bănci.* FROM Directory.Bănci AS Bănci

2. Comandarea datelor după câmpul de referință

Când trebuie să organizăm datele de interogare pe tipuri primitive: „Șir”, „Număr”, „Data”, etc., atunci totul este rezolvat folosind constructul „ORDER BY” dacă trebuie să ordonați datele după un câmp de referință? Câmpul de referință este o legătură, un identificator unic, adică În linii mari, un set arbitrar de caractere și o ordine obișnuită pot produce un rezultat care nu este în întregime așteptat. Pentru a comanda câmpuri de referință se folosește construcția „AUTO ORDER”. Pentru a face acest lucru, trebuie mai întâi să ordonați datele direct după tipul de referință folosind constructul „ORDER BY”, apoi constructul „AUTO ORDER”.

În acest caz, pentru documente comanda se va face în ordinea „Data->Număr”, pentru cărțile de referință în „Vizualizarea principală”. Dacă comandarea nu are loc prin câmpuri de referință, atunci nu se recomandă utilizarea construcției „COMANDĂ AUTOMATĂ”.

În unele cazuri, constructul „AUTO ORDER” poate încetini procesul de selecție. În mod similar, puteți rescrie fără comandă automată pentru documente:

3.Obținerea unei reprezentări text de tip referință. Design „PRESENTARE”.

Când trebuie să afișați un câmp de tip de referință, de exemplu, câmpul „Bancă”, care este o legătură către un element din directorul „Bănci”, trebuie să înțelegeți că atunci când afișați acest câmp, o subinterogare către „ Directorul „Bănci” va fi executat automat pentru a obține o vizualizare a directorului. Acest lucru va încetini producția de date. Pentru a evita acest lucru, trebuie să utilizați construcția „PRESENTARE” în ​​cerere pentru a obține imediat o reprezentare a obiectului și apoi afișat-o pentru vizualizare.

În sistemul de compunere a datelor, acest mecanism este utilizat în mod implicit, dar atunci când creați machete în celule, ar trebui să specificați reprezentarea câmpului de referință și, de exemplu, să plasați legătura în sine în transcriere.

4. Condiție pentru eșantionarea datelor conform unui șablon.

De exemplu, trebuie să obțineți telefoane mobile ale angajaților din formular (8 -123-456-78-912). Pentru a face acest lucru, trebuie să setați următoarea condiție în cerere:

SELECTEAZĂ Employee.Name, Employee.Phone AS Phone FROM Directory.Employees AS Angajati WHERE Phone LIKE "___-_-___-__-__"

Caracterul „_” este un caracter de serviciu și înlocuiește orice caracter.

5. Utilizarea simultană a totalurilor și grupărilor.


Totalurile sunt adesea folosite împreună cu grupările; în acest caz, funcțiile agregate pot să nu fie specificate în totaluri.

SELECT Prestare de servicii.Organizare AS Organizație, Furnizare de servicii.Nomenclatură AS Nomenclatură, SUM(Furnizare de servicii.Sumă document) AS Sumă document FROM Document.Prestare de servicii AS Prestare de servicii GROUP BY Prestare de servicii.Organizare, Furnizare de Servicii.Nomenclatura REZULTATE PENTRU GENERAL, Organizare, Nomen klatura

În acest caz, interogarea va returna aproape la fel ca următoarea interogare:

SELECT Prestare de servicii.Organizație AS Organizație, Furnizare de servicii.Nomenclator AS Nomenclator, Furnizare de servicii.Suma de document AS Cantitatea de document FROM Document.Prestare de servicii AS Furnizare de servicii REZULTATE SUMA (Suma de document) BY GENERAL, Organizație, Nomenclatură

Doar prima interogare va restrânge înregistrările cu aceeași nomenclatură.

6. Dereferențiarea câmpurilor.

Referirea la câmpuri printr-un punct se numește operația de dereferențiere a câmpurilor de referință. De exemplu Plata.Organizarea.Unitatea Administrativa. În acest caz, în câmpul de referință „Organizație” din documentul „Plată” se referă la un alt tabel „Organizații”, în care se va obține valoarea atributului „Unitate administrativă”. Este important să înțelegeți că atunci când accesați câmpuri printr-un punct, platforma creează implicit o subinterogare și se alătură acestor tabele.

Cerere:

Poate fi reprezentat ca:

SELECTAȚI Payment.Link, Payment.Organization, Payment.Organization, Organizations. AdministrativeUnit FROM Document.Payment AS Payment LEFT JOIN Directory.Organizations AS Organizations Software Payment.Organization = Organizations.Link

Când dereferențează câmpurile de referință de tip compus, cadrul încearcă să creeze îmbinări implicite la toate tabelele care fac parte din tipul acelui câmp. În acest caz, interogarea nu va fi optimă.Dacă se știe clar ce tip de câmp este, este necesar să se limiteze astfel de câmpuri după tip cu un construct EXPRES().

De exemplu, există un registru de acumulare „Plăți nedistribuite”, unde mai multe documente pot acționa ca registrator. În acest caz, este incorect să obțineți valorile detaliilor registratorului în acest fel:

SELECTAȚI Plăți nealocate.Data.Înregistrare, ..... FROM RegisterAcumulare.Plăți nealocate AS Plăți nealocate

ar trebui să restricționați tipul câmpului compus la logger:

SELECTAȚI EXPRESS(Plăți nealocate.Înregistrați ca document.Plată).Data, ..... FROM RegisterAcumulare.Plăți nealocate AS Plăți nealocate

7. Construcție „UNDE”

Cu o îmbinare la stânga a două tabele, când impuneți o condiție „UNDE” pe masa din dreapta, vom obține un rezultat similar cu rezultatul cu o îmbinare interioară a meselor.

Exemplu. Este necesar să se selecteze toți Clienții din Directorul Clienți iar pentru acei clienți care au un document de plată cu valoarea atributului „Organizație” = &Organizare, să se afișeze documentul „Plată”, pentru cei care nu au, să nu-l afișeze.

Rezultatul interogării va returna înregistrări numai pentru acei clienți care au avut plata prin organizație în parametru și va filtra alți clienți. Prin urmare, trebuie să primiți mai întâi toate plățile pentru „un astfel de” organizație într-un tabel temporar și apoi să o conectați la directorul „Clienți” folosind o alăturare stângă.

SELECT Plata.Link AS Plata, Plata.Acţionar AS Client PLACE laPlăţi FROM Document.Plata AS Plata WHERE Plata.Sucursala = &Branch; //////////////////////////////////////////////////////////////////// ////////////////////////// SELECT Clients.Link AS Client, ISNULL(tPayment.Payment, "") AS Payment FROM Directory .Clients AS Clienții LEFT CONNECTION topayments AS topayments SOFTWARE Clients.Link = topayments.Client

Puteți ocoli această afecțiune într-un alt mod. Este necesar să se impună o condiție „UNDE” direct relației dintre cele două tabele. Exemplu:

SELECT Clients.Link, Payment.Link FROM Directory.US_Subscribers AS US_Subscribers LEFT CONNECTION Document.Payment AS Payment Software (Clients.Link = Payment.Client AND Payment.Client.Name LIKE "Sugar Packet") GROUP BY Clients.Link, Payment. Legătură

8. Uniri cu tabele imbricate și virtuale

Interogări imbricate adesea necesar pentru a prelua date pe baza unei anumite condiții. Dacă apoi le utilizați împreună cu alte tabele, acest lucru poate încetini critic execuția interogării.

De exemplu, trebuie să obținem suma soldului de la data curentă pentru unii clienți.

SELECT UnallocatedPaymentsRemains.Customer, UnallocatedPaymentsRemains.AmountRemaining FROM (SELECT Clients.Link AS Link FROM Directory.Clients AS Clients WHERE Clients.Link IN(&Clients)) AS NestedQuery LEFT JOIN RegisterAccumulations.UnallocatedPayments.BaquestedPayments. lăncile. Client

La executarea unei astfel de interogări, optimizatorul DBMS poate face erori la alegerea unui plan, ceea ce va duce la o execuție suboptimă a interogării. La unirea a două tabele, optimizatorul DBMS selectează un algoritm de îmbinare a tabelelor pe baza numărului de înregistrări din ambele tabele. Dacă există o interogare imbricată, este extrem de dificil să se determine numărul de înregistrări pe care le va returna interogarea imbricată. Prin urmare, ar trebui să utilizați întotdeauna tabele temporare în loc de interogări imbricate. Deci, să rescriem cererea.

SELECTARE Clienți.Link AS Link PLACE tClienți DIN Director.Clienți AS Clienți WHERE
Clienți.Link B (&Clienți) ; //////////////////////////////////////////////////////////////////// /////////////////////////// SELECTAȚI tClients.Link, UnalocatedPaymentsRemains.AmountRemaining, FROM tClients AS tClients LEFT JOIN RegisterAccumulations.UnallocatedPayments.Balances (, Client IN (SELECTARE tClients.Link FROM tClients)) AS UnallocatedPaymentsBalances tClients.Link = UnallocatedPaymentsBalances.Clients

În acest caz, optimizatorul va putea determina câte înregistrări folosește tabelul temporar tClients și va putea selecta algoritmul optim pentru unirea tabelelor.

Mesele virtuale , vă permit să obțineți date practic gata făcute pentru majoritatea sarcinilor aplicate (Slice of the First, Slice of the Last, Remains, Turnovers, Remains și Turnovers) Cuvântul cheie aici este virtual. Aceste tabele nu sunt fizice, ci sunt compilate de sistem din mers, adică. Când primește date de la tabele virtuale, sistemul colectează date din tabelele de registru finale, le asamblează, le grupează și le transmite utilizatorului.

Acestea. Când vă conectați la o tabelă virtuală, se face o conexiune la o subinterogare. În acest caz, optimizatorul DBMS poate alege și un plan de conexiune neoptimal. Dacă interogarea nu este generată suficient de rapid și interogarea folosește îmbinări în tabele virtuale, atunci se recomandă să mutați accesul la tabelele virtuale într-un tabel temporar și apoi să faceți o îmbinare între două tabele temporare. Să rescriem cererea anterioară.

SELECTAȚI Clienți.Link AS Link PLACE tClienți DIN Director.Clients AS Clienți INDEX BY Link WHERE
Clienți.Link B (&Clienți) ; //////////////////////////////////////////////////////////////////// ////////////////////////// SELECTAȚI Plăți Nealocate.SoldBalance, Plăți Nealocate.Client AS Client PLACE solduri FROM RegisterAccumulations.UnallocatedPayments.Balances(, Client B ( SELECTAȚI tClients. Link FROM tClients)) AS UnallocatedPaymentsBalances; //////////////////////////////////////////////////////////////////// /////////////////////////// SELECTAȚI tClients.Link, toRemainders.AmountRemaining AS AmountRemaining FROM tClients AS tClients LEFT JOIN toRemainders AS Remainders BY tClients.Link = tRemainings.Client

9.Verificarea rezultatului cererii.

Rezultatul interogării poate fi gol; pentru a verifica valorile goale, utilizați următorul construct:

ResRequest = Request.Execute(); Dacă resQuery.Empty() Apoi Return; endIf;

Metodă Gol() trebuie folosit înainte de metode Alege() sau Descărca(), deoarece recuperarea colecției necesită timp.

Nu este o revelație pentru nimeni că este extrem de nedorit să folosești interogări într-o buclă. Acest lucru poate afecta în mod critic timpul de funcționare al unei anumite funcții. Este foarte de dorit să primiți toate datele din cerere și apoi să procesați datele într-o buclă. Dar uneori există cazuri când devine imposibil să mutați cererea în afara buclei. În acest caz, pentru optimizare, puteți muta crearea interogării în afara buclei, iar în buclă, înlocuiți parametrii necesari și executați interogarea.

Solicitare = Solicitare nouă; Query.Text = "SELECT | Clients.Link, | Clients.Birthdate |FROM | Directory.Clients AS Clients |WHERE | Clients.Link = &Client"; Pentru fiecare rând FROM TableClients Loop Query.SetParameter("Client", Client); QueryResult = Query.Execute().Select(); EndCycle;

Acest lucru va salva sistemul de la verificarea sintaxei cererii într-o buclă.

11. Construcție „AVÂND”.

Un design destul de rar la solicitari. Vă permite să impuneți condiții asupra valorilor funcțiilor agregate (SUMA, MINIM, MEDIE etc.). De exemplu, trebuie să selectați numai acei clienți a căror sumă de plată în septembrie a fost mai mare de 13.000 de ruble. Dacă utilizați condiția „UNDE”, va trebui mai întâi să creați un tabel temporar sau o interogare imbricată, să grupați înregistrările acolo după suma de plată și apoi să aplicați condiția. Construcția „HAVING” va ajuta la evitarea acestui lucru.

SELECT Plata.Client, SUMA(Suma.Plată) AS Sumă FROM Document.Plata AS Plată WHERE MONTH(Data.Plată) = 9 GROUP BY Plată.Client HAVING AMOUNT(Suma.Plata) > 13000

În constructor, pentru a face acest lucru, trebuie doar să accesați fila „Condiții”, adăugați o nouă condiție și bifați caseta de selectare „Personalizat”. Atunci doar scrie Sumă (Plată. Sumă) > 13000


12. Valoare NULL

Nu voi descrie aici principiile logicii cu trei valori din baza de date; există multe articole pe această temă. Doar pe scurt despre cum NUL poate afecta rezultatul interogării. Valoarea NULL nu este de fapt o valoare, iar faptul că valoarea este nedefinită este necunoscut. Prin urmare, orice operație cu NULL returnează NULL, fie că este adunare, scădere, împărțire sau comparație. O valoare NULL nu poate fi comparată cu o valoare NULL deoarece nu știm ce să comparăm. Acestea. ambele aceste comparații sunt: ​​NULL = NULL, NULL<>NULL nu este adevărat sau fals, este necunoscut.

Să ne uităm la un exemplu.

Pentru acei clienți care nu au plăți, trebuie să afișăm câmpul „Semnați” cu valoarea „Fără plăți”. Mai mult, știm sigur că avem astfel de clienți. Și pentru a reflecta esența a ceea ce am scris mai sus, să o facem astfel.

SELECTAȚI „Fără plăți” AS Atribut, NULL AS Document PLACE la plăți; //////////////////////////////////////////////////////////////////// ///////////////////////// SELECT Clients.Link AS Client, Payment.Link CUM PUNE Payment tClientPayment FROM Directory.Clients AS Clients LEFT CONNECTION Document. Payment AS Payment Software Clients.Link = Payment.Shareholder; //////////////////////////////////////////////////////////////////// ////////////////////////// SELECTAȚI tClientPayment.Client FROM tClientPayment AS tClientPayment INTERNAL JOIN tPayment AS tTopay BY tClientPayment.Payment = tPayment. Document

Acordați atenție celui de-al doilea tabel temporar tClientPayment. Cu alăturarea din stânga selectez toți clienții și toate plățile pentru acești clienți. Pentru acei clienți care nu au plăți, câmpul „Plată” va fi NULL. Urmând logica, în primul tabel temporar „tPayments” am desemnat 2 câmpuri, unul dintre ele NULL, a doua linie „Nu are plăți”. În al treilea tabel, conectez tabelele „tClientPayment” și „tPayment” folosind câmpurile „Plată” și „Document” cu o îmbinare internă. Știm că în primul tabel câmpul „Document” este NULL, iar în al doilea tabel, cei care nu au plăți în câmpul „Plată” sunt și NULL. Ce ne va returna o astfel de conexiune? Dar nu va returna nimic. Deoarece comparația NULL = NULL nu se evaluează la True.

Pentru ca cererea să returneze rezultatul așteptat, să o rescriem:

SELECTAȚI „Fără plăți” AS Atribut, VALUE(Document.Payment.EmptyLink) AS Document PLACE to Payments; //////////////////////////////////////////////////////////////////// ////////////////////////// SELECT Clients.Link AS Client, ISNULL(Payment.Link, VALUE(Document.Payment.EmptyLink )) CUM Payment PUT tClientPayment FROM Directory.Clients AS Clients LEFT CONNECTION Document.Payment AS Payment BY Clients.Link = Payment.Shareholder; //////////////////////////////////////////////////////////////////// ////////////////////////// SELECTAȚI tClientPayment.Client FROM tClientPayment AS tClientPayment INTERNAL JOIN tPayment AS tTopay BY tClientPayment.Payment = tPayment. Document

Acum, în cel de-al doilea tabel temporar, am indicat că dacă câmpul „Plată” este NULL, atunci acest câmp = un link gol către documentul de plată. În primul tabel am înlocuit, de asemenea, NULL cu o referință goală. Acum conexiunea implică câmpuri non-NULL și cererea va returna rezultatul așteptat.

Toate cererile cuprinse în articol reflectă situațiile pe care aș dori să le iau în considerare și nimic mai mult. DESPRE Ele pot să nu fie delirante sau suboptimale, principalul lucru este că reflectă esența exemplului.

13. O caracteristică nedocumentată a designului „ALEGE CÂND... ATUNCI... Sfârșit”.

În cazul în care este necesar să descriem construcția „Condiții” în cerere, folosim sintaxa standard:

SELECTAȚI SELECTAREA CÂND Utilizatori.Nume = „Vasya Pupkin” APOI „Angajatul nostru preferat” ELSE „Nu știm asta” END AS Field1 FROM Directory.Users AS Users

Dar dacă, de exemplu, trebuie să obținem numele lunii într-o solicitare? Scrierea unei construcții uriașe într-o solicitare este urâtă și necesită timp, așa că această formă de scriere de mai sus ne poate ajuta:

SELECTAȚI LUNA(US_CalculationConsumption_ScheduleTurnover.CalculationPeriod) CÂND 1 APOI „Ianuarie” CÂND 2 APOI „Februarie” CÂND 3 APOI „Martie” CÂND 4 APOI „Aprilie” CÂND 5 APOI „Mai” CÂND 7 IUNIE CÂND 6 IUNIE CÂND 8 APOI "August" CÂND 9 APOI "Septembrie" CÂND 10 APOI "Octombrie" CÂND 11 APOI "Noiembrie" CÂND 12 APOI "Decembrie" SE SFÂRȘTEȘTE CA O LUNĂ

Acum, designul pare mai puțin greoi și este ușor de înțeles.

14. Executarea interogării pe lot.


Pentru a nu multiplica cererile, puteți crea o cerere mare, o puteți împărți în pachete și puteți lucra cu ea.
De exemplu, trebuie să obțin următoarele câmpuri din directorul „Utilizatori”: „Data nașterii” și rolurile disponibile pentru fiecare utilizator. încărcați acest lucru în diferite părți tabelare din formular. Desigur, puteți face acest lucru într-o singură solicitare, apoi va trebui să repetați înregistrările sau să le restrângeți, sau puteți face acest lucru:

SELECT Users.Link AS Nume complet, Users.Date of Birth, Users.Role PUT vtUsers FROM Directory.Users AS Users; //////////////////////////////////////////////////////////////////// ////////////////////////// SELECT tueUsers.Nume complet, tueUsers.Data nașterii FROM tueUsers AS tueUsers GROUP BY tueUsers.nume complet, tueUsers . Data nașterii; //////////////////////////////////////////////////////////////////// ////////////////////////// SELECT wUsers.Full Name, wUsers.Role FROM wUsers AS wUsers GROUP BY wUsers.Full Name, wUsers. Data de nastere

tPackage = Request.ExecutePackage();

TP_BirthDate = tPackage.Upload();
TP_Roles = tPackage.Unload();

După cum putem vedea, interogarea poate fi executată într-un lot, iar rezultatul poate fi procesat ca o matrice. În unele cazuri este foarte convenabil.

15. Condiții într-o cerere de lot

De exemplu, avem o cerere de lot, unde mai întâi primim câmpurile: „Nume, Data nașterii, Cod” din directorul „Utilizatori” și dorim să obținem înregistrări cu condiții pentru aceste câmpuri din directorul „Persoane fizice”.

SELECT Users.Individual.Name AS Nume, Users.Individual.Date of Birth AS Data of Birth, Users.Individual.Code AS Cod PLACE vtUsers FROM Directory.Users AS Users; //////////////////////////////////////////////////////////////////// ////////////////////////// SELECTAȚI Persoane. Legătură ca persoană fizică din director. Persoane ca persoane fizice

Puteți impune condiții ca aceasta:

WHERE Individuals.Code IN (SELECT vtUsers.Code FROM vtUsers) AND Individuals.Name IN (SELECT vtUsers.Code FROM vtUsers) AND Individuals.BirthDate IN (SELECT vtUsers.DateBirth FROM tvUsers)

Și poți face așa:

WHERE (Persoane.Cod, Nume persoane fizice, Persoane fizice.Data nașterii) IN (SELECT tueUsers.Code, tueUsers.Name, tueUsers.Data nașterii FROM tueUsers)

Mai mult, este necesară menținerea ordinii.

16. Apelarea generatorului de interogări pentru „condiție” într-o cerere de lot

Când este necesar să se impună o condiție, ca în exemplul de mai sus, puteți uita cum este numit acest sau acel câmp în tabelul virtual.
De exemplu, trebuie să impuneți o condiție câmpului „Data nașterii”, iar în tabelul virtual acest câmp se numește „Data nașterii debitorului”, iar dacă uitați numele, va trebui să părăsiți editarea condiției fără salvând și uită-te la numele câmpului. Pentru a evita acest lucru, puteți utiliza următoarea tehnică.

Este necesar să puneți paranteze după Construcția „B” și să lăsați un spațiu gol (spațiu) între paranteze, selectați acest spațiu și apelați constructorul de interogare. Proiectantul va avea acces la toate tabelele interogării lot. Tehnica funcționează atât pe tabele de registre virtuale, cât și pe fila „Condiții”. În acest din urmă caz, trebuie să bifați caseta „P (condiție arbitrară)” și să intrați în modul de editare „F4”.

Interogările au fost adesea făcute din mers și servesc pur și simplu pentru a ilustra „tehnicile” pe care le aveam în vedere.

Am vrut să mă uit la utilizarea indecșilor în interogări, dar acesta este un subiect foarte larg. Îl voi pune într-un articol separat sau îl voi adăuga aici mai târziu.

upd1. Punctele 11,12
upd2. Punctele 13,14,15,16

Cărți folosite:
Limbajul de interogare „1C:Enterprise 8” - E.Yu. Khrustaleva
Dezvoltare profesională în sistemul 1C:Enterprise 8.”

În acest articol dorim să discutăm totul cu tine Funcții de limbaj de interogare 1C, și constructele limbajului de interogare. Care este diferența dintre funcție și design? Funcția este apelată cu paranteze și posibili parametri în ele, iar constructul este scris fără paranteze. Fara indoiala toate structurile și funcțiile limbajului de interogare 1C face procesul de achiziție a datelor flexibil și multifuncțional. Aceste funcții și constructe se aplică câmpurilor de interogare, iar unele se aplică și condițiilor.

1C Funcții limbaj de interogare

Pentru că o descriere clară Funcții de limbaj de interogare 1C este mult mai puțin frecventă decât descrierile structurilor, am decis să începem să ne uităm la funcții. Acum să ne uităm la fiecare separat, descriindu-i scopul, sintaxa și exemplul de utilizare, deci:

1. Funcţie DATA ORA- această funcție creează un câmp constant cu tipul „Date”.

Sintaxă: DATA ORA(<Год>,<Месяц>,<День>,<Час>,<Минута>,<Секунда>)

Exemplu de utilizare:

2. Funcția DATE DIFERENTĂ- returnează diferența dintre două date într-unul dintre dimensiuni (an, lună, zi, oră, minut, secundă). Măsurarea este trecută ca parametru.

Sintaxă: DIFERENCEDATE(<Дата1>, <Дата2>, <Тип>)

Exemplu de utilizare:

Query.Text = „SELECT | DIFFERENCEDATE(DATETIME(2015, 4, 17), DATETIME(2015, 2, 1), DAY) | AS Număr de zile”;

3. Funcția VALUE- setează un câmp constant cu o înregistrare predefinită din baza de date; puteți obține și un link gol de orice tip.

Sintaxă: VALUE(<Имя>)

Exemplu de utilizare:

Request.Text = „SELECT //element predefinit | VALUE(Directory.Currencies.Dollar) AS Dollar, //link gol | VALUE(Document.Receipt of Goods and Services.EmptyLink) AS Receipt, //transfer value | VALUE(Transfer . Persoană fizică juridică. Persoană fizică) AS Persoană fizică, //cont predefinit | VALUE(Planul de conturi. Autoportant. Materiale) AS Account_10" ;

4. Funcția SELECT- avem în fața noastră un analog al construcției IF, care este folosit în cod, doar acesta este folosit în interogările 1C.

Sintaxă: ALEGERE CÂND<Выражение>APOI<Выражение>IN CAZ CONTRAR<Выражение>Sfârşit

Exemplu de utilizare:

Solicitare.Text = //dacă suma este mai mare de 7500, atunci ar trebui să existe o reducere de 300 de ruble, //deci dacă condiția este declanșată, atunci funcția //returnează Suma - 300 //în caz contrar, cererea va returna pur și simplu Suma „SELECT | SELECT | WHEN TTCReceipts.Amount > 7500 | THEN TTCReceipts.Amount - 300 | ELSE TTCReceipts.Amount | END AS AmountWithDiscount |FROM | Document.Receipt of GoodsServices.Goods AS TTCReceipts”;

5. Funcția EXPRESS- vă permite să exprimați un câmp constant cu un anumit tip.

Sintaxă: EXPRESS(FieldName AS TypeName)

Exemplu de utilizare:

Query.Text = "SELECT VARIOUS | Sales.Registrar.Number, | SELECT | WHEN Sales.Registrar LINK Document.Consumable | THEN EXPRESS(Sales.Registrar AS Document.Consumable) | ELSE SELECT | WHEN Sales.Registrar LINK Document.Implementation | THEN EXPRESS(Sales.Registrar AS Document.Implementation) | END | ... | END AS Număr | FROM | RegisterAcumulations.Purchases AS Purchase";

Există o altă opțiune pentru utilizarea funcției EXPRESS în câmpuri de tipuri mixte, unde apar acestea? Cel mai simplu exemplu este „Registrul” pentru orice registru. Deci, de ce ar trebui să calificăm tipul în registrator? Să luăm în considerare situația când selectăm câmpul „Număr” de la registrator, din ce tabel va fi selectat numărul? Răspunsul corect al tuturor! Prin urmare, pentru ca interogarea noastră să funcționeze rapid, ar trebui să specificăm un tip explicit folosind funcția EXPRESS

Exemplu de utilizare:

Query.Text = "SELECT | EXPRESS(Nomenclature.Comment AS Line(300)) AS Comment, | EXPRESS(Nomenclature.Sum AS Number(15,2)) AS Sum |FROM | Directory.Nomenclature AS Nomenclature";

6. Funcția ISNULL(ortografie alternativă ISNULL) - dacă câmpul este de tip NULL, atunci se înlocuiește cu al doilea parametru al funcției.

Sintaxă: ISNULL(<Поле>, <ПодставляемоеЗначение>)

Exemplu de utilizare:

De asemenea, rețineți că este recomandabil să înlocuiți ÎNTOTDEAUNA tipul NULL cu o anumită valoare, deoarece comparația cu tipul NULL returnează întotdeauna FALSE chiar dacă comparați NULL cu NULL. Cel mai adesea, valorile NULL sunt formate ca urmare a îmbinării tabelelor (toate tipurile de îmbinări, cu excepția celor interne).

Query.Text = //Selectați întregul articol și soldurile acestuia //dacă nu există sold într-un articol, atunci va exista un câmp //NULL care va fi înlocuit cu valoarea 0 "SELECT | No. Link, | ISNULL (ProductsInStockRemains.InStockRemaining, 0) AS Rest | FROM | Directory.Nomenclature AS Nr. | LEFT CONNECTION Înregistrați acumulări. BunuriÎnDepozite. Rămășite AS BunuriÎnDepoziteRemains | ON (GoodsInWarehousesRemains. Nomenclatură)"; = No.

7. Funcția REPREZENTARE- vă permite să obțineți o reprezentare a câmpului de solicitare.

Sintaxă: PERFORMANŢĂ(<НаименованиеПоля>)

Exemplu de utilizare:

Query.Text = "SELECT | REPRESENTATION(FreeRemainingRemains.Nomenclature) AS Nomenclature, | REPRESENTATION(FreeRemainingRemaining.Warehouse) AS Warehouse, | FreeRemainingRemaining.InStockRemaining |FROM |Acumulation Register.FreeRemaining AS FreeRemaining;Remaining"

Construcții în limbajul de interogare 1C

Am discutat cu tine mai sus Funcții de limbaj de interogare 1C, acum este timpul să luați în considerare constructe în limbajul de interogare 1C, nu sunt mai puțin importante și utile, să începem.

1. Constructii LINK- este un operator logic pentru verificarea unui tip de referință. Cel mai des întâlnit la verificarea unui câmp de tip complex cu un anumit tip. Sintaxă: LEGĂTURĂ<Имя таблицы>

Exemplu de utilizare:

Solicitare.Text = //dacă tipul de valoare înregistrator este document Recepție, //atunci interogarea va returna „Recepție de mărfuri”, în caz contrar, „Vânzări de mărfuri” „SELECT | SELECT | WHEN Remainings.Registrar LINK Document.Receipt of Goods and Servicii | ATUNCI ""Chitare"" | ALTA ""Consum"" | END AS Tip de miscare | DIN | Registrul de acumulare. Produse ramase in depozite AS Resturi" ;

2. Design INTRE- acest operator verifică dacă valoarea se află în intervalul specificat.

Sintaxă: ÎNTRE<Выражение>ȘI<Выражение>

Exemplu de utilizare:

Request.Text = //obține întreaga nomenclatură al cărei cod este în intervalul de la 1 la 100 "SELECT | Nomenclature.Link |FROM | Directory.Nomenclature AS Nomenclature |WHERE | Nomenclature.Code BETWEEN 1 AND 100" ;

3. Construcția B și B IERARHIE- verificați dacă valoarea se află în lista transferată (matricele, tabelele de valori etc. pot fi transferate ca listă). Operatorul ÎN IERARHIE vă permite să vizualizați ierarhia (un exemplu de utilizare a Planului de conturi).

Sintaxă: ÎN(<СписокЗначений>), ÎN IERARHIE(<СписокЗначений>)

Exemplu de utilizare:

Solicitare.Text = //selectați toate subconturile contului „SELECT | Auto-susținut. Link AS Account | FROM | Plan de conturi. Auto-susținut AS Auto-susținut | WHERE | Auto-susținător. Link ÎN VALOAREA IERARHIEI (Graficul de Conturi. Autoportante. Bunuri)";

4. Design similar- Această funcție ne permite să comparăm un șir cu un model de șir.

Sintaxă: LIKE "<ТекстШаблона>"

Opțiuni de model de rând:

% - o secvență care conține orice număr de caractere arbitrare.

Un personaj arbitrar.

[...] - orice caracter unic sau secvență de caractere enumerate între paranteze drepte. Enumerarea poate specifica intervale, de exemplu a-z, adică un caracter arbitrar inclus în interval, inclusiv capetele intervalului.

[^...] - orice caracter unic sau secvență de caractere enumerate între paranteze drepte, cu excepția celor enumerate după semnul de negație.

Exemplu de utilizare:

Interogare.Text = //găsiți întreaga nomenclatură care conține rădăcina TABUR și începe //fie cu litera mică sau majusculă t „SELECT | Nomenclatură. Link | FROM | Director. Nomenclatura AS Nomenclatură | WHERE | Produse. Nume LIKE "" [Tt ]abur%""" ;

5. Design PERMIS- acest operator vă permite să selectați doar acele înregistrări din baza de date pentru care apelantul are permisiunea de citire. Aceste drepturi sunt configurate la nivel de înregistrare (RLS).

Sintaxă: ALLOWED este scris după cuvântul cheie SELECT

Exemplu de utilizare:

Request.Text = "SELECTARE PERMIS | Contrapartide. Link | DIN | Director. Contrapartide AS Counterparties";

6. Design DIVERSE- vă permite să selectați înregistrări în care nu există înregistrări duplicat.

Sintaxă: VARIOUS este scris după cuvântul cheie SELECT

Exemplu de utilizare:

Request.Text = //selectează înregistrările la care cititorul are drepturi „SELECT VARIOUS | Counterparties.Name |FROM | Directory. Counterparties AS Counterparties” ;

De asemenea, construcția VARIOUS poate fi folosită cu operatorul PERMIS și alți operatori.

Exemplu de utilizare:

Request.Text = //selectează diverse înregistrări la care cititorul are drepturi „SELECT ALLOWED VARIOUS | Counterparties.Name |FROM | Directory. Counterparties AS Counterparties”;

7. Design FIRST- selectează numărul de înregistrări specificat în parametru din rezultatul interogării.

Sintaxă: FIRST<число>

Exemplu de utilizare:

Solicitare.Text = //selectați primele 4 numere CCD din directorul "SELECT FIRST 4 | Numere CCD. Link | FROM | Director. Numere CCD AS Numere CCD";

8. Design PENTRU SCHIMBARE- vă permite să blocați un tabel, funcționează numai în tranzacții (relevant doar pentru blocările automate).

Sintaxă: PENTRU SCHIMBARE<НаименованиеТаблицы>

Exemplu de utilizare:

Query.Text = "SELECT | Resturi libere. Nomenclator, | Resturi libere. Depozit, | Resturi libere. În stoc rămase | DIN | Registrul acumulărilor. Resturi libere. Rămășii ca resturi libere | PENTRU SCHIMBARE | Registrul acumulărilor. . Resturi libere. Resturi";

9. Design COMANDA DE- organizează datele după un anumit câmp. Dacă câmpul este un link, atunci când setați steag COMANDĂ AUTOMATĂ Sortarea va avea loc prin reprezentarea link-ului; dacă steag-ul este dezactivat, atunci link-urile sunt sortate după vechimea adresei link-ului din memorie.

Sintaxă: FILTREAZĂ DUPĂ<НаименованиеПоля>COMANDĂ AUTOMATĂ

Exemplu de utilizare:

Query.Text = "SELECT | Resturi libere. Nomenclator AS Nomenclator, | Resturi libere. Depozit AS Depozit, | Resturi libere. În stoc rămas | DIN | Înregistrați acumulări. Resturi libere. Rămase AS Resturi libere rămase BY | | Nomenclator | AUTO COMANDA VANIE";

10. Design GROUP BY- folosit pentru gruparea șirurilor de interogări după anumite câmpuri. Câmpurile numerice trebuie utilizate cu orice funcție de agregare.

Sintaxă: A SE GRUPA CU<НаименованиеПоля1>, .... , <НаименованиеПоляN>

Exemplu de utilizare:

Query.text = "SELECT | itemsInwarehouses.nomenclature as nomenclature, | itemSInwarehouses.warehouse, | sum (articolesInWarehouses.Instock) ca instank | de la | RegisterAccumulations.Itemsinwarehouses ca articolesInwarehouses | ;

11. Design AVÂND- vă permite să aplicați o funcție agregată unei condiții de selecție a datelor, similară construcției WHERE.

Sintaxă: AVÂND<агрегатная функция с условием>

Exemplu de utilizare:

Query.Text = //selectează înregistrările grupate în care câmpul InStock este mai mare de 3 "SELECT | ItemsInStocks.Nomenclature AS Nomenclature, | ItemsInWarehouses.Warehouse, | SUM(ItemsInStocks.InStock) AS INSTOCK |FROM | RegisterAccumulations.Stocks AS | ItemsInStocks AS | GROUP BY | ProductsInWarehouses.Nomenclature, | ProductsInWarehouses.Warehouse | | DISPONIBIL | SUMĂ(ProductsInWarehouses.InStock) > 3" ;

12. Constructii INDEX BY- folosit pentru indexarea câmpului de interogare. O interogare cu indexare durează mai mult, dar accelerează căutarea prin câmpurile indexate. Poate fi folosit doar în mesele virtuale.

Sintaxă: INDEX PRIN<Поле1, ... , ПолеN>

Exemplu de utilizare:

Query.Text = „SELECT | Ts.NameOS, | Ts.FolderNumber, | Ts.CodeOS, | Ts.Term, | Ts.Type | PLACE DataTs | FROM | &Ts AS Ts | | INDEX BY | Ts.NameOS, | Ts .CodeOS";

13. Design UNDE- vă permite să impuneți o condiție oricăror câmpuri de selecție. Rezultatul va include numai înregistrările care îndeplinesc condiția.

Sintaxă: UNDE<Условие1 ОператорЛогСоединения УсловиеN>

Exemplu de utilizare:

Query.Text = //toate înregistrările cu CompensationRemaining sunt selectate<>0 și //AmountForCalcCompRemaining > 100 "SELECT | CompensationRPORemains.Counterparty, |CompensationRPORemains.Child, | CompensationRPORemains.CompensationRemaining, | CompensationRPORemains.AmountForCalcCompRemains |Place Data Compensation.RPORemains.WHRemains.RPORemains.RP | ERE |CompensationRPORremaining.CompensationRemaining<>0 | Și CompensationRPORemains.AmountForCalcCompRemaining> 100" ;

14. Design REZULTATE... GENERAL- folosit pentru calcularea totalurilor; proiectul specifică câmpurile prin care vor fi calculate totalurile și funcțiile de agregare aplicate câmpurilor totale. Când se folosesc totaluri pentru fiecare câmp după construcția TOTAL, datele sunt grupate. Există o construcție GENERAL opțională; utilizarea sa oferă și grupări suplimentare. Veți vedea un exemplu de rezultat al cererii mai jos.

Sintaxă: REZULTATE<АгрегатнаяФункция1, ... , АгрегатнаяФункцияN>DE<ОБЩИЕ> <Поле1, ... , ПолеN>

Exemplu de utilizare:

Solicitare.Text = "SELECTARE | Calcule. Contract de contrapartidă. Tip de acord AS Tip de contract, | Calcule. Contract de contraparte AS Contract, | Calcule. Contraparte, | Calcule. Valoarea soldului decontării reciproce AS Sold | FROM | Registrul de acumulări. Mutual Decontare CU Contrapărțile. Solduri AS Calcule | TOTAL | SUMA (Sold) |Software | GENERAL, | Tip de acord";

Figura conturează grupările care s-au format în timpul executării cererii, cea de sus se referă la secțiunea GENERAL, iar cea de-a doua la câmpul Counterparty Agreement Agreement Type.

O interogare este un instrument puternic care servește la obținerea și procesarea rapidă (în comparație cu toate celelalte metode) a datelor conținute în diferite obiecte ale bazei de informații 1C.

Creați o cerere

Solicitarea este creată ca un obiect separat care are un atribut obligatoriu Text, unde cererea în sine este de fapt plasată. În plus, la cerere pot fi trecuți diverși parametri necesari executării acestuia. După ce textul și parametrii cererii sunt completați, cererea trebuie executată și rezultatul execuției plasat într-o selecție sau tabel de valori. Totul arată cam așa:

//Creează o cerere
Solicitare = cerere nouă;

//Completați textul de solicitare
Cerere. Text= „Aici scriem textul cererii”;

//Trimite parametri la cerere
Cerere. SetParameter("ParameterName" , ParameterValue) ;

//Execută cererea
Rezultat = Interogare. Alerga() ;

//Încărcați rezultatul interogării în selecție
Eșantion = Rezultat. Alegeți() ;

//Încărcați rezultatul interogării în tabelul cu valori
Tabel = Rezultat. Descărcați() ;

//Ultimele acțiuni pot fi combinate
Preluare = Interogare. Alerga() . Alegeți() ;
//sau
Tabel = Interogare. Alerga() . Descărcați() ;

Bazele limbajului de interogare 1C

Cele mai simple și mai frecvent utilizate interogări sunt folosite pentru a obține date dintr-o anumită sursă. Sursa poate fi aproape toate obiectele care conțin orice date: directoare, documente, registre, constante, enumerari, planuri pentru tipuri de caracteristici etc.

Din aceste obiecte, folosind o interogare, puteți obține valorile detaliilor, părților tabelului, detaliilor părților tabelului, modificărilor, resurselor etc.

Pentru a obține textul de solicitare, este adesea convenabil de utilizat Constructor de solicitări. Este apelat atunci când faceți clic dreapta oriunde în modulul programului.

De exemplu, dacă trebuie să obțineți valorile tuturor detaliilor directorului Contrapartide, atunci cererea va arăta astfel:

Cerere. Text = "ALEGE
| *
|DIN
| Director. Contrapărți"
;

Dacă trebuie să obțineți numai detalii individuale, atunci procedați astfel:

Cerere. Text = "ALEGE
| Cod,
| Nume,
| Mamă
|DIN
| Director. Contrapărți"
;

Pentru a primi un astfel de text de solicitare în Constructor de interogări trebuie să selectați câmpurile corespunzătoare din filă Tabele și câmpuri.

Puteți atribui alias-uri elementelor și surselor selectate în interogare și să le utilizați ulterior atât în ​​interogarea în sine, cât și atunci când lucrați cu rezultatul. În plus, cererea poate conține câmpuri cu o valoare specifică predefinită sau cu o valoare calculată:

Cerere. Text = "ALEGE
| Clients.Code AS Număr,

| 1000 AS FieldWithValue
|DIN
;

Preluare = Interogare. Alerga() . Alegeți() ;

Pa selecție. Buclă Next()
ClientNumber = Exemplu. Număr;
ClientName = Selecție. Nume;
Valoare = Probă. FieldWithValue;
EndCycle ;

Utilizați fila pentru a seta aliasuri Sindicate/Alias-uri V Generator de interogări.

Un câmp cu o valoare fixă ​​sau calculată este creat manual în filă Tabele și câmpuri, într-o coloană Câmpuri.

Toate elementele selectate pot fi aranjate fie în ordine înainte, fie în ordine inversă. Puteți selecta unul sau mai multe câmpuri pentru comandă. Pe lângă aranjare, uneori poate fi util să selectați doar unul sau câteva dintre primele elemente.

//Ordonați clienții după nume de la A la Z și selectați primii 10
Cerere. Text = „SELECTAȚI PRIMILE 10
| Clients.Code AS Număr,
| Clients.Name AS Nume,
| 1000 AS FieldWithValue
|DIN

|COMANDA DE
| Nume"
;

//Selectați cel mai recent client alfabetic
Cerere. Text = „SELECTARE TOP 1
| Clients.Code AS Număr,
| Clients.Name AS Nume,
| 1000 AS FieldWithValue
|DIN
| Director.Contrapărți AS Clienți
|COMANDA DE
| Nume DESCĂCERE"
;

Puteți limita selecția articolelor la acelea la care utilizatorul are drepturi de acces. Sau eliminați liniile duplicate din rezultatul interogării.

//Eșantionarea datelor permisă utilizatorului
Cerere. Text = „SELECTARE PERMIS
| Clients.Code AS Număr,
| Clients.Name AS Nume,
| 1000 AS FieldWithValue
|DIN
| Director. Contrapărți AS Clienți"
;

//Selectarea elementelor care nu se repetă
Cerere. Text = „SELECTARE DIVERSE
| Clients.Code AS Număr,
| Clients.Name AS Nume,
| 1000 AS FieldWithValue
|DIN
| Director. Contrapărți AS Clienți"
;

Ordinea este setată pe filă Ordin V Generator de interogări numărul de elemente selectate, rezoluția și parametrii de repetabilitate sunt pe filă În plus.

Va urma…