Reprezentare in cerere 1s. Caracteristici de lucru cu câmpul View și funcția View() a limbajului de interogare

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. Ordonarea 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 construcția „ORDER BY”, iar apoi construcția „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 Software Organizations 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 Clients 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.”

Limbajul de interogare este unul dintre mecanismele fundamentale ale 1C 8.3 pentru dezvoltatori. Folosind interogări, puteți prelua rapid orice date stocate în baza de date. Sintaxa sa este foarte asemănătoare cu SQL, dar există unele diferențe.

Principalele avantaje ale limbajului de interogare 1C 8.3 (8.2) față de SQL:

  • dereferențiarea câmpurilor de referință (referirea unuia sau mai multor puncte la detalii despre obiect);
  • lucrul cu rezultate este foarte convenabil;
  • capacitatea de a crea tabele virtuale;
  • cererea poate fi scrisă atât în ​​engleză, cât și în rusă;
  • capacitatea de a bloca datele pentru a evita blocajele.

Dezavantajele limbajului de interogare în 1C:

  • spre deosebire de SQL, interogările în 1C nu permit modificarea datelor;
  • lipsa procedurilor stocate;
  • imposibilitatea de a converti un șir într-un număr.

Să aruncăm o privire la mini-tutorialul nostru despre constructele de bază ale limbajului de interogare 1C.

Datorită faptului că interogările din 1C vă permit doar să primiți date, orice interogare trebuie să înceapă cu cuvântul „SELECT”. După această comandă sunt indicate câmpurile din care trebuie obținute datele. Dacă specificați „*”, toate câmpurile disponibile vor fi selectate. Locul din care vor fi selectate datele (documente, registre, directoare etc.) este indicat după cuvântul „DIN”.

În exemplul discutat mai jos, numele întregii nomenclaturi sunt selectate din directorul „Nomenclatură”. După cuvântul „CUM”, sunt indicate pseudonimele (numele) pentru tabele și câmpuri.

ALEGE
Nomenclatură Nume AS Numele Nomenclaturii
DIN
Director.Nomenclatura AS Nomenclatura

Lângă comanda „SELECT” puteți specifica cuvinte cheie:

  • VARIAT. Interogarea va selecta numai rânduri care diferă în cel puțin un câmp (fără duplicate).
  • Primul N, Unde n– numărul de rânduri de la începutul rezultatului care trebuie selectat. Cel mai adesea, această construcție este utilizată împreună cu sortarea (ORDER BY). De exemplu, atunci când trebuie să selectați un anumit număr de documente care sunt recente după dată.
  • PERMIS. Acest design vă permite să selectați din baza de date numai acele înregistrări care sunt disponibile utilizatorului curent. Pe baza utilizării acestui cuvânt cheie, utilizatorul va primi un mesaj de eroare atunci când încearcă să interogheze înregistrările la care nu are acces.

Aceste cuvinte cheie pot fi folosite împreună sau separat.

PENTRU SCHIMBARE

Această propunere blochează datele pentru a preveni conflictele reciproce. Datele blocate nu vor fi citite de la o altă conexiune până la încheierea tranzacției. În această clauză, puteți specifica anumite tabele care trebuie blocate. În caz contrar, toată lumea va fi blocată. Designul este relevant doar pentru modul de blocare automată.

Cel mai adesea, clauza „PENTRU SCHIMBARE” este folosită la primirea soldurilor. La urma urmei, atunci când mai mulți utilizatori lucrează în program simultan, în timp ce unul primește solduri, altul le poate schimba. În acest caz, restul rezultat nu va mai fi corect. Dacă blocați datele cu această propunere, atunci până când primul angajat primește soldul corect și efectuează toate manipulările necesare cu acesta, al doilea angajat va fi obligat să aștepte.

ALEGE
Acorduri reciproce. Salariat,
Decontări reciproce.Cuantumul decontărilor reciproce Sold
DIN
Registrul Acumulărilor.Decontări reciproce cu angajații.Solduri AS Decontări reciproce
PENTRU SCHIMBARE

UNDE

Designul este necesar pentru a impune un fel de selecție asupra datelor încărcate. În unele cazuri de obținere a datelor din registre, este mai rezonabil să se specifice condițiile de selecție în parametrii tabelelor virtuale. Când utilizați „UNDE”, toate înregistrările sunt preluate mai întâi și numai apoi se aplică selecția, ceea ce încetinește semnificativ interogarea.

Mai jos este un exemplu de solicitare de a obține persoane de contact pentru o anumită poziție. Parametrul de selecție are formatul: &ParameterName (numele parametrului este arbitrar).

SELECTARE (CAZ)

Designul vă permite să specificați condiții direct în corpul cererii.

În exemplul de mai jos, „AdditionalField” va conține text în funcție de dacă documentul este postat sau nu:

ALEGE
AdmitereT&U.Link,
ALEGERE
CÂND AdmitereaT&U.Efectuat
ATUNCI „Documentul a fost aprobat!”
ELSE „Documentul nu a fost postat...”
TERMINAȚI CA SuplimentarField
DIN
Document. Primirea Bunurilor și Serviciilor CUM Primirea T&C

A TE ALATURA

Îmbinările leagă două tabele pe baza unei anumite condiții de relație.

CONEXIUNE STÂNGA/DREAPTA

Esența îmbinării LEFT este că primul tabel specificat este luat în întregime, iar al doilea este legat de acesta în funcție de condiția de conectare. Dacă nu există înregistrări care să corespundă primului tabel din al doilea, atunci NULL este înlocuit ca valorile lor. Mai simplu spus, tabelul principal este primul tabel specificat, iar datele celui de-al doilea tabel (dacă există) sunt deja înlocuite cu datele acestuia.

De exemplu, este necesar să obțineți articole de articole din documentele „Recepție de bunuri și servicii” și prețuri din registrul de informații „Prețuri articole”. În acest caz, dacă prețul pentru orice poziție nu este găsit, înlocuiți NULL. Toate articolele din document vor fi selectate indiferent dacă au un preț sau nu.

ALEGE
Nomenclatura de primire&U,
Preturi.Pret
DIN
Document. Primirea Bunurilor și Serviciilor. Bunuri CUM Primirea și Specificațiile
INTERNAL JOIN RegisterInformation.PricesNomenclature.SliceLast AS Preturi
Software Receipt&U.Nomenclature = Prices.Nomenclature

ÎN DREPT totul este exact invers.

CONEXIUNE COMPLETA

Acest tip de conexiune diferă de cele anterioare prin aceea că, ca rezultat, toate înregistrările atât din primul tabel, cât și din cel de-al doilea vor fi returnate. Dacă nu se găsesc înregistrări în primul sau al doilea tabel pe baza condiției de legătură specificate, va fi returnat NULL.

Când utilizați o conexiune completă în exemplul anterior, vor fi selectate toate articolele din documentul „Primire de bunuri și servicii” și toate cele mai recente prețuri din registrul „Prețuri articole”. Valorile înregistrărilor negăsite atât în ​​primul cât și în cel de-al doilea tabel vor fi egale cu NULL.

INNER JOIN

Diferența dintre un INNER JOIN și un FULL JOIN este că, dacă o înregistrare nu este găsită în cel puțin unul dintre tabele, interogarea nu o va afișa deloc. Ca urmare, vor fi selectate doar acele articole din documentul „Recepție de bunuri și servicii” pentru care există înregistrări în registrul de informații „Prețuri articole”, dacă în exemplul anterior înlocuim „FULL” cu „INTERN”.

A SE GRUPA CU

Gruparea în interogări 1C vă permite să restrângeți rândurile de tabel (câmpuri de grupare) în funcție de o anumită caracteristică comună (câmpuri de grupare). Câmpurile de grupare pot fi afișate numai folosind funcții de agregare.

Rezultatul următoarei interogări va fi o listă de tipuri de produse cu prețuri maxime pentru acestea.

ALEGE
,
MAX(Preț.Preț) AS Preț
DIN

A SE GRUPA CU
Preturi.Nomenclatura.Tipul Nomenclatorului

REZULTATE

Spre deosebire de grupare, atunci când se utilizează totaluri, toate înregistrările sunt afișate și rândurile totale sunt adăugate acestora. Gruparea afișează numai înregistrări generalizate.

Rezultatele pot fi rezumate pentru întregul tabel (folosind cuvântul cheie „GENERAL”), pentru mai multe câmpuri, pentru câmpuri cu structură ierarhică (cuvinte cheie „IERARHIE”, „NUMAI IERARHIE”). La rezumarea rezultatelor, nu este necesar să folosiți funcții agregate.

Să ne uităm la un exemplu similar cu cel de mai sus folosind gruparea. În acest caz, rezultatul interogării va returna nu numai câmpuri grupate, ci și înregistrări detaliate.

ALEGE
Prețuri.Nomenclatură.Tip de nomenclatură AS Tip de nomenclatură,
Preturi.Pret AS Pret
DIN
Registrul de informații Prețurile Nomenclatorului Instantaneu al celor mai recente prețuri AS
REZULTATE
MAXIM (Preț)
DE
TypeNomenclature

AVÂND

Acest operator este similar cu operatorul WHERE, dar este folosit doar pentru funcții agregate. Câmpurile rămase, cu excepția celor utilizate de acest operator, trebuie grupate. Operatorul WHERE nu este aplicabil funcțiilor agregate.

În exemplul de mai jos, prețurile maxime ale unui articol sunt selectate dacă depășesc 1000, grupate după tipul articolului.

ALEGE

MAX(Preț.Preț) AS Preț
DIN
Registrul de informații Prețurile Nomenclatorului Instantaneu al celor mai recente prețuri AS
A SE GRUPA CU
Preturi.Nomenclatura.Tipul Nomenclatorului
AVÂND
MAXIM(Prețuri.Preț) > 1000

FILTREAZĂ DUPĂ

Operatorul ORDER BY sortează rezultatul unei interogări. Pentru a vă asigura că înregistrările sunt afișate într-o ordine consecventă, se utilizează COMANDA AUTOMATĂ. Tipurile primitive sunt sortate după regulile obișnuite. Tipurile de referință sunt sortate după GUID.

Un exemplu de obținere a unei liste de angajați sortați după nume:

ALEGE
Angajații.Nume AS Nume
DIN
Director.Angajați CUM Angajații
FILTREAZĂ DUPĂ
Nume
COMANDĂ AUTOMATĂ

Alte constructe de limbaj de interogare 1C

  • COMBINA– rezultatele a două interogări într-una.
  • COMBINA TOTUL– similar cu COMBINE, dar fără a grupa rânduri identice.
  • MASĂ GOL– folosit uneori la alăturarea interogărilor pentru a specifica un tabel imbricat gol.
  • LOC– creează un tabel temporar pentru a optimiza interogările complexe 1C. Astfel de solicitări se numesc solicitări în lot.

Caracteristicile limbajului de interogare

  • SUBSTRING trunchiază un șir dintr-o poziție specificată la un număr specificat de caractere.
  • AN... AL DOILEA vă permit să obțineți valoarea selectată a unui tip numeric. Parametrul de intrare este data.
  • ÎNCEPUTUL PERIOADEI și sfârșitul perioadei utilizat atunci când se lucrează cu date. Tipul perioadei (ZI, LUNA, AN etc.) este indicat ca parametru suplimentar.
  • ADDKDATE vă permite să adăugați sau să scădeți o oră specificată de un anumit tip dintr-o dată (SECOND, MINUT, DAY etc.).
  • DATA DIFERENTATA determină diferența dintre două date, indicând tipul valorii de ieșire (ZI, AN, LUNA etc.).
  • ISNULLînlocuiește valoarea lipsă cu expresia specificată.
  • REPREZENTARE și REPRESENTATIONLINKS obține o reprezentare șir a câmpului specificat. Aplicați oricăror valori și, respectiv, numai valorilor de referință.
  • TIP, VALORI DE TIP sunt utilizate pentru a determina tipul parametrului de intrare.
  • LEGĂTURĂ este un operator logic de comparare pentru tipul de valoare de atribut.
  • EXPRES folosit pentru a converti o valoare în tipul dorit.
  • DATA ORA primește o valoare de tip „Data” din valorile numerice (Anul, Luna, Ziua, Ora, Minutul, Secunda).
  • SENSîntr-o solicitare 1C este folosit pentru a indica valori predefinite - directoare, enumerari, planuri pentru tipuri de caracteristici. Exemplu de utilizare: " Unde Persoană juridică = Valoare (Enumerare. Persoană juridică. Persoană fizică)«.

Generator de interogări

Pentru a crea interogări cu 1C, există un mecanism încorporat foarte convenabil - designerul de interogări. Conține următoarele file principale:

  • „Tabele și câmpuri” - conține câmpurile care trebuie selectate și sursele acestora.
  • „Conexiuni” - descrie condițiile pentru structura CONEXIUNE.
  • „Gruparea”—conține o descriere a structurilor de grupare și a câmpurilor însumate pe baza acestora.
  • „Condiții” - este responsabil pentru selectarea datelor din cerere.
  • „Avansat”—parametri de interogare suplimentari, cum ar fi cuvintele cheie pentru comanda „SELECT” etc.
  • „Joins/Aliases” - sunt indicate posibilitățile de îmbinare a tabelelor și sunt specificate aliasuri (constructia „CUM”).
  • „Comanda” este responsabil pentru sortarea rezultatului interogărilor.
  • „Totale” - similar cu fila „Grupare”, dar folosit pentru constructul „TOTALURI”.

Textul cererii în sine poate fi vizualizat făcând clic pe butonul „Solicitare” din colțul din stânga jos. În acest formular, poate fi corectat manual sau copiat.


Solicitare Consola

Pentru a vizualiza rapid rezultatul unei interogări în modul Enterprise sau pentru a depana interogări complexe, utilizați . Acesta conține textul cererii, stabilește parametrii și afișează rezultatul.

Puteți descărca consola de interogări pe discul ITS sau prin .

Articolul oferă tehnici utile atunci când lucrați cu interogări 1C v.8.2, precum și informații care nu sunt atât de bine cunoscute despre limbajul de interogare. Nu mă străduiesc să ofer o descriere completă a limbajului de interogare, dar vreau să mă opresc doar asupra unor puncte care pot fi utile cuiva.

Deci, să începem. O cerere este un obiect special în 1C 8.2, care este folosit pentru a genera și executa interogări împotriva tabelelor bazei de date din sistem. Pentru a executa o interogare, trebuie să compuneți un text de interogare care să descrie ce tabele vor fi folosite ca surse de date de interogare, ce câmpuri trebuie selectate, ce sortări și grupări se aplică etc. Puteți citi mai multe despre interogări în cartea „1C 8.2 Developer’s Guide”. Limbajul de interogare 1C 8.2 este foarte asemănător ca sintaxă cu alte limbaje de interogare a bazei de date SQL, dar există și diferențe. Printre principalele avantaje ale limbajului de interogare încorporat, merită remarcată dereferința câmpurilor, prezența tabelelor virtuale, lucrul convenabil cu totaluri și câmpurile netipizate în interogări. Dezavantajele sunt că nu puteți utiliza o interogare ca câmp de ieșire, nu puteți utiliza proceduri stocate și nu puteți converti un șir într-un număr.

Voi oferi informații și recomandări cu privire la limbajul de interogare punct cu punct:
1. Pentru a crește lizibilitatea cererii și a reduce numărul de parametri de cerere, puteți utiliza un literal pentru a accesa datele de configurare predefinite în cerere VALOARE (REPREZENTAREA VALORII). Ca reprezentare a valorilor, valorile enumerarilor, date predefinite ale directoarelor, planuri de tipuri de calcul, planuri de tipuri de caracteristici, planuri de conturi, link-uri goale, valori ale punctelor de traseu, valori ale transferurilor de sistem ( de exemplu, tipul de mișcare de acumulare, tipul de cont) pot fi utilizate.
Exemple:

WHERE City = VALUE(Directory.Cities.Moscow)
WHERE City = VALUE(Directory.Cities.EmptyLink)
WHEREProductType = VALUE(Enumeration.ProductTypes.Service)
WHEREMovementType = VALUE(MovementTypeAccumulation.Incoming)
UNDE este Route Point =
Valoare

Expresia dintre paranteze începe întotdeauna cu un cuvânt singular (Director, Enumerare etc.) care se potrivește cu tipul valorii predefinite.

2. Comanda automată într-o interogare poate încetini foarte mult procesul. Dacă nu este necesară sortarea, este mai bine să nu o folosiți deloc. În multe cazuri, este mai eficient să scrieți sortarea folosind un cuvânt cheie FILTREAZĂ DUPĂ.

3. Trebuie să vă asigurați că atunci când utilizați aliasuri, nu apare un câmp ambiguu. În caz contrar, sistemul nu va înțelege ce obiect trebuie accesat.
Exemplu de solicitare cu un câmp ambiguu:
ALEGE
Nomenclatură.Link,
Bunuri rămaseRemaining.QuantityRemaining
DIN
Director.Nomenclatura AS Nomenclatura
CONEXIUNEA STÂNGA Înregistrați acumulări Mărfuri rămase Restul AS Bunuri rămase rămase
Software Remaining ProductsRemaining.Nomenclature = Nomenclature.Link
Este necesar să corectați alias-ul tabelului, de exemplu, astfel: „Directory.Nomenclature AS Nomenclature1” și „Nomenclature.Link” ar trebui corectate în consecință cu „Nomenclature1.Link”.

4.Uneori este util să obțineți o reprezentare a câmpurilor de referință folosind un cuvânt cheie PERFORMANŢĂîmpreună cu un link astfel încât să nu existe acces repetat la baza de date. Acest lucru este util când se afișează rezultatul unei interogări într-un tabel.
Exemplu:
ALEGE
REPREZENTARE(Document.Contraparte) CA Destinatar,
PREZENTARE(Document.Base)
DIN
Document.Factura AS Document

5. Utilizați într-o cerere EXPRESS(Tipul AS de câmp) vă permite să eliminați tabelele inutile dintr-o conexiune cu un câmp de tip de date complex. Accelerând astfel executarea cererii.
Exemplu (registrar este un câmp cu tip compozit pentru tabelul fizic al registrului de acumulare a bunurilor rămase, în cerere se selectează Data și Numărul documentelor Primirea mărfurilor, în timp ce la accesarea detaliilor documentului Data și Numărul prin Registrator, nu există o conexiune multiplă a tabelului de registru cu tabelele de documente care sunt registratori pentru Registrul Resturilor de Bunuri):
SELECTAȚI DIVERSE[b] EXPRESS(Mărfuri rămase.Registrul AS Document.Recepția mărfurilor).Număr AS NUMĂR DE PRESTAȚIE,
[b] EXPRESS(Mărfuri rămase.Registrul AS Document.Recepția mărfurilor).Date AS RECEIPT DATE
[b]DIN Registrul de acumulări Bunuri rămase AS Bunuri rămase UNDE (EXPRESS(Mărfuri rămase. Înregistrare ca document. Primire a mărfurilor) NU ESTE NUL)

6. Când în configurația 1C există utilizatori care au drepturi limitate asupra anumitor obiecte de configurare, cuvântul cheie trebuie utilizat în cererea către astfel de obiecte PERMIS astfel încât cererea să fie executată fără eroare (Selectați Permis...)

7. Când îmbinați tabele care conțin tabele imbricate (de exemplu, un document cu o parte tabelară), cuvântul cheie poate fi util TABUL GOLIT când, de exemplu, unul dintre documente nu are o parte tabelară.
Exemplu:
SELECT Link.Number, EMPTY TABLE.(Nr., Articol, Cantitate) AS Compoziție

COMBINA TOTUL
SELECT Link.Number, Composition.(LineNumber, Nomenclatură, Cantitate)
DIN Document.Factură

8. Când lucrați cu îmbinări de tabele care conțin câte un rând fiecare, poate fi necesară îmbinarea rândurilor de tabele (în ambele tabele nu există niciun câmp prin care acestea să poată fi unite). Acest lucru se poate realiza prin utilizarea construcției " FULL CONNECTION Tabel de TRUE" Dacă tabelele au mai multe rânduri, rezultatul va fi un număr de rânduri egal cu produsul dintre numărul de rânduri din ambele tabele. Dacă există O rânduri într-un tabel, atunci numărul de rânduri din tabelul rezultat va fi egal cu numărul de rânduri din al doilea tabel. De asemenea, pentru a conecta astfel de tabele, puteți utiliza produsul cartezian al tabelelor, în care toate combinațiile de rânduri din ambele tabele vor apărea în tabelul rezultat. Trebuie să ne amintim că dacă există 0 rânduri într-unul dintre tabele, atunci produsul cartezian va fi 0, deci o îmbinare completă va fi mai bună. În general, în loc de o conexiune completă PRIN ADEVĂRAT Puteți folosi orice alt tip de îmbinare, dar în acest caz este posibil și ca tabelul rezultat să aibă 0 rânduri, chiar dacă unul dintre tabele are un număr de rânduri diferit de zero. În cazul unei îmbinări complete, această situație va apărea doar într-un singur caz, dacă numărul de rânduri din ambele tabele este 0. Dacă știți că există exact cel puțin un rând în tabel, atunci puteți utiliza CONEXIUNEA STÂNGA cu o alta masa cu conditie PRIN ADEVĂRAT.
Exemplu (desigur, conceput, pentru Full Join):
ALEGE
Primul 1
Gender.Link,
K. Contrapartidă
DIN
Enumerare.Sex AS Gen
CONEXIUNE COMPLETĂ (Selectați primul 1 D. Contraparte DIN Document. Vânzări de bunuri CUM D Aranjați după D. Momentul de timp) CUM SE
ACTIVAT(ADEVĂRAT)

9. Pentru a obține înregistrări unice pentru un anumit câmp, este mai corect să folosiți un cuvânt cheie în loc de grupare VARIATîn cerere, deoarece această construcție este mult mai clară și cuvântul cheie A SE GRUPA CU are o aplicație mai largă și este adesea folosit dacă este suplimentar necesar să se calculeze funcții agregate pe grupări. În unele cazuri, este necesar să ieșiți un număr limitat de linii. Pentru a face acest lucru, ar trebui să specificați cuvântul cheie în descrierea cererii PRIMUL iar după el - numărul necesar de linii.
Exemplu pentru PRIMUL:
Selectați Primele 5
Directory.Nomenclature.Name,
Director.Nomenclatură.PurchasingPrice
Filtrează după
Director.Nomenclatură.PurchasePrice Descendent
Exemplu pentru VARIAT:
Selectați Diverse
Document.Consumabil.Contraparte

10. Funcțiile de agregare dintr-o interogare pot fi utilizate fără un cuvânt cheie GRUP. În acest caz, toate rezultatele vor fi grupate într-o singură linie.
Exemplu:
Alege
Sumă (Factură. Sumă) Ca Sumă
Din
Document.Factură.Compoziție Ca Factură

11.În interogările din câmpurile de selecție, puteți accesa liber detaliile câmpurilor de selecție. Această caracteristică se numește select field dereferencing. Dacă sursa de date este un tabel imbricat (partea tabelară a documentului), atunci în câmpurile de selecție puteți accesa și câmpurile tabelului principal (de exemplu, prin câmpul Link, accesați câmpul tabelului principal Cont)
Exemplu:
ALEGE[b] Primirea Bunurilor si Serviciilor Bunuri Cantitate AS Cantitate, Primirea Bunurilor și Serviciilor Bunuri.Link.Contraparte DIN UNDE
Există o particularitate a utilizării dereferențării câmpurilor dacă există grupări în cerere. În orice interogări cu grupări în listele câmpurilor de interogare, puteți accesa liber detaliile câmpurilor de grupare.
Exemplu:
ALEGE
Recepția Bunurilor și Bunurilor Servicii. Nomenclator,
Recepție Bunuri și Servicii Bunuri. Nomenclator. Cod,
SUM (Recepția Bunurilor și Serviciilor Bunuri. Cantitate) AS Cantitate,
Primirea Bunurilor și Serviciilor Bunuri.Link.Contraparte,
Primirea Bunurilor și Serviciilor Bunuri.Link.Data
DIN
Document.Recepția de Bunuri și Servicii.Bunuri CUM Primirea de Bunuri și Servicii Bunuri
UNDE
Primirea de Bunuri și ServiciiGoods.Link = &Link
A SE GRUPA CU
Recepția Bunurilor și Bunurilor Servicii. Nomenclator,
Primirea Bunurilor și Serviciilor Bunuri.Link
Ajutorul 1C spune că, dacă există grupare, numai câmpurile de grupare și funcțiile de agregare pentru câmpurile de selecție pot participa la câmpurile de selecție a interogării. Există un caz excepțional când funcțiile agregate sunt aplicate câmpurilor unui tabel imbricat. În acest caz, în lista câmpurilor de selecție, este posibilă accesarea câmpurilor din tabelul de nivel superior, fără a grupa rezultatele după aceste câmpuri.
Exemplu:
ALEGE
Primirea de bunuri și servicii, bunuri (SUMA (cantitate), nomenclatură),
Primirea Bunurilor și Serviciilor. Link,
Primirea Bunurilor și Serviciilor Contraparte
DIN
Document.Recepția Bunurilor și Serviciilor CUM Primirea Bunurilor și Serviciilor
A SE GRUPA CU
Primirea de bunuri și servicii, bunuri (nomenclatură)

12. Uneori, în loc să specificați orice câmp din grupare, este util să includeți următorul parametru în câmpurile de selecție a interogării:
ALEGE DocProducts.Nomenclature, &Contraparte, &Perioadă, SUM(DocProducts.Quantity * DocProducts.Q) AS Cantitate, SUM(DocProducts.Amount) AS Sumă DIN Document.Admitere.Produse AS DocProducts UNDE DocProducts.Link = &Link
A SE GRUPA CU DocProducts.Nomenclatură
Și apoi setați parametrul în corpul cererii:
Request.SetParameter("&Cont", SelectAccount);
Query.SetParameter("&Period", Data);

13. În interogările universale, parametrii pot fi utilizați în descrierea surselor de date de interogare, în condiții UNDE, in conditiile unirii tabelelor si parametrilor tabelelor virtuale. Există două tehnici pentru a crea interogări generice:
A) folosind mecanismul de concatenare a șirurilor de caractere, adăugarea de variabile la textul de solicitare;
Exemplul 1:

OrderingType = ?(UNE VARIABILE,"","DESC");
Query.Text = "Selectați... Aranjați BY Field1 " + OrderType + "...";
Exemplul 2:
Query.Text = "Selectați Câmp1...";

Dacă UNELE VARIABILE = 1 Atunci
Request.Text = Request.Text + ",Field2 ...";
endIf;
B) utilizați parametrii în diferite părți ale cererii (de exemplu, în secțiunea surse de date a cererii), apoi metoda limbajului încorporat - STREPLACE(). Când proiectați interogări universale, este util să accesați proprietatea obiectelor METADATE(), cu care puteți determina numele tabelului pentru un link (de exemplu, pentru un document va fi ceva de genul acesta - Link . METADATA().NAME), trecut printr-un parametru la o procedură universală.
Exemplu:
Alege
DocTch.Nomenclatura,
...
DIN
&Unele DocTC AS DocTC
Și apoi setați parametrul în corpul solicitării
Request.Text = StrReplace(Request.Text, "&SomeDocTCH", "Document."+Link.Metadata().Name+".Products");

Parametrii pot fi utilizați în condiții de interogare pentru a activa o condiție opțională &Parametru SAU NU SomeProperty:
Request.SetParameter(“&Parameter”, “Counterparty.Name="”Ivanov”””);
Folosind un literal ADEVĂRAT puteți elimina anumite filtre din cerere
Query.SetParameter("&Parametru", True);

14. Foarte utilă în designerul de interogări este comanda meniului contextual al tabelului - " Redenumiți tabelul...", cu care puteți veni cu un nume generalizat pentru sursa de date. Pentru a crea interogări pentru tabele de același tip, similare ca structură, poate fi util ca al doilea tabel să copieze textul de interogare al primului tabel, mergeți la fereastra de proiectare de interogări și selectați elementul din meniul contextual al tabelului - Înlocuiește masa...și selectați al doilea tabel.

15. Când lucrați cu crearea de interogări imbricate în secțiunile de condiții sau parametri ai tabelelor virtuale ale designerului de interogări, se folosește tehnica de evidențiere a unui spațiu între paranteze, apoi elementul „Query Designer” apare în meniul contextual și la editarea unei interogări imbricate, întreaga interogare între paranteze este evidențiată în condiție.
Exemplu de interogare imbricată:
Produs B (Selectați produsul...)

16. La proiectarea rapoartelor ACS în interogări de echilibrare a registrelor, este mai convenabil și mai corect să folosiți expresia ca parametru Perioadă AddToDate(EndPeriod(Period,DAY),SECOND,1), deoarece soldurile virtuale se obțin la începutul perioadei, fără a include ultima secundă. Tehnica +1 secundă nu poate fi utilizată cu documente: conform noii metode de înregistrare a documentelor, soldurile de registru trebuie să fie primite pentru Perioada specificată de obiectul Limită cu momentul în care documentul include (și nu la data document +1 secundă!), și conform vechii metode de postare - la momentul documentului (și nu la data documentului!). Când analizați cifra de afaceri sau datele pentru o perioadă, este convenabil să adăugați un parametru cu tipul Perioada standard(în acest caz nu este necesară furnizarea ultimei date a intervalului la sfârșitul zilei). Pentru câmpul standard „Începutul perioadei”, în câmpul „Expresie” trebuie să introduceți „&Perioada.Data de începere" Și pentru câmpul standard „Sfârșitul perioadei” în câmpul „Expresie” scrieți „ &Perioada.Data de încheiere”. O mulțime de informații utile despre limbajul de interogare pot fi găsite nu în asistentul de sintaxă, ci în ajutorul complet al configuratorului 1C 8.2 (butonul F1)

17.Funcția de interogare EsteNull(este mai convenabil să scrieți versiunea în limba engleză EsteNull) este de obicei folosit pentru a scăpa de valorile nule pentru câmpurile de interogare numerică. În unele cazuri, de exemplu, o îmbinare completă a două tabele, funcția IsNull (Parametrul 1, Parametrul 2) poate înlocui cu succes designul ALEGERE CÂND... ATUNCI..ALTĂ....Sfârșit, când pentru orice câmp valorile NULL pot fi atât în ​​primul tabel, cât și în al doilea (această construcție vă permite să obțineți o valoare non-Null pentru câmp). Dar trebuie să ne amintim că, spre deosebire de operatorul condiționat ALEGERE funcţie EsteNull convertește tipul celui de-al doilea argument în tipul primului argument, care trebuie luat în considerare dacă tipurile de argument sunt diferite!
Exemplu:
IsNull(Reg.Remaining,0)
IsNull(Doc.Product, Doc1.Item)

18. La construcţia condiţionată ALEGERE Există o sintaxă alternativă pentru cazul simplu de testare a egalității la o anumită valoare, dar este, totuși, nedocumentată:
Alegere expresie Când 1 Apoi „Ridicat” Când 2 Apoi „Mijloc” Altfel „Scăzut” Final

19. Operator de verificare a valorii NULL Da Null(Putem recomanda utilizarea versiunii în limba engleză Este nul). Această construcție a apărut deoarece orice operație care compară două valori, dintre care cel puțin una este Nulă, este întotdeauna falsă. Scrie Unde Nume = Null gresit. Interesantă este și forma de negație a acestui operator Nu Null- greșit, dar corect Da, nu nul sau formă Nu (Câmpul 1 este nul)- aceasta este o diferență semnificativă față de toți operatorii utilizați împreună cu operatorul He.

20. Uneori formularul operator este util ÎN pentru a verifica dacă există o potrivire cu una dintre valorile enumerate.
Exemplu:
...Unde este produsul.Numele B („Electrocasnice”, „Computere”)
Pentru cărțile de referință, formularul de operator poate fi util ÎN verificări de apartenență la ierarhie.
Exemplu:
...Unde este Nomenclatura ÎN IERARHIE (&Grup)
Operator ÎN adesea folosit pentru a verifica dacă o valoare este inclusă în rezultatul unei subinterogări.
Exemplu:
...Unde Nomenclature.Link B (Selectați Nomenclature.Link...).
Într-o subinterogare, puteți accesa câmpurile de interogare exterioare într-o condiție.
Exemplu:
// Selectați numele produselor care au fost prezente
// în facturi
ALEGE
Produse.Nume
DIN
Director.Nomenclator CUM Produse
UNDE
Produse.Link B
(ALEGE
FacturăCompoziție.Nomenclatură
DIN
Document.Invoice.Composition AS InvoiceComposition
UNDE
InvoiceContent.Nomenclature = Products.Link)
Operațiune ÎN poate fi folosit cu matrice, liste de valori, tabele de valori, interogări imbricate. În acest caz, este posibil să se reducă condițiile
Sintaxă pentru o subinterogare
(expresia1, expresia2,...,expresiaN) În (Selectați expresia1, expresia2,...,expresiaN...)
Sintaxa pentru tabelul de valori
(expresie1, expresie2,...,expresieN) În (&TK), unde primele N coloane sunt utilizate în tabelul cu valorile TK

20. Există o glumă pe Internet despre cum face întotdeauna designerul de interogări STÂNGA alăturarea meselor (și schimbarea lor), indiferent de modul în care specificăm DREAPTA:
1C: Întreprinderea iubește „în stânga”.

21. Este convenabil să depanați interogări complexe în consola de interogări. Sunt multe dintre ele pe Internet. După depanarea interogării, o puteți copia și în designerul de interogări există un buton minunat „ Cerere", unde îl puteți lipi în aceeași formă și îl puteți salva (anterior era posibil doar să îl copiați în configurator și să formatați cererea folosind caracterul de întrerupere de linie). În fereastra care se deschide când faceți clic pe butonul „Interogare”, puteți edita interogarea și vizualiza rezultatul execuției, ceea ce este destul de convenabil.

22.La proiectarea rapoartelor ACS, trebuie să rețineți că, dacă trebuie să furnizați filtrarea după un anumit câmp, nu este necesar să adăugați un parametru la textul solicitării. Generatorul de interogări are o filă „ Compoziția datelor", unde puteți adăuga parametri la condiții. În plus, la nivelul raportului ACS există o filă de condiții în care puteți adăuga condiții arbitrare și le puteți salva în setări rapide. În acest caz, condițiile vor fi universale (egalitate, inegalitate, apartenență, includere în listă etc.).

23. Când lucrați cu documente, poate fi necesar să adăugați sortarea după un câmp de tabel virtual MOMENT DE TIMP, dar ghinion - în interogările imbricate, sortarea după acest câmp nu funcționează corect. Dansul cu tamburine ajută: sortarea după câmp virtual MOMENT DE TIMP se înlocuiește cu două sortări: după dată și după link. De asemenea, puteți rezolva problema printr-un tabel temporar mutând interogarea imbricată într-o interogare separată. Pentru multe versiuni, această caracteristică sau eroare nu a fost remediată.
Un exemplu de cerere defectuoasă care primește ultimul document postat pentru contrapartea specificată (sau, mai degrabă, partea tabelară a documentului):

ALEGE
ConsumableProducts.Link,
Consumabile.Număr linie,
ConsumableProducts.Product,
Articole consumabile.Cantitate,
Produse consumabile.Pret,
Articole consumabile.Cant
DIN

UNDE
Produse consumabile. Link B
(SELECTARE TOP 1
D. Link
DIN
Document.Consumabil AS D
UNDE
D. Link. Realizat

COMANDA DE D. Link. Momentul timpului DESCENDENT)

Solutii posibile:
A) Înlocuiți cu FILTREAZĂ DUPĂ pe
COMANDA PENTRU D.Data DESC.
COMANDĂ PRIN D.Link DESCENDENT

B) Puteți muta interogarea imbricată într-un tabel temporar:
SELECTARE TOP 1
D. Link
PUNEȚI TZLink
DIN
Document.Consumabil AS D
UNDE
D. Link. Realizat
Și D.Counterparty = &Counterparty

FILTREAZĂ DUPĂ
D. Link. Momentul timpului DESCENDENT
;

////////////////////////////////////////////////////////////////////////////////
ALEGE
ConsumableProducts.Link,
Consumabile.Număr linie,
ConsumableProducts.Product,
Articole consumabile.Cantitate,
Produse consumabile.Pret,
Articole consumabile.Cant
DIN
Document.Consumabil.Bunuri AS ConsumabileBunfuri
UNDE
Produse consumabile. Link B
(ALEGE
T.Link
DIN
TZLink AS T)
C) Vă puteți referi la tabelul principal al documentului și abia apoi la partea tabulară
SELECTARE TOP 1
Consumabile.Link,
Consumabile.Marfuri.(
Legătură,
Numărul de linie,
Produs,
Cantitate,
Preț,
Sumă
)
DIN
Document.Consumabile AS Consumabile
UNDE
Expense.Counterparty = &Contraparte
Și Consumabile.Realizat

FILTREAZĂ DUPĂ
Consumabil.Momentul Timpului SCADĂ

24. La accesarea tabelului principal al unui document (director), puteți accesa și datele din tabelul subordonat (partea tabelară). Această oportunitate se numește dereferențierea câmpurilor de tabel. Un exemplu de sarcină este sarcina de a căuta documente care conțin un anumit produs în secțiunea tabelară.
Exemplu:
Selectați Receipt.Link FROM Document.Receipt Unde Receipt.Goods.Nomenclature = &Nomenclatură.

Avantajul acestei interogări față de o interogare pe tabelul imbricat Receipt.Goods este că, dacă există duplicate în documente, rezultatul interogării va returna doar documente unice fără a utiliza cuvântul cheie. VARIAT.
Comparaţie:
Selectați diverse produse.Link FROM Document.Receipt.Products ca produse unde Products.Nomenclature = &Nomenclatură.
Acesta este, probabil, tot ceea ce există. Este clar că există încă multe întrebări în limbajul de interogare pe care nu le-am acoperit. Pentru a scrie acest articol, am folosit informațiile primite după finalizarea cursului de bază 1C 8.2 spec8.ru, precum și din cartea „Ghidul dezvoltatorului 1C 8.2” și pe Internet.
Mulțumiri tuturor!

Pentru a afișa câmpuri de referință într-un raport, trebuie să obțineți o reprezentare a câmpului de referință în cerere și, atunci când îl trimiteți, să îl utilizați și nu linkul în sine. Această secțiune descrie câteva caracteristici ale câmpului „Vizualizare” și funcțiile pentru obținerea vizualizărilor - View(). Puteți citi mai multe despre ieșirea câmpurilor de referință în secțiunea „Ieșirea câmpurilor de referință”.

Reprezentarea câmpului

Fiecare tabel de obiecte din baza de informații are un câmp virtual - „Vizualizare”. Acest câmp conține o reprezentare text a obiectului. Într-o interogare, este posibil să obțineți acest câmp în același mod ca și alte câmpuri de tabel, dar nu pot fi efectuate operații pe acest câmp. Această caracteristică se datorează faptului că acest câmp este virtual și, de fapt, la preluarea acestui câmp din baza de date, interogarea primește mai multe câmpuri, iar atunci când primește valoarea câmpului din rezultatul interogării, convertește valorile primite într-o sfoară. Deci, singurul lucru pe care îl puteți face cu câmpul Vizualizare este să îl introduceți în rezultatul interogării.

Ca urmare, nu este recomandat să sortați rezultatul interogării după câmpul „Vizualizare”, deoarece aceasta nu va produce rezultatul dorit - rezultatul interogării va fi ordonat în ordinea crescătoare a referințelor obiectului. Puteți citi mai multe despre acest lucru în secțiunea „Caracteristici de ordonare după câmpuri de referință”.

Vizualizare funcție()

Funcția de vizualizare este concepută pentru a obține o reprezentare textuală a oricărei valori care poate fi obținută folosind un limbaj de interogare. Funcția View() funcționează atât pentru tipurile de referință, cât și pentru cele primitive. Pentru tipurile de referință, rezultatul funcției este complet similar cu primirea câmpului „Reprezentare” de la referința transmisă ca parametru funcției. Pentru tipurile primitive, rezultatul funcției este șirul în care a fost convertită valoarea transmisă ca parametru. Particularitatea acestei funcții este că rezultatul ei nu poate fi folosit într-o expresie. Această caracteristică se datorează faptului că conversia valorilor într-un șir se realizează deja atunci când se primesc date din rezultatul interogării, deoarece Nu se realizează conversia unei valori arbitrare într-un șir atunci când se execută o solicitare pe server, din cauza faptului că la conversia valorilor într-un șir, trebuie luate în considerare setările locale.

Utilizarea funcției View() are mai multe avantaje față de utilizarea câmpului View. De exemplu, în cazul în care câmpul din care este derivată o reprezentare poate conține atât tipuri de referință, cât și tipuri primitive, preluarea câmpului Reprezentare punctat dintr-un astfel de câmp va avea ca rezultat neobținerea reprezentărilor pentru valorile tipului primitiv. Dacă, totuși, funcția Representation() este utilizată pentru un astfel de câmp, atunci se va obține o reprezentare șir indiferent de tipul de valoare conținută în câmp. În plus, dacă funcția View() este aplicată unui câmp care este o referință la mai mult de trei tabele, limbajul de interogare preia numai valorile de referință din baza de date și preia valorile de vizualizare printr-una sau mai multe interogări suplimentare. Acest comportament vă permite să obțineți mai eficient vizualizări pentru câmpurile care se referă la un număr mare de tabele (de exemplu, la orice director), datorită faptului că interogarea care se execută nu va conține un număr mare de conexiuni care sunt necesare pentru a obține câmpurile care alcătuiesc vederea.

Utilizarea funcției Representation() poate fi utilă și la obținerea unei reprezentări a unui câmp - o enumerare, în cazul executării unei cereri printr-o conexiune COM

Limbajul de interogare 1C este una dintre principalele diferențe dintre versiunile 7.7 și 8. Unul dintre cele mai importante puncte în învățarea programării 1C este limbajul de interogare. În 1C 8.3, interogările sunt cel mai puternic și eficient instrument pentru obținerea datelor. Limbajul de interogare vă permite să obțineți informații din baza de date într-un mod convenabil.

Sintaxa în sine amintește foarte mult de T-SQL clasic, cu excepția faptului că în 1C, folosind limbajul de interogare, puteți primi date doar folosind constructul Select. Limbajul acceptă, de asemenea, constructe mai complexe, de exemplu, (cerere în cadrul unei cereri). Interogările în 1C 8 pot fi scrise atât în ​​chirilic, cât și în latină.

În acest articol voi încerca să vorbesc despre principalele cuvinte cheie în limbajul de interogare 1C:

  • alege
  • permis
  • variat
  • expres
  • primul
  • pentru schimbare
  • sens
  • tipul valorii (și operatorul REFERENCE)
  • alegere
  • a se grupa cu
  • având
  • ISNULL
  • Da NULL
  • conexiuni - dreapta, stânga, interne, pline.

Precum și câteva mici trucuri ale limbajului 1C, folosindu-te de care poți construi în mod optim textul de solicitare.

Pentru a depana interogările în sistemul 1C 8.2, este furnizat un instrument special - consola de interogări. Puteți vedea descrierea și o puteți descărca folosind link-ul -.

Să ne uităm la cei mai importanți și interesanți operatori ai limbajului de interogare 1C.

SELECTAȚI

În limbajul de interogare 1C Enterprise 8, orice interogare începe cu un cuvânt cheie ALEGE. În limbajul 1C nu există constructe UPDATE, DELETE, CREATE TABLE, INSERT; aceste manipulări sunt efectuate în tehnologia obiectelor. Scopul său este de a citi numai datele.

De exemplu:

ALEGE
Director curent.Nume
DIN
Director.Nomenclatură AS Director curent

Interogarea va returna un tabel cu nume de elemente.

Aproape de structura ALEGE puteți găsi cuvinte cheie PENTRU SCHIMBARE, PERMIS, VARIAT, PRIMUL

PERMIS— selectează numai înregistrările din tabel la care utilizatorul curent are drepturi.

VARIAT— înseamnă că rezultatul nu va conține linii duplicate.

SELECTARE (CAZ)

Foarte des, acest design este subestimat de programatori. Un exemplu de utilizare a acestuia:

Director curent.Nume,

CÂND Directorul curent.Serviciul ATUNCI

"Serviciu"

SFÂRȘIT CUM SE VEZI Nomenclatura

Director.Nomenclatură AS Director curent

Exemplul va returna o valoare text în câmpul „Tip articol” - „Produs” sau „Serviciu”.

UNDE

Designul limbajului de interogare 1C, care vă permite să impuneți selecția datelor primite. Vă rugăm să rețineți că sistemul primește toate datele de la server și numai atunci este selectat pe baza acestui parametru.

ALEGE
Director.Nume
DIN
Director curent.Nomenclatură AS Director curent
WHERE CurrentDirectory.Service = TRUE

În exemplu, selectăm înregistrări pentru care valoarea atributului „Service” este setată la „True”. În acest exemplu, ne-am descurca cu următoarea condiție:

„UNDE ESTE SERVICIUL”

În esență, selectăm rânduri în care expresia de după cuvântul cheie este egală cu „Adevărat”.

Puteți folosi condiții directe în expresii:

Cod WHERE = "005215"

Folosind operatorul „VALUE()” în condiții, utilizați accesul la elemente și enumerari predefinite într-o solicitare 1C:

WHERE Tipul articolului = Valoare(Enumeration.Item Types.Product)

Valorile de timp pot fi specificate după cum urmează:

WHERE Data primirii > DATETIME(2012,01,01):

Cel mai adesea, condițiile sunt specificate ca parametri trecuți la cerere:

Obțineți 267 de lecții video pe 1C gratuit:

WHERE NomenclatureGroup= &NomenclatureGroup

O condiție poate fi impusă tipului de atribut dacă este de tip compus:

Dacă trebuie să limitați selecția dintr-o listă de valori sau dintr-o matrice, puteți face următoarele:

UNDE este Registrul de acumulare. Registrator B (&Lista documentelor pentru selecție)

Condiția poate fi, de asemenea, complexă, constând din mai multe condiții:

WHERE Data primirii > DATETIME(2012,01,01) AND NomenclatureGroup= &NomenclatureGroup AND NOT Service

A SE GRUPA CU

Proiectarea limbajului de interogare 1C 8.2 utilizat pentru gruparea rezultatului.

De exemplu:

ALEGE
Recepție de bunuri și servicii Bunuri. Bunuri,
SUM(Recepția BunurilorServiciiMarfurilor.Cantitate) AS Cantitate,
SUM(Recepția BunurilorServiciiMarfurilor.Suma) AS Sumă
DIN
Document.Recepția de Bunuri și Servicii.Bunuri CUM Primirea de Bunuri și Servicii Bunuri

A SE GRUPA CU
Primirea mărfurilorServiciiBunuri.Marfuri

Această solicitare va rezuma toate încasările după sumă și cantitate pe articol.

Pe lângă cuvântul cheie SUMĂ Puteți utiliza alte funcții agregate: CANTITATE, NUMĂR DE DIFERITE, MAXIM, MINIM, IN MEDIE.

AVÂND

Un design care este adesea uitat, dar este foarte important și util. Vă permite să specificați selecția sub forma unei funcții agregate, acest lucru nu se poate face în proiectare UNDE.

Exemplu de utilizare a HAVING într-o solicitare 1C:

ALEGE
Recepție de bunuri și servicii Bunuri. Bunuri,
SUM(Recepția BunurilorServiciiMarfurilor.Cantitate) AS Cantitate,
SUM(Recepția BunurilorServiciiMarfurilor.Suma) AS Sumă
DIN
Document.Recepția de Bunuri și Servicii.Bunuri CUM Primirea de Bunuri și Servicii Bunuri

A SE GRUPA CU
Primirea Bunurilor si Serviciilor Bunuri.marfuri

SUM(Recepția mărfurilorServiciiMarfurilor.Cantitate) > 5

Deci vom selecta numărul de produse care au sosit mai mult de 5 bucăți.

SENS()

De exemplu:

WHERE Bank = Valoare(Directory.Banks.EmptyLink)

WHERE Tip de nomenclatură = Valoare(Directory.Tipuri de nomenclatură.Produs)

WHERE Tip element = Valoare(Enumeration.Item Types.Service)

TYPE la cerere

Tipul de date poate fi verificat folosind funcțiile TYPE() și VALUETYPE() sau folosind operatorul logic REFERENCE.

EXPRES()

Operatorul Express în interogările 1C este utilizat pentru a converti tipurile de date.

Sintaxă: EXPRES(<Выражение>CUM<Тип значения>)

Folosind-o, puteți converti valorile șirurilor în date sau valorile de referință în date șirurile și așa mai departe.

În aplicațiile practice, operatorul Express() este folosit foarte des pentru a converti câmpuri de lungime nelimitată, deoarece câmpurile de lungime nelimitată nu pot fi selectate, grupate etc. Dacă astfel de câmpuri nu sunt convertite, veți primi o eroare Nu puteți compara câmpuri de lungime nelimitată și câmpuri de tipuri incompatibile.

ALEGE
ContactInformation.Object,
EXPRESS(ContactInfo.View AS ROW(150)) AS View
DIN
Registrul de informații Informații de contact CUM Informații de contact

A SE GRUPA CU
EXPRESS(ContactInfo.Representation AS ROW(150)),
ContactInformation.Object

ISNULL (ISNULL)

O funcție destul de utilă a limbajului de interogare 1C care verifică valoarea din înregistrare și dacă este egală NUL, Acest lucru vă permite să îl înlocuiți cu propria dvs. valoare. Cel mai adesea folosit la obținerea tabelelor virtuale de solduri și cifre de afaceri pentru a se ascunde NULși pune un 0 clar (zero).

ISNULL(Impozite înainte de lună. Beneficiu FSS aplicat, 0)

O astfel de funcție a limbajului de interogare 1C ISNULL va returna zero dacă nu există nicio valoare, ceea ce va evita o eroare.

A TE ALATURA

Există 4 tipuri de conexiuni: STÂNGA, DREAPTA, COMPLET, INTERN.

CONEXIUNEA STÂNGA și DREAPTA

Îmbinările sunt folosite pentru a lega două tabele pe baza unei anumite condiții. Caracteristică când LEFT JOIN este că luăm primul tabel specificat în întregime și legăm condiționat al doilea tabel. Câmpurile celui de-al doilea tabel care nu au putut fi legate de condiție sunt completate cu valoarea NUL.

Un exemplu de alăturare stângă într-o solicitare 1C:

Va returna întregul tabel și va completa câmpul „Bancă” numai în acele locuri în care este îndeplinită condiția „Contrapărți.Nume = Bănci.Nume”. Dacă condiția nu este îndeplinită, câmpul Bank va fi setat la NUL.

RIGHT JOIN în limba 1C 8.3 absolut asemănătoare Conexiune LEFT, cu excepția unei diferențe: în DREPTUL DE CONECTARE Masa „principală” este a doua, nu prima.

CONEXIUNE COMPLETA

CONEXIUNE COMPLETA diferă de stânga și dreapta prin faptul că afișează toate înregistrările din două tabele și le conectează numai pe cele pe care le poate conecta în funcție de condiție.

De exemplu:

CONEXIUNE COMPLETA
Director.Bănci CUM Bănci

DE

Limbajul de interogare va returna ambele tabele complet numai dacă este îndeplinită condiția Join records. Spre deosebire de o îmbinare stânga/dreapta, este posibil ca NULL să apară în două câmpuri.

INNER JOIN

INNER JOIN diferă de cel complet prin faptul că afișează numai acele înregistrări care ar putea fi conectate în funcție de o anumită condiție.

De exemplu:

DIN
Director.Contrapărți AS Clienți

INNER JOIN
Director.Bănci CUM Bănci

DE
Clients.Name = Banks.Name

Această interogare va returna numai rândurile în care banca și contrapartea au același nume.

Concluzie

Aceasta este doar o mică parte din sintaxa din limbajul de interogare 1C 8; în viitor voi încerca să iau în considerare câteva puncte mai detaliat, să arătam și multe altele!

CATEGORII

ARTICOLE POPULARE

2023 „kingad.ru” - examinarea cu ultrasunete a organelor umane