1С-Предприятие 8.0. Практическое пособие разработчика

       

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


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

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

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

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

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

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

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

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



       Возврат;

   КонецЕсли;

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

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

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

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

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

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

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

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

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

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

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

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

       Возврат;

   КонецЕсли;

   //*** Чтение документов XML

   // Попытаться открыть файл

   ЧтениеXML = Новый ЧтениеXML;

   Попытка

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




   Исключение

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

       Возврат;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

       Возврат;

   КонецЕсли;

   //*** Чтение документов XML

   // Попытаться открыть файл

   ЧтениеXML = Новый ЧтениеXML;

   Попытка

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

   Исключение

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



       Возврат;

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

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

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

   // Загрузить из найденного файла

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

       Возврат;

   КонецЕсли;

   //*** Чтение документов XML

   // Попытаться открыть файл

   ЧтениеXML = Новый ЧтениеXML;



   Попытка

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

   Исключение

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

       Возврат;

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

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

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

   // Загрузить из найденного файла

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

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

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

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

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

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

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

   КонецЕсли;

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

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

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

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

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

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

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

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

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

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

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



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

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

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

       Возврат;

   КонецЕсли;

   //*** Чтение документов XML

   // Попытаться открыть файл [414]

   ЧтениеXML = Новый ЧтениеXML;

   Попытка

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

   Исключение

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

       Возврат;

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

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

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

   // Загрузить из найденного файла

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

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

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

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

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

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

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

   КонецЕсли;

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

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

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

   ПланыОбмена.УдалитьРегистрациюИзменений(

       ЧтениеСообщения.Отправитель, ЧтениеСообщения.НомерПринятого);

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

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

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

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

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

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



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

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

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

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

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

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

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

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

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

       Возврат;

   КонецЕсли;

   //*** Чтение документов XML

   // Попытаться открыть файл

   ЧтениеXML = Новый ЧтениеXML;

   Попытка

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

   Исключение

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

       Возврат;

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

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

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

   // Загрузить из найденного файла

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

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

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

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

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

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

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

   КонецЕсли;

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

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

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



   ПланыОбмена.УдалитьРегистрациюИзменений(

       ЧтениеСообщения.Отправитель, ЧтениеСообщения.НомерПринятого);

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

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

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

   КонецЦикла;

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

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

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

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

КонецПроцедуры [416]

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

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

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

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

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

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

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

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

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

       Возврат;

   КонецЕсли;

   //*** Чтение документов XML

   // Попытаться открыть файл

   ЧтениеXML = Новый ЧтениеXML;

   Попытка

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

   Исключение

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



       Возврат;

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

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

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

   // Загрузить из найденного файла

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

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

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

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

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

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

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

   КонецЕсли;

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

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

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

   ПланыОбмена.УдалитьРегистрациюИзменений(

       ЧтениеСообщения.Отправитель, ЧтениеСообщения.НомерПринятого);

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

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

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

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

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

   КонецЦикла;

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

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

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

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

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

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

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

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

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

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



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

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

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

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

       Возврат;

   КонецЕсли;

   //*** Чтение документов XML

   // Попытаться открыть файл

   ЧтениеXML = Новый ЧтениеXML;

   Попытка

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

   Исключение

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

       Возврат;

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

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

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

   // Загрузить из найденного файла

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

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

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

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

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

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

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

   КонецЕсли;

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

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

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

   ПланыОбмена.УдалитьРегистрациюИзменений(

       ЧтениеСообщения.Отправитель, ЧтениеСообщения.НомерПринятого);

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

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

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



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

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

       // Не переносим изменение полученное в главный из неглавного

       // если есть регистрация изменения

       Если Не ЧтениеСообщения.Отправитель.Главный И

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

           Сообщить("- Изменения отклонены");

           Продолжить;

       КонецЕсли;

   КонецЦикла;

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

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

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

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

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

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

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

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

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

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

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

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

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

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



       Возврат;

   КонецЕсли;

   //*** Чтение документов XML

   // Попытаться открыть файл

   ЧтениеXML = Новый ЧтениеXML;

   Попытка

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

   Исключение

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

       Возврат;

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

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

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

   // Загрузить из найденного файла

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

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

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

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

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

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

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

   КонецЕсли;

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

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

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

   ПланыОбмена.УдалитьРегистрациюИзменений(

       ЧтениеСообщения.Отправитель, ЧтениеСообщения.НомерПринятого);

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

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

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

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

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

       // Не переносим изменение полученное в главный из неглавного

       // если есть регистрация изменения

       Если Не ЧтениеСообщения.Отправитель.Главный И



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

           Сообщить("- Изменения отклонены");

           Продолжить;

       КонецЕсли;

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

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

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

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

   КонецЦикла;

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

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

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

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

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

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

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

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


Содержание раздела