Главная
Статьи
Ресурсы
Информация

Часть II. Использование основных объектов конфигурации. Глава 13 - 16


Глава 13. Обмен данными

В этой главе мы познакомимся с механизмами обмена данными, которые содержит система 1С:Предприятие и добавим в нашу конфигурацию возможность обмена данными с удаленными филиалами и отделениями.

 

Общие сведения об обмене данными

С

редства обмена данными, которые содержит система 1С:Предприятие 8.0 позволяют организовывать обмен информацией, хранимой в базе данных, с другими программными системами. В качестве таких систем могут выступать как другие информационные базы 1С:Предприятия 8.0 (имеющие аналогичную или отличающуюся конфигурацию), так и программные системы, не основанные на 1С:Предприятии 8.0.

Такая гибкость обмена данными достигается тем, что средства обмена данными 1С:Предприятия 8.0 могут использоваться в различных комбинациях, и кроме этого, формат обмена данными основан на языке XML, являющимся на сегодняшний день общепринятым средством представления данных.

К механизмам обмена данными могут быть отнесены:

• Планы обмена,

• XML-сериализация,

• Средства чтения и записи документов XML.

В общем случае схема взаимодействия этих трех составляющих может быть представлена следующим образом:

 

При помощи планов обмена мы получаем информацию о том, какие элементы данных были изменены, и в какой узел обмена их необходимо передать. Это возможно благодаря тому, что планы обмена содержат механизм регистрации изменений. Информация об

 

измененных данных переносится с помощью сообщений, инфраструктура которых также поддерживается планами обмена.

XML-сериализация    позволяет    преобразовать    объект

1С:Предприятия в последовательность данных, представленных в формате XML. Кроме этого, XML-сериализация выполняет и обратное преобразование - преобразует последовательность данных формата XML в объект 1С:Предприятия, при условии, что имеется соответствующий тип 1С:Предприятия.

Запись и чтение документов XML обеспечивают запись/чтение документов формата XML из встроенного языка.

При реализации алгоритма обмена данными перечисленные механизмы могут быть использованы как все вместе, так и в различной комбинации. В каждом конкретном случае разработчик решает эту задачу самостоятельно.

В примере, приведенном в этой книге, мы используем все три механизма обмена данными, поэтому прежде чем перейти непосредственно к написанию кода, познакомимся с каждым из них более подробно.

Объект конфигурации ПланОбмена

Д

ля того, чтобы существовала возможность обмена какими-либо данными с кем-либо, необходимо некоторым образом идентифицировать тех, с кем мы будем обмениваться и для каждого из них описать перечень того, чем мы будем с ним обмениваться.

Обе эти задачи позволяет решать прикладной объект конфигурации План обмена.

узел,

Подобно тому, как элементами данных справочника являются элементы справочника, элементами данных плана обмена являются узлы плана обмена. Каждый узел идентифицирует участника обмена данными по данному плану обмена. Кроме этого, в каждом плане обмена всегда существует один предопределенный идентифицирующий данную информационную базу.

В одной конфигурации может существовать несколько планов обмена. Каждый план обмена определяет набор данных, которым будет производиться обмен в рамках данного плана и сам механизм этого обмена. Наличие нескольких планов обмена может

 

потребоваться в случае, если с разными узлами ведется обмен разным составом данных, или когда схема организации обмена с одними узлами отличается от схемы организации обмена с другими узлами.

В состав данных, которыми может производиться обмен, входят элементы информационных структур базы данных, которые описываются следующими объектами встроенного языка:

• Константа.МенеджерЗначения<имя>,

• СправочникОбъект.<имя>,

• ДокументОбъект.<имя>,

• ПоследовательностьНаборЗаписей<имя>,

• ПланВидовХарактеристикОбъект<имя>,

• ПланСчетовОбъект.<имя>,

• ПланВидовРасчетаОбъект<имя>,

• РегистрСведенийНаборЗаписей.<имя>,

• РегистрНакопленияНаборЗаписей<имя>,

• РегистрБухгалтерииНаборЗаписей.<имя>,

• РегистрРасчетаНаборЗаписей.<имя>,

• ПерерасчетНаборЗаписей.<имя>,

• БизнесПроцессОбъект.<имя>,

• ЗадачаОбъект.<имя>,

• УдалениеОбъекта.

Для упрощения изложения, в дальнейшем будем называть эти элементы информационных структур объектами обмена.

Разработчик имеет возможность определить состав каждого плана обмена, указав, объекты конфигурации, данные которых должны участвовать в обмене по данному плану.

При описании состава данных плана обмена разработчик имеет возможность указать для каждого типа объектов признак «Авторегистрация». Этот признак определяет, каким образом план обмена будет отслеживать изменения этих данных.

Возможность отслеживать изменения данных реализована в плане обмена за счет использования механизма регистрации изменений. Работа этого механизма базируется на том, что каждый из объектов обмена имеет свойство «ОбменДанными», с помощью которого можно указать, для каких узлов необходимо производить регистрацию изменений этого объекта. Любые изменения объекта обмена сводятся,

 

в конечном итоге, к записи или удалению объекта обмена. Механизм регистрации изменений анализирует события записи и удаления объектов обмена и на основании параметров обмена данными, содержащихся в каждом из объектов обмена, формирует записи регистрации изменений. Следует отметить, что свойство «ОбменДанными» не хранится в базе данных, а используется только во время записи объекта обмена.

Так вот, признак «Авторегистрация», устанавливаемый при указании состава данных плана обмена, позволяет указать, что параметры обмена данными будут формироваться каждый раз самим механизмом регистрации изменений на основании информации, содержащейся в плане обмена. После автоматического заполнения параметров обмена, разработчик все же имеет возможность внести изменения в сформированные таким образом параметры. Для этого следует использовать обработчики событий объектов, участвующих в обмене - «ПередЗаписью» и «ПередУдалением», в которых можно модифицировать список узлов-получателей (т.е. тех узлов, для которых регистрируются изменения). Кроме этого, существует возможность отключить авторегистрацию изменений, и тогда параметры обмена данными нужно будет формировать полностью средствами встроенного языка. Гипотетически делать это можно в любом фрагменте кода, но для того, чтобы конфигурация была легко читаема, рекомендуется использовать для этих целей все те же обработчики событий «ПередЗаписью» и «ПередУдалением». В этом случае код формирования параметров обмена данными будет сосредоточен в логически понятных точках, а не разбросан по всей конфигурации.

Итак, как мы теперь знаем, при записи и удалении объектов обмена план обмена формирует записи регистрации изменений. Записи регистрации изменений хранятся в таблицах регистрации изменений, причем для каждого объекта обмена ведется своя отдельная таблица регистрации изменений. При изменении объекта обмена в таблице регистрации изменений создается столько записей, сколько узлов-получателей указано в параметрах обмена данными у объекта обмена. Каждая запись при этом будет хранить ссылку на свой узел-получатель. Таблицы регистрации изменений создаются лишь в том случае, если соответствующий объект метаданных указан в составе хотя бы одного плана обмена.

 

Кроме ссылки на узел обмена, для которого регистрируюТс изменения, каждая запись таблицы регистрации изменений храцИт также номер сообщения, в котором изменение было передано в первый раз в этот узел. До тех пор, пока сообщение не будет передано в первый раз, это поле хранит Null.

Сообщение, с точки зрения плана обмена, это единица обмена информацией. Поэтому одной из важнейших составляющих плана обмена, помимо службы регистрации изменений, является инфраструктура сообщений. Поскольку сообщения передаются в рамках плана обмена от одного узла к другому, каждое сообщение точно ассоциировано с планом обмена, имеет уникальный номер и имеет одного отправителя и одного получателя. За нумерацию сообщений отвечает инфраструктура сообщений, и благодаря этому записи регистрации изменений и имеют возможность хранить номера сообщений, в которых эти изменения были переданы первый раз.

Инфраструктура сообщений позволяет, также, получать подтверждения от узла-получателя о приеме сообщений. Такое подтверждение содержится в каждом сообщении, приходящем от узла-получателя в виде номера последнего принятого сообщения.

Впоследствии, проанализировав номер последнего принятого сообщения и номера сообщений, содержащиеся в записях регистрации изменений, разработчик может удалить записи регистрации изменений, прием которых подтвержден получателем.

XML-сериализация

Т

ермином XML-сериализация обозначается механизм, позволяющий представить объект 1С:Предприятия в виде последовательности данных в формате XML. Кроме этого XML-сериализация позволяет выполнить и обратное преобразование - представить последовательность данных формата XML в виде объекта 1С:Предприятия, если существует подходящий тип данных.

Дело в том, что объект обмена, являющийся в системе 1С:Предприятие единым целым, на самом деле представляет собой совокупность данных различных типов, определенным образом связанных между собой. Например, элемент справочника может содержать, кроме кода и наименования, некоторое количество реквизитов различного типа и некоторое количество табличных

 

частей, содержащих в свою очередь некоторое количество реквизитов различного типа. В результате XML-сериализации вся эта совокупность данных представляется в виде последовательности соответствующих данных формата XML. B результате обратного преобразования производится «сборка» объекта, при условии, что существует подходящий тип данных 1С:Предприятия.

Запись/чтение документов XML

В

отличие от XML-сериализации, механизмы записи/чтения документов XML позволяют работать с данными формата XML на «базовом» уровне, без привязки к объектам 1С:Предприятия. В частности они позволяют открывать файлы XML для чтения, читать данные из файлов, создавать новые файлы XML и записывать в них данные.

 

Универсальный механизм обмена данными

Постановка задачи

И

так, наше OOO «На все руки мастер» открыло свой филиал в городе Урюпинск и установило в нем такую ясе конфигурацию для учета работы филиала. В результате возникла необходимость наладить обмен данными между этими двумя базами таким образом, чтобы каждая из баз отражала полную информацию о материалах и услугах, в то время как бухгалтерский учет и расчет зарплаты велся бы в каждоЙ базе отдельно.

Для этого мы создадим план обмена, опишем состав данных, которые будут включены в обмен и создадим несколько процедур, которые будут позволять нам формировать на жестком диске файлы обмена и соответственно загружать полученные файлы обмена с жесткого диска. Для упрощения примера мы не будем программировать какой-либо автоматический обмен файлами между двумя базами, и запуск процедуры обмена будем осуществлять вручную.

Прежде чем мы начнем непосредственно программировать алгоритм обмена, следует сказать о некоторых доработках, которые нам придется предварительно внести в нашу базу.

Эти доработки будут связаны с тем, что до сих пор мы работали только в одной базе и использовали уникальность номеров кодов справочников и номеров документов. Теперь, когда создание новых элементов справочников и новых документов будет происходить в двух базах одновременно и независимо друг от друга, нам снова необходимо обеспечить уникальность номеров кодов элементов справочников и номеров документов теперь уже «в пространстве» двух баз. Если мы этого не сделаем, то не исключена ситуация, когда в каждой из баз будут созданы, например, новые документы с одинаковыми номерами и при обмене данными возникнет конфликт, поскольку система будет пытаться записать в базу документ с номером, который уже используется другим документом.

Для исключения подобных ситуаций в каждой базе к номерам документов и кодам справочников мы будем добавлять уникальный префикс, однозначно идентифицирующий базу данных. Тогда, даже

 

если номера новых документов в двух базах совпадут, они все равно будут отличаться префиксом и конфликта не возникнет.

Для хранения префикса номеров мы используем объект конфигурации, с которым до сих пор еще не работали - это объект Константа.

Создание константы ПрефиксНомеров

О

бъект конфигурации Константа является прикладным объектом и предназначен для создания в базе данных структур, в которых будет храниться информация, которая не изменяется во времени или изменяется очень редко. Каждый объект конфигурации Константа описывает структуру для хранения одного значения.

Теперь приступим к созданию константы, в которой мы будем хранить значение префикса номеров. Откроем конфигуратор и создадим новый объект конфигурации Константа с именем «ПрефиксНумерации». Определим тип значения константы - Строка, с фиксированной длиной 2 символа.

Доработка объектов конфигурации, участвующих в обмене

П

ервое, что нам следует сделать - внести изменения в модули всех объектов, участвующих в обмене (в нашем случае это будут документы, справочники и планы видов характеристик). Эти изменения будут заключаться в том, что теперь при формировании номера документа и кода справочника или плана видов характеристик будет использоваться значение константы «ПрефиксНумерации» для обеспечения уникальности номеров и кодов в каждой из наших баз.

Функцию формирования префикса номера мы вынесем в общий модуль, поскольку не исключена возможность того, что в будущем алгоритм формирования префикса документов может быть изменен.

Функцию мы разместим в общем модуле «ОбменДанными», выглядеть она будет следующим образом:

Функция ПопучитьПрефиксНомера() Экспорт ВозвратКонсташы.ПрефиксНумерации.Получить();

КонецФункции

Как вы видите, эта функция просто возвращает значение константы «ПрефиксНумерации».

Теперь доработаем справочник «Клиенты». В модуль объекта

добавим    следующий    обработчик    события

«ПриУстановкеНовогоКода»:

Процедура ПриУстановкеНовогоКодаССтандартнаяОбработка, Префикс)

Префикс = ПолучитьПрефиксНомера();

КонецПроцедуры   

Событие «При установке нового кода» возникает в момент, когда выполняется установка нового кода элемента справочника. Вторым параметром вызова обработчика передается префикс, который будет использоваться системой для генерации кода. В обработчике события мы устанавливаем его равным значению константы «ПрефиксНумерации».

Такие же обработчики нужно будет добавить во все справочники и планы видов характеристик, участвующие в обмене. После этого у всех справочников и планов видов характеристик, участвующих в обмене, нужно будет изменить тип кода на Строка и увеличить длину кода до 7 символов.

Теперь займемся доработкой документов. В модуль документа

«ПриходнаяНакладная»    добавим    обработчик    события

«ПриУстановкеНовогоНомера»:

 

Обмен данными

Такие же обработчики нужно будет добавить во все документы, участвующие в обмене. После этого для всех них нужно изменить тип номера на Строка и увеличить длину номера до 7 символов.

На этом подготовительная работа с существующими объектами конфигурации завершена, и мы можем перейти к созданию процедур обмена данными.

Создание плана обмена Филиалы

Т

еперь займемся созданием «центра» любого алгоритма обмена данными, вокруг которого группируются прочие механизмы -плана обмена. Откроем конфигуратор и создадим новый объект конфигурации ПланОбмена с именем «Филиалы». На закладке «Данные» создадим реквизит плана обмена «Главный», имеющий тип Булево.

Этот реквизит понадобится нам для того, чтобы разрешать коллизии при обмене данными. Под коллизией понимается ситуация, когда один и тот же объект обмена данными был изменен одновременно в двух узлах. В этом случае мы будем анализировать значение реквизита «Главный» и принимать изменения только в том случае, если они сделаны в главном узле. В случае коллизии, изменения, произведенные не в главном узле, мы будем отвергать.

Теперь перейдем на закладку «Прочее» и определим состав объектов обмена данными (кнопка «Состав»).

Установим отбор по подсистеме «УчетУслугИМатериалов» и включим в обмен все объекты, относящиеся к этой подсистеме. Проверьте, что константа «ПрефиксНумерации» не участвует в обмене, поскольку ее значение должно быть уникальным для каждой базы, участвующей в обмене.

ПроцедураПриУстановкеНовогоНомераССтандартнаяОбработка,

Префикс)

Префикс = ПолучитьПрефиксНомера();

КонецПроцедуры   

Состав данных обмена должен выглядеть следующим образом:

 

Теперь создадим с помощью конструктора основную форму узла, для того, чтобы описать в ней некоторые действия, которые должны выполняться при создании нового узла обмена.

Суть этих действий будет заключаться в том, что при создании нового узла обмена мы должны будем сформировать для него все необходимые записи регистрации изменений для всех объектов конфигурации, входящих в данный план обмена. Это будет, своего рода, начальная синхронизация узла обмена всеми данными обмена.

Прежде всего, опишем в модуле формы узла служебную переменную, которая будет хранить признак того, является ли записываемый узел новым, или нет:

Перем РегистрацияВНовыйУзел;

Затем создадим обработчик события формы «ПередЗаписью»:

Процедура ПередЗаписью(Отказ)

РегистрацияВНовыйУзел = ЭтоНовый();

КонецПроцедуры   

 

Этот обработчик и будет устанавливать значение нашей служебной переменной в Истина, в случае записи нового узла плана обмена. После этого создадим обработчик события формы «ПриЗаписи»:

Процедура ПриЗаписи(Отказ) Если РегистрацияВНовыйУзел Тогда // Регистрация изменений всех данных для узла

ПланыОбмена.ЗарегистрироватьИзменения(Ссылка)-КонецЕсли;

КонецПроцедуры

Событие формы «ПриЗаписи» возникает после записи объекта ПланОбменаОбъект.Филиалы, но до окончания транзакции. Именно в этот момент мы обращаемся к механизму регистрации изменений, вызывая метод менеджера планов обмена -ЗарегистрироватьИзменения(). В данном случае будут созданы записи регистрации изменений, предназначенные для пересылки в созданный нами узел, для всех объектов обмена, указанных в составе данного плана обмена.

В заключение, создадим обработчик события формы «ПередОткрытием» для того, чтобы запретить установку реквизита «Главный» для предопределенного узла, соответствующего данной информационной базе:

!роцедура ПередОткрытием(Отказ, СтандартнаяОбработка) Если Ссылка = ПланыОбмена.Филиалы.ЭтотУзел() Тогда

ЭлементыФормы.Главный.Достуггаость = Ложь; КонецЕсли;

КонецПроцедуры

В этой процедуре мы используем метод менеджера плана обмена ЭтотУзел(), который возвращает ссылку на узел плана обмена, соответствующий данной информационной базе.

На этом создание плана обмена завершено, и мы можем перейти непосредственно к созданию процедур обмена данными.

Создание процедур обмена данными

Д

ля инициализации обмена данными мы используем объек конфигурации Обработка. Этот объект раньше не встреча7С нам, поэтому следует сказать о нем несколько слов. С точки зрения структуры и организации работы обработка ничем не отличается от отчета. Разница состоит лишь в том, что обработка обычно используется для того, чтобы выполнить какие-либо действия над информационной базой, а отчет - чтобы получить некоторое визуальное представление данных.

Создание обработки ОбменДанными

О

ткроем конфигуратор и создадим новый объект конфигурации Обработка с именем «ОбменДанными». Перейдем на закладку «Прочее» и откроем модуль объекта. Создадим в нем процедуру «ОбменСФилиалами»:

Процедура ОбменСФилналами() Экспорт

ВыборкаУзлов = ПланыОбмена.Филиалы.Выбрать();

Пока ВыборкаУзлов.Следующий() Цикл

// Произвести обмен данными со всеми узлами,

// кроме текущего (ЭтотУзел)

Если ВыборкаУзлов.Ссылка о ПланыОбмена

.Филиалы

.ЭтотУзел() Тогда УзелОбъект = ВыборкаУзлов.ПолучитьОбъект();

// Получить сообщение

УзелОбъект.ПрочитатьСообщениеСИзменениями();

// Сформировать сообщение

УзелОбъект.ЗаписатьСообщениеСИзменениямиО;

КонецЕсли; КонецДикла; КонепПроцедуры

Алгоритм работы этой процедуры заключается в следующем: i цикле мы перебираем узлы, которые содержатся в плане обмена «Филиалы», и для всех узлов, кроме себя самого, производим сначала чтение сообщений, поступивших из других узлов обмена (процеДУРУ

 

Обмен данными

«ПрочитатьСообщенияСИзменениями» мы создадим позднее), а затем формируем для них сообщения, предназначенные для передачи и содержащие измененные данные для этого узла (процедура «ЗаписатьСообщениеСИзменениями» также будет создана нами позднее).

Теперь создадим основную форму обработки и в обработчик события нажатия кнопки «Выполнить» - «КнопкаВыполнитьНажатие» вставим вызов процедуры ОбменСФилиалами():

ПроцедураКнопкаВыполнитьНажатие(Элемент)

ОбменСФилиалами(); КонедПроцедуры

Создание процедуры записи данных

С

ами процедуры записи и чтения данных обмена мы разместим в модуле объекта План обмена «ОбменСФилиалами». Сначала создадим процедуру, которая используется нами при обмене данными - «ЗаписатьСообщениеСИзменениями». Порядок создания этой процедуры будет следующим: сначала мы сформируем имя файла, который будет содержать данные для обмена:

Процедура ЗаписатьСообщениеСИзменениями() Экспорт

Сообщить("    Выгрузка в узел" + Строка(ЭтотОбъект) + "    ");

Каталог = КаталогВременныхФайлов();

// Сформировать имя временного файла

ИмяФайла = Каталог +?(Прав(Каталог, 1) = "\","", "\") +

"Message" + СокрЛЩПланыОбмена.Филиалы.ЭтотУзел().Код) + "_" + СокрЛП(Ссылка.Код) + ".xml";

Сообщить("    Конец выгрузки    ");

КонецПроцедуры

Для упрощения примера, мы будем обмениваться сообщениями через каталог временных файлов. Имена сообщений стандартизованы и имеют вид «Ме8$а§еКодУзлаОтправителя_КодУзлаПолучателя.хт1».

После этого обратимся к механизмам записи/чтения XML документов и создадим новый объект ЗаписьХМЦ с помощью которого откроем новый XML файл для записи, запишем в него

объявление XML, и в конце процедуры завершим запись закроем файл:

Процедура ЗаписатьСообщениеСИзменениями() Экспорт

Сообщить("    Выгрузка в узел " + Строка(ЭтотОбъект) + "    ");

Каталог = КаталогВременныхФайлов(); // Сформировать имя временного файла ИмяФайла = Каталог +?(Прав(Каталог, 1) = "\","", "\") +

"Message" + СокрЛП(ПланыОбмена.Филиалы.ЭтотУзел().Код) + *_"

СокрЛП(Ссылка.Код) + ".xrnl;

// Создать объект записи XML //*** запись XML документов ЗаписьXML = Новый ЗаписьXML; ЗаписьXML.ОткрытьФайл(ИмяФайла); ЗаписьXML.ЗаписатьОбъявлениеXML();

ЗаписьXML.Закрыть();

Сообщить("    Конец выгрузки    ");

КонецПроцедуры   

Теперь мы обратимся к механизмам инфраструктуры сообщений и создадим новый объект ЗаписьСообщенияОбмена, метод которого НачатьЗапись() позволяет, кроме всего прочего, создать очередной номер сообщения и записать заголовок сообщения в XML. В конце процедуры мы опять же закончим запись сообщения:

 

Обмен данными

ЗаписьСообщения.ЗакончитьЗапись();

ЗаписьXML.Закрыть();

Сообщить("    Конец выгрузки    ");

КонецПроцедуры

После этого, чтобы получить данные, которые необходимо сохранить в этом файле, мы обратимся к механизму регистрации изменений и получим выборку из записей регистрации изменений, предназначенных данному узлу.

При формировании выборки мы передаем вторым параметром номер сообщения, которым эти данные будут переданы:

Процедура ЗаписатьСообщениеСИзменениями() Экспорт

Сообщить("    Выгрузка в узел " + Строка(ЭтотОбъект) + "----------");

Каталог = КаталогВременныхФайлов(); // Сформировать имя временного файла ИмяФайла = Каталог +?(Прав(Каталог, 1) = "\","", "\") +

"Message" + СокрЛП(ПланыОбмена.Филиалы.ЭтотУзел().Код) + "_" + СокрЛП(Ссылка.Код) + ".xml";

// Создать объект записи XML //*** запись XML документов ЗаписьXML = Новый ЗаписьXML; ЗaписьXML.OткpытьФaйл(ИмяФaйлa);

ЗaписьXML.ЗаписатьОбъявлениеXML();

 

 

 

Процедура ЗаписатьСообщениеСИзменениями() Экспорт

Сообщить("    Выгрузка в узел " + Строка(ЭтотОбъект) + "    ");

Каталог = КаталогВременныхФайлов(); // Сформировать имя временного файла ИмяФайла = Каталог +?(Прав(Каталог, 1) = "\","", "\") +

"Message" + СокрЛП(ПланыОбмена.Филиалы.ЭтотУзел().Код) + "_* СокрЛП(Ссьшка.Код) + ".xml*;

// Создать объект записи XML //*** запись XML документов ЗаписьXML = Новый ЗаписьХМЦ ЗaпиcьXML.OткpьrтьФaйл(ИмяФaйлa);

ЗaписьXML.ЗаписатьОбъявлениеXML();

//*** инфраструктура сообщений

ЗаписьСообщения = ПланыОбмена.СоздатьЗаписьСообщенияО;

ЗаписьСообщения.НачатьЗапись(ЗаписьХМЬ, Ссылка);

Сообщить(" Номер сообщения; " + ЗаписьСообщения.НомерСообшения),^

 

//*** инфраструктура сообщений

ЗаписьСообщения = ПланыОбмена.СоздатьЗаписьСообщения();

ЗаписьСообщения.НачатьЗапись(ЗаписьXML, Ссылка);

Сообщить(" Номер сообщения:" + ЗаписьСообщения.НомерСообщения);

// Получить выборку измененных данных //*** механизм регистрации изменений ВыборкаИзменений = ПланыОбмена

.ВыбратьИзмененияЗаписьСообщения.Получатель,

ЗаписьСообщения.НомерСообщеиия);

ЗаписьСообщения.ЗакончитьЗапись();

ЗаписьXML.Закрыть();

Сообщить("    Конец выгрузки    ");

КонецПроцедуры

Теперь осталось только перебрать выборку записей в цикле сериализовать их в открытый XML файл:

Процедура ЗаписатьСообщениеСИзменениями() Экспорт

Сообщить("    Выгрузка в узел " + Строка(ЭтотОбъект) + "    ");

Каталог = КаталогВременныхФайлов(); // Сформировать имя временного файла ИмяФайла = Каталог +?(Прав(Каталог, 1)= "\'\"", "\") +

"Message" + СокрЛП(ПланыОбмена.Филиалы.ЭтотУзел().Код) + "_" + СокрЛП(Ссылка.Код) + ".xml";

// Создать объект записи XML //*** запись XML документов ЗаписьXML = Новый ЗаписьXML; ЗаписьXML.ОткрытьФайл(ИмяФайла); ЗаписьXML.ЗаписатьОбъявлениеXML();

//*** инфраструктура сообщений

ЗаписьСообщения = ПланыОбмена.СоздатьЗаписьСообщения();

ЗаписьСообщения.НачатьЗапись(ЗаписьXML,Ссылка);

Сообщить(" Номер сообщения:" + ЗаписьСообщения.НомерСообщения);

// Получить выборку измененных данных //*** механизм регистрации изменений ВыборкаИзменений = ПланыОбмена

.ВыбратьИзменения(ЗаписьСообщения.Получатель,

ЗаписьСообщения.НомерСообщения);

Пока ВыборкаИзмеиений.Следующий() Цикл

// Записать данные в сообщение

//***XML-сериализация

ЗаписатьХМЦЗаписьХМЬ,ВыборкаИзменешш.Получить()); КонецЦикла;

ЗаписьСообщения.ЗакончитьЗапись();

ЗаписьXML.Закрыть();

Сообщить("    Конец выгрузки    ");

КонецПроцедуры

На этом создание процедуры записи данных обмена закончено.

Создание процедуры чтения данных

П

орядок создания процедуры чтения данных обмена будет таким же, как и ранее: сначала мы сформируем имя файла, содержащего данные обмена:

 

ПроцедураПрочитатьСообщениеСИзменениями() Экспорт

Каталог = КаталогВременныхФайлов();

// Сформировать имя файла

ИмяФайла= Каталог+ ?(Прав(Каталог, 1) = "\","", "\") + "Message" + СокрЛП(Ссылка.Код) + "_" + СокрЛП(ПланыОбмена.Филиалы.ЭтотУзел().Код) + ".xml" Файл = Новый Файл(ИмяФайла); Если Не Файл.Существует() Тогда

Возврат; КонецЕсли;

УдаяитьФайлы(ИмяФайла);

Сообщить("    Конец загрузки    ");

КонецПроцедуры

Сначала мы формируем имя файла, которое надеемся найти в этом каталоге, а затем, создав новый объект Файл с таким именем, проверяем, существует ли он. Если такого файла нет, мы завершаем работу процедуры. Если же такой файл найден, нужно будет удить его после того, как все данные, содержащиеся в нем, будут обработаны.

Теперь добавим в процедуру команды чтения найденного файла с данными обмена:

Процедура ПрочитатьСообщениеСИзменениями() Экспорт Каталог = КаталогВременныхФайлов();

// Сформировать имя файла

ИмяФайла = Каталог +?(Прав(Каталог, 1) = "\","", "\") + "Message" + СокрЛП(Ссылка.Код) + "_* + СокрЛП(ПланыОбмена.Филиалы.ЭтотУзел()-Код) + ".xml"; Файл = Новый Файл(ИмяФайла); Если Не Файл.Существует() Тогда

Возврат; КонецЕсли;

//*** Чтение документов XML // Попытаться открыть файл ЧтениеXML = Новый ЧтениеXML; Попытка

ЧтениеXML.ОткрытьФайл(ИмяФайла); Исключение

Сообщить("Невозможно открыть файл обмена данными.");

 

Возврат; КонецПопытки;

Сообщить("    Загрузка из " + Строка(ЭтотОбъект) + "    ");

Сообщить(" - Считывается файл " + ИмяФайла);

ЧтениеХМЬ.Закрыть();

УдалитьФайлы(ИмяФайла);

Сообщить("    Конец загрузки    ");

КонецПроцедуры

Именно в этот момент мы обращаемся к механизмам записи/чтения документов XML, которые работают с ними на «базовом» уровне.

Для этого мы создаем новый объект ЧтениеХМЦ с помощью которого открываем найденный файл для чтения. В случае успеха мы выводим сообщение о начале загрузки данных из файла. В конце процедуры мы также прекращаем чтение XML-данных из файла методом Закрыть().

Полученные таким образом данные должны являться некоторым сообщением обмена данными. Для того, чтобы представить их в терминах сообщений, мы добавим в процедуру следующий код:

 

// Загрузить из найденного файла //*** Инфраструктура сообщений ЧтениеСообщения = ПланыОбмена.СоздатьЧтениеСообщения();

//читать заголовок сообщения обмена данными - файла XML ЧтениеСообщения.НачатьЧтение(ЧтениеХМЬ),-

ЧтениеСообщения.ЗакончитьЧтение();

ЧтениеХМЬ.Закрыть(); УдалитьФайлы(ИмяФайла);

Сообщить("    Конец загрузки    ");

КонецПроцедуры

Здесь мы обращаемся к механизмам инфраструктуры сообщений планов обмена и создаем объект ЧтениеСообщенияОбмена. Используя метод этого объекта НачатьЧтение() мы считываем заголовок XML-сообщения, в котором содержится, в том числе, информация об отправителе сообщения. После того, как все сообщение будет нами обработано, мы заканчиваем чтение.

Теперь, когда мы представили данные обмена в виде сообщения и получили его заголовок, можно произвести одну проверку перед тем, как начать собственно обрабатывать данные:

 

Процедура ПрочитатьСообщениеСИзменениями() Экспорт Каталог = КаталогВременныхФайяов();

// Сформировать имя файла

ИмяФайла = Каталог + ?(Прав(Каталог, 1) = "\","", "\") + "Message" + СокрЛП(Ссылка.Код) + "_" + СокрЛП(ПланыОбмена.Филиалы.ЭтотУзел().Код) + " .xml"

Файл = Новый Файл(ИмяФайла);

Если Не Файл.Существует() Тогда Возврат;

КонецЕсли;

//*** Чтение документов XML // Попытаться открыть файл ЧтениеXML = Новый ЧтениеXML; Попытка

ЧтениеXML.ОткрытьФайл(ИмяФайла); Исключение

Сообщит("'Невозможно открыть файл обмена данными.");

Возврат; КонецПопытки;

Сообщить("    - Загрузка из " + Строка(ЭтотОбъект) + "    ");

Сообщить(" - Считывается файл " + ИмяФайла);

 

Процедура ПрочитатьСообщениеСИзменениями() Экспорт Каталог = КаталогВременныхФайлов();

// Сформировать имя файла

ИмяФайла = Каталог +?(Прав(Каталог, 1) = "\","", "\") + "Message" + СокрЛП(Ссылкз.Код) + "_" + СокрЛП(ПланыОбмена.Филиалы.ЭтотУзел().Код) + ".xml"; Файл = Новый Файл(ИмяФайла); Если Не Файл.Существует() Тогда

Возврат; КонецЕсли;

//*** Чтение документов XML // Попытаться открыть файл ЧтениеXML = Новый ЧтениеXML; Попытка

ЧтениеXML.ОткрытьФайл(ИмяФайла); Исключение

Сообщить("Невозможно открыть файл обмена данными.");

Возврат;

КонецПопытки;

Сообщить("    Загрузка из " + Строка(ЭтотОбъект) + "    -");

Сообщить(" - Считывается файл " + ИмяФайла);

// Загрузить из найденного файла //*** Инфраструктура сообщений ЧтениеСообщения = ПланыОбмена.СоздатьЧтениеСообщения();

//читать заголовок сообщения обмена данными - файла XML ЧтениеСообщения.НачатьЧтение(ЧтениеXML);

// Сообщение предназначено не для этого узла

Если ЧтениеСообщения.Отправитель <> Ссылка Тогда

ВызватьИсключение "Неверный узел"; КонецЕсли;

ЧтениеСообщения.ЗакончитьЧтение();

ЧтениеXML.Закрыть();

УдалитьФайлы(ИмяФайла);

Сообщить("    Конец загрузки-    —");

КонецПроцедуры

Мы проверяем, является ли отправитель сообщения тем узлом, для которого мы в данном вызове этой процедуры производим обмен данными.

Если все в порядке, то перед тем, как начать чтение данных следует удалить все записи регистрации изменений, которые были сделаны для этого узла и соответствовали номерам сообщений меньше или равным тому, который указан в обрабатываемом нами сообщении как номер принятого. Это делается затем, чтобы исключить повторную посылку данных, которые уже были ранее посланы этому узлу и им обработаны:

 

ЧтениеXML = Новый ЧтениеXML; Попытка

ЧтениеXML.ОткрытьФайл(ИмяФайла); Исключение

Сообщить("Невозможно открыть файл обмена данными.");

Возврат; КонецПопьггки;

Сообщить("    Загрузкаиз " + Строка(ЭтотОбъект) + "    ");

Сообщить(" - Считывается файл " + ИмяФайла);

// Загрузить из найденного файла //*** Инфраструктура сообщений ЧтениеСообщения = ПланыОбмена.СоздатьЧтениеСообщения();

//читать заголовок сообщения обмена данными - файла XML

// Сообщение предназначено не для этого узла

Если ЧтениеСообщения.Отправитель <> Ссылка Тогда

ВызватьИсключение "Неверный узел"; КонецЕсли;

// Удаляем регистрацию изменений // для узла отправителя сообщения //*** служба регистрации изменений

ПланыОбмена.УдалитьРегистрациюИзменений(ЧтениеСообщения.Отправитель,

ЧтениеСообщения.НомерПринятого); ЧтениеСообщения.ЗакончитьЧтение(); ЧтениеXML.Закрыть(); УдалитьФайлы(ИмяФайла);

Сообщить("    Конец загрузки    ");

КонецПроцедуры

 

 

 

Процедура ПрочитатьСообщениеСИзменениями() Экспорт Каталог = КаталогВременныхФайлов();

// Сформировать имя файла

ИмяФайла = Каталог +?(Прав(Каталог, 1) = "\","", "\") + "Message" + СокрЛП(Ссылка.Код) + "_" + СокрЛП(ПланыОбмена.Филиалы.ЭтотУзел().Код) + ".xml"

Файл = Новый Файл(ИмяФайла);

Если Не Файл.Существует() Тогда Возврат;

КонецЕсли;

//*** Чтение документов XML // Попытаться открыть файл

 

Обратите внимание, что здесь мы    обращаемся    к службе

регистрации изменений и    используем    метод

УдалитьРегистрациюИзменений() для    выполнения    описанных

действий.

Теперь, наконец, мы можем приступить к чтению непосредственно самих данных, содержащихся в сообщении:

Процедура ПрочитатьСообщениеСИзменениями() Экспорт Каталог = КаталогВременныхФайлов();

// Сформировать имя файла

ИмяФайла = Каталог +?(Прав(Каталог, 1) = "\","", "\")+

_    "Message" + СокрЛП(Ссылка.Код) + "_" +

 

СокрЛП(ПланыОбмена.Филиалы.ЭтотУзел().Код) + ".xml"; Файл = Новый Файл(ИмяФайла); Если Не Файл.Существует() Тогда

Возврат; КонецЕсли;

//*** Чтение документов XML // Попытаться открыть файл ЧтениеXML = Новый ЧтениеXML; Попытка

ЧтениеXML.ОткрытьФайл(ИмяФайла); Исключение

Сообщить("Невозможно открыть файл обмена данными.");

Возврат; КонецПопытки;

Сообщить("    Загрузка из " + Строка(ЭтотОбъект) +"    ");

Сообщить(" - Считывается файл " + ИмяФайла);

// Загрузить из найденного файла //*** Инфраструктура сообщений ЧтениеСообщения = ПланыОбмена.СоздатьЧтениеСообщения();

//читать заголовок сообщения обмена данными - файла XML ЧтениеСообщения.НачатьЧтение^тениеXML);

// Сообщение предназначено не для этого узла

Если ЧтениеСообщения.Отправитель <> Ссылка Тогда

ВызватьИсключение "Неверный узел"; КонецЕсли;

// Удаляем регистрацию изменений // для узла отправителя сообщения //*** служба регистрации изменений ПланыОбмена.УдалитьРегистрациюИзменений(ЧтениеСообщения.Отправитель,

ЧтениеСообщения.НомерПринятого);

// Читаем данные из сообщения

//*** XML-сериалшация

Пока ВозможностьЧтенияXML(ЧтениеXML) Цикл

КонецЦикла;

ЧтениеСообщения.ЗакончитьЧтение();

ЧтениеXML.Закрыть();

УдалитьФайлы(ИмяФайла);

Сообщить("    Конец загрузки    ");

КонецПроцедуры       

Чтение данных выполняется в цикле, причем мы снова обращаемся к механизмам XML-сериализации и методом глобального контекста ЕЗозможностьЧтенияХМЦ) получаем очередной тип данных XML из объекта 4TeHneXML и определяем, имеется ли соответствующий тип 1С:Предприятия. В случае успеха выполнение цикла продолжается.

И первое, что нам нужно сделать - представить данные XML в виде некоторого значения, имеющего тип 1С:Предприятия. Для этого мы используем метод глобального контекста ПрочитатьХМЦ):

Процедура ПрочитатьСообщениеСИзменениями() Экспорт Каталог = КаталогВременныхФайлов();

// Сформировать имя файла

ИмяФайла = Каталог +?(Прав(Каталог, 1) = "\","", "\") + "Message" + СокрЛП(Ссылка.Код) + "_" + СокрЛП(ПланыОбмена.Филиалы.ЭтотУзел().Код) + ".xml"; Файл = Новый Файл(ИмяФайла); Если Не Файл.Существует() Тогда

Возврат; КонецЕсли;

//*** Чтение документов XML // Попытаться открыть файл ЧтениеXML = Новый ЧтениеXML; Попытка

ЧтениеXML.ОткрытьФайл(ИмяФайла); Исключение

Сообщить("Невозможно открыть файл обмена данными.");

Возврат; КонецПопытки;

Сообщить("    Загрузка из " + Строка(ЭтотОбъект) + "    *);

Сообщить(" - Считывается файл " + ИмяФайла);

// Загрузить из найденного файла //*** Инфраструктура сообщений ЧтениеСообщения = ПланыОбмена.СоздатьЧтениеСообщения();

//читать заголовок сообщения обмена данными - файла XML ЧтениеСообщения.НачатьЧтение(ЧтеииеXML);

// Сообщение предназначено не для этого узла

Если ЧтениеСообщения.Отправитель о Ссылка Тогда

ВызватьИсключение "Неверный узел"; КонецЕсли;

// Удаляем регистрацию изменений

// для узла отправителя сообщения

//*** служба регистрации изменений

ПланыОбмена.УдалитьРегастрациюИзменени(ЧтениеСообщения.Отправитель,

ЧтениеСообщения.НомерПринятого)-

// Читаем данные из сообщения

//*** XML-сериализация

Пока ВозможностьЧтенияXMLЧтениеХМЬ) Цикл

// Читаем очередное значение

Данные = ПрочитатьXML(ЧтениеXML);

КонецЦикла;

ЧтениеСообщения.ЗакончитьЧтениеО;

ЧтениеХМЬ.Закрыть();

УдалитьФайлы(ИмяФайла);

Сообщить("    Конец загрузки    ");

КонецПроцедуры

В результате выполнения этого метода переменная «Данные» будет содержать объект 1С:Предприятия, соответствующий данным XML.

Теперь, после того, как объект 1С:Предприятия получен, следует разрешить возможную коллизию:

Процедура ПрочитатьСообщениеСИзменениями() Экспорт

Каталог = КаталогВремениыхФайлов();

// Сформировать имя файла

ИмяФайла = Каталог +?(Прав(Каталог, 1) = "\","", "\") + "Message" + СокрЛП(Ссылка.Код) + "_" + СокрЛП(ПланыОбмена.Филиалы.ЭтотУзел().Код) + ".xml"

Файл = Новый Файл(ИмяФайла);

Если Не Файл.Существует() Тогда Возврат;

КонецЕсли;

//*** Чтение документов XML // Попытаться открыть файл ЧтениеXML = Новый ЧтениеXML; Попытка ЧтeниeXML.OткpытьФaйл(ИмяФaйлa);

Исключение Сообщить("Невозможно открыть файл обмена данными.");

Возврат;

КонецПопытки;

Сообщить("    Загрузка из " + Строка(ЭтотОбъект) + "    ");

Сообщить(" - Считывается файл " + ИмяФайла);

 

// Загрузить из найденного файла //*** Инфраструктура сообщений ЧтениеСообщения = ПланыОбмена.СоздатьЧтениеСообщения();

//читать заголовок сообщения обмена данными - файла XML ЧтениеСообщения.НачатьЧтение(ЧтениеXML);

// Сообщение предназначено не для этого узла

Если ЧтениеСообщения.Отправитель <> Ссылка Тогда

ВызватьИсключение "Неверный узел"; КонецЕсли;

// Удаляем регистрацию изменений // для узла отправителя сообщения //*** служба регистрации изменений ПланьОбмена.УдалитьРегистрациюИзменений(ЧтениеСообщения.Отправитель,

ЧтениеСообщения.НомерПринятого);

// Читаем данные из сообщения

//*** XML-сериализация

Пока ВозможностьЧтенияXML(ЧтениеXML) Цикл

// Читаем очередное значение

Данные = ПрочитатьXMLЧтениеXML);

// Не переносим изменение полученное // в главный из неглавного // если есть регистрация изменения Если Не ЧтениеСообщения.Отправитель.Главный И

ПланыОбмена

.ИзменеииеЗарегистрировано(ЧтениеСообщения.Отправитель,

Данные) Тогда

Сообщить("- Изменения отклонены"); Продолжить; КонецЕсли;

КонецЦикла;

ЧтениеСообщения.ЗакончитьЧтение();

ЧтениеXML.Закрыть();

УдалитьФайлы(ИмяФайла);

Сообщить("    Конец загрузки    ");

КонецПроцедуры

Возможная коллизия разрешается следующим образом: мы проверяем, является ли узел-отправитель главным узлом и есть ли записи об изменении этого объекта для этого узла в нашей базе

данных. В случае если объект изменялся в нашей базе и отправите^ не является главным узлом, мы отклоняем запись полученного объекта. Во всех остальных случаях мы принимаем изменения полученного объекта.

Теперь единственное, что нам осталось сделать - записать полученные данные:

Процедура ПрочитатьСообщениеСИзменениями() Экспорт Каталог = КаталогВременныхФайлов();

// Сформировать имя файла

ИмяФайла = Каталог +?(Прав(Каталог, 1) = "V,"", "\") + "Message" + СокрЛП(Ссылка.Код) + "_" + СокрЛП(ПланыОбмена.Филиалы.ЭтотУзел().Код) + " .xml";

Файл = Новый Файл(ИмяФайла);

Если Не Файл.Существует() Тогда Возврат;

КонецЕсли;

//*** Чтение документов XML // Попытаться открыть файл ЧтениеXML = Новый ЧтениеXML; Попытка

ЧтениеXML.ОткрытьФайл(ИмяФайла); Исключение

Сообщить("Невозможно открыть файл обмена данными.");

Возврат; КонецПопытки;

Сообщить("    Загрузка из " + Строка(ЭтотОбъект) + "    ");

Сообщить(" - Считывается файл " + ИмяФайла);

// Загрузить из найденного файла //*** Инфраструктура сообщений ЧтениеСообщения = ПланыОбмена.СоздатьЧтениеСообщения();

//читать заголовок сообщения обмена данными - файла XML ЧтениеСообщения.НачатьЧтение^тениеXML);

// Сообщение предназначено не для этого узяа

Если ЧтениеСообщения.Отправитель <> Ссылка Тогда

ВызватьИсключение "Неверный узел"; КонецЕсли;

// Удаляем регистрацию изменений // для узла отправителя сообщения //*** служба регистрации изменений ПланыОбмена.УдалитьРегистрациюИзменений(ЧтениеСообщения.Отправитель,_

 

Обмен данными

ЧтениеСообшения.НомерПринятого);

// Читаем данные из сообщения

//*** XML-сериализация

Пока ВозможностьЧтенияXML(ЧтениеXML) Цикл

// Читаем очередное значение

Данные = ПрочитатьXMLЧтениеXML);

// Не переносим изменение полученное // в главный из неглавного // если есть регистрация изменения Если Не ЧтениеСообщения.Отправитель.Главный И

ПланыОбмена.ИзменениеЗарегистрировано(ЧтениеСообщения.Отправитель,

Данные) Тогда

Сообщить("- Изменения отклонены"); Продолжить; КонецЕсли;

// Записать полученные данные

Данные.ОбменДанными.Отправитель = ЧтениеСообщения.Отправитель;

Даниые.ОбменДанными.Загрузка = Истина;

ДанныеЗаписать();

КонецЦикла;

ЧтениеСообщения.ЗакончитьЧтение();

ЧтениеXML.Закрьпъ();

УдалитьФайлы(ИмяФайла);

Сообщить("    Конец загрузки    ");

КонецПроцедуры

Перед записью полученного объекта мы устанавливаем у него в параметрах обмена данными узел-отправителя, для того, чтобы система, при записи этого объекта в нашей базе данных, не формировала записи регистрации изменений этого объекта для того узла, от которого мы его только что получили.

Кроме этого, в параметрах обмена данными мы устанавливаем свойство «Загрузка», информирующее систему о том, что запись объекта будет происходить в режиме обновления данных, полученных в результате обмена. Такое указание позволяет системе упростить процедуру записи объекта, отказавшись от ряда стандартных проверок и исключив изменения связанных данных, которые выполняются при, обычной записи.

На этом создание процедуры получения и обработки данных обмена закончено.

 

Проверка работы обмена данными

П

режде всего создадим новый каталог, в котором будет

размещаться база нашего филиала и сохраним в этот каталог

нашу    конфигурацию

(Конфигурация | Сохранить конфигурацию в файл...). Запустим 1С:Предприятие в режиме отладки и установим необходимые значения в нашей центральной базе. Прежде всего зададим значение константы «ПрефиксНомеров» - «ЦБ»:

 

Затем создадим новый узел, который будет соответствовать базе филиала, присвоим ему код «Фил» и наименование «Филиал»:

 

Теперь вызовем обработку «ОбменДанными» и нажмем «Выполнить». В окне сообщений появится следующий текст:

 

После этого откроем план обмена «Филиалы» и зададим параметры узла по умолчанию - т.е. параметры нашей базы. Код базы будет «ЦБ», а наименование - «Центральная база».

Не забудьте, что именно код идентифицирует узлы обмена в различных базах, поэтому в базе филиала мы будем создавать узлы с такими же кодами.

 

 

 

Таким образом, в результате обмена данными центральная база сформировала файл обмена, содержащий изменения всех данных, которыми она обменивается с филиалом.

Настало время перейти к базе филиала. Запустим систему в режиме

Конфигуратора и добавим в список баз новую базу с пустой

конфигурацией, которая будет расположена в созданном нами

каталоге базы филиала. В конфигураторе откроем конфигурацию и

загрузим    конфигурацию    из    файла

(Конфигурация | Загрузить конфигурацию из файла...). Запустим 1С:Предприятие в режиме отладки.

 

Первым делом зададим значение константы «ПрефиксНомеров» «ФЛ»:

 

Затем откроем план обмена «Филиал» и опишем предопределенный узел (узел текущей информационной базы) кодом «Фил» и наименованием «Филиал»:

 

Теперь, для большей наглядности откроем список справочника «Клиенты». Сейчас в этом справочнике нет ни одного элемента. Запустим обработку «ОбменДанными» и нажмем «Выполнить».

Справочник будет заполнен элементами, а в окне сообщений появится текст:

 

Теперь проверим, как будет происходить обмен в другую сторону. Создадим в справочнике «Клиенты» нового клиента с произвольным наименованием. После этого снова нажмем «Выполнить» в открытой форме обработки «ОбменДанными». Затем перейдем в центральную базу, также выполним обмен данными и убедимся, что клиент, созданный в базе филиала перенесен в центральную базу.

После этого создадим новый узел плана обмена с кодом «ЦБ», наименованием «Центральная база» и признаком «Главный»:

Механизм распределенных информационных баз

М

еханизм распределенных информационных баз является развитием универсального обмена данными. Он реализует привычную, по версии 7.7, модель распределенной информационной базы, которая подразумевает наличие идентичных конфигураций во всех узлах, имеет древовидную структуру и позволяет выполнять обмен как измененными данными так и изменениями, внесенными в конфигурацию.

Механизм распределенных информационных баз реализуется планами обмена. Для этого объект конфигурации План обмена содержит свойство «Распределенная информационная база». Если это свойство установлено, для данного плана обмена включается механизм распределенных информационных баз и разработчик получает возможность создать распределенную базу исключительно интерактивными средствами, без написания кода. Такая возможность не исключает программное управление обменом, которое также доступно при работе с распределенными информационными базами и в ходе создания примера мы рассмотрим оба варианта организации обмена в распределенных информационных базах.

 

Основные сведения о распределенных информационных базах

К

ак мы уже говорили выше, распределенная информационная база должна иметь четко определенную древовидную структуру. Количество уровней в такой структуре не ограничено, главное - между двумя связанными узлами всегда должно быть определено отношение «главный - подчиненный»:

 

 

Таким образом, любой узел этой структуры может иметь произвольное количество подчиненных узлов (в том числе и ни одного). Кроме этого все узлы, кроме одного, должны иметь по одному главному узлу, и один узел не будет иметь главного узла - это корневой узел.

Такое жесткое задание структуры узлов необходимо для определения порядка миграции изменений данных и изменений конфигурации.

Конфигурация может быть изменена только в узле, не имеющем главного узла (то есть в корневом узле). Изменения данных могут выполняться в любом узле.

Изменения конфигурации будут передаваться от главного к подчиненным узлам. Изменения данных могут передаваться между любыми связанными узлами.

Разрешение коллизий также будет производиться исходя Из отношения «главный-подчиненный». Если изменения выполнены одновременно и в главном, и в подчиненном узле, при обмене данными будут приняты только изменения главного узла, а изменения подчиненного отвергнуты.

Для любого подчиненного узла возможно создание начального образа - информационной базы, созданной на основании конфигурации и данных главного узла, в соответствии с правилами определяемыми планом обмена. Процедура создания начального образа узла может выполняться неоднократно, при этом удаляются все записи изменений в базе главного узла для подчиненного узла. Сразу после создания начальный образ готов к обмену с главным узлом.

Создание начального образа является рекомендуемым способом создания подчиненного узла в распределенной информационной базе.

Постановка задачи

В

качестве примера, на котором мы проиллюстрируем использование механизма распределенных информационных баз, будет создание нескольких отделений нашего OOO «На все руки мастер». В отличие от филиалов, которые расположены в других городах, являются отдельными юридическими лицами и довольно самостоятельны в плане организации учета своей деятельности, отделения нашего OOO расположены в этом же городе, никакой юридической самостоятельностью не обладают и ведут учет в точности так, как это организовано в главном офисе. Поэтому все они используют ту же конфигурацию, что и главный офис, причем, если главный офис вносит какие-либо изменения в свою конфигурацию, все эти изменения должны быть своевременно внесены и в конфигурации отделений.

Для реализации такой схемы работы распределенная информационная база подойдет как нельзя лучше, и сначала мы организуем обмен с отделениями, используя исключительно интерактивные средства.

 

Обмен данными

Пример интерактивного обмена в распределенной информационной базе

Д

ля построения распределенной информационной базы нам понадобится создать еще один объект конфигурации План обмена, который мы назовем «Отделения».

Для этого плана обмена мы установим свойство «Распределенная информационная база»:

Установим свойство «Распределенная информационная база»...

 

Перейдем на закладку «Прочее» и определим тот же состав данных для обмена, что и в плане обмена «Филиалы»: отметим все объекты конфигурации, относящиеся к подсистеме «УчетУслугИМатериалов».

Запустим 1С:Предприятие в режиме отладки.

Откроем план обмена «Отделения» и зададим параметпк центрального узла (предопределенный элемент плана обмена): код «ЦБ» и наименование «Центральная база». После этого создадим новый узел с кодом «Отд» и наименованием «Отделение». Обратите внимание, что для созданного нами узла стали доступны три иконки в командной панели формы плана обмена: «Создать начальный образ» «Записать изменения» и «Прочитать изменения»:

 

Обмен данными

На следующем шаге укажем каталог информационной базы и нажмем «Готово». Система создаст в указанном каталоге начальный образ информационной базы нашего отделения.

Запустим 1С:Предприятие, подключим новую базу нашего отделения и откроем ее в конфигураторе. Обратите внимание на то, что конфигурация нашего отделения стала защищена от изменений средствами управления распределенной информационной базой:

 

 

 

 

Стали доступны команды работы с распределенной информационной базой...

Не откладывая в долгий ящик, воспользуемся первой из них, чтобы создать начальный образ информационной базы нашего отделения. Для этого нам потребуется сначала создать на диске новый каталог, в котором будет располагаться база отделения. После этого выполним команду «Создать начальный образ» и укажем, что информационная база будет расположена на данном компьютере:

 

 

Конфигурация подчиненного узла защищена от изменений

средствами управления распределенной информационной

базой...

Запустим базу отделения в режиме отладки и откроем план обмена «Отделения»:

 

Обмен данными

После этого закроем конфигуратор информационной базы отделения, и выполним чтение изменений в базе подчиненного узла. По окончании чтения система выдаст следующее сообщение:

 

 

 

 

 

 

 

Обратите внимание, что в базе подчиненного узла сам подчиненный узел является предопределенным узлом плана обмена, а узел центральной базы отмечен красной пиктограммой, указывающей на то, что он является главным для информационной базы отделения. Кроме этого для узла центральной базы доступны только команды «Записать изменения» и «Прочитать изменения».

Теперь проверим работу обмена данными. Откроем список констант и зададим значение константы «ПрефиксНумерации» - «ОТ».

После этого откроем справочник клиентов и добавим в него нового клиента. Затем выполним запись изменений для центральной базы (указав каталог обмена).

Перейдем в центральную базу и выполним чтение изменений в центральной базе. Убедимся, что новый клиент, созданный в базе отделения, присутствует и в центральной базе.

Теперь посмотрим, как будут переноситься изменения конфигурации между главным и подчиненным узлом. В конфигураторе центральной базы создадим новую константу с именем «НоваяКонстанта». Выполним обновление конфигурации базы данных и запустим 1С:Предприятие в режиме отладки. Откроем план обмена «Отделения» и выполним запись изменений для подчиненного узла.

Теперь запустим конфигуратор базы отделения и увидим, что в основной конфигурации появилась новая константа «НоваяКонстанта», т.е. изменения, внесенные в конфигурацию центральной базы, были автоматически перенесены в конфигурацию подчиненного узла. Теперь единственное, что остается сделать - это выполнить обновление конфигурации базы данных в подчиненном узле.

Следует сказать несколько слов о порядке принятия изменений, когда в одном сообщении получены как изменения конфигурации, так и изменения данных. В этом случае сначала будет изменена основная конфигурация и выдано сообщение о необходимости выполнения сохранения конфигурации базы данных. После объединения конфигураций следует выполнить повторное получение данных, при котором будут приняты уже изменения данных, содержащиеся в сообщении. Такой порядок принятия изменений не зависит от того, относятся ли измененные данные к существующим объектам конфигурации, или к новым.

Программный обмен в распределенной информационной базе

В

се описанные выше действия по обмену данными в распределенной информационной базе можно выполнить программно.

Мы создадим обработку, которая будет программно выполнять для выбранного узла все те действия, которые были рассмотрены в предыдущем разделе.

 

Для этого в конфигураторе центральной базы создадим новь,й объект конфигурации Обработка с именем «ОбменСОтделениями». Создадим основную форму обработки и расположим на неи поле ввода с именем «ПолеВводаОтделение», подписью «Отделение:» и типом ПланОбменаСсылка.Отделения:

 

После этого расположим в форме три кнопки: «Создать начальный образ» с именем «КнопкаСоздатьНачальныйОбраз», «Записать изменения» с именем «КнопкаЗаписатьИзменения» и «Прочитать изменения» с именем «КнопкаПрочитатьИзменения»:

 

Начнем с создания обработчика нажатия кнопки «Создать начальный образ». Текст обработчика будет выглядеть следующим образом:

ПроиедураКнопкаСоздатьНачальныйОбразНажатие(Элемент)

Диалог = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.ВыборКаталога); Диалог.Заголовок = "Укажите каталог информационной базы:"; Если Диалог.Выбрать() Тогда ПланыОбмена.СоздатьНачальныйОбраз(ПолеВводаОтделение,

"Filе="+Диалог.Каталог);

Предупреждение("Создание начального образа узла завершено."); КонецЕсли; КонецПроцедуры

В начале процедуры мы вызываем диалог выбора каталога, в который будет помещен образ информационной базы, и затем выполняем метод СоздатьНачальныйОбраз() объекта ПланыОбменаМенеджер. Именно этот метод и позволяет нам создать образ подчиненного узла распределенной информационной базы. В первом параметре метода передается ссылка на узел, для которого мы хотим создать начальный образ, а во втором - строка соединения, указывающая информационную базу.

Теперь создадим обработчик нажатия кнопки «Записать изменения»:

ПроцедураКиопкаЗаписатьИзмененияНажатие(Элемент)

Диалог = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.Сохранение); Диалог.Заголовок = "Укажите файл обмена:"; Если Диалог.Выбрать() Тогда

// Создать и проинициализаровать объект ЗаписьХМL

ЗаписьХМL = Новый ЗаписьХМL; ЗаписьХМL.ОткрыгьФайл(Диалог.ПолноеИмяФайла);

// Создать объект ЗаписьСообщенияОбмена и начать запись сообщения

ЗаписьСообщения = ПланыОбмена.СоздатьЗаписьСообщения(); ЗаписьСообщетм.НачатьЗапись(ЗагшсьХМL, ПолеВводаОтделение);

// Записать содержимое тела сообщения //обмена данными распределенной ИБ

ПланыОбмена.ЗаписатьИзменения(ЗаписьСообщения);

ончить запись сообщения и запись ХМL

ЗаписьСообщения.ЗакончитьЗапись();

ЗаписьХМL.Закрыть();

Предупреждение("Запись изменений завершена."); КонецЕсли; КонецПроцедуры

В начале процедуры мы вызываем диалог ввода имени файла, в который будут записаны изменения. После этого мы создаем объект 3arwcbXML для работы с этим файлом. Затем создаем объект ЗаписьСообщенияОбмена, с помощью которого будем создавать сообщение обмена. В методе НачатьЗапись(), во втором параметре, мы указываем, для какого узла обмена будет создаваться это сообщение. После этого мы выполняем метод ЗаписатьИзменения() объекта ПланыОбменаМенеджер, который и записывает изменения, предназначенные для передачи в выбранный узел, в указанное сообщение обмена. В заключение мы как обычно заканчиваем запись сообщения обмена и закрываем файл.

<*? Узнай больше!

Следует отметить, что метод ЗаписатьИзменения() позволяет задать максимальное число элементов данных, которые помещаются в сообщение в рамках одной транзакции базы данных. По умолчанию все данные помещаются в сообщение в рамках одной транзакции. Такой режим является рекомендуемым, так как гарантирует согласованность данных, помещаемых в сообщение.

Но при создании сообщения в многопользовательском режиме могут быть конфликты блокировок между транзакцией, в которой данные помещаются в сообщение, и транзакциями, выполняемыми другими пользователями. Для снижения вероятности возникновения таких конфликтов можно задать значение этого параметра, отличное от значения no умолчанию. Чем меньше значение параметра, тем меньше вероятность конфликта блокировок, но выше вероятность помещения в сообщение несогласованных данных.

Учитывая все вышесказанное, идеальным вариантом являегпсЯ выполнения обмена данными в монопольном режиме. Однако такой вариант не всегда приемлем, в силу специфики организации работы конкретных информационных баз.

 

И последним мы создадим обработчик нажатия кнопки «Прочитать

изменения»:

ПроцедураКнопкаПрочитатьИзмененияНажатие(Элемент)

Диалог = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.Открытие); Диалог.Заголовок = "Укажите файл обмена:"; Если Диалог.Выбрать() Тогда

// Создать я проинициализаровать объект ЧтениеХМL ЧтениеХМL = Новый ЧтениеХМL; ЧтениеХМL.ОткрытьФайл(Диалог.ПолноеИмяФайла);

// Создать объект ЧтениеСообшенияОбмена // и начать чтение сообщения

ЧтениеСообщения = ПланыОбмена.СоздатьЧтениеСообщения(); ЧтениеСообщения.НачатьЧтение(ЧтениеХМL);

// Прочитать содержимое тела сообщения

ПланыОбмена.ПрочитатьИзмененияЧтениеСообщения);

// Закончить чтение сообщения и чтение XML

ЧтениеСообщения.ЗакончитьЧтение(); ЧтениеХМL. Закрыть();

Предупреждение("Чтение изменений завершено."); КонецЕсли; КонецПроцедуры

В начале процедуры мы снова вызываем диалог ввода имени файла, который будет прочитан, и создаем объект ЧтениеХМЬ для работы с этим файлом. Затем создаем объект ЧтениеСообщенияОбмена для чтения сообщения, содержащегося в указанном файле. Затем методом ПрочитатьИзменения() объекта ПланыОбменаМенеджер мы читаем полученное сообщение. В заключение процедуры мы завершаем чтение сообщения обмена и закрываем файл.

Проверить работу нашей обработки можно на примере, аналогичном приведенному в разделе универсального обмена Данными.

Следует лишь сделать несколько заключительных замечаний.

При использовании механизма распределенных информационных баз становятся доступными четыре события объект ПланОбменаОбъект, которые позволяют управлять отправкой \ приемом данных на уровне отдельных элементов данных:

• ПриОтправкеДанныхГлавному(),

• ПриОтправкеДанныхПодчиненному(),

• ПриПолученииДанныхОтГлавного(),

• ПриПолученииДанныхОтПодчиненного().

Эти события будут вызываться для каждого элемента данных включаемого в сообщение. Работу этих событий можно увидеть добавив в модуль объекта План обмена следующий текст:

ПроцедураПриОтправкеДанныхГлавному(ЭлементДанных, ОтправкаЭлемента)

Сообщить("ПриОтправкеДанныхГлавному "+ЭлементДанных); КонецПроцедуры

ПроцедураПриОтправкеДанныхПодчиненному(ЭлементДанньгх, ОтправкаЭлемента)

Сообщить(" ПриОтправкеДанныхПодчиненному"+ЭлементДанных); КонецПроцедуры

ПроцедураПриПолученииДаннькОтГлавного(ЭлементДанных,ПолучениеЭлемента,

ОтправкаНазад)

Сообщить("ПриПолученииДанныхОтГлавного "+ЭлементДанных); КонецПроцедуры

ПроцедураПриПолученииДанныхОтПодчиненного(ЭлементДанньк,

ПолучениеЭлемента, ОтправкаНазад) Сообщить("ПриПолученииДанныхОтПодчиненного "+ЭлементДанных);

В первом параметре всех перечисленных событий находится тот элемент данных, для которого вызвано это событие.

Параметр «ОтправкаЭлемента» позволяет управлять тем, какая информация будет помещена в сообщение. Он может принимать три значения:

• ОтправкаЭлементаДанных.Авто - значение по умолчанию

- указывает на то, что элемент данных будет помещен в

сообщение,

• ОтправкаЭлементаДанных.Удалить - в сообщение будет

помещено значение, предназначенное для удаления этого

элемента данных,

• ОтправкаЭлементаДанных.Игнорировать - в сообщение

не будет помещено ничего, связанного с этим элементом

данных.

Параметр «ПолучениеЭлемента» позволяет указать, будет ли прочитанный элемент данных записан в базу данных, или нет. Параметр также может принимать три значения:

• ПолучениеЭлементаДанных.Авто - значение по

умолчанию. Если элемент данных получен от главного узла -

он будет записан всегда. Если элемент данных получен от

подчиненного узла, он будет записан только в случае, если не

зарегистрированы изменения для этого элемента данных,

• ПолучениеЭлементаДанных.Принять - полученный

элемент данных будет записан всегда,

• ПолучениеЭлементаДанных.Игнорировать

проигнорировать получение элемента данных и ничего не

записывать.

Также в событиях получения данных существует третий параметр -«ОтправкаНазад», имеющий тип Булево. Этот параметр позволяет выполнять принудительную регистрацию изменений для полученного элемента данных в базе-получателе. Такая необходимость может возникнуть, например, в случае, когда при приеме данных от узла-отправителя обнаружено, что полученные данные противоречивы (например, в узле-отправителе была допущена ошибка при изменении Данных). Тогда мы можем проигнорировать присланные изменения и, подняв флаг «ОтправкаНазад», вызвать принудительную регистрацию изменений полученного элемента данных в нашей базе для узла-отправителя. В результате последующего обмена состояние этого

элемента данных в узле-отправителе будет установлено таким же, как и в нашей базе.

В заключение следует сказать о том, что механизм распределенных информационных баз содержит программное средство реконфигурирования структуры узлов распределенной базы.

Для этого следует использовать метод УстановитьГлавныйУзел() объекта ПланыОбменаМенеджер. В параметре этого метода передается ссылка на узел плана обмена распределенной информационной базы, который устанавливается главным для текущей базы. Также в этом параметре может быть передано значение Неопределено, и это приведет к тому, что у текущей информационной базы будет отсутствовать главный узел.

Рассмотрим несколько вариантов реконфигурирования структуры узлов распределенной информационной базы.

Допустим, необходимо переместить один из подчиненных узлов в корень дерева:

 

 

// В информационной базе Узла1

ПланыОбменаМенеджер.УстановитьГлавныйУзел(Узел2);

При этом будут удалены все записи регистрации изменений конфигурации Узла1, относящиеся к Узлу2, т.к. передача изменений конфигурации будет возможна теперь только от Узла2 к Узлу1. Записи регистрации изменения данных удалены не будут, т.к. передача изменений данных будет по-прежнему возможна между этими узлами.

Таким же образом, используя значение параметра метода Неопределено, мы можем отключать от дерева отдельную информационную базу или целое поддерево:

 

// В информационной базе Узла1

ПланыОбменаМенеджер.УстановитьГлавныйУзел(Неопредеяено);

 

Для этого следует выполнить следующие действия:

// В информационной базе Узла2

ПланыОбменаМенеджер.УстановитьГлавныйУзел(Неопределено);

 

Кроме этого мы можем создавать распределенную информационную базу из отдельных информационных баз с идентичной конфигурацией:

 

Что нового мы узнали

 

 

 

 

 

// В информационных базах Узла2, УзлаЗ н Узла4

ПланыОбменаМенеджер.УстанавитьГлавныйУзел(Узел 1);

 

- какие средства входят в состав механизма универсального

обмена данными

- для чего предназначен объект конфигурации План обмена - каковы основные составляющие плана обмена - что такое узлы плана обмена - что такое состав плана обмена, и для каких элементов

данных возможен обмен данными - что такое авторегистрация

- для чего предназначен механизм регистрации изменений - как работает инфраструктура сообщений - каково назначение XML-сериализации - для чего используется запись/чтение документов XML - как создать план обмена

- как настроить конфигурацию для обмена данными - как реализовать обмен данными в общем виде - как реализовать обмен данными в распределенной

информационной базе - как программно управлять обменом данными в

распределенной информационной базе

- как изменить структуру дерева распределенной информационной базы

 

Глава 14. Анализ и прогнозирование данных

В этой главе мы познакомимся с возможностями, которм предоставляет система 1С:Предприятие 8.0 для поиска и анализ закономерностей в имеющихся данных, и построения прогнозов на основе найденных закономерностей.

Следует заметить, что наше изложение будет касаться лищь непосредственно тех механизмов, которые реализованы в платформе 1С:Предприятия 8.0. Для получения базовой теоретической информации по методам анализа данных, соответствующим реализованным моделям, следует обратиться к специальной литературе. Мы полагаем, что разработчик, приступающий к анализу данных, уже владеет необходимыми теоретическими знаниями.

Поскольку анализ данных подразумевает наличие большого объема исходной информации, для всех примеров, рассматриваемых далее, мы будем использовать не информационную базу нашего OOO «На все руки мастер», а некую абстрактную базу данных, которая позволит проиллюстрировать работу анализа и прогнозирования данных.

На диске информационно - технологического сопровождения, в составе демонстрационной конфигурации «Анализ данных», вы можете найти универсальную обработку «Консоль анализа данных», которая позволит вам работать с анализом данных в любом прикладном решении без какого-либо программирования.

 

Общие сведения об анализе и прогнозировании данных

В

общем случае анализ и прогнозирование данных связаны следующим образом. Анализ данных позволяет найти неочевидные закономерности в анализируемых данных, и представить их в виде легко воспринимаемого результата.

Прогнозирование позволяет, на основе проведенного анализа данных, предсказать последующие события или значения некоторых характеристик для новых исходных данных.

Таким образом, результаты анализа являются основой, на которой строятся последующие прогнозы.

Например, в нашей базе имеются данные о том, какие товары и когда приобретались нашими клиентами. Было замечено, что если клиент приобретал, скажем, диван «Сказка», то через некоторое время он, зачастую, приобретал и кресло «Сказка», из того же набора мягкой мебели.

Мы хотим проанализировать данные нашей базы в следующем виде: какие существуют наиболее вероятные последовательности покупок товаров одним и тем же клиентом? Иначе говоря - «как обстоят дела сейчас, если взять текущие данные и попробовать определить, какие существуют последовательности покупаемых товаров»?

 

В терминах 1С:Предприятия 8.0 такой процесс анализа данньп можно представить следующей схемой:

 

Источник данных - представляет исходные данные для анализа. В качестве источника данных может выступать результат запроса, область ячеек табличного документа или таблица значений.

Тип анализа - определяет вид результата, к которому должны быть сведены исходные данные. Система поддерживает пять различных типов анализа:

• общая статистика - позволяет получить общую статистическую информацию об источнике данных для его предварительного исследования (количество значений и количество уникальных значений, минимальное, максимальное и среднее значение, размах, стандартное отклонение, медиана, мода, частота появления каждого значения в источнике),

 

 

• поиск ассоциаций    предназначен для поиска часто

встречаемых групп характеристик объектов и создания правил

ассоциации «Если ... To ...» (например, такой анализ может

быть использован для поиска групп товаров, часто

покупаемых вместе),

• поиск последовательностей - применяется для выявления

цепочек событий часто наблюдаемых в источнике данных

(например, это может быть цепочка товаров или услуг,

которые часто последовательно приобретают клиенты),

• дерево решений - предназначен для выявления

закономерностей того, что объект относится к тому или иному

классу (например, при помощи дерева решения можно

проанализировать какие характеристики клиента влияют на то,

что он перейдет к другому поставщику),

• кластерный анализ - при помощи кластерного анализа можно

объединить объекты в группы (кластеры), в которых будут

находиться объекты, наиболее схожие по ряду характеристик.

Например, можно сгруппировать клиентов по их

характеристикам и деятельности, чтобы в дальнейшем

проанализировав полученные кластеры принять решение о

стратегии работы с клиентами определенных групп.

Анализ данных - объект встроенного языка (АнализДанных), непосредственно выполняющий анализ данных. Объекту устанавливается источник данных, задаются параметры, настраиваются колонки анализа данных. Результатом работы данного объекта является результат анализа данных, тип которого зависит от типа анализа. Каждому типу анализа соответствует свой тип результата анализа.

Результат анализа - объект встроенного языка, содержащий информацию о результате анализа. Для каждого типа анализа предусмотрен свой тип результата. Например, результатом анализа данных типа АнализДанныхДеревоРешений будет объект типа РезультатАнализаДанныхДеревоРешений.

В дальнейшем результат может быть выведен в табличный Документ при помощи построителя отчета анализа данных (о нем будет рассказано далее), может быть выведен посредством программного доступа к его содержимому, может быть использован

для создания модели прогноза. Любой результат анализа данны может быть сохранен для последующего использования.

Теперь рассмотрим, как выглядит прогнозирование данных Прогнозирование является попыткой предсказать новый результат, на основе некоторой совокупности новых данных и определенной ранее модели. Иными словами, прогнозирование позволяет ответить на вопрос: «как будут обстоять дела, если мы будем иметь такие данные при такой модели их взаимосвязи»?

Возвращаясь к нашему примеру - «какой товар, с большой долей вероятности, клиент приобретет в следующий раз, если до этого он совершал вот такие покупки, и текущие последовательности покупок товаров выглядят следующим образом»?

В терминах 1С:Предприятия 8.0 этот процесс прогнозирования данных можно представить следующей схемой:

 

 

Анализ и прогнозирование даннь

Источник данных - таблица значений, результат запроса или область табличного документа, содержащая информацию, по которой необходимо построить прогноз. Например, для модели прогноза МодельПрогнозаПоискАссоциаций, выборка может содержать перечень товаров документа продажи. Результат же работы модели может рекомендовать, какие товары можно еще предложить покупателю.

Модель прогноза - специальный объект, позволяющий выполнять

прогноз на основании входных данных. Тип модели зависит от типа

анализа данных. Например, модель, созданная для анализа данных

АнализДанныхПоискАссоциаций    будет    иметь    тип

МодельПрогнозаПоискАссоциаций. Такая модель сможет выдавать прогнозы типа: «т.к. данный покупатель купил заданный набор товаров, то с определенной вероятностью он должен купить и другой набор товаров». На вход модели прогноза передается источник данных для прогноза. Результатом является таблица значений, содержащая прогнозируемые значения.

Таблица значений - таблица значений, состоящая из колонок, согласно настройкам результирующих колонок модели прогноза, содержащая прогнозируемые данные. Конкретное содержание таблицы определяется типом анализа данных.

 

 

Если обобщить обе схемы, представленные выше, то анализ и прогнозирование данных в терминах 1С:Предприятия 8.0 можно представить следующим образом:

 

Как вы видите, на этой схеме появились новые прямоугольники. Мы рассмотрим их назначение в следующем разделе.

 

Анализ данных

О

бъект анализ данных имеет возможность настройки колонок источника данных и указания параметров анализа. Каждый тип анализа подразумевает свою структуру исходных данных и свой набор параметров анализа.

Общая статистика

Т

ип анализа АнилизДанныхОбщаяСтатистика позволяет получать общестатистические показатели выборки, которую представляют исходные данные.

Колонки исходных данных для общестатистического анализа могут быть двух видов: содержащие непрерывные данные, либо содержащие дискретные данные.

Если анализируемые значения являются числовыми, или имеют тип Дата, то для такой колонки следует указывать вид данных «Непрерывные». Во всех остальных случаях (в том числе при анализе значений объектного типа), следует указывать вид данных «Дискретные».

Для указания того или иного вида исходных данных используется свойство объекта АнализДанных - НастройкаКолонок. Это свойство содержит коллекцию значений, элементами которой являются объекты КолонкаАнализаДанных. Каждый такой объект описывает одну колонку исходных данных. Для указания вида данных, содержащихся в колонке, нужно использовать свойство объекта КолонкаАнализаДанных - ВидДанных.

Для непрерывных и дискретных данных рассчитываются различные статистические показатели.

Для непрерывных данных рассчитывается:

• количество значений - количество значений, присутствующих

в исходной выборке,

• минимальное значение - минимальное значение,

присутствующее в исходной выборке,

• максимальное значение - максимальное значение,

присутствующее в исходной выборке,

 

• среднее значение - среднее арифметическое значений

выборки,

• размах - разность между максимальным и минимальным

значением выборки,

• стандартное отклонение - среднее квадратичное отклонение

равное корню квадратному из дисперсии выборки,

• медиана - значение, лежащее в середине выборки

упорядоченной по возрастанию или убыванию. Другими

словами медиана делит выборку пополам; одна половина

выборки имеет значения меньше медианы, другая - больше. В

случае четного числа значений выборки, медиана

рассчитывается как среднее арифметическое двух значений

ближайших к центру выборки.

Для дискретных данных рассчитывается:

• количество значений - общее количество значений,

присутствующих в исходной выборке,

• количество уникальных значений - количество уникальных

значений, присутствующих в исходной выборке,

• мода - значение, наиболее часто встречающееся в исходной

выборке. В выборке могут быть два или более значения, с

максимальной частотой (би- или мультимодальная выборка).

В этом случае в качестве моды будет взято первое найденное

значение с максимальной частотой.

Кроме того, для дискретных значений рассчитывается таблица частот, содержащая следующие показатели:

• частота - количество вхождений уникального значения в

выборку,

• относительная частота - частота, выраженная в процентах

от общего количества значений выборки,

• накопленная частота - сумма частоты значения и частот всех

предыдущих значений выборки,

• накопленная относительная частота - сумма относительной

частоты и относительных частот всех предыдущих значении

выборки.

При выводе отчета при помощи построителя отчета анализа данных, будет создана круговая диаграмма по относительной частоте значений в выборке.

Типы колонок источника данных:

• Не используется - колонка не участвует в анализе,

• Входная - содержит исходные данные для анализа.

Параметры анализа данных при общестатистическом анализе не задаются.

Пример

В

качестве примера общестатистического анализа рассмотрим анализ данных, содержащихся в регистре накопления «Продажи». Для анализа выберем все записи регистра, в которых нас будут интересовать значение ресурсов «Сумма», «Количество» и значение измерения «Контрагент».

Допустим, мы будем иметь следующие исходные данные для

анализа:

 

Результат анализа будет выглядеть следующим образом:

Общая статистика

Информация о данных

Количествообьектов:    20

Непрерывные поля

Дискретные поля Контрагент

Количество значений:    20

Количествоуникальных значений;    6

Мода:    Федоров Д.Е.

 

Диаграмма частот

Таблица частот

 

Поиск ассоциаций

Т

ип анализа АнализДанныхПоискАссоциаций предназначен для поиска часто встречаемых вместе групп объектов или значений характеристик, а также выполняет поиск правил ассоциаций. Этот тип анализа может использоваться для определения часто приобретаемых вместе товаров или услуг.

Типы колонок источника данных:

• Не используется - колонка не используется в анализе.

• Объект - колонка содержит объект, например документ

«Оказание услуги».

• Элемент - колонка содержит элемент, например

номенклатуру из документа «Оказание услуги».

Параметры:

• МинимальныйПроцентСлучаев - (Число) - минимальный

процент случаев, в которых наблюдается группа элементов.

Найденные группы, у которых процент случаев меньше, в

отчет включены не будут.

• МинимальнаяДостоверностъ - (Число) - минимальная

достоверность правила. Найденные правила, у которых

достоверность меньше, в отчет включены не будут.

• МинималънаяЗначимостъ - (Число) - минимальная

значимость правила. Найденные правила, значимость которых

меньше, в отчет включены не будут. Значимость правила -

величина, характеризующая насколько правило важно. Чем

выше значимость, тем интересней правило.

• ПоискПоИерархии - (Булево) - необходимость поиска по

иерархии. При помощи этого параметра можно указать

анализу, что необходимо искать ассоциации не только среди

элементов, но и среди групп.

• ТипОтсеченияПравил - (избыточные, покрытые) - тип

отсечения найденных правил. Избыточные - отсекать

избыточные правила, покрытые - отсекать правила, покрытые

другими правилами.

• ТипИсточникаДанных - (объектный, событийный) - тип

источника данных. Анализ работает с двумя типами

источника. Объектный - каждая строка источника содержит

В

объект с его характеристиками. Событийный - источник данных содержит список событий. Например, состав документа «Оказание услуги».

ИспользованиеЧисловыхЗначений ~ (как булево, как число) как интерпретировать числовые значения. Можно интерпретировать числовые значения как числа или как логические значения, т.е. рассматривать ноль как Ложь, а все остальные ненулевые значения как Истина. ИгнорироватьНезаполненныеЗначения ~ (Булево) - Как использовать незаполненные значения. Т.е. игнорировать их

или нет.

Порядок - (по достоверности, по значимости, по количеству случаев) - определяет порядок отображения данных в результате анализа.

 

Пример

качестве примера возьмем данные регистра «Продажи»: поле «Регистратор» и измерение «Номенклатура»:

 

 

Результат анализа будет выглядеть следующим образом:

Поиск ассоциативных правил

Параметры анализа

Минимальный процент случаев:

Минимальнаядостоверность:    60

Минимальная значимость:    0

Отсечениеправил:    Избыточные

Колонки источника данных Входные колонки

 

Информация о данньк

Количество элементов:    12

Количество обьектов:    11

Средиее количество элементов в объекте:    1,82

Результат анализа

Найдено часто встречаемых групп:    4

Найдено ассоциативных правил:    5

 

Часто встречаемые группы

 

Поиск последовательностей

Т

ип анализа АнализДанныхПоискПоследовательностей предназначен для выявления в источнике данных последовательных цепочек событий. Например, это может быть цепочка услуг, которые часто последовательно заказывают клиенты.

Поддерживается поиск по иерархии, что позволяет отслеживать не только последовательности конкретных событий, но и последовательности родительских групп.

Набор параметров анализа позволяет ограничивать временные расстояния между элементами искомых последовательностей, а также регулировать точность получаемых результатов.

Типы колонок источника данных:

• Не используется - колонка не используется в анализе.

• Элемент - колонка содержит исследуемый элемент.

Например, в случае исследования продаж, это может быть

колонка, содержащая товар.

• Последовательность    -    колонка    содержащая

последовательности. Например, это может быть контрагент.

• Время - время события.

Параметры:

• МинимальныйПроцентСлучаев - (Число) - минимальное

число последовательностей, в которых должен наблюдаться

шаблон последовательности.

• ПоискПоИерархии - (Булево) - необходимо ли осуществлять

поиск по иерархии.

• МинимальныйИнтервал - (Булево) - признак того, что

установлен минимальный интервал между наблюдаемыми

событиями. Установка минимального интервала означает, что

для того, чтобы элементы попали в искомую

последовательность необходимо, чтобы временной интервал

между элементами был не менее установленного.

• ЕдиницаМинимальногоИнтервала - единица минимального

интервала

 

В

КратностъМинималъногоИнтервала - (Число) - кратность минимального интервала

МаксималъныйИнтервал - (Булево) - признак того, что установлен максимальный интервал между наблюдаемыми событиями. Установка максимального интервала означает, что для того, чтобы элементы попали в искомую последовательность необходимо, чтобы временной интервал между элементами был не более установленного. ЕдиницаМаксималъногоИнтервала - единица максимального интервала

КратностъМаксималъногоИнтервала - (Число) - кратность максимального интервала

ИнтервапЭквивалентностиВремени - (Булево) - признак того, что установлен интервал эквивалентности времени между наблюдаемыми событиями. Если установлен интервал эквивалентности времени, то события, временной интервал

между которыми меньше интервала эквивалентности времени

считаются произошедшими в одно время.

ЕдиницаИнтервалаЭквталентностиВремени — единица

интервала эквивалентности времени

КратностьИнтервалаЭквталентностиВремени - (Число) -

кратность интервала эквивалентности времени

Минимальная длина - (Число) - минимальная длина

последовательности.

Порядок - (по длине, по количеству случаев) - определяет

порядок отображения данных в результате анализа.

 

Пример

качестве примера снова возьмем данные регистра «Продажи»: измерения «Номенклатура», «Контрагент» и поле «Период»:

 

 

Результат анализа будет выглядеть следующим образом:

Поиск последовательностей

Параметры анализа

Минимальный процент случаев:    10

Минимальный интервал:

Максимальный интервал:

Интервал эквивалентности времени:

Минимальная длина последовательности:    2

Информация о данных

Количество элементов:    12

Количество последовательностей:    6

Результат анализа

Найдено последовательностей:    2

Последовательности

 

Дерево решений

Т

ип анализа АнализДанныхДеревоРешении дерево решений позволяет построить иерархическую структуру классифицирующих правил, представленную в виде дерева.

Для построения дерева решений необходимо выбрать целевой атрибут, по которому будет строиться классификатор и ряд входных атрибутов, которые будут использоваться для создания правил. Целевой атрибут может содержать, например информацию о том, перешел ли клиент к другому поставщику услуг, удачна ли была сделка, качественно ли была выполнена работа и т.д. Входными атрибутами, для примера, могут выступать возраст сотрудника, стаж его работы, материальное состояние клиента, количество сотрудников в компании и т.п.

Результат работы анализа представляется в виде дерева, каждый узел которого содержит некоторое условие. Для принятия решения к

 

какому классу следует отнести некий новый объект, необходимо отвечая на вопросы в узлах пройти цепочку от корня до листа дерева, переходя к дочерним узлам в случае утвердительного ответа и к соседнему узлу в случае отрицательного.

Набор параметров анализа позволяет регулировать точность полученного дерева.

Типы колонок источника данных:

• Неиспользуемая - колонка не используется в анализе,

• Входная - колонка будет использоваться как атрибут для

создания узлов дерева, содержит характеристику

исследуемого объекта.

• Прогнозируемая - колонка, содержащая классификацию.

Например - признак того, что контрагент перешел к другому

поставщику.

Параметры:

• МинимальноеКоличествоСлучаев - (Число) - минимальное

количество случаев в узле.

• МаксимальнаяГлубина - (Число) - максимальная глубина

дерева.

• ТипУпрощения - (не упрощать, упрощать) - тип упрощения

дерева решений. Упрощать или не упрощать построенное

дерево решений.

Пример

Н

а этот раз мы проанализируем данные справочника

«Контрагенты». В качестве входных колонок мы используем

поля    реквизитов    справочника

«КоличествоРозничныхТочек»,    «КоличествоАвтомобилей»

«ВремяРаботыОрганизации» и «ВремяЗаключенияДоговора»' Прогнозируемой колонкой будет поле реквизита справочника «Контрагенты» - «ПрекращениеОтношений».

 

 

Результат анализа будет иметь следующий вид:

Дерево решений

Параметры анализа

Минимальноеколичествоэлементов вузле:    0

Максимальная глубина дерева:    1 000

Тип упрощения дерева решений:    Упрошать

Колонки источника данных Входные колонки

 

Имя колонки Тип данных Количест в оРозничныхТочек Непреры в ный Количест во А в томобилей Непрерывный ВремяРаботыОрганизации Дискретный ВремяЗаключенияДоговора Дискретный Прогнозируемые колонки

 

Имя колонки Тип данных ПрекрашениеОтношений Дискретный

 

 

Информация о данных

Количество объектов Количество классов:

Результат анализа

Глубина дерева решений: Количество внутренних узлов: Количество листьев' Ошибка, %:

 

ч 3

3 2

3

11,11

 

Дерево решений

 

 

Ошибки кпассиФикзции

Кластерный анализ

Т

ип анализа АнализДанныхКластеризация позволяет разделить исходный набор исследуемых объектов на группы объектов, таким образом, чтобы каждый объект был более схож с объектами из своей группы, чем с объектами других групп. Анализируя в дальнейшем полученные группы, называемые кластерами, можно определить, чем характеризуется та или иная группа, принять решение о методах работы с объектами различных групп.

Например, при помощи кластерного анализа можно разделить клиентов, с которыми работает компания на группы, для того, чтобы применять различные стратегии при работе с ними.

При помощи параметров кластерного анализа аналитик может настроить алгоритм, по которому будет производиться разбиение, а также может динамически изменять состав характеристик, учитываемых при анализе, настраивать для них весовые коэффициенты.

Результат кластеризации может быть выведен в дендрограмму специальный объект, предназначенный для отображения последовательных связей между объектами.

 

Типы колонок источника данных:

• Не используется - колонка не используется при анализе.

• Входная - колонка используется для группирования объектов.

• Прогнозируемая - будет создан прогноз для значения колонки

для каждого кластера.

• ВходнаяИПрогнозируемая - колонка используется как

входная и как прогнозируемая.

• Ключ - ключевая колонка, предназначенная для

идентификации объекта.

Параметры:

• КоличествоКластеров - (Число) - количество искомых

кластеров.

• ТипЗаполненияТаблицы - (все поля, используемые поля,

ключевые поля, не заполнять) - какие поля выводить в таблицу

кластеризации.

• Стандартизация - (не стандартизировать, стандартизировать) -

необходимость стандартизации данных. Если необходимо

стандартизировать данные, то анализатор предварительно

приведет все характеристики объектов к одной весовой

категории.

• МераРасстояния -    (ЕвклидоваМетрика,

ЕвклидоваМетрикаВКвадрате,    МетрикаГорода,

МетрикаДоминирования) - каким    образом вычислять

расстояние между объектами.

• МетодКластеризации - (БлижняяСвязь, ДальняяСвязь,

КСредних, ЦентрТяжести) - каким    методом выполнять

кластеризацию.

Пример

д

ля анализа мы возьмем те же поля справочника «Контрагенты», что и в предыдущем примере: «КоличествоРозничныхТочек», «КоличествоАвтомобилей»,

 

 

«ВремяРаботыОрганизации» «ПрекращениеОтношений». значение поля «Ссылка»:

«ВремяЗаключенияДоговора» и В качестве ключа мы используем

 

Центры кластеров

 

 

 

 

Результат анализа будет выглядеть следующим образом:

 

Расстояния между кластерами

 

Кластерный анализ

Денрограмма связей

 

 

Параметры анализа

Количество искомых кластеров:    3

Стандартизация:    Стандартизировать

Мера расстояния:    Евклидова метрика в квадрате

Метод кластеризации:    Метод центра тяжести

Колонки источника данных Входные колонки

 

Информация о данных

Количествообъектов:    9

Результат анализа

Найденокластеров:    3

 

 

Модель прогноза

О

бъект модель прогноза представляет собой специальный объект, который создается из результата анализа данных, и позволяет в дальнейшем строить прогнозы для новых данных.

Например, модель прогноза поиска ассоциаций, созданная при анализе покупок клиентов, может быть использована при работе с осуществляющим покупку клиентом, для того, чтобы предложить ему товары, которые он с определенной степенью вероятности приобретет вместе с теми товарами, которые он уже выбрал.

Объект Модель прогноза можно получить из соответствующих объектов результат анализа путем выполнения метода СоздатьМодельПрогноза().

 

 

 

В дальнейшем для модели прогноза можно задать некоторый набор исходных данных и получить результат прогноза в виде таблицы значений.

Источник данных для модели прогноза задается при помощи свойства ИсходныеДанные, а для получения результата прогноза необходимо выполнить метод Выполнить().

Используя соответствующие свойства модели прогноза можно настраивать для нее входные колонки, колонки самой модели и колонки результата.

Кроме этого каждая из моделей прогноза содержит дополнительные свойства, определяемые типом анализа, к которому относится модель прогноза.

Пример

В

качестве примера мы рассмотрим использование модели прогноза данных при оформлении покупки, выполняемой контрагентом.

Предположим, что периодически проводится анализ данных базы типа поиск ассоциаций, и сохраняется актуальная модель прогноза.

Тогда, при формировании расходной накладной контрагента, мы можем использовать эту модель прогноза для того, чтобы исходя из состава расходной накладной, предложить контрагенту дополнительные товары, которые он, с большой долей вероятности, может приобрести.

Предположим, контрагент оформляет следующую покупку:

 

Тогда менеджер, нажав на кнопку «Предложение», может откры список товаров, которые, с большой долей вероятности, также имеет смысл предложить этому клиенту:

 

Построитель отчета анализа данных

О

бъект ПостроительОтчетаАнализаДанных позволяет представить данные анализа в виде табличного документа. Структура такого табличного документа определяется типом анализа, для каждого из типов анализа документ будет содержать определенный набор областей.

Объект    ПостроительОтчетаАнализаДанных    может

использоваться для выполнения трех различных задач.

Во-первых, для визуального отображения существующего результата анализа данных.

Во-вторых, для интерактивной настройки параметров анализа данных, выполнения анализа и отображения полученного результата. В-третьих, для настройки параметров модели прогноза.

Отображение существующего результата анализа

О

бъект ПостроительОтчетаАнализаДанных может быть использован для отображения результата анализа данных, который был получен ранее. Для этого можно с помощью стандартного конструктора создать новый объект ПостроительОтчетаАнализаДанных и в методе Вывести() передать ему существующий результат анализа:

 

Результат анализа

 

Построитель = Новый ПостроителъОтчетаАнализаДанных; Построитель.Вывести(РезультатАнализа, ТабличныйДокумент);

Настройка параметров и выполнение анализа

О

бъект ПостроительОтчетаАнализаДанных может быТь использован для выполнения анализа с интерактивной настройкой параметров и последующего отображения результата.

Исходные данные для анализа задаются свойством ИсточникДанных. Свойства НастройкаКолонок и Параметры позволяют интерактивно настраивать колонки анализа (через табличные поля), и задавать параметры для выбранного типа анализа который задается свойством ТипАнализа. Кроме того, построитель отчета анализа данных допускает переопределение стандартного макета отчета путем использования свойства Макет.

В дальнейшем методом Выполнить() можно получить результат анализа данных, который будет доступен через свойство построителя Результат. Таким образом, при необходимости, его можно сохранить в базе данных. Если же сохранения результата не требуется, можно выполнить метод Вывести(), который выведет данные результата анализа, полученного методом Выполнить().

Кроме    всего    перечисленного,

ПостроительОтчетаАнализаДанных позволяет получить объект АнализДанных, соответствующий всем интерактивным настройкам, выполненным в построителе, методом ПолучитьАнализ():

 

Настройка параметров модели прогноза

 

 

О

бъект ПостроительОтчетаАнализаДанных может быть использован для интерактивной настройки параметров модели прогноза (через табличные поля). Для этого следует использовать его свойство МодельПрогноза, в которое передается настраиваемая модель. После того, как настройка модели выполнена, результат прогноза может быть получен методом модели прогноза Выполнить():

 

 

 

Что нового мы узнали

- чем анализ данных отличается от прогнозирования - какие объекты встроенного языка обеспечивают работу механизма анализа данных

-    какие объекты встроенного языка обеспечивают работу

механизма прогнозирования данных

- какие типы анализа данных реализованы в платформе

- как работать с моделью прогноза - что такое построитель отчета анализа данных

-    как получить визуальное представление результата

анализа данных

- как настроить параметры модели прогноза

 

Глава 15. Создание документа ввода начальных остатков

В нашей информационной базе, как, впрочем, и в любой другой, обязательно следует предусмотреть возможность ввода начальных остатков в регистры. Это необходимо для того, чтобы пользователи могли начать работу с нашей информационной базой не с «чистого листа», а с некоторого «исходного состояния», которое было в их прежней системе учета (пусть даже они вели учет на бумаге).

Задача ввода начальных остатков отличается от прочих алгоритмов изменения состояния регистров нашей информационной базы тем, что подразумевает изменение данных непосредственно в регистрах, без использования каких-либо промежуточных алгоритмов (заполнения документов данными, проведения документов, контроля правильности данных, указанных в документах и пр.).

Рассмотрим пример ввода начальных остатков регистра накопления «ОстаткиМатериалов». Для выполнения этой задачи мы создадим документ, в котором будем вручную редактировать его движения по регистру «ОстаткиМатериалов» прямо в форме документа.

Откроем конфигуратор и создадим новый объект конфигурации Документ с именем «ВводНачальныхОстатковНоменклатуры». На закладке «Движения» запретим проведение документа (поскольку сами будем формировать записи регистра), и отметим, что движения документа будут находиться в регистре накопления «ОстаткиМатериалов». После этого перейдем на закладку «Формы» и создадим основную форму документа.

 

Раздвинем форму вниз и разместим в ней табличное поле

командной панелью. Зададим имя табличного поля

«ОстаткиМатериалов»    и    тип    значения

«РегистрНакопленияНаборЗаписей.ОстаткиМатериалов»:

Удалим из табличного поля колонки «Регистратор» и «Активность» (они нам не понадобятся), и изменим размеры формы и расположение элементов управления:

 

 

 

 

 

 

 

В свойствах табличного поля укажем, что источником данных для него будут являться движения документа по регистру «ОстаткиМатериалов»:

Запустим 1С:Предприятие в режиме отладки и проверим работу нашего документа.

Введем в документ следующие данные:

 

 

 

 

 

 

 

Обратите внимание на то, что дата документа не совпадает с датами отдельных записей, которые мы создаем в движениях документа.

 

Нажмем «Записать», и из формы списка документа откроем движения нашего документа в регистре «ОстаткиМатериалов» (кнопка «Перейти»).

Вы видите, что записи регистра накопления в точности соответствуют тем, которые мы создали в документе:

Снова запустим 1С:Предприятие в режиме отладки, откроем наш документ и нажмем «Записать». Открыв движения документа в регистре «ОстаткиМатериалов» увидим, что значение поля «Период» у всех записей стало равно дате документа:

 

 

 

 

 

 

 

Таким образом, мы добились поставленной цели: с одной стороны, задавая дату документа, мы можем фиксировать момент внесения изменений в записи регистра, с другой стороны - для каждой создаваемой нами записи регистра, мы можем указать индивидуальное значение поля «Период».

Теперь займемся «ужесточением» требований, предъявляемых к тому, как наш документ формирует записи регистра, и рассмотрим два типичных варианта.

Первое требование, которое мы реализуем, будет заключаться в том, что записи регистра должны формироваться той же датой, что и дата документа. Иначе говоря, синхронизируем дату движений с датой документа.

Для этого в обработчик события «Перед записью» формы документа добавим следующий текст:

Можно сказать, что мы достигли поставленной цели, но лишь в ситуации, когда запись документа выполняется интерактивными средствами.

Если программно вызвать метод Записать() у объекта нашего документа, он будет записан без участия формы документа. Это значит, что событие «При записи» формы документа вызвано не будет, и наш код обработчика не отработает.

Чтобы предусмотреть возможность синхронизации периода движений документа с датой документа и в случае программной записи объекта Документ, следует использовать обработчик события «Перед записью» объекта документ, а не формы документа.

Процедура ПередЗаписью(Отказ, РежимЗаписи, РежимПроведения)

Для Каждого ЗаписьРегистра Из Движения.ОстаткиМатериалов Цикл

ЗаписьРегистра.Период = Дата; КонецЦикла; КонецПроцедуры

 

 

Событие «Перед записью», в случае интерактивной запи документа, сначала будет вызвано у формы документа, а затем объекта документ (смотри схему событий в раздел «Последовательность событий при записи документа из форм документа» на странице 581). Поэтому вернемся в конфигуратоп удалим из модуля формы добавленный нами текст и создадим обработчик события «Перед записью» в модуле объекта документ:

Процедура ПередЗаписью(Отказ, РежимЗаписи, РежимПроведення) //Определить нужно ли обновлять дату в движениях

ОбновитьДатуДвижений = ЭтоНовый() Или

Движения.ОстаткиМатериалов.Модифицированность(); Если Не ОбновитьДатуДвижений Тогда // Проверить, что дата изменилась

Запрос = Новый Запрос;

Запрос.УстановитьПараметр("ТекущийДокумент", Ссылка);

Запрос.Текст =

"ВЫБРАТЬ

| Дата

|ИЗ

| Документ.ВводНачальныхОстатковНоменклатуры

|ГДЕ Ссылка = &ТекущийДокумент";

Выборка = Запрос.Выполнить().Выбрать(); Выборка.СледующийО;

ОбновитьДатуДвижений = Выборка.Дата о Дата; КонецЕсли;

//Установить всем новую дату, если нужно

Если ОбновитьДатуДвижений Тогда Если Не Движения.ОстаткиМатериалов.Выбран() И

Не Движения.ОстаткиМатериалов.Модифицированность() Тогда Движения.ОстаткиМатериалов.Прочитать(); КонецЕсли; Для Каждого ЗаписьРегистра Из Движения.ОстаткиМатериалов Цикл

ЗаписьРегистра.Период = Дата; КонецЦикла; КонецЕсли;

Как вы видите, в этом случае обработчик содержит больше кода за счет дополнительных проверок, которые выполняются в результат того, что возможна как интерактивная, так и программная запис объекта.

Поясним содержание обработчика. Если записывается новый документ или были изменены его движения - следует обновить дату движений. В противном случае мы считываем запросом дату документа из базы данных и сравниваем ее с датой, установленной у записываемого объекта. Если даты разные - также следует обновить дату движений.

Перед установкой даты мы проверяем, был ли прочитан набор записей в свойстве «Движения» объекта и изменялся ли он. Если оба этих условия ложны - это значит, что набор записей в свойстве «Движения» объекта пуст, и это состояние не связано с его изменением. В этом случае, чтобы предотвратить ошибочное удаление записей в регистре (перезапись пустым набором записей), мы предварительно читаем движения из регистра в набор записей в свойстве «Движения». Затем, как и в предыдущем случае, устанавливаем нужную дату для всех записей этого набора. При выполнении записи объекта Документ, этот набор будет записан в регистр накопления.

Запустим 1С:Предприятие в режиме отладки и убедимся, что указав новую дату для нашего документа и записав его, мы получим движения в регистре накопления с новой датой.

В процессе записи нашего документа можно управлять не только периодом записей регистра накопления, но и значениями других полей регистра.

Например, по аналогичному принципу может быть создан документ «Операция», позволяющий вводить ручные операции в регистр бухгалтерии. При этом, вероятно, кроме управления периодом записей регистра, вам потребуется управлять значением поля «Активность» («включать» и «выключать» проводки документа) и т.д.

В заключение следует сказать, что выбор обработчика, в котором будет размещен текст процедуры, зависит от логики работы создаваемого объекта. Если конфигурация не предусматривает программной записи объекта - можно выбрать обработчик модуля формы. Если предполагается и программная модификация объекта -следует выбирать обработчик модуля объекта.

Заметьте, что оба эти способа не исключают модификацию записей регистра через объект Регистр<...>НаборЗаписей.<имя регистра>. Поэтому, если логика конфигурации подразумевает возможность программной модификации объекта набор записей, код обработки

 

следует размешать в обработчике события набора записей. Все попытки изменить данные регистра будут сведены, в конечном счете, к записи именно набора записей.

 

Глава 16. Легким движением брюки превращаются...

Вот мы и создали с вами небольшое прикладное решение, которое позволило автоматизировать работу нашей ремонтной фирмы OOO «На все руки мастер». Теперь настало время для одного чудесного превращения.

Дело в том, что наше прикладное решение настолько понравилось сотрудникам OOO «На все руки мастер», что они рассказали о нем своим соседям - косметическому салону «Королева красоты». Сотрудники салона посмотрели, как работает наше прикладное решение, и обратились к нам с просьбой автоматизировать и их салон тоже.

И мы, конечно же, с радостью согласились, по одной простой причине: мы с вами создали универсальную конфигурацию, подходящую для автоматизации практически любой деятельности, связанной с оказанием услуг.

Все, что нам осталось теперь сделать, чтобы наша конфигурация смогла работать в косметическом салоне, - просто создать новую информационную базу с нашей конфигурацией, и заполнить ее новыми данными, - сотрудниками и новой номенклатурой. Все механизмы учета, которые мы с вами создавали, не были привязаны к какой-либо специфике конкретного предприятия, а потому могут с успехом использоваться на любом другом предприятии, имеющем аналогичную область деятельности.

Таким образом, даже если в косметическом салоне пожелают иметь дополнительную функциональность, нам потребуется всего лишь дописать несколько модулей к нашей конфигурации, что гораздо эффективнее, чем создавать заново индивидуальное решение только для данного предприятия.

 

 



  Copyright © 2007 Udex.Ru

Hosted by uCoz