Rating:
4
Joined: Sep 1, 2014
Company: Smart ID Dynamics
Can anyone provide a configuration example of data exhange mechanism (exchange plan or other method) between main infobase and mobile devices(1C mobile) depending on which user is logged in on the device?
Rating:
4
Joined: Sep 1, 2014
Company: Smart ID Dynamics
Hello Timofey and thanks. But i don`t understand the mechanism implemented in Data exchange demo. Can you please give me a more accurate example for my point of view (on mobile receive from main infobase only data corresponding to authetificated mobile user)?
You will need to use same mechanism that is implemented in the example in Data exchange demo. The message transport method you should use a web service for data exchange. The user authentication described in the Users/Login topic.
Code
Address = "<web service URL>?wsdl";
Definitions = New WSDefinitions(Address, <user name>, <password>);
URI = "<namespace>";
Proxy = New WSProxy(Definitions, URI, "WebExchange", "WebExchangeSoap");
Proxy.User = <user name>;
Proxy.Password = <password>;
Here are most interesting parts:
Code
// Writes a new message to the exchange file
//
// Parameters:
// FileName - the name of file to which the exchange message will be written
// ExchangePlan - the reference to an exchange plan which for the exchange message is generated
//
// Returns:
// MessageNo - the number of message which have been written to the exchange file
//
Function WriteNewMessage(FileName)
MessageNo = 0;
// Creating an object for writing an XML
XMLWriter = New XMLWriter;
XMLWriter.OpenFile(FileName);
XMLWriter.WriteXMLDeclaration();
// Creating a new message
MessageWriter = ExchangePlans.CreateMessageWriter();
MessageWriter.BeginWrite(XMLWriter, Ref);
// To reduce the file message size writing a namespace
XMLWriter.WriteNamespaceMapping("xsd", "http://www.w3.org/2001/XMLSchema");
XMLWriter.WriteNamespaceMapping("xsi", "http://www.w3.org/2001/XMLSchema-instance");
XMLWriter.WriteNamespaceMapping("v8", "http://v8.1c.ru/data");
MessageNo = MessageWriter.MessageNo;
Message(" Message number: " + MessageNo);
// Getting the selection of changed data
Counter = 0;
ChangesSelection = ExchangePlans.SelectChanges(MessageWriter.Recipient, MessageNo);
While ChangesSelection.Next() Do
Data = ChangesSelection.Get();
#If Client Then
Counter = Counter + 1;
Status("Exporting data: " + String(Counter));
#EndIf
// If the data transfer is not required, maybe it is required to write the data deletion
If Not DataTransferRequired(Data) Then
// Getting the value with the possible data deletion
DeleteData(Data);
EndIf;
// Writing the data to the message
WriteData(XMLWriter, Data);
#If Client Then
// Displaying a diagnostic message about the written data
OutputData(Data);
#EndIf
EndDo;
// Finishing the message writing
MessageWriter.EndWrite();
XMLWriter.Close();
Return MessageNo;
EndFunction
// Reads the new exchange message from the file
//
// Parameters:
// FileName - the name of file with the exchange message
//
// Returns:
// MessageNo - the number of the received message
//
Function ReadNewMessage(FileName)
// Creating an object for reading XML
XMLReader = New XMLReader;
// Setting the XML data read parameters not to loose the data of 1 character length
ReadingParameters = New XMLReaderSettings(
, // Version
, // Language
, // Whitespace
, // IgnoreXMLDeclaration
, // ValidationType
, // IgnoreDocumentType
, // IgnoreProcessingInstructions
, // IgnoreComments
, // IgnoreWhitespace
, // CDATASectionAsText
True // UseIgnorableWhitespace
);
// Opening a file for reading
XMLReader.OpenFile(FileName, ReadingParameters);
// Importing from the found file
MessageReader = ExchangePlans.CreateMessageReader();
MessageReader.BeginRead(XMLReader);
MessageNo = MessageReader.MessageNo;
If MessageReader.Sender <> Ref Then
// The message is not intended for this node
Raise "Invalid node";
EndIf;
// Deleting the changes registration for the message sender node
// by the number of the received message which is got from the message
ExchangePlans.DeleteChangeRecords(MessageReader.Sender, MessageReader.ReceivedNo);
// Reading the data from the message while it is possible
Counter = 0;
While ReadDataAbility(XMLReader) Do
// Reading the next value
Data = ReadData(XMLReader);
#If Client Then
Counter = Counter + 1;
Status("Importing data: " + String(Counter));
#EndIf
// The collision resolving when there are changes in both nodes
If Not MessageReader.Sender.Master
And ExchangePlans.IsChangeRecorded(MessageReader.Sender, Data) Then
Message("- Changes rejected:");
#If Client Then
OutputData(Data);
#EndIf
Continue;
EndIf;
// Displaying a diagnostic message about the loaded data
OutputData(Data);
// Setting the sender to make the change not to be registered for it
Data.DataExchange.Sender = MessageReader.Sender;
// Sets the Loading mode as the data can be loaded in an arbitrary order and
// it is required to turn off the control data such as checking the numbers uniqueness
Data.DataExchange.Load = True;
// Writing the transferred data
Data.Write();
EndDo;
MessageReader.EndRead();
XMLReader.Close();
Return MessageNo;
EndFunction
If you need to manually change set of objects marked as having changes, you might need this example:
Code
// Performs the changes registration for object by the selected method
//
// Parameters:
// ExchangePlan - Metadata object description for nodes of which
// it is required to perform registration
// Nodes - Nodes array which for it is required to perform registration
// ExchangeContent - Exchange Plan content
//
Procedure RecordChanges(ExchangePlan, Nodes, ExchangeContent) Export
// Registering changes of objects which correspond to metadata description objects
For Each Row In ExchangeContent Do
MetadataObject = Row.ContentItem.Metadata;
If Row.Registration = ChangeRecords_CallMethod Then
Message("Registering changes for data items '" + FullObjectNameMetadata(MetadataObject) + "' for nodes:");
For Each Node In Nodes Do
Message(" - " + Node);
EndDo;
// calling a standard method of the exchange plan
ExchangePlans.RecordChanges(Nodes, MetadataObject);
ElsIf Row.Registration = ChangeRecords_WriteItem Then
// creating objects of this type writing them
If Metadata.Constants.Contains(MetadataObject) Then
// constants are written using the constant value manager
ManagerValues = Constants[MetadataObject.Name].CreateValueManager();
ManagerValues.Read();
// filling in the set of nodes-recipients
ManagerValues.DataExchange.Recipients.AutoFill = False;
FillNodeSet(ManagerValues.DataExchange.Recipients, Nodes);
// writing a data item
ManagerValues.Write();
ElsIf Metadata.Catalogs.Contains(MetadataObject) Then
// Selecting all catalog items one by one
Selection = Catalogs[MetadataObject.Name].Select();
While Selection.Next() Do
Object = Selection.GetObject();
// filling in the set of nodes-recipients
Object.DataExchange.Recipients.AutoFill = False;
FillNodeSet(Object.DataExchange.Recipients, Nodes);
// writing a data item
Object.Write();
EndDo;
ElsIf Metadata.Documents.Contains(MetadataObject) Then
// Selecting all documents one by one
Selection = Documents[MetadataObject.Name].Select();
While Selection.Next() Do
Object = Selection.GetObject();
// filling in the set of nodes-recipients
Object.DataExchange.Recipients.AutoFill = False;
FillNodeSet(Object.DataExchange.Recipients, Nodes);
// writing a data item
Object.Write();
EndDo;
ElsIf Metadata.Sequences.Contains(MetadataObject) Then
// The changes registration is performed by record sets
// Selecting unique recorders of the RegisterRecords sequence
Query = New Query;
Query.Text = "SELECT DISTINCT Recorder FROM Sequence." + MetadataObject.Name;
Selection = Query.Execute().Select();
While Selection.Next() Do
// Creating a records set
Set = Sequences[MetadataObject.Name].CreateRecordSet();
Set.Filter.Recorder.Set(Selection.Recorder);
// reading the records set data
Set.Read();
// filling in the set of nodes-recipients
Set.DataExchange.Recipients.AutoFill = False;
FillNodeSet(Set.DataExchange.Recipients, Nodes);
// Writing the records set data
Set.Write();
EndDo;
ElsIf Metadata.ChartsOfCharacteristicTypes.Contains(MetadataObject) Then
// Selecting all charts or characteristic types one by one
Selection = ChartsOfCharacteristicTypes[MetadataObject.Name].Select();
While Selection.Next() Do
Object = Selection.GetObject();
// filling in the set of nodes-recipients
Object.DataExchange.Recipients.AutoFill = False;
FillNodeSet(Object.DataExchange.Recipients, Nodes);
// writing a data item
Object.Write();
EndDo;
ElsIf Metadata.ChartsOfAccounts.Contains(MetadataObject) Then
// Selecting all charts of accounts one by one
Selection = ChartsOfAccounts[MetadataObject.Name].Select();
While Selection.Next() Do
Object = Selection.GetObject();
// filling in the set of nodes-recipients
Object.DataExchange.Recipients.AutoFill = False;
FillNodeSet(Object.DataExchange.Recipients, Nodes);
// writing a data item
Object.Write();
EndDo;
ElsIf Metadata.ChartsOfCalculationTypes.Contains(MetadataObject) Then
// Selecting all charts of calculation types one by one
Selection = ChartsOfCalculationTypes[MetadataObject.Name].Select();
While Selection.Next() Do
Object = Selection.GetObject();
// filling in the set of nodes-recipients
Object.DataExchange.Recipients.AutoFill = False;
FillNodeSet(Object.DataExchange.Recipients, Nodes);
// writing a data item
Object.Write();
EndDo;
ElsIf Metadata.BusinessProcesses.Contains(MetadataObject) Then
// Selecting all business-processes one by one
Selection = BusinessProcesses[MetadataObject.Name].Select();
While Selection.Next() Do
Object = Selection.GetObject();
// filling in the set of nodes-recipients
Object.DataExchange.Recipients.AutoFill = False;
FillNodeSet(Object.DataExchange.Recipients, Nodes);
// writing a data item
Object.Write();
EndDo;
ElsIf Metadata.Tasks.Contains(MetadataObject) Then
// Selecting all business-processes tasks one by one
Selection = Tasks[MetadataObject.Name].Select();
While Selection.Next() Do
Object = Selection.GetObject();
// filling in the set of nodes-recipients
Object.DataExchange.Recipients.AutoFill = False;
FillNodeSet(Object.DataExchange.Recipients, Nodes);
// writing a data item
Object.Write();
EndDo;
ElsIf Metadata.InformationRegisters.Contains(MetadataObject) Then
// defining fields which are in the register key
RecordKey = New Array;
If MetadataObject.WriteMode = Metadata.ObjectProperties.RegisterWriteMode.RecorderSubordinate Then
RecordKey.Add("Recorder");
Else
If MetadataObject.InformationRegisterPeriodicity <> Metadata.ObjectProperties.InformationRegisterPeriodicity.Nonperiodical
And MetadataObject.MainFilterOnPeriod Then
RecordKey.Add("Period");
EndIf;
For Each Dimension In MetadataObject.Dimensions Do
If Dimension.MainFilter Then
RecordKey.Add(Dimension.Name);
EndIf;
EndDo;
EndIf;
// Selecting unique recorders of the accumulation RegisterRecords
Query = New Query;
Query.Text = "SELECT DISTINCT ";
SemicolonRequired = False;
For Each Field In RecordKey Do
Query.Text = Query.Text + ?(SemicolonRequired, ", ", "") + Field;
SemicolonRequired = True;
EndDo;
Query.Text = Query.Text + " FROM InformationRegister." + MetadataObject.Name;
Selection = Query.Execute().Select();
While Selection.Next() Do
// Creating a records set
Set = InformationRegisters[MetadataObject.Name].CreateRecordSet();
// setting the filter values
For Each Field In RecordKey Do
Set.Filter[Field].Set(Selection[Field]);
EndDo;
// reading the records set data
Set.Read();
// filling in the set of nodes-recipients
Set.DataExchange.Recipients.AutoFill = False;
FillNodeSet(Set.DataExchange.Recipients, Nodes);
// Writing the records set data
Set.Write();
EndDo;
ElsIf Metadata.AccumulationRegisters.Contains(MetadataObject) Then
// The changes registration is performed by record sets
// Selecting unique recorders of the accumulation RegisterRecords
Query = New Query;
Query.Text = "SELECT DISTINCT Recorder FROM AccumulationRegister." + MetadataObject.Name;
Selection = Query.Execute().Select();
While Selection.Next() Do
// Creating a records set
Set = AccumulationRegisters[MetadataObject.Name].CreateRecordSet();
Set.Filter.Recorder.Set(Selection.Recorder);
// reading the records set data
Set.Read();
// filling in the set of nodes-recipients
Set.DataExchange.Recipients.AutoFill = False;
FillNodeSet(Set.DataExchange.Recipients, Nodes);
// Writing the records set data
Set.Write();
EndDo;
ElsIf Metadata.AccountingRegisters.Contains(MetadataObject) Then
// The changes registration is performed by record sets
// Selecting distinct recorders of the accounting RegisterRecords
Query = New Query;
Query.Text = "SELECT DISTINCT Recorder FROM AccountingRegister." + MetadataObject.Name;
Selection = Query.Execute().Select();
While Selection.Next() Do
// Creating a records set
Set = AccountingRegisters[MetadataObject.Name].CreateRecordSet();
Set.Filter.Recorder.Set(Selection.Recorder);
// reading the records set data
Set.Read();
// filling in the set of nodes-recipients
Set.DataExchange.Recipients.AutoFill = False;
FillNodeSet(Set.DataExchange.Recipients, Nodes);
// Writing the records set data
Set.Write();
EndDo;
ElsIf Metadata.CalculationRegisters.Contains(MetadataObject) Then
// The changes registration is performed by record sets
// Selecting distinct recorders of the calculation RegisterRecords
Query = New Query;
Query.Text = "SELECT DISTINCT Recorder FROM CalculationRegister." + MetadataObject.Name;
Selection = Query.Execute().Select();
While Selection.Next() Do
// Creating a records set
Set = CalculationRegisters[MetadataObject.Name].CreateRecordSet();
Set.Filter.Recorder.Set(Selection.Recorder);
// reading the records set data
Set.Read();
// filling in the set of nodes-recipients
Set.DataExchange.Recipients.AutoFill = False;
FillNodeSet(Set.DataExchange.Recipients, Nodes);
// Writing the records set data
Set.Write();
EndDo;
ElsIf MetadataObject.Parent() <> Undefined Then
Parent = MetadataObject.Parent();
If ExchangeMetadataObjectType(Parent) = "CalculationRegister"
And Parent.Recalculations.Contains(MetadataObject) Then
// Selecting distinct recorders of the calculation RegisterRecords
Query = New Query;
Query.Text = "SELECT DISTINCT RecalculationObject FROM CalculationRegister." + Parent.Name + "." + MetadataObject.Name;
Selection = Query.Execute().Select();
While Selection.Next() Do
// Creating a records set
Set = CalculationRegisters[MetadataObject.Name].CreateRecordSet();
Set.Filter.RecalculationObject.Set(Selection.RecalculationObject);
// reading the records set data
Set.Read();
// filling in the set of nodes-recipients
Set.DataExchange.Recipients.AutoFill = False;
FillNodeSet(Set.DataExchange.Recipients, Nodes);
// Writing the records set data
Set.Write();
EndDo;
EndIf;
EndIf;
EndIf;
EndDo;
EndProcedure