Desktop version

Main > Knowledge Base > Knowledge Base > Knowledge base > Practical developer guide 8.3 > Lesson 24 (6:10). Data exchange > Universal data exchange > Creating data exchange procedures > Data reading procedure > Practical developer guide 8.3 > Lesson 24 (6:10). Data exchange > Universal data exchange > Creating data exchange procedures > Data reading procedure

Data reading procedure

The steps for creating the procedure that reads exchange data will be similar to the steps for creating the procedure that writes exchange data. First, let us generate the name of the file that will store exchange data.

  1. Add the procedure shown in listing 24.16 to the Branches configuration object module.

    Listing 24.16. Generating a data exchange file name

    Procedure ReadMessageWithChanges() Export
     
        Directory = TempFilesDir();
     
        // Generating file name
        FileName = Directory + ?(Right(Directory,1)= "\", "", "\") + "Message"
            + TrimAll(Ref.Code) + "_" + TrimAll(ExchangePlans.Branches.ThisNode().Code)
            + ".xml";
        File = New File(FileName);
        If Not File.Exist() Then
            Return;
        EndIf;
     
        DeleteFiles(FileName);
        
        Message = New UserMessage;
        Message.Text = "-------- Import completed --------";
        Message.Message();
     
    EndProcedure
    The procedure generates the name of the file that it expects to find in the directory and then creates a File object with that name and checks whether the file exists. If there is no such file, the procedure execution is terminated. If the file is found, the procedure deletes the file once it processes all its data.

    Let us add the procedure part that reads the exchange data file.
  2. Update the procedure as shown in listing 24.17.

    Listing 24.17. Adding the reading of the exchange data file

    Procedure ReadMessageWithChanges() Export
        
        Directory = TempFilesDir(); 
     
        // Generating file name
        FileName = Directory + ?(Right(Directory,1)= "\", "", "\") + "Message"
            + TrimAll(Ref.Code) + "_" + TrimAll(ExchangePlans.Branches.ThisNode().Code) 
            + ".xml";
        File = New File(FileName);
        If Not File.Exist() Then
            Return;
        EndIf;
     
        // *** Reading XML document
        // Trying to open the file
        XMLReader = New XMLReader;
        Try
            XMLReader.OpenFile(FileName);
     
        Except
            Message = New UserMessage;
            Message.Text = "Cannot open the data exchange file.";
            Message.Message();
     
            Return;
     
        EndTry;
     
        Message = New UserMessage;
        Message.Text = "-------- Starting import from: " + String(ThisObject) + "---------";
        Message.Message();
        Message = New UserMessage;
        Message.Text = "– Reading file: " + FileName;
        Message.Message();
        
        XMLReader.Close(); 
    
        DeleteFiles(FileName);
     
        Message = New UserMessage;
        Message.Text = "-------- Import completed --------";
        Message.Message();
     
    EndProcedure
    The added procedure part utilizes the XML document read/write feature, which works with files at the basic level.

    First, it creates an XMLReader object that opens the file for reading. If the file is successfully opened, a message is displayed informing the user that the data import begins. At the end the procedure stops reading data from the XML file using the Close() method.

    The data received in this manner should be some sort of data exchange message. To present such data in message terms, let us add the next procedure part.
  3. Update the procedure as shown in listing 24.18.

    Listing 24.18. Adding the reading of XML message header

    Procedure ReadMessageWithChanges() Export
        
        Directory = TempFilesDir(); 
     
        // Generating file name
        FileName = Directory + ?(Right(Directory,1)= "\", "", "\") + "Message"
            + TrimAll(Ref.Code) + "_" + TrimAll(ExchangePlans.Branches.ThisNode().Code) 
            + ".xml";
        File = New File(FileName);
        If Not File.Exist() Then
            Return;
        EndIf;
     
        // *** Reading XML document
        // Trying to open the file
        XMLReader = New XMLReader;
        Try
            XMLReader.OpenFile(FileName);
     
        Except
            Message = New UserMessage;
            Message.Text = "Cannot open the data exchange file.";
            Message.Message();
     
            Return;
     
        EndTry;
     
        Message = New UserMessage;
        Message.Text = "-------- Starting import from: " + String(ThisObject) + "---------";
        Message.Message();
        Message = New UserMessage;
        Message.Text = "– Reading file: " + FileName;
        Message.Message();
     
        // Importing data from the file
        // *** Message infrastructure
        ExchangeMessageReader = ExchangePlans.CreateMessageReader();
     
        // Reading the data exchange message header from the XML file
        ExchangeMessageReader.BeginRead(XMLReader);
     
        ExchangeMessageReader.EndRead();
     
        XMLReader.Close(); 
    
        DeleteFiles(FileName);
     
        Message = New UserMessage;
        Message.Text = "-------- Import completed --------";
        Message.Message();
     
    EndProcedure
    Here the procedure utilizes the exchange plan message infrastructure and creates an ExchangeMessageReader object. The BeginRead() method of this object reads the XML message header, which contains information about the message sender among other data. Once the entire message is processed, the reading is stopped.

    Now that exchange data is presented as a message and the header is received, let us make one more check before actual data processing begins.
  4. Update the procedure as shown in listing 24.19.

    Listing 24.19. Adding a message check

    Procedure ReadMessageWithChanges() Export
        
        Directory = TempFilesDir(); 
     
        // Generating file name
        FileName = Directory + ?(Right(Directory,1)= "\", "", "\") + "Message"
            + TrimAll(Ref.Code) + "_" + TrimAll(ExchangePlans.Branches.ThisNode().Code) 
            + ".xml";
        File = New File(FileName);
        If Not File.Exist() Then
            Return;
        EndIf;
     
        // *** Reading XML document
        // Trying to open the file
        XMLReader = New XMLReader;
        Try
            XMLReader.OpenFile(FileName);
     
        Except
            Message = New UserMessage;
            Message.Text = "Cannot open the data exchange file.";
            Message.Message();
     
            Return;
     
        EndTry;
     
        Message = New UserMessage;
        Message.Text = "-------- Starting import from: " + String(ThisObject) + "---------";
        Message.Message();
        Message = New UserMessage;
        Message.Text = "– Reading file: " + FileName;
        Message.Message();
     
        // Importing data from the file
        // *** Message infrastructure
        ExchangeMessageReader = ExchangePlans.CreateMessageReader();
     
        // Reading the data exchange message header from the XML file
        ExchangeMessageReader.BeginRead(XMLReader);
     
        // The message is not for this node
        If ExchangeMessageReader.Sender <> Ref Then
            Raise "Incorrect node";
        EndIf;
     
        ExchangeMessageReader.EndRead();
        XMLReader.Close();
        DeleteFiles(FileName);
     
        Message = New UserMessage;
        Message.Text = "-------- Import completed --------";
        Message.Message();
     
    EndProcedure
    Here the procedure checks whether the message sender is exactly the exchange plan node processed by the current procedure call.

    If the node is correct, before actual data reading begins, you have to delete all the change registration records made for this node that correspond to message numbers less than or equal to the received message number specified in the message being processed. The idea is to prevent duplicating data that is already sent to the node and processed by it.
  5. Update the procedure as shown in listing 24.20.

    Listing 24.20. Deleting change registration records for the source node

    Procedure ReadMessageWithChanges() Export
        
        Directory = TempFilesDir(); 
     
        // Generating file name
        FileName = Directory + ?(Right(Directory,1)= "\", "", "\") + "Message"
            + TrimAll(Ref.Code) + "_" + TrimAll(ExchangePlans.Branches.ThisNode().Code) 
            + ".xml";
        File = New File(FileName);
        If Not File.Exist() Then
            Return;
        EndIf;
     
        // *** Reading XML document
        // Trying to open the file
        XMLReader = New XMLReader;
        Try
            XMLReader.OpenFile(FileName);
     
        Except
            Message = New UserMessage;
            Message.Text = "Cannot open the data exchange file.";
            Message.Message();
     
            Return;
     
        EndTry;
     
        Message = New UserMessage;
        Message.Text = "-------- Starting import from: " + String(ThisObject) + "---------";
        Message.Message();
        Message = New UserMessage;
        Message.Text = "– Reading file: " + FileName;
        Message.Message();
     
        // Importing data from the file
        // *** Message infrastructure
        ExchangeMessageReader = ExchangePlans.CreateMessageReader();
     
        // Reading the data exchange message header from the XML file
        ExchangeMessageReader.BeginRead(XMLReader);
     
        // The message is not for this node
        If ExchangeMessageReader.Sender <> Ref Then
            Raise "Incorrect node";
        EndIf;
     
        // Deleting change records for the source node
        // *** Change registration service
        ExchangePlans.DeleteChangeRecords(ExchangeMessageReader.Sender,
            ExchangeMessageReader.ReceivedNo);
     
        ExchangeMessageReader.EndRead();
        XMLReader.Close();
        DeleteFiles(FileName);
     
        Message = New UserMessage;
        Message.Text = "-------- Import completed --------";
        Message.Message();
     
    EndProcedure
    Note that the new procedure part accesses the change registration service and uses the DeleteChangeRecords() method to delete the messages.

    Now you can proceed to reading the data stored in the message.
  6. Update the procedure as shown in listing 24.21.

    Listing 24.21. Reading the message data

    Procedure ReadMessageWithChanges() Export
        
        Directory = TempFilesDir(); 
     
        // Generating file name
        FileName = Directory + ?(Right(Directory,1)= "\", "", "\") + "Message"
            + TrimAll(Ref.Code) + "_" + TrimAll(ExchangePlans.Branches.ThisNode().Code) 
            + ".xml";
        File = New File(FileName);
        If Not File.Exist() Then
            Return;
        EndIf;
     
        // *** Reading XML document
        // Trying to open the file
        XMLReader = New XMLReader;
        Try
            XMLReader.OpenFile(FileName);
     
        Except
            Message = New UserMessage;
            Message.Text = "Cannot open the data exchange file.";
            Message.Message();
     
            Return;
     
        EndTry;
     
        Message = New UserMessage;
        Message.Text = "-------- Starting import from: " + String(ThisObject) + "---------";
        Message.Message();
        Message = New UserMessage;
        Message.Text = "– Reading file: " + FileName;
        Message.Message();
     
        // Importing data from the file
        // *** Message infrastructure
        ExchangeMessageReader = ExchangePlans.CreateMessageReader();
     
        // Reading the data exchange message header from the XML file
        ExchangeMessageReader.BeginRead(XMLReader);
     
        // The message is not for this node
        If ExchangeMessageReader.Sender <> Ref Then
            Raise "Incorrect node";
        EndIf;
     
        // Deleting change records for the source node
        // *** Change registration service
        ExchangePlans.DeleteChangeRecords(ExchangeMessageReader.Sender,
            ExchangeMessageReader.ReceivedNo); 
        
        // Reading data from the message
        // *** XML serialization
        While CanReadXML(XMLReader) Do
        
        EndDo; 
     
        ExchangeMessageReader.EndRead();
        XMLReader.Close();
        DeleteFiles(FileName);
     
        Message = New UserMessage;
        Message.Text = "-------- Import completed --------";
        Message.Message();
     
    EndProcedure
    The data reading is executed in the loop and XML serialization is involved again. The CanReadXML() global context method gets the next XML data type from the XMLReader object and checks whether a matching 1C:Enterprise data type is available. If it is available, the loop execution continues.

    You have to present XML data as a value that has a type available in 1C:Enterprise. Let us use the ReadXML() global context method for this purpose.
  7. Update the procedure as shown in listing 24.22.

    Listing 24.22. Presenting XML data as a value that has a type

    Procedure ReadMessageWithChanges() Export
        
        Directory = TempFilesDir(); 
     
        // Generating file name
        FileName = Directory + ?(Right(Directory,1)= "\", "", "\") + "Message"
            + TrimAll(Ref.Code) + "_" + TrimAll(ExchangePlans.Branches.ThisNode().Code) 
            + ".xml";
        File = New File(FileName);
        If Not File.Exist() Then
            Return;
        EndIf;
     
        // *** Reading XML document
        // Trying to open the file
        XMLReader = New XMLReader;
        Try
            XMLReader.OpenFile(FileName);
     
        Except
            Message = New UserMessage;
            Message.Text = "Cannot open the data exchange file.";
            Message.Message();
     
            Return;
     
        EndTry;
     
        Message = New UserMessage;
        Message.Text = "-------- Starting import from: " + String(ThisObject) + "---------";
        Message.Message();
        Message = New UserMessage;
        Message.Text = "– Reading file: " + FileName;
        Message.Message();
     
        // Importing data from the file
        // *** Message infrastructure
        ExchangeMessageReader = ExchangePlans.CreateMessageReader();
     
        // Reading the data exchange message header from the XML file
        ExchangeMessageReader.BeginRead(XMLReader);
     
        // The message is not for this node
        If ExchangeMessageReader.Sender <> Ref Then
            Raise "Incorrect node";
        EndIf;
     
        // Deleting change records for the source node
        // *** Change registration service
        ExchangePlans.DeleteChangeRecords(ExchangeMessageReader.Sender,
            ExchangeMessageReader.ReceivedNo); 
        
        // Reading data from the message
        // *** XML serialization
        While CanReadXML(XMLReader) Do
     
            // Reading next value
            Data = ReadXML(XMLReader);  
         
        EndDo; 
     
        ExchangeMessageReader.EndRead();
        XMLReader.Close();
        DeleteFiles(FileName);
     
        Message = New UserMessage;
        Message.Text = "-------- Import completed --------";
        Message.Message();
     
    EndProcedure
    The ReadXML() method assigns the 1C:Enterprise object that matches the XML data to the Data variable. 

    Next you have to resolve a possible collision.
  8. Update the procedure as shown in listing 24.23.

    Listing 24.23. Resolving possible collisions

    Procedure ReadMessageWithChanges() Export
        
        Directory = TempFilesDir(); 
     
        // Generating file name
        FileName = Directory + ?(Right(Directory,1)= "\", "", "\") + "Message"
            + TrimAll(Ref.Code) + "_" + TrimAll(ExchangePlans.Branches.ThisNode().Code) 
            + ".xml";
        File = New File(FileName);
        If Not File.Exist() Then
            Return;
        EndIf;
     
        // *** Reading XML document
        // Trying to open the file
        XMLReader = New XMLReader;
        Try
            XMLReader.OpenFile(FileName);
     
        Except
            Message = New UserMessage;
            Message.Text = "Cannot open the data exchange file.";
            Message.Message();
     
            Return;
     
        EndTry;
     
        Message = New UserMessage;
        Message.Text = "-------- Starting import from: " + String(ThisObject) + "---------";
        Message.Message();
        Message = New UserMessage;
        Message.Text = "– Reading file: " + FileName;
        Message.Message();
     
        // Importing data from the file
        // *** Message infrastructure
        ExchangeMessageReader = ExchangePlans.CreateMessageReader();
     
        // Reading the data exchange message header from the XML file
        ExchangeMessageReader.BeginRead(XMLReader);
     
        // The message is not for this node
        If ExchangeMessageReader.Sender <> Ref Then
            Raise "Incorrect node";
        EndIf;
     
        // Deleting change records for the source node
        // *** Change registration service
        ExchangePlans.DeleteChangeRecords(ExchangeMessageReader.Sender,
            ExchangeMessageReader.ReceivedNo); 
        
        // Reading data from the message
        // *** XML serialization
        While CanReadXML(XMLReader) Do
     
            // Reading next value
            Data = ReadXML(XMLReader);
      
            // The change received from a subordinate node is not applied 
            // to the master one if a change record is found
            If Not ExchangeMessageReader.Sender.Main And
                ExchangePlans.IsChangeRecorded(ExchangeMessageReader.Sender, Data) Then
     
                Message = New UserMessage;
                Message.Text = "- Changes rejected";
                Message.Message();
      
                Continue;
            EndIf;
    
     
        EndDo; 
     
        ExchangeMessageReader.EndRead();
        XMLReader.Close();
        DeleteFiles(FileName);
     
        Message = New UserMessage;
        Message.Text = "-------- Import completed --------";
        Message.Message();
     
    EndProcedure
    A possible collision is resolved as follows: the procedure checks whether the sender node is the main node and whether any records regarding changes of this object for this node are available in the database. If the object has been changed in the database and the sender is not a main node, the change record of the received object is rejected. Otherwise the changes of the received object are accepted.

    Now the only thing that is left is writing the received data.
  9. Update the procedure as shown in listing 24.24.

    Listing 24.24. Writing the received data

    Procedure ReadMessageWithChanges() Export
        
        Directory = TempFilesDir(); 
     
        // Generating file name
        FileName = Directory + ?(Right(Directory,1)= "\", "", "\") + "Message"
            + TrimAll(Ref.Code) + "_" + TrimAll(ExchangePlans.Branches.ThisNode().Code) 
            + ".xml";
        File = New File(FileName);
        If Not File.Exist() Then
            Return;
        EndIf;
     
        // *** Reading XML document
        // Trying to open the file
        XMLReader = New XMLReader;
        Try
            XMLReader.OpenFile(FileName);
     
        Except
            Message = New UserMessage;
            Message.Text = "Cannot open the data exchange file.";
            Message.Message();
     
            Return;
     
        EndTry;
     
        Message = New UserMessage;
        Message.Text = "-------- Starting import from: " + String(ThisObject) + "---------";
        Message.Message();
        Message = New UserMessage;
        Message.Text = "– Reading file: " + FileName;
        Message.Message();
     
        // Importing data from the file
        // *** Message infrastructure
        ExchangeMessageReader = ExchangePlans.CreateMessageReader();
     
        // Reading the data exchange message header from the XML file
        ExchangeMessageReader.BeginRead(XMLReader);
     
        // The message is not for this node
        If ExchangeMessageReader.Sender <> Ref Then
            Raise "Incorrect node";
        EndIf;
     
        // Deleting change records for the source node
        // *** Change registration service
        ExchangePlans.DeleteChangeRecords(ExchangeMessageReader.Sender,
            ExchangeMessageReader.ReceivedNo); 
        
        // Reading data from the message 
        // *** XML serialization
        While CanReadXML(XMLReader) Do
     
            // Reading next value
            Data = ReadXML(XMLReader);
      
            // The change received from a subordinate node is not applied 
            // to the master one if a change record is found
            If Not ExchangeMessageReader.Sender.Main And
                ExchangePlans.IsChangeRecorded(ExchangeMessageReader.Sender, Data) Then
                Message = New UserMessage;
                Message.Text = "- Changes rejected";
                Message.Message();
      
                Continue;
            EndIf; 
     
            // Writing received data
            Data.DataExchange.Sender = ExchangeMessageReader.Sender;
            Data.DataExchange.Load = True;
            Data.Write();
          
        EndDo; 
     
        ExchangeMessageReader.EndRead();
        XMLReader.Close();
        DeleteFiles(FileName);
     
        Message = New UserMessage;
        Message.Text = "-------- Import completed --------";
        Message.Message();
     
    EndProcedure
    Before writing the received object, the procedure records the source node to the data exchange parameters of the object, so that when the object is written to the database, no change registration record is generated for the node it is just received from.

    The procedure also sets the Load property in the data exchange parameters to True. This states that the object is written during the update of the data received during the exchange, which simplifies the object writing procedure for the system because it can avoid some standard checks and prevent modifications of related data that should happen for normal writing.

    This completes the procedure of receiving and processing exchange data.
Next page: Testing data exchange



© 1C LLC. All rights reserved
1C Company respects the privacy of our customers and visitors
to our Web-site.