Primirea datelor din stocarea valorii 1s 8.3. Limitări atunci când lucrați cu clientul Web

Aproape orice informație poate fi stocată într-un depozit de valori, de ex.

... poze (fotografii):

CurrentImage.Object = SprFabric.Link; CurrentImage.DataType = Enumerări.Tipuri de informații suplimentare despre Objects.Image; Stocare = NewValueStorage(NewPicture, NewDataCompression()); CurrentImage.Storage = Storage.Get();

// în acest loc afișează totul... Form Elements.PictureField1.Picture = Storage.Get(); CurrentImage.Write();

...document foaie de calcul:

TabDoc=New TabularDocument; TabDoc.Output(FormElements.TabularDocumentField1); Stocare=NewValueStorage(TabDoc); Scrie();

Sfârșitul procedurii

Procedura RestoreFromStoragePress(Element)

TabDoc=Storage.Get(); Dacă TabDoc<>Nedefinit ThenFormElements.TabularDocumentField1.Output(TabDoc); endIf;

Sfârșitul procedurii

...fișiere arbitrare (date binare):

XZ = NewValueStorage(NewBinaryData(fișier));

Opt acceptă comprimarea datelor plasate în stocare:

XZ = NewValueStorage(NewBinaryData(fișier),NewDataCompression(9));

... prelucrare și raportare externă:

Procedura LoadProcessingIntoStorage(PropsStorageType)

CompressionRate = NewDataCompression(9); //9 PropsStorageType maxim = New StorageValues(New BinaryData("c:\reports\report.epf", Compression Rate));

Sfârșitul procedurii

Procedure StartProcessingFromStorage(PropsStorageType)

TemporaryFileName = TemporaryFileDirectory()+"report.epf"; BinaryData = PropsStorageType.Get(); BinaryData.Write(TemporaryFileName); ExternalProcessing = ExternalProcessing.Create(TemporaryFileName); ExternalProcessing.GetForm().Open();

Sfârșitul procedurii

Lucrul cu stocarea

Dacă au fost date binare, atunci pot fi restaurate din depozitul de valori folosind metoda Get și scrise într-un fișier folosind metoda Write().

If TypeValue(Stocare)<>Tastați ("BinaryData") Apoi

BinaryData = Storage.Get();

BinaryData = Stocare;

endIf; BinaryData.Write(FileName);

Dacă a fost, de exemplu, un document Word (fișier doc sau alt tip de fișier înregistrat), atunci poate fi deschis astfel:

LaunchApplication(FileName);

Pentru a șterge un câmp de tip Value Storage, trebuie să-l atribuiți Nedefinit:

PropsStorage = Nedefinit;

Lucrul cu fișiere și imagini în limbajul încorporat 1C:Enterprise 8

Scop

Aplicația gestionată implementează un nou mecanism de lucru cu fișierele. Oferă schimb de fișiere între baza de informații și aplicația client. Particularitatea acestui mecanism este că este conceput pentru utilizare într-un client subțire și un client Web și este conceput ținând cont de restricțiile de lucru cu fișiere impuse de browserele web.

Mecanismul este un set de metode care pot fi utilizate pentru a plasa datele stocate local pe computerul utilizatorului într-o stocare temporară a bazei de informații, a transfera aceste informații din stocarea temporară în baza de date și a le primi înapoi pe computerul utilizatorului. Cele mai frecvente probleme de aplicare rezolvate de acest mecanism sunt stocarea informațiilor însoțitoare, de exemplu, imagini ale mărfurilor, documente legate de contracte etc.

Domeniul de aplicare al metodei

Depozitare temporara

Stocarea temporară este o zonă specializată a bazei de informații în care pot fi plasate date binare. Scopul principal este stocarea temporară a informațiilor în timpul interacțiunii client-server înainte ca acestea să fie transferate în baza de date.

Necesitatea stocării temporare apare deoarece modelul de operare al browserului web necesită ca fișierul selectat de utilizator să fie transferat direct pe server fără posibilitatea stocării lui pe client. Când un fișier este transferat, acesta este plasat în stocare temporară și poate fi apoi utilizat atunci când scrieți un obiect în baza de date.

Cea mai tipică sarcină a aplicației rezolvată prin stocarea temporară este furnizarea de acces la fișiere sau imagini înainte ca obiectul să fie înregistrat în baza de informații, de exemplu, sub forma unui element.

Un fișier sau date binare plasate în stocare sunt identificate printr-o adresă unică, care poate fi folosită ulterior în operațiuni de scriere, citire sau ștergere. Această adresă este dată de metode de scriere a unui fișier în stocarea temporară. O metodă separată în limbajul încorporat vă permite să determinați dacă adresa transmisă este o adresă care indică date în stocare temporară.

Baza de informatii

Mecanismul vă permite să accesați date binare stocate în atribute de tipul Value Storage.

Ca și în cazul stocării temporare, accesul la informații este posibil printr-o adresă specială. Îl puteți obține printr-o metodă specială prin transmiterea unui link către un obiect sau o cheie de intrare în registrul de informații și numele atributului. În cazul unei piese tabulare, este necesar să se transfere în plus indexul de rând al părții tabulare.

Metodele de lucru cu fișiere au limitări atunci când se lucrează cu detaliile bazei de informații. Pentru ei, spre deosebire de stocarea temporară, sunt disponibile doar informațiile de citire, dar nu scrierea sau ștergerea acestora.

Descrierea metodelor de lucru cu fișiere

Salvarea datelor în stocarea temporară

Scenariul cel mai tipic pentru utilizarea acestui mecanism implică plasarea inițială a datelor utilizatorului în stocare temporară. Există două metode pentru aceasta: PlaceFile() și PlaceFileInTemporaryStorage().

Prima metodă, PlaceFile(), plasează un fișier din sistemul de fișiere local în stocarea temporară. Metoda poate accepta o adresă țintă în stocare. Dacă nu este definit sau este un șir gol, atunci va fi creat un fișier nou și metoda își va returna adresa prin parametrul corespunzător.

Dacă parametrul care determină modul interactiv de operare este True, atunci metoda va afișa o casetă de dialog standard de selecție a fișierelor în care puteți selecta un fișier pe care să îl plasați în stocare. În acest caz, metoda va returna și adresa fișierului selectat.

Ca rezultat, metoda returnează False dacă utilizatorul a refuzat în mod interactiv să efectueze o operație în dialogul de selecție a fișierului. Metoda este disponibilă numai pentru client.

A doua metodă, PlaceFileInTemporaryStorage(), este similară cu cea anterioară, cu excepția faptului că este disponibilă pe server, iar datele care urmează să fie scrise în stocarea temporară sunt reprezentate nu ca o cale în sistemul de fișiere, ci ca o variabilă de tip BinaryData. De asemenea, dacă nu este specificată nicio adresă țintă, este creat un fișier nou în stocare. Adresa sa este returnată ca rezultat al funcției.

Preluarea unui fișier din stocarea temporară

Când scrieți un obiect în baza de informații, poate fi necesar să extrageți date din stocarea temporară și să le plasați, de exemplu, într-un atribut. Există o metodă de server corespunzătoare pentru aceasta - GetFileFromTemporaryStorage(). Această metodă preia datele din stocarea temporară și, ca rezultat, le returnează. Pentru a face acest lucru, trebuie să specificați adresa în stocarea temporară. Această adresă este returnată de metodele descrise mai sus PlaceFile() și PlaceFileInTemporaryStorage() dacă sunt executate cu succes.

Ștergerea unui fișier din stocarea temporară

După ce datele sunt salvate în detalii, fișierul din stocare temporară poate fi șters. În acest scop, există o metodă DeleteFileFromTemporaryStorage(), care șterge un fișier din stocarea temporară. Metoda ia ca parametru adresa unui fișier aflat în stocare temporară. Disponibil pe server.

Verificarea adresei pentru stocare temporară

Adresa fișierului poate indica atât stocarea temporară, cât și detalii în baza de informații. Pentru a-i verifica tipul, există o metodă This isTemporaryStorageAddress().

Verifică dacă adresa transmisă este o adresă care indică către magazin. Returnează True dacă adresa indică o stocare temporară. Metoda este disponibilă pe server.

Primirea adresei de recuzită

După ce datele sunt plasate în detaliile din baza de informații, poate fi necesar să le accesați folosind metode de fișier.

Dar înainte de a primi date, de exemplu de la o proprietate, trebuie să obțineți adresa acestei proprietăți. În acest scop, există o metodă GetFileAddressInInformationBase().

Scopul său este de a returna adresa fișierului în baza de informații conform parametrilor originali. Pentru a face acest lucru, trebuie să transmiteți cheia obiectului (aceasta poate fi fie un link către obiect, fie o cheie de intrare în registrul de informații) și numele atributului. Dacă trebuie să obțineți adresa unui fișier stocat într-un atribut al părții tabelare, înainte de numele atributului din parametrul care specifică numele atributului, trebuie să adăugați numele părții tabelare și un punct „.”. Metoda este disponibilă atât pe client, cât și pe server.

Preluarea unui fișier din baza de informații

Metoda GetFile() primește un fișier din baza de informații și îl salvează în sistemul de fișiere local al utilizatorului. Primul parametru specifică adresa fișierului din elementele de recuzită sau stocarea temporară a fișierului. Al doilea parametru specifică locația de destinație a fișierului rezultat. În modul non-interactiv, trebuie să specificați calea. În modul interactiv, parametrul este opțional.

Implicit, metoda este executată în modul interactiv, adică ultimul parametru este True. Aceasta înseamnă că este afișată o casetă de dialog în care puteți specifica o acțiune cu fișierul primit: rulați-l sau salvați-l într-o locație specificată de utilizator. Dacă modul interactiv este activ și parametrul Cale fișier disc țintă nu este specificat, operația de deschidere a fișierului nu este disponibilă. Returnează o valoare booleană. Fals înseamnă că utilizatorul a ales să anuleze operația în caseta de dialog interactivă de salvare a fișierului.

Exemplu de utilizare a metodelor de fișiere

// Primirea unui fișier de pe disc în modul interactiv // și plasarea acestuia în stocare temporară &Pe Procedura Client SelectDiskFileAndWrite()

Variabila SelectedName; VariableTemporaryStorageAddress; Dacă PutFile(TemporaryStorageAddress, SelectedName, True) Atunci Object.FileName = SelectedName; PlaceObjectFile(TemporaryStorageAddress); endIf;

Sfârșitul procedurii

// Copierea unui fișier din stocarea temporară într-un atribut de director //, înregistrarea unui obiect, ștergerea unui fișier din stocarea temporară // &Pe server Procedure Place Object File (Adresa de stocare temporară)

Director Element = Form AttributesValue("Obiect"); BinaryData = GetFileFromTemporaryStorage(TemporaryStorageAddress); Director Element.File Data = NewValueStorage(BinaryData); FilePathOnDisk = Fișier nou (DirectoryItem.FileName); Director Item.FileName = FilePathOnDisk.Name; Director element.Write(); Modificat = Fals; DeleteFileFromTemporaryStorage(TemporaryStorageAddress); ValueВFormAttributes(Element director, „Obiect”);

Sfârșitul procedurii

// Citirea unui fișier din elemente de recuzită și salvarea lui // pe discul local în modul interactiv &Pe Procedura Client ReadFileAndSaveToDisk()

Adresă = GetFileAddressInInformationBase(Object.Link, "FileData"); GetFile(Adresă, Object.FileName, True);

Sfârșitul procedurii

Suport pentru adrese din câmpul de imagine

Controlul Picture Field acceptă afișarea unei imagini specificate de adresa unui fișier în stocarea temporară sau într-o bază de date.

Pentru a face acest lucru, trebuie să setați un atribut de tip șir în proprietatea Data a elementului de formular. Valoarea acestui atribut va fi interpretată ca adresa imaginii.

Exemplu // Legarea câmpului de imagine la adresa imaginii în // stocare temporară. AddressPictures formează detalii de tip șir

PlaceFile(Adresă imagine, adevărat)

Picture.Data = AddressPictures

Limitări atunci când lucrați cu clientul Web

Funcționarea mecanismului descris atunci când se utilizează clientul Web are unele limitări. Aceste restricții sunt legate de modelul de securitate al browserului. Deci, de exemplu, clientul nu poate salva independent un fișier în sistemul de fișiere local, adică este disponibilă doar versiunea interactivă a metodelor client PlaceFile() și GetFile(). O excepție este aruncată atunci când încercați să utilizați modul non-interactiv. Casetele de dialog care apar interactiv sunt specifice tipului dvs. de browser.

Caracteristici atunci când lucrați cu Value Storage pe Client

Problemă:

Când un document are un atribut de tipul de stocare a valorii în secțiunea tabelară, încetinește deschiderea formularului de document dacă acest atribut conține date mari.

Motiv presupus:

Poate că, la deschiderea unui formular, nu linkul către datele aflate în Value Store este trimis către client, ci datele în sine.

Soluţie

  • În proprietățile atributului tabel al formularului există un steag „Folosește întotdeauna”. Dacă este setat, conținutul câmpului este întotdeauna transferat între server și client - de exemplu, la deschiderea unui formular. Acest flag trebuie să fie dezactivat, dar acest lucru trebuie luat în considerare în cod, deoarece implicit nu va exista nicio valoare pentru acest câmp pe client. Un exemplu poate fi găsit în 1C:Arhive.

Este chiar mai bine de folosit depozitare temporara pentru a transfera fișiere între client și server.

Avem un director „Produse”, în atributul „Date” al cărui informații sunt stocate sub formă de date binare. Atributul în sine are tipul de valoare „Value Storage”. Următoarea captură de ecran arată structura metadatelor directorului.

Pentru a atașa un fișier arbitrar de pe disc sub forma unui element, a fost implementată comanda „AttachFile”. Codul programului său este prezentat în următoarea listă:

& Pe procedura clientului AttachFile(Command) // Handler de comandă pe client. Selectarea fișierului // Dialog pentru selectarea unui fișier de pe disc Mod = FileSelectionDialogMode. Deschidere; OpenFileDialog = NewFileSelectDialog(Mod); Dialog OpenFile. FullFileName = " " ; Dialog OpenFile. MultipleSelect = Fals ; Dialog OpenFile. Titlu = „Selectați fișierele” ; Dacă FileOpenDialog. Selectați() Apoi FilePath = FileOpenDialog. FullFileName; // Primește date de fișier binar BinaryData = nou BinaryData(PathToFile) ; // Transferați date binare pe server AttachFileServer(BinaryData) ; Altfel Text = "ru = " " Fișier (e) nu sunt selectate!" " ; ro =" " Fișier (e) nu sunt selectate!" " " ; Avertisment(NStr(Text) ) ; EndIf ; EndProcedure & OnServer Procedure AttachFileServer(BinaryData) // Handler pe server pentru înregistrarea unui fișier în securitatea informațiilor // Transformă obiectul formular într-un obiect de referință ObjectCurrent = FormAttributesValue("Obiect"); // Atribuiți o nouă valoare atributului „Date”. ObjectCurrent. Date = NewValueStorage(BinaryData) ; // Salvează modificările ObjectCurrent. Scrie() ; Sfârșitul procedurii

Dacă descriem algoritmul în termeni generali, atunci mai întâi este selectat un fișier de pe discul de pe client. Datele rezultate din fișierul binar sunt trimise către server, unde sunt înregistrate în baza de informații, și anume în atributul „Date” al elementului de director curent.

În principiu, totul funcționează. Când deschidem un element, putem citi aceste date după cum este necesar. Dacă, de exemplu, o imagine este salvată în recuzită, atunci o putem obține și o putem afișa în câmpul de formular. Această soluție are un loc, dar în majoritatea sarcinilor nu este optim să folosiți atribute cu tipul de valoare „Value Storage” în directoare și documente. Si de aceea...

Impactul asupra performanței

Să facem câteva teste de performanță. Testele vor folosi două elemente din directorul „Produse”, cu și fără fișier atașat. Dimensiunea fișierului atașat este de 5 megaocteți.

Toate testele sunt efectuate folosind procesarea „GetElement” din configurația testului. Puteți descărca această configurație din linkul de la sfârșitul articolului.

Să măsurăm timpul necesar pentru deschiderea articolelor din directorul „Produse”. Pentru a deschide un element, este utilizată metoda contextului global „OpenValue()”, căruia i se transmite o referință la element ca parametru. Să măsurăm timpul de deschidere folosind un instrument standard de măsurare a performanței. Rezultatele sunt prezentate în următoarea captură de ecran:

După cum putem vedea, timpul necesar pentru a deschide un element cu un fișier atașat este de 10 ori mai mare! Hai să facem un alt test. Să executăm metoda „GetObject()” pentru a face referire la elementul catalogului de produse. Puteți vedea rezultatul testului în următoarea captură de ecran.

Diferența este destul de semnificativă. Primirea unui element fără un fișier atașat este de 194 de ori mai rapidă!

Acest lucru se întâmplă deoarece metoda „GetObject()” primește toate datele din detaliile elementului director prin referință. În consecință, metoda primește nu numai valorile atributelor „Cod” și „Nume”, ci și valoarea atributului „Date”. Dacă stochează date binare de 5 megaocteți (ca în exemplul nostru), atunci când obiectul este primit, aceste date sunt plasate în RAM (ca și alte detalii) și apoi transmise către client. Primirea datelor din acest atribut este cea care mărește timpul de obținere a obiectului element. Dacă se utilizează un canal de comunicare subțire, atunci timpul de deschidere va crește și mai semnificativ datorită transferului unei cantități mari de informații prin rețea.

Notă: la executarea metodei „OpenValue()”, obiectul element director este mai întâi obținut, apoi transformat într-un obiect formular și transmis clientului (pentru formularele gestionate). Adică, atunci când un element este deschis prin referință, obiectul este și el recuperat.

Să efectuăm un test final privind timpul necesar pentru a deschide și scrie un element de director cu și fără un fișier atașat. Rezultatul este afișat în următoarea captură de ecran.

Rezultat natural. Timpul pentru a primi și apoi a scrie pentru un element de director cu un fișier atașat s-a dovedit a fi de ~19 ori mai lung. După cum sa menționat mai sus, la primirea unui obiect, se obțin valorile tuturor detaliilor acestuia, inclusiv atributul „Date” în care sunt stocați 5 megaocteți de informații. Când un element este scris, această cantitate de date este din nou scrisă în baza de informații. În consecință, stocarea datelor într-un atribut de director (sau document) cu tipul „Depozitare valori” afectează negativ performanța atât la preluarea unui obiect, cât și la plasarea acestuia în baza de informații.

Care este cel mai corect mod de a rezolva problema stocării datelor pentru obiectele bazei de informații?

Soluție corectă

Dacă ne uităm la implementarea acestui mecanism în configurații tipice, vom vedea că pentru obiecte informații suplimentare sunt stocate într-un tabel separat de registru de informații. Acesta este, de exemplu, cum arată mecanismul fișierului atașat într-o configurație standard a „Trade Management” versiunea 11.

Directorul „Nomenclature” este proprietarul directorului „NomenclatureAttachedFiles”. Acesta, la rândul său, este asociat cu registrul de informații AttachedFiles, a cărui dimensiune AttachedFile se referă la elementul său. Astfel, datele atașate obiectelor de bază de informații sunt de fapt stocate în tabelul registrului de informații, a cărui funcționare practic nu este afectată de cantitatea de date stocată în resursă. Directorul intermediar „Nomenclatura fișierelor atașate” este necesar pentru a stoca informații suplimentare pentru fișierul atașat, precum și pentru a sprijini accesul la fișierul atașat prin referință.

Toate cele de mai sus confirmă încă o dată impactul enorm asupra performanței al unei structuri de metadate de configurare proiectate corespunzător.

Testați configurația cu un exemplu din articol: LEGĂTURĂ .

Platforma 1C: Enterprise oferă o mulțime de posibilități de stocare a datelor de diferite tipuri.

Dar de multe ori aceste oportunități nu sunt suficiente. Și apoi un obiect special ne vine în ajutor - Valori de stocare. Acest obiect vă permite să stocați într-un format special atât obiectele standard 1C:Enterprise, de exemplu, un tabel de valori, cât și cele nestandard pentru care nu este prevăzut un tip în platformă. Tipurile non-standard pot include fișiere. De exemplu, folosind un depozit de valori într-o bază de date 1C, puteți stoca fotografii ale angajaților, scanări ale documentelor, procesări externe etc. Avantajul aici este că toate aceste obiecte sunt stocate în baza de date însăși. În consecință, la implementarea unei noi baze de date dintr-o copie de rezervă, toate aceste obiecte vor fi prezente și în noua bază de date. Pe de altă parte, dacă stocați fișiere mari în baza de date, acest lucru poate crește semnificativ volumul acesteia și poate afecta negativ performanța acesteia. Prin urmare, aici trebuie menținut un echilibru rezonabil.

Să ne uităm la lucrul cu un magazin de valori folosind un exemplu. Să creăm un director special în configurator - să-l numim ExternalObjects, iar la rândul nostru vom crea cerințele pentru director Un obiect cu tip Valori de stocare

Și acum putem crea elemente în acest director și în elemente de recuzită Un obiect Fiecare element este scris într-un fișier.

Lucrul cu un magazin de valori este foarte simplu. Dacă ne uităm la ajutorul de sintaxă, vom vedea că acest obiect are o singură metodă și un constructor.

Acum, pentru demonstrație, să scriem cel mai simplu cod care va scrie un fișier în elemente de recuzită Un obiect un element de director creat anterior, apoi citiți acest fișier din elemente de recuzită și scrieți-l pe disc, dar sub un alt nume.

&Pe server Procedura LoadUnloadFile(Directory Element)Directory Object =Directory Element. GetObject() ; //Plasați imaginea în depozitul de valori LabelDownload = Imagine nouă("g:\musor\favicon.ico" ) NewValueStorage; //Scrieți un element de director Obiect director. Obiect DirectoryObject. Scrie() ; //Încărcați imaginea din depozitul de valori într-un fișier FileName = "g:\musor\favicon_1.ico" ; LabelUpload = Obiect Director. Un obiect. Obține() ; LabelUpload. Scrie (Nume Fișier); Sfârșitul procedurii

Și câteva explicații pentru cod.

  • Obiectul este plasat în magazin direct atunci când magazinul este creat folosind constructorul.

Pentru a stoca alte tipuri de fișiere, altele decât imaginile, puteți utiliza obiectul BinaryData. Pur teoretic, puteți chiar stoca elemente de director, documente etc. în depozitul de valori. Dar, în practică, acest lucru nu are niciun sens. Dar uneori este posibil să folosiți un depozit de valori pentru a stoca un tabel de valori, un arbore de valori și alte colecții universale.