Expanding the functionality of working with binary data. Working with binary data 1c get an xls file from binary data

Binary data in 1C is intended for storing files of arbitrary format. With their help you can:

  • Organize interaction using a binary protocol with various devices;
  • Store files of any formats as metadata object attributes;
  • Convert text data to binary (most often used for sending reports);
  • Work with binary data in memory.

What the system can do

When working with binary data, Platform 8.3 can perform the following actions:

  1. Read and write binary data;
  2. Move data from client to server and back using temporary storage;
  3. Initialize an object of the “Picture” type using binary files;
  4. Read them from the World Wide Web using the objects “Mail Attachment”, “HTTP Connection”, etc.
  5. Use cryptographic tools to encrypt and sign important attachments;
  6. Using the “Data Hashing” object, calculate the hash function.

Saving data to details

For example, let's create a directory in a test configuration.

In fact, using the same directory to store information about nomenclature and binary image data is a little incorrect. With sufficiently large volumes of data and heavy, large files, unwanted downtime and “brakes” in the operation of the system may occur. From the point of view of the system, it would be much more correct to organize a separate “Pictures” directory, a link to which we could set as a props type.


It is important to note that due to the fact that attributes of the “ValueStorage” type containing binary data are not available in managed application mode, they can only be accessed using the FormAttributesValue method.


The message field represents a value store binary data record.

Reading data from props

Let's create a processing that will output the file stored in binary form in our configuration into a spreadsheet document (this is necessary, for example, to print a company logo).


Basically, this is all the code we need. Using the Get() operator, we read the binary data stored in the corresponding directory attribute and transfer it to the “Picture” object, which will be shown in the upper left cell of the spreadsheet document of the form (Fig. 9).

Fig.9

Data Conversion

It is not common, but it happens that when working with non-standard exchanges with external systems, it is necessary to convert data from binary format to Base64 format or vice versa.

In most cases, the platform automatically converts the data; if this does not happen, you need to use global translation functions:

  1. Base64String – converts the specified value into a string of the corresponding encoding;
  2. Base64Value – does the reverse conversion.

Optimization of the above code

The code presented in Fig. 4 certainly works, but with one significant caveat: if the “Modality use mode” checkbox is selected in the configuration properties (Fig. 10). Otherwise, using it will cause an error.
Fig.10

To prevent this from happening, while in the directory element form module, go to the menu Text->Refactoring->Deprecated synchronous calls->Convert module calls.

After some time, synchronous calls will automatically be converted to asynchronous, and the code will take the form (Fig. 11)

Fig.11

The 1C:Enterprise 8 technology platform allows you to save arbitrary files in the information base, retrieve them from there and use them in various ways. Let's look at these operations using examples.

Before uploading a file to the 1C information base, you need to obtain the full address of the file on disk. Working with file selection dialogs is described in .

To store files, use an attribute (or register resource) with the type StorageValues.

Uploading an arbitrary file to the 1C information base

Any file can be represented as binary data and loaded into Value Storage.

When converting binary data to an object StorageValues design used new StorageValues(Data, Compression) with two parameters:

  1. Data— binary data that needs to be stored in storage
  2. Compression— compression ratio of the Deflation algorithm. Integer in the range -1...9. -1 is the default compression level. 0 - no compression, 9 - maximum compression. Default value: -1. The parameter is optional; if not specified, then compression is not used.

//Convert the file to binary data
File = New BinaryData(Path) ;

//Create a new Value Storage object

DataStorage = NewValueStorage(File, NewDataCompression(9) ) ;

Saving an arbitrary file from the 1C infobase to disk

To save a file from the 1C database to disk, you need to determine the path and file name. To do this, there is a file saving dialog, working with which is described in.

//Get binary data from storage
//Data Storage - attribute of an object with the Value Storage type

//Write the received data to disk
//The Path variable contains the full address of the file on disk
Data. Write(Path) ;

Viewing a file located in the 1C information base

To view a file saved in the database, you must have an application installed on your computer that opens the file.

//Get the name of the temporary file with the required extension
//In the Extension variable you need to put the file extension, for example "pdf"
Path = GetTemporaryFileName(Extension) ;

//Receive data from storage
//Data Storage - attribute of an object with the Value Storage type
Data = Datastore. Get() ;

//Write data to a temporary file
Data. Write(Path) ;

//Trying to open the file in the intended application
//If the application is not found, the system dialog "Open with..." will appear.
LaunchApplication(Path) ;

Implemented in version 8.3.10.2168.

We are gradually increasing the functionality for working with binary data. There are several reasons for this. Firstly, we did not implement everything that we had planned. And secondly, in the process of discussing new opportunities, we received a number of wishes from you, which we also decided to implement.

New functions for converting binary data to different formats

In a global context, we have added a large number of new functions for converting binary data. So, for example, you can perform forward and reverse conversion of binary data into a regular string, format string Base64 and format string BinHex. In addition, you can convert the binary data itself into formats Base64, BinHex and back.

Similar conversions are supported for the type BufferBinaryData. In addition, you can convert a binary data buffer to binary data and vice versa.

In addition, two new functions allow you to split binary data into several parts, and vice versa, to combine several objects of the type BinaryData into one. In this case, the new object will contain the data of all parts in the order that you specify.

These functions are similar in concept to splitting and merging files, but in many cases they are more efficient. Because there is no need to first save the binary data to a file, and because there is no unnecessary copying of data when splitting.

Adding the ability to work with streams to objects that work with files

Since the use of binary data is largely related to file operations, we considered it completely logical and natural to add work with streams to those objects that currently read and write files in one way or another.

As a result, you can now open streams for reading and writing when using objects such as:

  • ReadingText And WriteText;
  • ReadingFastInfoSet And EntryFastInfoSet;
  • ReadingHtml And PostHtml;
  • Reading JSON And JSON entry;
  • Reading XML And XML entry;
  • Reading Zip File And Record Zip File.

You can receive the body as a stream when working with HTTP:

  • HTTPRequest And HTTPResponse;
  • HTTPServiceRequest And HTTPServiceResponse.
  • Text Document;
  • TabularDocument;
  • FormattedDocument;
  • GeographicalScheme;
  • GraphicScheme;
  • FTPConnection.

Writing to a stream is now available when working with types Picture And ConvertToCanonicalXML. And besides this, working with streams is now supported in various methods that types have XSL Conversion, Cryptography Manager, CertificateCryptography And HashingData.

Efficient copying by reading and writing data

The binary tools we implemented made it possible to copy streams. But this operation was not performed very efficiently on large volumes of data.

Therefore, the type ReadData we have implemented a new method CopyB(). It not only eliminates this problem, but also simplifies the text, making it more understandable.

For example, previously it was possible to receive binary data from one stream and write it to another stream.

Now there is no need to receive binary data; copying is performed at the data reading stage.

The nice thing is that you can copy not only to a stream, but also to an object WriteData. This option is convenient when, in addition to data from the source stream, you need to write some of your own data to the output stream.

Bitwise logical operations on a binary data buffer

You can now use bitwise logical operations when working with binary data buffers. As a result of these operations, the result of a bitwise combination of the source bytes and the bytes in the specified buffer will be written to the source buffer according to the rules of the selected logical operation. We implemented the following operations:

  • WriteBitBit();
  • WriteBitOr();
  • WriteBitExclusiveOr();
  • WriteBitIne();
  • Invert().

A good example of the use of bitwise logical operations is the task of decoding the exchange format with retail equipment. For example, the exchange format with retail equipment is described by a 1-byte field. This field contains a set of characteristics describing the product range:

  • Bits 0-2: tax rate;
  • Bit 3: 0 - piece goods, 1 - weight goods;
  • Bit 4: 0 - allow sale, 1 - prohibit sale;
  • Bit 5: 0 - enable quantity counting, 1 - disable quantity counting;
  • Bit 6: 0 - single sale is prohibited, 1 - single sale is allowed;
  • Bit 7: Reserved.

Then the code that extracts this information and presents it in a form convenient for further processing may look like this.

Getting a number from hexadecimal and binary literals

  • NumberFromHexString();
  • NumberFromBinaryString().

Binary literals are useful for defining masks when used in conjunction with bitwise operations. For example, in the previous example with analysis of the exchange format with commercial equipment, masks are specified using decimal numbers. This is not very convenient, since when writing and reading code you need to constantly mentally translate the decimal number into the binary system.

It is much more convenient to use binary literals instead. At the same time, the code becomes more clear and the likelihood of errors is significantly reduced.

Hexadecimal literals are convenient to use when parsing technical formats: image, sound, video formats.

Changes in the technology of external NativeAPI components

Previously, there were a number of restrictions when transferring binary data between 1C:Enterprise and an external component. For example, it was impossible to transfer binary data to an external component, and when working in a web client, exchanging binary data was generally impossible.

Now we are removing all these restrictions. You can exchange binary data in both directions and even in the web client.

This will not affect the operation of existing external components in any way. They will work as before. But in newly created components you can now pass objects as parameters BinaryData.

Almost any information can be stored in a value store, e.g.

... pictures (photos):

CurrentImage.Object = SprFabric.Link; CurrentImage.DataType = Enumerations.Types of Additional Information of Objects.Image; Storage = NewValueStorage(NewPicture, NewDataCompression()); CurrentImage.Storage = Storage.Get();

// in this place it displays everything... Form Elements.PictureField1.Picture = Storage.Get(); CurrentImage.Write();

...spreadsheet document:

TabDoc=New TabularDocument;

TabDoc.Output(FormElements.TabularDocumentField1);

Storage=NewValueStorage(TabDoc);

Write();<>End of Procedure

Procedure RestoreFromStoragePress(Element)

TabDoc=Storage.Get();

If TabDoc

Undefined ThenFormElements.TabularDocumentField1.Output(TabDoc);

endIf;

End of Procedure

...arbitrary files (binary data):

XZ = NewValueStorage(NewBinaryData(file));

TabDoc.Output(FormElements.TabularDocumentField1);

Eight supports compression of data placed in storage:

XZ = NewValueStorage(NewBinaryData(file),NewDataCompression(9));

Procedure RestoreFromStoragePress(Element)

... external processing and reporting:

Procedure LoadProcessingIntoStorage(PropsStorageType)

CompressionRate = NewDataCompression(9); //9 maximum PropsStorageType = New StorageValues(New BinaryData("c:\reports\report.epf", Compression Rate));<>Procedure StartProcessingFromStorage(PropsStorageType)

TemporaryFileName = TemporaryFileDirectory()+"report.epf";

BinaryData = PropsStorageType.Get();

BinaryData.Write(TemporaryFileName);

ExternalProcessing = ExternalProcessing.Create(TemporaryFileName);

ExternalProcessing.GetForm().Open();

Working with storage

If it was Binary Data, then it can be restored from the value store using the Get method and written to a file using the Write() method.

If TypeValue(Storage)

Type("BinaryData") Then

BinaryData = Storage.Get();

The mechanism is a set of methods that can be used to place data stored locally on the user’s computer in a temporary storage of the information base, transfer this information from the temporary storage to the database, and receive it back to the user’s computer. The most common application problems solved by this mechanism are the storage of accompanying information, for example, images of goods, documents related to contracts, etc.

Method Scope

Temporary storage

Temporary storage is a specialized area of ​​the information base into which binary data can be placed. The main purpose is the temporary storage of information during client-server interaction before it is transferred to the database.

The need for temporary storage arises because the web browser operating model requires that the user-selected file be transferred directly to the server without the possibility of storing it on the client. When a file is transferred, it is placed in temporary storage and can then be used when writing an object to the database.

The most typical application task solved by temporary storage is providing access to files or pictures before the object is recorded in the information base, for example, in the form of an element.

A file or binary data placed in storage is identified by a unique address, which can later be used in write, read, or delete operations. This address is given by methods for writing a file to temporary storage. A separate method in the built-in language allows you to determine whether the passed address is an address pointing to data in temporary storage.

Information base

The mechanism allows you to access binary data stored in attributes of the Value Storage type.

As in the case of temporary storage, access to information is possible through a special address. You can get it through a special method by passing a link to an object or an information register entry key, and the name of the attribute. In the case of a tabular part, it is additionally required to transfer the row index of the tabular part.

Methods for working with files have limitations when working with infobase details. For them, unlike temporary storage, only reading information is available, but not writing or deleting it.

Description of methods for working with files

Saving data to temporary storage

The most typical scenario for using this mechanism involves initially placing user data in temporary storage. There are two methods for this: PlaceFile() and PlaceFileInTemporaryStorage().

The first method, PlaceFile(), places a file from the local file system into temporary storage. The method can accept a target address in storage. If it is not defined or is an empty string, then a new file will be created and the method will return its address through the corresponding parameter.

If the parameter that determines the interactive mode of operation is True, then the method will display a standard file selection dialog box in which you can select a file to place in storage. In this case, the method will also return the address of the selected file.

As a result, the method returns False if the user interactively refused to perform an operation in the file selection dialog. The method is only available on the client.

The second method, PlaceFileInTemporaryStorage(), is similar to the previous one, except that it is available on the server, and the data to be written to temporary storage is represented not as a path in the file system, but as a variable of type BinaryData. Likewise, if no target address is specified, a new file is created in the storage. Its address is returned as the result of the function.

Retrieving a file from temporary storage

When writing an object to the infobase, you may need to extract data from temporary storage and place it, for example, in an attribute. There is a corresponding server method for this - GetFileFromTemporaryStorage(). This method retrieves data from temporary storage and returns it as a result. To do this, you need to specify the address in temporary storage. This address is returned by the above-described methods PlaceFile() and PlaceFileInTemporaryStorage() if they are executed successfully.

Deleting a file from temporary storage

After the data is saved in the details, the file in temporary storage can be deleted. For this purpose, there is a method DeleteFileFromTemporaryStorage(), which deletes a file from temporary storage. The method takes as a parameter the address of a file in temporary storage. Available on the server.

Checking the address for temporary storage

The file address can indicate both temporary storage and details in the infobase. To check its type, there is a method This isTemporaryStorageAddress().

It checks that the passed address is an address pointing to the store. Returns True if the address points to temporary storage. The method is available on the server.

Receiving the props address

After the data is placed in the details in the infobase, you may need to access it using file methods.

But before receiving data, for example from a property, you need to obtain the address of this property. For this purpose, there is a method GetFileAddressInInformationBase().

Its purpose is to return the file address in the infobase according to the original parameters. To do this, you need to pass the object key (this can be either a link to the object or an information register entry key) and the name of the attribute. If you need to get the address of a file stored in a tabular part attribute, before the attribute name in the parameter specifying the attribute name, you need to add the name of the tabular part and a dot “.”. The method is available on both the client and the server.

Retrieving a file from the infobase

The GetFile() method receives a file from the infobase and saves it to the user's local file system. The first parameter specifies the address of the file in the props or temporary file storage. The second parameter specifies the destination location of the resulting file. In non-interactive mode, you must specify the path. In interactive mode, the parameter is optional.

By default, the method is executed in interactive mode, that is, the last parameter is True. This means that a dialog box is displayed in which you can specify an action with the received file: run it or save it to a user-specified location. If interactive mode is active and the Target disk file path parameter is not specified, the file open operation is not available. Returns a boolean value. False means the user chose to cancel the operation in the interactive save file dialog box.

Example of using file methods

// Receiving a file from disk in interactive mode // and placing it in temporary storage &On the Client Procedure SelectDiskFileAndWrite()

Variable SelectedName;

TabDoc.Output(FormElements.TabularDocumentField1);

VariableTemporaryStorageAddress;

Directory Element = Form AttributesValue("Object");

TabDoc.Output(FormElements.TabularDocumentField1);

BinaryData = GetFileFromTemporaryStorage(TemporaryStorageAddress);

Directory Element.File Data = NewValueStorage(BinaryData);

Procedure RestoreFromStoragePress(Element)

FilePathOnDisk = New File(DirectoryItem.FileName);

Directory Item.FileName = FilePathOnDisk.Name;

Directory element.Write();

Modified = False; DeleteFileFromTemporaryStorage(TemporaryStorageAddress);

ValueВFormAttributes(Directory Element, "Object");

// Reading a file from the props and saving it // on the local disk in interactive mode &On the Client Procedure ReadFileAndSaveToDisk()

Address = GetFileAddressInInformationBase(Object.Link, "FileData");

GetFile(Address, Object.FileName, True);

Support for addresses in the picture field

The Picture Field control supports displaying a picture specified by the address of a file in temporary storage or in a database.

To do this, you must set a string type attribute in the Data property of the form element. The value of this attribute will be interpreted as the address of the picture.

Example

// Binding the image field to the image address in temporary // storage. AddressPictures form details of string type

PlaceFile(PictureAddress,True)

  • In the properties of the form's table attribute there is a flag "Always use". If it is set, the contents of the field are always transferred between the server and the client - for example, when opening a form. This flag must be disabled, but this must be taken into account in the code, since by default there will be no value for this field on the client. An example can be found in 1C:Archive.

It's even better to use temporary storage to transfer files between client and server.