Текст
                    Д.И.Гончаров
Е. Ю. Хрусталева
Технологии
интеграции
«1C:Предприятия 8.2»
Москва
2011


УДК 658.012.011.56:004.42 ББК 65.29 Г65 Г65 Гончаров Д. И. Технологии интеграции «1С:Предприятия 8.2» / Д. И. Гончаров, Е. Ю. Хрусталева. - М.: ООО «1С-Паблишинг», 2011. - 358 е.: ил. - (Профессио- нальная разработка). ISBN 978-5-9677-1462-7 Данная книга посвящена углубленному изучению вопросов создания и модификации при- кладных решений на платформе системы «1С:Предприятие 8.2». Она является частичной перера- боткой популярной книги «Профессиональная разработка в системе "1С:Предприятие 8"». В книгу включены материалы, которые описывают механизмы «1С:Предприятия 8.2», пред- назначенные для обмена данными в распределенных системах, а также механизмы и технологии, позволяющие интегрировать прикладные решения с другими информационными системами, не использующими «1С:Предприятие». Книга является очередным изданием серии «1С:Профессиональная разработка», в которой уже вышли пособия «Реализация прикладных задач в системе "1С:Предприятие 8.2"» и «Разработка управляемого интерфейса». Другие вопросы разработки планируется рассмотреть в следующих книгах, выпускаемых в этой серии. Все рассматриваемые в книге примеры адаптированы для использования с версией платформы «1С:Предприятие 8.2» в режиме управляемого приложения. Кроме этого, описание механизмов дополнено новыми возможностями, появившимися в версиях платформы 8.1 и 8.2. Книга рассчитана на разработчиков, обладающих некоторым навыком создания и модифика- ции прикладных решений в системе «1С:Предприятие 8.2» и желающих повысить свой профес- сиональный уровень. Также книга будет интересна IT-специалистам, не занимающимся разработкой, но желаю- щим получить представление о возможностях системы, ее идеологии, архитектуре и реализации конкретных механизмов. В помощь разработчикам прикладных решений книга содержит компакт-диск с демонс- трационными конфигурациями, используемыми в книге. Все конфигурации созданы на версии платформы 8.2.13.205. Книга выпущена под редакцией Максима Радченко. Группа подготовки издания: Дизайн обложки - Кира Федотова. Литературное редактирование, корректура - Елена Семененко. Верстка, препресс - Ольга Шестакова. ISBN 978-5-9677-1462-7 Все права защищены. Никакая часть данной книги не может быть вос- произведена в какой бы то ни было форме без письменного разрешения владельцев авторских прав. Полное или частичное копирование материалов книги без письменно- го разрешения фирмы «1С-Паблишинг» запрещается. ISBN 978-5-9677-1462-7 © ООО «ic-паблишинг», 2011 © Оформление. ООО «1С-Паблишинг», 2011 Подписано в печать 16.02.2011. Формат 60x84 1/16. Печ. л. 22,375. Тираж 5 000 экз. Заказ 3-531. Отпечатано с оригиналов ООО «1С-Паблишинг». Фирма «1С». 123056, Москва, а/я 64, Селезневская ул., 21. Тел.: (495) 737-92-57, факс: (495) 681-44-07, lc@lc.ru, http://www.lc.ru Издательство ООО «1С-Паблишинг». 127473, Москва, ул. Достоевского, 1/21, строение 1. Тел.: (495) 681-02-21, факс: (495) 681-44-07, publishing@lc.ru Казанский производственный комбинат программных средств. 420044, Казань, ул. Ямашева, 36.
Оглавление Что находится на компакт-диске 8 Форматы файлов обмена 12 Работа с текстом 13 Работа с форматированным документом 22 Работа с DBF 25 Работа с XML-документами 30 XDTO-сериализация 66 Пример реализации обмена при разной структуре объектов конфигурации 69 Работа с ZIP-архивами 78 Использование интернет-технологий 86 Работа с HTML 87 Использование FTP 94 Работа с электронной почтой 97 Automation 106 Automation Server 107 Automation Client Ш
Внешнее соединение 113 Использование внешнего соединения для интеграции с интернет-приложением 116 ActiveDocument 131 Внешние компоненты 134 Подключение внешнего компонента в толстом клиенте или на сервере (на примере Native API компонента) 135 Подключение внешнего компонента в тонком клиенте или в веб-клиенте (на примере Native API компонента) 136 Web-сервисы 137 Предоставление функциональности через Web-сервисы 138 Работа с Web-сервисами сторонних поставщиков 143 Пример реализации механизма Web-сервиса 143 Планы обмена 157 Служба регистрации изменений 160 Инфраструктура сообщений 176 Универсальный механизм обмена данными 180 Использование возможностей работы с XML-документами 180 Пример реализации универсального обмена 183 Регистрация в произвольные узлы 204 Пример работы универсального обмена данными 206 Распределенные информационные базы 208 Общие принципы 209 Главный и подчиненный узлы 212 Сообщение обмена данными в распределенной информационной базе 213 Создание узла распределенной информационной базы 215 Запись и чтение сообщений обмена 221 Подготовка конфигурации к работе в распределенной информационной базе 223 Пример работы обмена данными в распределенной информационной базе 226 Сценарии обмена данными в распределенной информационной базе 228 Разрешение коллизий 231 Восстановление узла распределенной информационной базы из резервной копии 233 Особенности использования последовательности документов в распределенной информационной базе 234 Использование транзакций при организации обмена 236 Методика включения в сообщение обмена дополнительной информации 238 Организация одностороннего обмена 241 Примеры реализации автоматического обмена данными 243
Использование регламентных заданий 243 Использование объекта СОМСоединение 245 Основные положения 251 ADO.NET 253 ASP.NET 255 Конструкторы Web-расширения для веб-приложений 269 VSListForm 272 V8 Item Form 296 V8 Report Form 304 V8ChartForm 315 Доступ к данным 4epe3ADO.NET 318 Получение данных 319 Добавление данных 324 Изменение данных 326 Удаление данных 329 Web-сервисы 330 Обращение к Web-сервису из веб-формы 335 Вызов процедур, функций. Преобразование типов 336 Настройка прав доступа 339 Идентификация пользователя 340 Файл Web.config 340 Файл global.asax 342 Форма, используемая для авторизации на основе форм 343 Работа с метаданными 345 Пул соединений 346 Полезные средства .NET Framework 349 Объект Response 349 Объект Request 351 Объект Session 351 Подготовка веб-приложения к работе 352 Состав файлов 353 Параметры автоформ 354 Форма списка (DefaultListForm) 354 Форма элемента объектной таблицы (DefaultObjectForm) 356 Форма записи регистра (DefaultRecordForm) 357 Форма строки табличной части (DefaultLineForm) 358
Введение В книге собрана и систематизирована наиболее важная информация, которая может понадобиться разработчику прикладных решений «^Предприя- тия 8.2». Несмотря на то, что в одной книге невозможно рассмотреть все ситуации, возникающие при разработке прикладных решений, на большинство вопросов в книге можно найти ответы. Причем читать будет одинаково интересно как начинающим, так и продвинутым разработчикам. При написании мы стремились к тому, чтобы книга стала серьезным инстру- ментом для разработчиков: к ней всегда можно было бы обратиться в случае затруднений, узнать что-то новое о хорошо известной предметной области или познакомиться с новым взглядом на привычные вещи. При подготовке материала были использованы различные источники инфор- мации: • опыт преподавания на учебных курсах по платформе и прикладным реше- ниям «1С:Предприятия 8»; • опыт внедрения прикладных решений; • опыт, накопленный разработчиками фирмы «1С»; • материалы информационно-технологической поддержки (ИТС); • материалы форума партнеров-разработчиков на сайте http://partners.v8.lc.ru; • общение на партнерских семинарах, проводимых фирмой «1С».
Что находится на компакт-диске К книге прилагается компакт-диск, который содержит пять демонстраци- онных конфигураций, предназначенных для самостоятельного изучения и использования: • конфигурация «Интеграция с другими информационными системами»; • конфигурация «Пример внешнего соединения»; • конфигурация «Web-сервисы»; • конфигурация «Web-сервисы (использование)»; • конфигурация «Пример обмена». Все демонстрационные конфигурации содержатся на компакт-диске в виде дистрибутива. После запуска исполняемого файла шаблоны конфигураций устанавливаются в текущий каталог шаблонов. Конфигурации созданы в версии «1С:Предприятия» 8.2.13.205.
Глава 1. Интеграция с другими информационными системами Очень часто при решении задач комплексного учета возникает необходимость в рамках одного программного комплекса использовать возможности другого программного комплекса, проводить обмен данными между различными системами и т. п. Это может быть обусловлено спецификой автоматизируемых задач, особенностями структуры автоматизируемой компании (организации) и массой других причин. К примеру, при необходимости работы с каким-либо оборудованием «общение» с ним производится через специализированную программу (драйвер). В компании может быть принято оформлять договоры в формате программы Microsoft Word. В связи с этим возникает необходимость работы с данной программой, хранения полученных документов в информационной базе. При организации обмена с такой же системой (информационной базой) или с другими возникает как задача формирования (и чтения) файла обмена, так и задача его доставки. На самом деле все подобные задачи не перечесть. Но возможность их решения определяет, насколько велик потенциал используемого програм- много комплекса по интеграции (организации совместной работы) с другими системами. Система «1С:Предприятие» является открытой. Предоставляется возмож- ность для интеграции практически с любыми внешними программами и оборудованием на основе общепризнанных открытых стандартов и прото- колов передачи данных.
В системе «1 С:Предприятие» имеется целый набор средств, с помощью которых можно: • создавать, обрабатывать и обмениваться данными различных форматов; • осуществлять доступ ко всем объектам системы «1С:Предприятие», реализующим ее функциональные возможности; • поддерживать различные протоколы обмена; • поддерживать стандарты взаимодействия с другими подсистемами; • разрабатывать собственные интернет-решения. Проведем краткий обзор технологий, которые могут использоваться платформой «1 С:Предприятия» при решении задач интеграции: Текстовые документы. Встроенный язык системы «1С:Предприятие» позволяет разработчику создавать, динамически формировать и записывать текстовые документы. Обмен данными с использованием текстовых доку- ментов может быть одним из менее «ресурсоемких» способов организации взаимодействия с другими информационными системами. Помимо обычных способов работы с текстовыми документами (чтение, запись, вставка и добавление строк, получение строк), разработчик имеет возможность динамического формирования текстовых документов на основе заранее созданных шаблонов. Текстовые файлы. Обмен с помощью текстовых файлов - наиболее простой механизм обмена данными. Он может быть использован для решения самых разнообразных задач. Его основное преимущество --- простота освоения и удобное текстовое представление информации. Форматированные документы. Форматированный документ предназначен для создания и редактирования текста различных форматов, содержащих оформление (картинки, текст, таблицы). XML-документы. Система «1С:Предприятие 8» позволяет организовывать интеграцию с прикладными системами с использованием XML-документов, являющихся на сегодняшний день общепринятым средством представления данных. DBF-файлы. Механизм работы с базами данных формата DBF предназначен для обеспечения возможности манипулирования ими непосредственно из встроенного языка системы «1С:Предприятие». Возможно практически любое манипулирование данными. Внешнее соединение. Основная задача, решаемая с помощью внешнего соединения, - обеспечение надежного и быстрого программного доступа к данным системы «1С:Предприятие 8» из внешних приложений. В общем
и целом работа с системой «1С:Предприятие» через внешнее соединение подобна работе с системой «1С:Предприятие» в режиме Automation- сервера. Существенное отличие заключается в том, что запускается вариант «1С:Предприятия», не содержащий интерфейсной части (подразумевается работа с данными только программными средствами, без использования интерфейсных возможностей). Automation Client/Server. Основное назначение Automation-сервера «^Пред- приятия 8» - управление приложением системы «1С:Предприятие» из других приложений и выполнение действий, аналогичных интерактивным действиям. HTML-документы. Средства работы с HTML-документами позволяют встраивать их в формы прикладного решения и выполнять редактирование средствами встроенного языка. Работа с файлами. «1С:Предприятие» средствами встроенного языка предо- ставляет доступ к функциям работы с файловой системой. Эта возможность может быть использована при организации взаимодействия с другими инфор- мационными системами через общие каталоги. Макеты ActiveDocument. Технология ActiveDocument предназначена для редактирования документов внешними по отношению к «^Пред- приятию 8» редакторами. Технология внешних компонентов. Технология создания внешних компо- нентов разработана для решения специальных задач интеграции, в которых требуется тесное взаимодействие между системой «1С:Предприятие 8» и другими программами. Работа с Интернетом. Работа с Интернетом возможна непосредственно из встроенного языка. Разработчик может выполнять отправку и прием писем электронной почты, а также осуществлять обмен данными по протоколам HTTP (HTTPS) и FTP. Web-расширение. Web-расширение является отдельным программным продуктом и позволяет встраивать доступ к данным «1С:Предприятия» в существующие веб-сайты и веб-приложения, а также создавать готовые веб- приложения, использующие информационную базу «1С:Предприятия». Обмен данными. Механизмы обмена данными, реализованные в технологи- ческой платформе «1С:Предприятия 8», позволяют создавать территориально распределенные информационные системы как на основе информационных баз «1С:Предприятия», так и с участием других информационных систем, не основанных на «1С:Предприятии».
Например, можно организовать работу главного офиса, филиалов и складов предприятия в единой информационной базе или обеспечить взаимодействие информационной базы «1 С:Предприятия» с существующей базой данных, например, MySQL. Web-сврвисы. Механизм Web-сервисов позволяет создавать Web-сервисы в конфигурации «1С:Предприятия 8», а также взаимодействовать в конфигу- рации «1С:Предприятия 8» с веб-сервисами, опубликованными сторонними поставщиками. XDTO. Механизм XDTO предназначен прежде всего для описания типов пара- метров и возвращаемых значений Web-сервисов. Также этот механизм может использоваться для обмена данными между различными конфигурациями «1С:Предприятия 8» или другими информационными системами. Про работу с Web-расширением рассказывается в главе «Web-расши- рение» на стр. 247, механизмы обмена данными описаны в главе «Обмен данными» на стр. 155, все остальные механизмы будут рассмотрены в данной главе. Форматы файлов обмена При реализации обмена данными между информационными системами одной из подзадач, требующей решения, является определение варианта передачи данных (и его реализация). Это может быть: • использование механизмов взаимодействия напрямую (например, OLE, СОМ); • использование промежуточных файлов. В данном же разделе рассмотрим подробно второй вариант - использование промежуточных файлов для передачи изменений данных. Будем считать, что известно, какими данными необходимо обмениваться. Тогда необходимо определиться с форматом файла передачи данных. С точки зрения «^Пред- приятия» можно использовать различные форматы файлов. Наиболее часто обмен реализуется посредством: • текстовых файлов; • файлов DBF; • XML-документов; • форматированных документов.
Рассмотрим все эти варианты на примере задачи выгрузки и загрузки спра- вочника Номенклатура. Считаем, что элемент справочника характеризуется (с точки зрения задачи обмена) следующими реквизитами: • код элемента (тип Строка); • наименование элемента (тип Строка); • закупочная цена (тип Число); • единица измерения (тип Строка). Работа с текстовыми файлами в «1С:Предприятии» может осуществляться в контексте двух моделей: • работа в модели последовательного доступа (объекты ЗаписьТекста, ЧтениеТекста); • работа с текстовым документом, который полностью загружается в память (объект ТекстовыйДокумент, поле формы вида ПолеТекстовогоДо- кумента). При использовании модели последовательного доступа, как при чтении, так и при записи, обрабатывается определенный фрагмент текста. Доступ к таким фрагментам осуществляется последовательно. Нельзя перескочить какой-либо фрагмент. Рассмотрение возможностей работы с текстовыми файлами начнем с модели, в которой содержимое файла загружается полностью. Прежде чем приступить к реализации обмена посредством текстовых файлов, сторонам (между которыми будет производиться обмен) необходимо «догово- рится» о логической структуре этого файла: • вариант использования текста: с фиксированной длиной полей, с пере- менной длиной полей; • если выбран вариант с переменной длиной полей, то какой используется разделитель; • последовательность следования данных; • возможная структура текстового документа и т. д. Считаем, что в результате были достигнуты следующие договоренности. В первой строке текстового документа с позиции No 1 по позицию No 39 вклю- чительно указывается наименование организации --- отправителя данных. Далее указывается дата отправки в формате «ДД.ММ.ГГГГ», т.е. первые две цифры - это день месяца, далее две цифры - это номер месяца, далее четыре цифры - это номер года.
В каждой следующей строке выгружается элемент справочника Номенклатура. Последовательно производится выгрузка кода, наименования, закупочной цены, наименования единицы измерения. Выгружаемые значения заключа- ются в кавычки, разделителем значения считается «,». Для включения как запятой, так и кавычек в выгружаемые данные используется символ «\». То есть для включения строки «Комплект «Подарочный», на 4 персоны» она должна быть преобразована к виду: «Комплект У'Пода- рочный\"\, на 4 персоны». Пример файла, который будет использоваться при обмене, приведен в листинге 1.1. Пример файла обмена ООО Быстрее, выше, сильнее 16.10.2010 "000000004","Посудомоечная машина","20 000","шт" "Q00000003","Стиральная машина","15 000","" "000000007","Фен","1 800","шт" "0ООООООО2","Холодильник","25 000","шт" "000000006","Чайник","2 000","" Только после фиксирования подобных договоренностей можно приступать к реализации механизмов выгрузки и загрузки. Для иллюстрации возможностей работы с текстовым файлом (с использо- ванием объекта ТекстовыйДокумент и поля формы вида ПолеТексто- вогоДокумента) создадим обработку, в которой будут производиться чтение и запись текста. Пример можно посмотреть на приложенном диске, конфигурация «Интеграция с другими информационными системами», обработка «РаботаСТекстом», команды формы «ЗаписатьНоменклатуру» и «Прочитать номенклатуру». В редакторе основной формы обработки создадим реквизит ПолеТД типа ТекстовыйДокумент и разместим в форме поле вида ПолеТексто- вогоДокумента, связанное с этим реквизитом (рис. 1.1). Для записи данных из справочника в текстовый документ может использо- ваться следующий программный код (листинги 1.2, 1.3, 1.4 и 1.5).
Вставка поля текстового документа Функция «ЭлементВСтрокуО»
Процедура «ЗаписатьНоменкпатуруО» Функция «ПолучитьСтрокиНоменкпатурыО»
Процесс записи инициирует процедура ЗаписатьНоменклатуру() (см. листинг 1.4). В процедуре производится создание объекта Тексто- выйДокумент и устанавливается тип кодировки этого документа. Затем вызывается функция ПолучитьСтрокиНоменклатурыО (см. лис- тинг 1.5). Эта функция выполняется на сервере. В ней в цикле выборки элементов справочника Номенклатура, не являющихся группой, формируются строки номенклатуры и в виде одной большой строки передаются обратно на клиента в процедуру ЗаписатьНоменклатуру (). В полученную строку добавляется заголовок файла обмена. Для полу- чения заголовка используется функция СформироватьЗаголовокО (см. листинг 1.3). Затем эта строка устанавливается в виде текста в текстовый документ методом УстановитьТекст (), и документ записывается. Для формирования строки элемента номенклатуры используется функция ЭлементВСтрокуО (см. листинг 1.2). Эта функция, а также функция СформироватьЗаголовокО реализует достигнутые при переговорах о формате файла «договоренности». Для чтения данных из полученного файла может использоваться следующий программный код (листинги 1.6 и 1.7). Функция «РазобратьСтрокуО»
Процесс чтения начинается с выполнения процедуры ПрочитатьНоменк- латуру() (см. листинг 1.7). Для чтения создается объект ТекстовыйДо- кумент. При выполнении его метода Прочитать () файл полностью загружается в оперативную память. Получение строк производится с помощью метода ПолучитьСтрокуО текстового документа. Функция РазобратьСтрокуО (см. листинг 1.6) извлекает из строки данные по элементу справочника, исходя из договоренностей по формату данных. Разбор заголовка реализован в процедуре ПрочитатьНоменклатуру() (см. листинг 1.7). Процедура «ПрочитатьНоменклатуруО»
Отображение текстового документа Для чтения и отображения в диалоге содержимого текстового документа может использоваться следующая процедура (листинг 1.8). Процедура «ПросмотрТДО» Перед выводом текстового документа реквизит ПолеТД типа Тексто- выйДокумент очищается, после чтения в качестве первой вставляется строка «Показывается в оригинальном виде» (она «сдвигает» ранее загруженные строки). Пользователь может проводить любые корректировки текста, представленного в поле формы, отражающем текстовый документ. Чтобы записать результат работы в файл, можно воспользоваться следующей процедурой (листинг 1.9). 1.9. Процедура записи результата в файл После записи реквизит, содержащий данные текстового документа, очищается (это можно и не делать). При работе с текстовыми файлами в «1С:Предприятии» следует учитывать особенности представления разделителей строк в файлах Windows и в тексте, используемом для обработки «внутри» «1С:Предприятия». Для целей внут- ренней обработки текста используется разделитель, состоящий из одного символа, в то время как в файлах Windows в качестве разделителя строк используется комбинация из двух последовательных символов. Внутри «1С:Предприятия» разделителем строк является символ Символы.ПС, он же LF (Line Feed, Перевод Строки), который имеет шест-
надцатеричный код OA. В то же время в кодировке текстовых файлов для Windows принято, что разделителем строк является пара символов - «CR-LF». CR (Carriage Return, Возврат Каретки) имеет шестнадцатеричный код 0D. При записи и чтении текстовых файлов «1С:Предприятие» производит преобразование внутренних разделителей строк в представление, принятое в текстовых файлах Windows. То есть при записи символ «ПС» (LF) преоб- разуется в пару символов «ВК-ПС» («CR-LF»). При чтении происходит обратное преобразование, то есть пара «ВК-ПС» («CR-LF») преобразуется в одиночный символ ПС (LF). Символ «ВК» («CR») при записи файла не преобразуется и не выбрасывается, то есть попадает в файл как есть. При чтении файла символы «ВК» («CR») и «ПС» («LF»), не образующие пару, также считываются без преобразований. В ранее рассмотренном примере работы с текстовыми файлами содержимое файла загружалось в оперативную память полностью. При работе с файлами большого размера такой подход может привести к замедлению обработки данных из файла. В этом случае можно воспользоваться возможностью «1С:Предприятия» работать с текстовыми файлами в рамках модели после- довательного доступа. Данная модель реализована объектами ЗаписьТекста и ЧтениеТекста. Пример можно посмотреть на приложенном диске, конфигурация «Интеграция с другими информационными системами», обработка «Рабо- таСТекстом», команды формы «ПоследовательнаяЗапись» и «Последователь- ноеЧтение». Для записи данных может использоваться следующая процедура (листинг 1.10). Пример записи текста
В процедуре создается объект ЗаписьТекста, и с помощью метода Запи- сатьСтрокуО документ построчно записывается в файл. Здесь так же, как и в случае с объектом ТекстовыйДокумент, строки элементов справочника Номенклатура получаются с сервера в виде одной большой строки функцией ПолучитьСтрокиНоменклатуры() и затем записываются на клиенте методом ЗаписатьСтрокуО объекта ЗаписьТекста. Необходимо заме- тить, что в случае записи файлов большого размера строку для записи нужно разбивать на небольшие порции (например, ограничить размер записываемой строки 1000 элементов номенклатуры). Текст функций СформироватьЗаголовокО, ЭлементВСтрокуО и ПолучитьСтрокиНоменклатуры() приводился ранее (см. листинги 1.3, 1.2 и 1.5). Для чтения данных может использоваться следующая процедура (листинг 1.11). Пример чтения текста Следует отметить, что чтение данных может осуществляться не только построчно, но и по указанному количеству символов (метод Прочитать () объекта ЧтениеТекста).
Предположим, что в справочнике Номенклатура существует также реквизит Картинка типа ХранилищеЗначения. И при выгрузке элементов справоч- ника необходимо включить его в файл обмена. Для этого воспользуемся объектом ФорматированныйДокумент и создадим обработку, в которой будет производиться чтение и запись форма- ' тированного текста. Пример можно посмотреть на приложенном диске, конфигурация «Интег- рация с другими информационными системами», обработка «РаботаСФорма- тированнымДокументом». В редакторе основной формы обработки создадим реквизит ПолеФД типа ФорматированныйДокумент и разместим в форме поле вида ПолеФор- матированногоДокумента, связанное с этим реквизитом. Для записи данных из справочника в форматированный документ могут использоваться следующие процедуры (листинги 1.12, 1.13). Процедура «ЗаписатьНоменкпатуруО» Выгрузка элементов справочника в форматированный документ
Процесс записи инициирует процедура ЗаписатьНоменклатуруО (см. листинг 1.12). В процедуре вызывается серверная функция Запи- сатьНоменклатуруНаСервере() (см. листинг 1.13), в которой создается объект ФорматированныйДокумент, заполняется элементами номенкла- туры с картинками, затем передается обратно на клиента и записывается. Добавление строк в форматированный документ производится методом Добавить () объекта ФорматированныйДокумент. Вторым параметром в этот метод передается тип элемента, который нужно вставить. Это значение системного перечисления ТипЭлементаФорматированногоДокумента, которое может принимать значения Текст, Картинка, ПереводСтроки. Для получения заголовка (первой строки) используется функция Сформи- роватьЗаголовок() (см. листинг 1.3), для записи элемента справочника в строку используется функция ЭлементВСтроку () (см. листинг 1.2). При переборе элементов справочника мы сначала получаем объект Картинка из реквизита Картинка методом Получить() и, если элемент справочника содержит картинку, добавляем ее в форматированный документ с соответс- твующим типом элемента. В конце каждого элемента справочника добавляем в форматированный доку- мент перевод строки с соответствующим типом элемента. После передачи на клиента, в процедуре ЗаписатьНоменклатуруО, форматированный документ записывается в файл обмена методом Запи- сать (). Вторым параметром в этот метод передается тип файла, в который производится запись. Это значение системного перечисления ТипФай- лаФорматированногоДокумента, которое может принимать значения HTML, TXT, ANSITXT. Поскольку форматированный документ содержит картинки, записываем его в файл типа HTML. Для чтения и отображения в форме содержимого форматированного доку- мента может использоваться следующая процедура (листинг 1.14).
Загрузка данных в форматированный документ Для чтения файла обмена воспользуемся объектом ЧтениеТекста. Методом ПрочитатьСтроку () построчно считываем файл, пока не будет достигнут конец файла. В цикле чтения файла мы разбираем прочитанную строку и разделяем ее на обычный текст и строку, содержащую адрес рисунка. По адресу рисунка создаем объект Картинка. И затем добавляем в форматированный документ текст и/или рисунок с соответствующим типом элемента. Таким образом, мы загружаем данные из файла обмена в форматированный документ. Поле формы вида ПолеФорматированногоДокумента отобра- жает данные этого форматированного документа (рис. 1.2).
Отображение форматированного документа в форме Пользователь может проводить любые корректировки текста, представленного в поле формы, отражающем форматированный документ, и затем записать его методом Записать (). Необходимо заметить, что в процедурах записи и чтения данных в/из файла обмена действуют «договоренности» о передаче картинки номенклатуры, например, что она будет записываться в конце строки, описывающей каждый элемент. Для работы с базами данных формата DBF (dBase I//) в системе имеется специальный объект - XBase. Механизм работы с базами данных формата DBF предназначен для обеспечения возможности манипулирования ими непосредственно из встроенного языка системы «1С:Предприятие». Возможно практически любое манипулирование данными. Помимо работы с существующими базами данных, объект XBase имеет набор методов, позволяющих создать новую базу данных произвольной структуры, новые индексы и новый индексный файл. Следует отметить, что
если использование методов, изменяющих структуру базы данных, возможно только для объектов, не связанных с существующей базой данных (т.е. для вновь создаваемых баз данных), то создание новых индексов и индексного файла возможно как для создаваемых баз данных, так и для уже существу- ющих и открытых. Для записи данных в файл DBF может использоваться следующий фрагмент кода (листинг 1.15). Пример можно посмотреть на приложенном диске, конфигурация «Интег- рация с другими информационными системами», обработка «Pa6oTaCDBF». 1.15. Пример записи данных в файл DBF Создается файл, у которого определяются четыре поля (CODE, NAME, COST, ED). Поле COST имеет числовой тип, остальные поля имеют строковый тип. У создаваемого DBF-файла определяется один индексный файл. Следует отметить, что у DBF-файла может быть определено несколько индексов, но создаваемый при этом индексный файл всегда один.
При записи данных следует обращать внимание на свойство АвтоСохра- нение объекта XBase. Если оно установлено в значение Истина, то добавление записи в файл производится при вызове следующего метода Добавить (), создающего новую запись. Из процедуры ЗаписьДанных() вызывается серверная функция Полу- читьСтрокиНоменклатуры(), которая возвращает на клиента массив строк элементов номенклатуры, не являющихся группой (листинг 1.16). Функция «ПолучитьСтрокиНоменклатурыО» В процедуре ЗаписьДанныхО в цикле обхода элементов массива в функции РазобратьСтрокуО каждая строка разбирается на данные структуры, в DBF-файл добавляется строка, и элементы этой структуры записываются в соответствующие поля DBF-файла. Текст функций ЭлементВСтроку() и РазобратьСтрокуО приводился ранее (см. листинги 1.2 и 1.6). Для чтения данных может использоваться следующий фрагмент кода (листинг 1.17). Пример чтения данных из файла DBF
В приведенном фрагменте не используется определенный при записи индекс, порядок отображения данных может быть следующий (фактически это соот- ветствует физическому положению записей в файле), листинг 1.18. Порядок отображения данных 000000004 Посудомоечная машина 000000003 Стиральная машина 000000007 Фен 000000002 Холодильник 000000006 Чайник Изменим код, добавив в него использование индекса (листинг 1.19). Пример чтения данных из файла DBF В этом случае в результате будут получены только следующие записи (листинг 1.20).
Полученные записи 00QQ00004 Посудомоечная машина 000000006 Чайник 000000007 Фен Дело в том, что при открытии файла объект XBase позиционируется на записи, которая является физически первой в файле. Однако с точки зрения используемого индекса, построенного в порядке возрастания кодов номенкла- туры, она далеко не первая. При выполнении метода Следующая () выбира- ется следующая запись в индексном файле. Поэтому в результате выполнения данного кода из пяти записей обходятся только три. Для того чтобы обойти все записи, необходимо явно использовать метод Первая(), как приведено ниже (листинг 1.21). Пример использования метода «Первая()» В результате будут получены все записи по возрастанию кода. Индексы полезно использовать не только для упорядочивания выборок записей по какому-либо полю, но и для реализации каких-либо «поисковых механизмов». Рассмотрим пример кода (листинг 1.22).
Пример чтения данных из файла DBF В результате будут получены только три записи (листинг 1.23). Полученные записи 000000004 Посудомоечная машина 000000006 Чайник 000000007 Фен Менять текущий индекс можно и во время выборки (однако следует помнить, что при «умелой» манипуляции индексами можно никогда не достигнуть конца DBF-файла). Ранее были рассмотрены возможности работы с текстовыми файлами и файлами DBF. К недостаткам рассмотренных подходов следует отнести тот факт, что обмен возможен после установки определенных «договорен- ностей». Фактически для каждого такого случая необходимо индивидуально создавать какие-либо обработки, реализующие механизм записи и чтения данных из файлов представленного формата. При организации обмена большим количеством типов данных (со сложной иерархией) алгоритмы данных механизмов будут получаться очень сложными и громоздкими. Отклонение от подобного формата в лучшем случае приведет к ошибке, в худшем --- к получению искаженных (неправильно проинтерпретированных) данных, причем факт искажения может быть и не замечен даже при исполь-
зовании этих данных (например, перепутали цену с количеством и т.п.). При таком подходе получается, что задача обмена очень часто решается в индивидуальном порядке. На каждый обмен - свой формат. К определенному моменту развития различных программных комплексов стало громадное количество форматов обмена. В итоге назрела необходи- мость в разработке универсального формата обмена. В качестве такого универсального формата в 1991 году и был представлен язык XML (расши- ряемый язык разметки). Считается, что для организации обмена данными посредством XML-доку- ментов достаточно договориться только о факте обмена с использованием этого формата. XML-документ в общем случае представляет собой файл с расширением xml, имеющий текстовое наполнение. Исходя из этого, можно сказать, что самым простейшим редактором таких документов может служить Блокнот (Notepad), хотя существует довольно большое количество специализированных редакторов. Может возникнуть вопрос: если XML-документ имеет текстовое наполнение, то чем же он отличается от обычного текстового файла (ведь можно сказать, что язык XML является частным случаем обмена посредством текстовых файлов), в чем его универсальность? Можно выделить несколько основных отличий: • XML-документ создается по строгим правилам, внутри него соблюдается четкая иерархия составных частей, вместе с данными передается струк- тура этих данных; • описание возможной структуры документа определяется на специальном, формализованном языке (одном из нескольких), вследствие чего эта струк- тура может быть программно разобрана (на приемной стороне можно разобрать возможную структуру, описанную на специальном языке, сопоставить структурные элементы документами с метаданными системы и после этого произвести загрузку данных); • при работе с XML-документами используется объектный подход (а не разбор строки с помощью специальных функций работы со строковыми значениями); • формальное описание типов.
Теперь если вернуться к универсальности XML-документов, то под ней понимается, что при необходимости произвести обмен данными посредством XML-документов должны быть реализованы такие понятия, как: • XML-документ с данными (созданный в соответствии со стандартом, определенным ко всем XML-документам); • к документу существует описание его структуры, которое можно формально разобрать (схема XML-документа); • определены пространства имен (в которых в том числе описаны типы данных, используемые в документе). Следует отметить, что, рассматривая особенности механизмов, позволяющих работать с XML-документами из «ЮПредприятия», мы в дальнейшем не будем подробно касаться таких понятий, как пространство имен (описанное в нем пространство типов), схема XML-документа. Но необходимо отдавать себе отчет в том, что при организации обмена с произвольными информаци- онными системами понадобится более детальная работа с ними. Пора перейти к рассмотрению структуры и общих принципов формирования XML-документов. При рассмотрении внутреннего наполнения XML-документов в них можно выделить определенные форматирующие конструкции. По аналогии с HTML (наверное, самый простой из языков разметки) их пока можно назвать тегами. Под тегом будем понимать некое выражение, заключенное в угловые скобки <выражение>. Различают открывающий тег <тег> и закрывающий тег </тег> (отличие в наклонной черте перед именем тега). Если продолжать сравнение с языком разметки HTML, то в языке HTML набор тегов фиксирован. Теги HTML условно можно разделить на теги определения структуры документа и теги «форматирования» представляемых данных. К примеру, с тега <body> начинается основное тело HTML-документа, весь текст, попавший между тегами <Ь> и </Ь>, отображается полужирным и т. п. Для тегов можно задать значения характерных для них свойств. Например, <body text=red>. Свойство text определяет цвет текста тела документа по умолчанию (в примере он будет красным). Таким образом, изучение языка HTML сводится к ознакомлению с множеством тегов (их назначением), свойствами тегов и их возможными значениями. В языке XML имена тегов не фиксированы, разработчик волен давать им собственные имена, определять у них произвольные свойства с любыми типами значений. В имени тега XML могут использоваться точки (правда, это может не поддерживаться рядом специализированных редакторов). В содержимом атрибутов, элемента пробелы и символы табуляции не игнорируются.
Перейдем от термина «тег» к терминам более правильным по отношению к XML-документу. Можно сказать, что минимальной логической единицей XML-документа является элемент. У элемента может быть определено несколько атрибутов (упрощенно атрибут можно назвать свойством элемента). У любого элемента может быть один (непосредственный) элемент-владелец (его нет только у единственного корневого элемента XML-документа) и любое количество подчиненных элементов (рис. 1.3). Пример иерархии элементов XML Следует отметить, что в различной литературе используемая терминология может отличаться. То, что в данной главе называется элементом, может назы- ваться «узлом». В используемой нами терминологии понятие «узел» также встречается, но под ним понимается структурная часть элемента XML (такая как начало элемента, текст и т.д.). Рассмотрим структуру элемента XML (рис. 1.4). Схема элемента XML Пример, иллюстрирующий приведенную схему, приведен в листинге 1.24. Пример элемента XML
В данной строке определен элемент с именем Товар. В начале элемента определяются два атрибута с именами ИмяСправочника и Код (соответственно со значениями Номенклатура и 14). Между началом элемента и его концом (</Товар>) расположен текст элемента (его значение Ardo TL10ОО ЕХ-1). Вместо текста между тегами, описывающими начало и конец элемента, может нахо- диться описание вложенных элементов. Также допускается следующий вариант определения элемента XML-доку- мента(рис. 1.5). Схема элемента XML Приведенная схема представляет следующий вариант описания элемента (листинг 1.25). Пример элемента XML Данный вариант допустим, когда между открывающим и закрывающим тегом нет текста и нет вложенных элементов. Поэтому вместо <Товар><Яовар> допустима конструкция <Товар/>. В приведенном описании определяется элемент с именем Товар и два атрибута с именами Код и Наименование. Рассмотрим пример XML-документа (листинг 1.26). Пример XML-документа
В первой строке XML-документа определяется директива, указывающая на то, что данный документ с текстовым содержимым является XML-доку- ментом. Далее определяется элемент Корневой. Внутри него определяются другие элементы. Можно сказать, что в данном документе просматривается определенная древовидная структура (она показана на рис. 1.6). Древовидная структура XML-документа Эта структура обеспечивается тем, что у XML-документа всегда один кор- невой элемент, описание одного элемента всегда находится внутри описания другого элемента (исключение составляет корневой элемент). Можно сказать, что древовидность структуры является обязательным признаком правиль- ности оформленного XML-документа. При рассмотрении любого XML-документа можно говорить о его синтакси- ческой правильности и корректности.
Синтаксически правильный XML-документ упрощенно удовлетворяет следу- ющим условиям: • Язык XML чувствителен к регистру символов. Это обязательно нужно учитывать при описании начала и конца элемента. • Все значения атрибутов, используемых в определении элементов, должны быть заключены в кавычки. • Каждому открывающему тегу соответствует закрывающий тег. Можно сказать, что XML-документ является совокупностью элементов. Два возможных варианта описания элементов были представлены выше. • Элементы образуют древовидную структуру с одним корневым элементом (он обязательно один). Это достигается тем, что области действия тегов не могут пересекаться (либо они рядом, либо одна находится целиком внутри другой). В «1С:Предприятии» существует базовая подсистема работы с XML-докумен- тами. Основой этой подсистемы являются два объекта «1С:Предприятия»: • ЧтениеХМЬ, • ЗаписьХМЬ. При работе с XML-документами данные объекты реализуют модель последо- вательного доступа. Основная особенность работы в этой модели заключается в том, что документ не загружается полностью, работа идет только с текущим его фрагментом (частью элемента XML, например началом элемента, текстом элемента и т. д.). Поэтому при работе с документом нет возможности получать выборки элементов, «перепрыгивать» узлы и т. п. Запись данных в XML-документ Вернемся к задаче обмена данными об элементах справочника Номенклатура. Рассмотрим пример использования объекта ЗаписьХМЬ (листинг 1.27). Пример можно посмотреть на приложенном диске, конфигурация «Интег- рация с другими информационными системами», обработка «Pa6oTaCXML». Пример записи XML-документа
Здесь так же, как и при записи DBF-файла, вызывается серверная функция ПолучитьСтрокиНоменклатуры(), которая возвращает на клиента массив строк элементов номенклатуры, не являющихся группой. Затем в цикле обхода элементов массива в функции РазобратьСтроку () каждая строка разбирается на данные структуры, и элементы этой структуры записываются в виде элементов XML-файла. Текст функций ЭлементВСтроку (), РазобратьСтроку () и Полу- читьСтрокиНоменклатуры () приводился ранее (см. листинги 1.2, 1.6 и 1.16). В результате выполнения представленного кода будет получен следующий XML-документ (листинг 1.28).
Первой строкой кода создается объект ЗаписьХМЬ. Через созданный объект в модели последовательного доступа будет производиться запись данных в XML-документ. С помощью метода ОткрытьФайл () указывается имя файла, куда будет производиться запись данных. Метод ЗаписатьОбъявле- ниеХМЬО определяет директиву, что создаваемый документ будет являться XML-документом (директива размещается в первой строке созданного документа). Для записи элемента XML-документа используются методы ЗаписатьНача- лоЭлемента(), ЗаписатьАтрибутО, ЗаписатьТекст(), ЗаписатьКо- нецЭлемента(), которые производят запись соответствующего узла элемента XML в файл. При этом важно соблюдать порядок (иерархию) вызова этих методов. Напомним, что элемент можно представить в виде следующих узлов (листинг 1.29). Полученный XML-документ
1.7. Последовательность использования методов при записи XML-документа Правильный XML-документ содержит единственный корневой элемент, запись всего документа начинается с записи этого элемента. 1.29. Узлы элемента XML Для записи вышепредставлеиного элемента можно использовать следующую последовательность методов (листинг 1.30). 1.30. Пример записи элемента XML Следует обратить внимание на тот факт, что если при определении начала элемента в соответствующем методе указывается его имя, то при закрытии имя не указывается. Закрывается элемент, открытый последним. В связи с этим следует внимательно относиться к последовательности исполняемых методов, чтобы не запутаться в иерархии (в ряде случаев для упрощения алгоритмов создания документов сложной структуры могут использоваться рекурсивные вызовы процедур, ответственных за создание элементов). Последовательность методов объекта ЗаписьХМЬ, вызываемых при создании элементов, можно проиллюстрировать следующей схемой (рис. 1.7).
Запись любого элемента XML начинается с записи открывающего тега (начала элемента, выполняемого с помощью метода ЗаписатьНачалоЭле- мента()). Только в контексте начала элемента можно записывать атрибуты XML-документа (используется метод ЗаписатьАтрибутО, вызываемый последовательно для каждого атрибута). Записать атрибут после записи текста или конца элемента нельзя. После записи начала элемента и всех его атрибутов можно провести запись текста (это означает, что у формируемого элемента XML нет вложенных элементов) или рекурсивно перейти к записи другого вложенного элемента. После того как либо текст, либо другой вложенный элемент (элементы) закрыт, производится запись конца элемента (метод ЗаписатьКонецЭлементаО). Чтение данных из XML-документа Объект ЧтениеХМЬ предназначен для чтения данных из XML-документа. Так же как при записи данных, чтение элемента производится узлами. Перечень узлов определен в системном перечислении ТипУзлаХМЬ): • НачалоЭлемента, • Атрибут, • Текст, • КонецЭлемента, • Ничего, • • ИнструкцияОбработки. Какой узел получен при чтении следующего структурного элемента, можно узнать, обратившись к свойству ТипУзла объекта ЧтениеХМЬ. Будем исходить из того, что необходимо прочитать следующий XML- документ (полученный при выгрузке с помощью объекта ЗаписьХМЬ), листинг 1.31. Читаемый XML-документ
Пример использования объекта ЧтениеХМЬ (листинг 1.32). Этот пример также можно посмотреть на приложенном диске, конфигу- рация «Интеграция с другими информационными системами», обработка «РаботаСХМЬ». Чтение XML-документа
Процесс чтения начинается с создания объекта ЧтениеХМЬ. С помощью метода ОткрытьФайл () производится указание файла, из которого в даль- нейшем будет производиться чтение данных. Само чтение осуществляется с помощью метода Прочитать (). Данный метод возвращает значение Истина, в случае если получилось позиционироваться на следующем узле элемента XML. Для того чтобы понять, какой узел явля- ется текущим, производится обращение к свойству ТипУзла. В случае если это НачалоЭлемента, можно провести выборку атрибутов (они существуют только в контексте начала элемента). После того как метод Прочитать () возвращает значение Ложь (достигнут конец документа), работа с XML-документом завершается вызовом метода Закрыть (). Порядок работы с объектом ЧтениеХМЬ можно проиллюстрировать следу- ющей схемой (рис. 1.8). Последовательность использования методов при чтении XML-документа
Общий принцип работы довольно прост. Открывается ХМ L-документ, далее в цикле выполняется метод Прочитать (). После чтения анализируется тип полученного узла. В зависимости от типа предпринимаются некие специ- фические действия по извлечению данных. Если полученный узел является началом элемента, предпринимается попытка получить все атрибуты, которые могут быть в нем определены. Как уже говорилось ранее, XML-документ имеет текстовое содержимое. Это в первую очередь означает, что при записи в него любого значения (числа, даты, ссылки на объект и т.д.) оно преобразуется к строке. При получении данных возникает обратная задача по преобразованию значения из строкового в нужный тип. С одной стороны, с помощью базовых средств чтения и записи документов XML можно решить любую задачу, связанную с организацией обмена. Но решение задачи преобразования типов в строковый и обратно потре- бует от разработчика очень больших затрат времени (на самостоятельную реализацию данных преобразований). Придется в полной мере работать со стандартными типами (W3C), определять собственное пространство имен (для описания некоторых типов «1С:Предприятия» в XML) и т.д. Альтернативным (более простым и удобным) решением данной задачи может быть использование уже реализованных средств XML-сериализации. С точки зрения данной системы каждый объект данных «1С:Предприятия» представляется как элемент XML-документа. Этот элемент может иметь подчиненные элементы. Как раз с этой точки зрения (есть у элемента подчи- ненные или нет) типы значений делятся на простые и сложные. К простым типам данных относятся типы, значения которых представляются подсистемой XML-сериализации в виде элементов XML только с текстовым содержимым (листинг 1.33). Пример сериализации значения ссылки на справочник Значения сложных типов представляются в виде элементов XML, содержащих вложенные элементы (листинг 1.34).
Если проанализировать типы, которые требуется подвергать преобразованию, то их можно разделить на три группы: ш Типы, которым можно найти прямое соответствие в типах, определенных в документе XML Schema Part 2: Datatypes консорциума W3C (пространство имен - http://www.w3.org/2001/XMLSchema). Значения данных типов могут представляться в виде элемента с текстовым содержимым. • Предопределенные типы «1С:Предприятия 8» (пространство имен - http://v8.1c.ru/data, http://v8.1c.rU/8.1/data, http://v8.1c.ru/8-2/data). Эти типы не зависят от структуры метаданных и существуют в любой информа- ционной базе. Исходя из этого, имеет смысл описать их в специализиро- ванном пространстве имен. Они могут относиться как к простым типам, так и к сложным. • Типы, производные от метаданных конфигурации «1С:Предприятия 8». Наличие таких типов зависит от состава и специфики определения объектов конфигурации. В каждой информационной базе они могут иметь произвольную реализацию. Исходя из этого, нет возможности описать все возможные варианты этих типов в каком-либо пространстве имен (при создании объекта конфигурации разработчик имеет столько степеней свободы, что описать все возможные варианты создаваемых объектов в принципе невозможно). В итоге такие типы не относятся ни к какому пространству имен и тоже могут являться как простыми, так и сложными типами (например, ссылка на объект относится к простым типам, сам объект - к сложным). При рассмотрении примеров представления различных значений в XML и при дальнейшем изложении будем исходить из предположения, что опреде- лены следующие соответствия пространств имен (после xmlns определены их префиксы): • xmlns:xsd="http://www.w3.org/2001/XMLSchema"; • xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"; • xmlns:v8="http://v8. lc.ru/data"; • xmlns:v8="http://v8.1 c.ru/8.1/data"; • xmlns:v8="http://v8.1c.ru/8.2/data". Пример сериализации значения типа «УдалениеОбъекта»
К простым типам с точки зрения представления в XML относятся следующие типы «1С:Предприятия»: • Число; • Строка; в Дата; • Булево; • ДвоичныеДанные; • Null; • УникальныйИдентификатор; • ХранилищеЗначения; • все ссылки на объекты базы данных; • ссылки на перечисления, определяемые в конфигурации. К сложным типам, значения которых могут быть представлены в XML, отно- сятся следующие типы: • Тип; • ОписаниеТипов; • КонстантаМенеджерЗначения,<имя>; • все объекты базы данных; • наборы записей регистров, последовательностей, перерасчетов; • УдалениеОбъекта. Простые типы Рассмотрим различные варианты представления значений простых типов в XML-документе. Число Типу Число соответствует тип данных XML decimal из пространства имен http://www.w3.org/2001/XMLSchema (префикс xsd). Правила представления значений данного типа определены в документе XML Schema Part 2: Datatypes. Ниже приведены примеры представления значений типа Число в XML (листинг 1.35).
Варианты представления значения типа «Число» - 3.14156 Варианты представления значений типа «Строка» Дата Типу Дата соответствует тип данных XML dateTime из пространства имен http://www.w3.org/2001/XMLSchema. Значения типа Дата представляются в виде CCYY-MM-DDTHH:MM:SS, где CCYY --- год, представленный в виде четырех цифр; ММ - месяц, пред- ставленный двумя цифрами; DD - день месяца двумя цифрами; Т - латинская В первом случае имя типа (пространство имен http://www.w3.org/2001/ XMLSchema) совпадает с именем элемента, в котором передается значение. Во втором случае именем узла является имя переменной (свойства, рекви- зита), из которого/в который должна производиться запись. В третьем случае тип определен явно. Используется тот факт, что в пространстве имен с префиксом xsi определена возможность использования такого атрибута, как type. С помощью значения этого атрибута может указываться тип, который был преобразован к строковому и размещен в тексте элемента XML. В нашем случае указано, что при загрузке текст «3.14156» необходимо интерпретиро- вать как тип decimal из пространства имен с префиксом xsd. Строка Типу Строка соответствует тип данных string из пространства имен http://www.w3.org/2001/XMLSchema. Строка записывается в XML как есть. Ниже приведены примеры представления в XML значений типа Строка (листинг 1.36).
буква Т; НН - час суток; ММ - минута; SS - секунда. Такой формат даты определен как допустимый в документе XML Schema Part 2: Datatypes. Ниже приведены примеры представления в XML значений типа Дата (листинг 1.37). Варианты представления значений типа «Дата» Булево Типу Булево соответствует тип данных boolean из пространства имен http://www.w3.org/2001/XMLSchema. Значение Ложь представляется строкой false, а значение Истина - строкой true. Такой формат предусмотрен в документе XML Schema Part 2: Datatypes. Ниже приведены примеры представления в XML значений типа Булево (листинг 1.38). Варианты представления значений типа «Булево» ДвоичныеДанные Типу ДвоичныеДанные соответствует тип данных XML base64Binary из пространства имен http://www.w3.org/2001/XMLSchema. Значения данного типа представляются как двоичные данные, закодиро- ванные с использованием алгоритма Base64, описанного в RFC 2045. Ниже приведены примеры представления в XML значений типа Двоич- ныеДанные (листинг 1.39).
Варианты представления значений типа «ДвоичныеДанные» Null Типу Null соответствует тип данных XML Null из пространства имен http://v8.1c.ru/data. Данный тип имеет одно-единственное значение, которое представляется пустой строкой. Ниже приведены примеры представления в XML значений типа Null (листинг 1.40). Варианты представления значения типа Null УникальныйИдентификатор Типу УникальныйИдентификатор соответствует тип данных XML UUID из пространства имен http://v8.1c.ru/data. Значения данного типа представляются в XML в соответствии с общепри- нятой практикой и стандартами (ISO-11578, DCE 1.1: Remote Procedure Call - Universal Unique Identifier). Ниже приведены примеры представления в XML значений типа Уникаль- ныйИдентификатор (листинг 1.41). Варианты представления значений типа «УникальныйИдентификатор»
ХранилищеЗначения Типу ХранилищеЗначения соответствует тип данных XML ValueSto- rage из пространства имен http://v8.1c.ru/data. Значения данного типа представляются в XML как данные Хранили- щеЗначения, сохраненные в файл, а затем закодированные с использованием алгоритма Base64. Ниже приведены примеры представления в XML значений типа Хранили- щеЗначения (листинг 1.42). Варианты представления значений типа «ХранилищеЗначения» Тип ссылки на объект базы данных Каждому из типов ссылок на объекты базы данных соответствует свой собственный тип данных XML. Имя типа данных XML для ссылок на объекты базы данных соответствует англоязычному имени типа значения ссылки «1С:Предприятия». Так, например, для справочника Валюты англоязычное имя типа ссылки будет выглядеть как CatalogRef.BanK)Tbi. Так же будет выглядеть и имя типа данных XML. Типы данных XML для ссылок на объекты базы данных не относятся ни к какому пространству имен (зависит от определенных в конфигурации объектов). Значения ссылок представляются в XML как значения типа Уникаль- ныйИдентификатор, полученные из ссылок. Ниже приведены примеры представления в XML значений ссылок на объекты базы данных (листинг 1.43). Варианты представления значений типа ссылки на объект базы данных
Тип ссылки на значение перечисления Каждому из типов ссылок на значения перечислений, определенных в конфигурации, соответствует свой собственный тип данных XML. Имя типа данных XML для ссылок на значения перечисления соответствует англоязычному имени типа «1С:Предприятия». Так, например, для перечисления ВидыАдресов англоязычное имя типа ссылки на значение будет выглядеть как EnumRef.ВидыАдресов. Так же будет выглядеть и имя типа данных XML. Типы данных XML для ссылок на значения перечислений не относятся ни к какому пространству имен (также определяются структурой любой конфигурации «1С:Предприятия»). В XML ссылки на значения перечислений представляются в виде имени соответствующего значения перечисления. Ниже приведены примеры представления в XML ссылок на значения перечислений (листинг 1.44). Варианты представления значений типа ссылки на значение перечисления Работа с простыми типами Для работы с XML-представлениями значений простых типов предназначены два метода глобального контекста - ХМЬСтрока () и ХМЬЗначение (). Метод ХМЬСтрока () имеет единственный параметр - значение, для которого нужно получить XML-представление. Это значение должно относиться к типу, являющемуся простым с точки зрения XML-сериализации. В противном случае будет вызвано исключение. При нормальном завершении функция возвращает строку, которая может быть использована как текст элемента XML, представляющего значение простого типа. Метод ХМЬЗначение () выполняет противоположную задачу. У этого метода два параметра. Первый параметр - тип значения, которое нужно получить из строки, второй параметр - сама строка. Для преобразования типа данных «1С:Предприятия» в тип данных XML и наоборот предназначены методы ХМЬТипО и ИзХМЬТипа(). Метод
ХМЬТипО имеет один параметр - тип, для которого нужно получить соот- ветствующий тип данных XML. Если соответствующий тип данных ХМ1. определен, то метод возвращает значение типа ТипДанныхХМЬ. Если же соответствующего типа данных XML нет, то метод возвращает значение Неопределено. Метод ИзХМЬТипа () имеет два варианта вызова. В первом варианте метод имеет единственный параметр типа ТипДанныхХМЬ. Во втором варианте параметра два: имя типа XML и пространство имен. В обоих случаях метод возвращает соответствующий типу данных XML тип данных «1С:Предпри- ятия», если таковой имеется, или Неопределено в противном случае. Поскольку большинство методов для работы с данными XML (за исключе- нием примитивных типов данных) не работают на клиенте, а получать файл с данными пользователю нужно в основном именно на клиенте, здесь и далее будем использовать следующий подход. При записи данных XML будем производить необходимую обработку данных на сервере, записывать эти данные во временный файл, в виде двоичных данных сохранять файл во временном хранилище, и адрес этих данных в хранилище передавать на клиента. И затем уже получать файл на клиенте по адресу во временном хранилище. При чтении данных XML будем сохранять XML-документ во временном хранилище и адрес данных в хранилище передавать в северную процедуру, в которой документ будет получаться из временного хранилища, записываться во временный файл, и будет производиться чтение документа. Рассмотрим пример использования вышеперечисленных методов (листинг 1.45, 1.46). Пример можно посмотреть на приложенном диске, конфигурация «Интег- рация с другими информационными системами», обработка «РаботаСХМЕ». Пример записи XML-документа В процедуре записи XML-документа вызывается серверная функция ЗаписьПростыхДанныхХМЬО (листинг 1.46), в которой производится необходимая обработка данных, затем эти данные записываются во временный файл, который в виде двоичных данных сохраняется во временном храни- лище, и адрес этих данных в хранилище возвращается на клиента.
Функция «ЗаписьПростыхДанныхХМЦ)»
Особенность вышеприведенного механизма заключается в том, что при записи элемента в его имя записывается имя типа XML (получаемого с при обращению к значению, полученному при обращении к методу ХМЬТипЗнчО). Также записывается пространство имени типа. Следует отметить, что тип XML можно было получить и при обращении к методу ХМЬТипО. В результате выполнения фрагмента кода сформируется следующий документ (листинг 1.47). Пример сформированного XML-документа Обратите внимание на следующий факт. Пространство имен типов должно быть записано для каждого элемента с данными. Однако в пятом и шестом элементах (для ссылки справочника номенклатуры) оно не определено. Так и должно быть, ведь для типов данных, производных от объектов конфи- гурации, пространство имен не определяется. Кроме этого, обратите внимание на различие результата записи ссылки. В первом случае используется метод ХМЬСтрокаО, записывается значение уникального идентификатора ссылки. Во втором записывается представление ссылки (чаще всего это наименование). Для чтения выгруженного XML-документа (см. листинг 1.47) может исполь- зоваться следующий программный код (листинг 1.48). Пример чтения XML-документа
В процедуре чтения XML-документа сначала документ помещается во временное хранилище. Адрес данных в хранилище передается в серверную процедуру ЧтениеПростыхДанныхХМЬО (листинг 1.49), в которой доку- мент получается из временного хранилища, записывается во временный файл, и производится чтение документа. Процедура «ЧтениеПростыхДанныхХМЦ)»
Сложные типы Перейдем к рассмотрению сложных (с точки зрения сериализации) типов. Тип Типу Тип соответствует тип данных XML Туре из пространства имен http://v8.1c.ru/data. Элемент XML, представляющий значение данного типа, содержит текст. В нем записано имя типа XML, соответствующего типу данных «1С:Предприятия». Примеры представления в XML значений типа Тип приведены ниже (листинг 1.50).
Варианты представления значений типа «Тип» ОписаниеТипов Типу ОписаниеТипов соответствует тип данных XML TypeDescription из пространства имен http://v8.1c.ru/data. Корневой элемент, представляющий значение типа ОписаниеТипов, содержит ряд вложенных элементов, каждый из которых содержит некоторую составляющую часть описания типов. Назначение составляющих частей понятно из примера (листинг 1.51). Пример представления значений типа «ОписаниеТипов» На первый взгляд тип Тип относится не к сложным, а к простым типам данных, так как элемент, представляющий значение данного типа, не содержит вложенных элементов. Однако это не так. Вложенных элементов действительно нет. Но при этом текст элемента, содержащий имя типа данных XML, содержит префикс пространства имен типа, который должен быть определен в данном элементе или одном из родительских элементов, что делает текст элемента не вполне самодостаточным. Поэтому данный тип не отнесен к простым типам.
Вложенный элемент Types из пространства имен http://v8.1c.ru/data содержи! представления отдельных типов, входящих в описание типов. Элемент с именем NumberQualifiers из пространства имен http://v8.1c.ru/data содержит квалификаторы числового значения. А элементы с именами StringQualifiers и DateQualifiers из того же пространства имен содержат квалификаторы строки и даты соответственно. КонстантаМенеджерЗначения.<имя> Каждому из типов КонстантаМенеджерЗначения.<имя> соответствует тип данных XML ConstantValueManager.<HMH>, не относящийся ни к какому пространству имен. Пример приведен ниже (листинг 1.52). Листинг 1.52. Пример представления значения типа «КонстантаМенеджерЗначения.НазваниеОрганизации» Объект Объекты базы данных представляются в XML как совокупность значений реквизитов и табличных частей. Имя типа данных XML, соответствующего объекту базы данных, определяется как англоязычное имя типа значения «1С:Предприятия». Типы данных XML для объектов базы данных не отно- сятся ни к какому пространству имен. Состав элементов XML, вложенных в корневой элемент, определяется типом объекта, а также составом рекви- зитов и табличных частей. Каждый из реквизитов представляется элементом XML, имя которого соответствует имени реквизита. Если тип значения имеет составной тип, то элемент XML, представляющий реквизит, содержит атрибут xsi:type, в котором указан тип значения XML. Каждая из табличных частей представляется элементом XML, имя которого совпадает с именем табличной части. Каждая из строк табличной части представляется элементом XML с именем Row. Реквизиты табличной части представлены элементами XML, вложен- ными в элемент Row. Ниже приведен пример представления в XML объекта типа Доку- мент. ЗаказПокупателя (листинг 1.53).
В используемом примере, а также в других примерах данной главы присутствуют длинные строки (например, «<ЕдиницаИзмерения>317fl 2 d9-5a08-11 ё7-9324-0050Ьа8480Ьс!</ЕдиницаИзмерения>»). Такие строки приводятся с переносом на следующую строку текста. Реально такие строки записываются в модуле в одну строку. Набор записей Представление в XML набора записей включает отбор, по которому получен набор записей и сами записи, входящие в отбор. Значения отбора пред- ставлены во вложенном элементе XML с именем Filter, не относящемся ни к какому пространству имен. А все записи, составляющие набор записей, - во вложенном элементе с именем Records, также не относящемся ни к какому пространству имен. Записи представлены элементами XML с именем Record, вложенными в элемент Records. Имя элемента Record также не относится ни к какому пространству имен. Ниже приведен пример представления в XML набора записей регистра накоп- ления ОстаткиТоваровКомпании (листинг 1.54). Пример представления значения типа «РегистрНакопленияНаборЗаписей.ОстаткиТоваровКомпании»
УдалениеОбъекта Типу УдалениеОбъекта соответствует тип данных XML ObjectDeletion, из пространства имен http://v8.1c.ru/data. Корневой элемент XML-пред- ставления значения типа УдалениеОбъекта содержит один вложенный элемент с именем Ref из пространства имен http://v8.1c.ru/data, в котором находится представление ссылки на объект базы данных. Ниже приведен пример представления в XML объекта типа УдалениеОбъ- екта (листинг 1.55). Пример представления значения типа «УдалениеОбъекта»
Работа со сложными типами Для работы со сложными с точки зрения сериализации значениями могут использоваться следующие методы «1С:Предприятия» (они же могут исполь- зоваться и для простых типов): • ЗаписатьХМЬО, • ПрочитатьХМЬО. Метод ЗаписатьХМЬО имеет два обязательных параметра. Первый параметр --- это объект типа ЗаписьХМЬ, через который осуществляется запись XML, а второй - значение, которое должно быть записано в XML. Необязательные параметры образуют три различных варианта вызова метода. В простейшем случае параметра три, и в качестве третьего параметра указы- вается значение перечисления НазначениеТипаХМЬ, определяющее необ- ходимость явного указания типа данных XML в атрибуте xsi:type корневого элемента XML. У следующего варианта вызова в качестве третьего параметра исполь- зуется строковое значение, указывается имя корневого элемента XML. При этом подразумевается, что пространство имен не определено. Четвертый параметр - значение типа НазначениеТипаХМЬ, определяющее необходи- мость явного указания типа данных XML. И, наконец, у последнего варианта вызова после параметра, указыва- ющего имя корневого элемента XML, появляется еще один параметр - строковое значение, обозначающее пространство имен, к которому относится корневой элемент. Последний параметр по-прежнему имеет тип Назначе- ниеТипаХМЬ. Рассмотрим пример использования объекта ЗаписатьХМЬ (листинг 1.56). Пример можно посмотреть на приложенном диске, конфигурация «Интег- рация с другими информационными системами», обработка «РаботаСХМЬ». Пример использования объекта «ЗаписьХМЬ» В результате выполнения приведенного кода будет получен следующий XML- фрагмент (листинг 1.57).
Фрагмент XML-документа Если в качестве значения, помещаемого в XML, будет передано значение типа, который не может быть представлен в XML, то будет вызвано исключение. Метод ПрочитатьХМЬО предназначен для чтения значений из XML. Данный метод имеет один обязательный параметр - объект ЧтениеХМЬ, из которого должно быть прочитано значение. В качестве второго параметра может быть указан тип значения, которое должно быть прочитано из XML. Если тип значения явно указан в XML, то в качестве второго параметра может быть указано значение Неопределено, или же он может быть вообще опущен. В этом случае метод ПрочитатьХМЬО пытается определить тип читаемого значения по содержимому атрибута xsi:type, а если атрибут xsi:type отсутствует, то по имени элемента. Если тип установить не удалось или значение указанного типа не может быть прочитано из XML, то вызывается исключение. При удачном завершении метод ПрочитатьХМЬО возвращает считанное значение. Следует обратить внимание на то, как считываются менеджеры значений конс- тант, объекты базы данных и наборы записей. После успешного выполнения чтения метод ПрочитатьХМЬО возвращает считанное из XML значение, но это значение еще не записано в базу данных. Если, например, считан элемент справочника, то для того чтобы считанный элемент справочника оказался записанным в базу данных, необходимо обратиться к его методу Записать(), как и при «обычной» записи измененного состояния объекта. Это же относится и к другим объектам базы данных, менеджерам записи констант и наборам записей. При чтении объекта базы данных из XML в базе данных производится поиск объекта с таким же значением ссылки. Если такой объект найден, то считы- вание из XML выглядит так, как будто объект был прочитан из базы данных, после чего значения его реквизитов, табличных частей и т. п. перезаписыва- ются полученными из XML значениями. Если же объект по ссылке не найден, то считывание из XML выглядит как создание нового объекта, установка ему значения ссылки и заполнение его содержимого значениями, прочитанными из XML. Метод ВозможностьЧтенияХМЬО определяет, возможно ли считывание значения из объекта ЧтениеХМЬ, находящегося в текущей позиции документа XML. Объект ЧтениеХМЬ передается данному методу в качестве параметра. Если метод возвращает Истина, то чтение возможно, если Ложь - значение не может быть считано.
Метод ПолучитьХМЬТипО позволяет получить из объекта ЧтениеХМЬ тип данных XML, соответствующий текущей позиции документа XML. Данный метод также имеет один параметр - ЧтениеХМЬ. Рассмотрим использование вышеперечисленных методов на примере. В контексте процедуры ЗаписьСложныхТиповДанныхО существует пере- менная Документ (тип ДокументСсылка.<имя>). Данный документ имеет следующую структуру: • реквизит Контрагент, тип СправочникСсылка.Контрагенты; • табличная часть Товары, реквизиты табличной части: • Номенклатура, тип СправочникСсылка.Номенклатура; • Количество, тип Число; • Цена, тип Число; • Сумма, тип Число. Следует отметить, что метод ЗаписатьХМЬО сам определяет структуру выгружаемого объекта. В данном случае она приводится для того, чтобы пояснить полученный XML-документ. При записи и чтении сложных типов XML данных так же, как это подробно описано в разделе «Работа с простыми типами» на стр. 50, передача XML-доку- мента между клиентом и сервером происходит через временное хранилище. Процедура, используемая для выгрузки, имеет следующий код (листинги 1.58, 1.59). Пример записи XML-документа Функция
В результате работы процедуры сформируется XML-документ следующего вида (листинг 1.60). Пример сформированного XML-документа Можно сказать, что структура выгруженного документа повторяет структуру его метаданных, причем дополнительно включаются такие данные, как: • ссылка на документ (Ref); • пометка на удаление (DeletionMark); • дата (Date); • номер (Number); • проведен (Posted).
Процедура чтения данных представлена в листингах 1.61, 1.62. Процедура чтения XML-документа Процедура «ЧтениеСложныхДанныхХМЦ)» Следует отметить, что если объект, в который производится загрузка, имеет отличную структуру (отличается состав реквизитов, табличных частей, реквизитов табличных частей или порядок их следования) от выгружаемого объекта, то метод ВозможностьЧтенияХМЬО может возвратить значение Истина. При попытке проведения чтения объекта из XML-документа будет вызвано исключение. Это объясняется тем, что метод Возмож- ностьЧтенияХМЬО анализирует текущее состояние объекта ЧтениеХМЬ.
В этот момент текущим является начало соответствующего элемента. Если имя элемента, атрибуты «понятны» методу, он и возвращает значение Истина. Проверка структуры, других моментов методом ВозможностьЧте- нияХМЬ () не производится. Механизм XDTO является универсальным способом представления данных для интеграции с другими системами. Аббревиатура XDTO расшифровыва- ется как XML Data Transfer Objects. XDTO является механизмом объектного моделирования данных, описываемых с помощью схемы XML. Можно выделить несколько задач, для решения которых используется меха- низм XDTO: • обмен данными между конфигурациями «1С:Предприятия» с разными структурами данных; • обмен данными на основе схем XML, не привязанных к той или иной конфигурации (например, обмен с информационными системами, постро- енными не на основе системы «1С:Предприятие»); • создание собственной системы типов и значений для обработки произ- вольных данных; • описание типов параметров и возвращаемых значений Web-сервисов. В данном разделе мы остановимся на вопросе сериализации данных на основе механизма XDTO. Использование механизма для описания типов параметров и возвращаемых значений Web-сервисов будет рассмотрено в отдельной главе «Использование XDTO для описания типов параметров и возвращаемых значений Web-сервисов» на стр. 139. В настоящее время обмен с различными программными системами реализу- ется с использованием XML. Механизм XDTO позволяет создавать требуемые для обмена схемы XML и формировать XML-документы, удовлетворяющие этим схемам. Основным понятием, на котором строится механизм XDTO, является фабрика XDTO. Фабрика XDTO содержит описание всех типов, с которыми оперирует система. В частности, при создании новой информационной базы «1С:Предприятия» автоматически создается глобальная фабрика XDTO, которая описывает все типы, используемые в конфигурации. Эта фабрика доступна через свойство глобального контекста ФабрикаХБТО. В общем случае фабрика XDTO создается на основании описаний всех типов, которые зарегистрированы в фабрике. Для создания фабрики XDTO средствами встроенного языка используется конструктор объекта Фабри- KaXDTO, которому передается набор схем XML, содержащийся в объекте НаборСхемХМЬ.
В системе «1С:Предприятие» реализована сериализация данных на основе механизма XDTO, которая позволяет сериализовать в/из XML: • все типы данных, хранящиеся в базе данных; ш некоторые другие типы. XDTO-сериализация предназначена для сохранения данных объекта в файл XML и создания объекта на основе данных, хранящихся в файле XML. Для этого используется объект СериализаторХОТО, который может быть получен с помощью конструктора на основе существующей фабрики XDTO. Например, сериализация ссылки на элемент справочника Номенклатура в файл XML может быть выполнена с помощью следующего программного кода (листинг 1.63). Пример можно посмотреть на приложенном диске, конфигурация «Интег- рация с другими информационными системами», обработка «РаботаСХМЬ». Сериализация ссылки на элемент справочника «Номенклатура» в файл XML В процедуре СериализацияВХМЬО используется серверная функция ПолучитьСсылкуНаЭлементСправочника(), которая возвращает на клиента ссылку на номенклатуру (листинг 1.64). Функция «ПолучитьСсылкуНаЭлементСправочника()»
Сериализация ссылки на элемент справочника Номенклатура из файла XML может быть выполнена с помощью следующего программного кода (листинг 1.65). Сериализация ссылки на элемент справочника «Номенклатура» из файла XML В процедуре СериализацияИзХМЬО используется серверная процедура ЗаписатьНоменклатуруО, в которую передается сериализованное значение ссылки на номенклатуру. В процедуре по этой ссылке получается XML-значение, из него получается объект - элемент справочника. И затем этот элемент редактируется и записывается (листинг 1.66). Процедура «ЗаписатьНоменклатуруО»
Даже при организации обмена данными между информационными базами «1С:Предприятия» довольно редкой является ситуация, когда структура объектов конфигурации (даже в рамках обмениваемых данных) полно- стью совпадает. Что делать, когда структура объектов различается? Один из вариантов решения задачи приводится ниже (данный подход не обяза- тельно должен использоваться только при организации обмена между базами «1 С:Предприятия 8»). Считаем что конфигурации, между которыми производится обмен, отлича- ются только структурой справочника Номенклатура. Структура остальных объектов совпадает. В базе данных - источнике в справочнике Номенклатура присутствует реквизит Артикул (тип СправочникСсылка.Артикулы), в базе-приемнике существует реквизит Куратор (тип СправочникСсылка.Физичес- киеЛица). Все остальные реквизиты совпадают, их состав: Код, тип Число; • Наименование, тип Строка; • ПолноеНаименование, тип Строка; • ЗакупочнаяЦена, тип Число; • Картинка, тип ХранилищеЗначения. В этом примере так же, как это подробно описано в разделе «Работа с простыми типами» на стр. 50, передача XML-документа между клиентом и сервером происходит через временное хранилище. Выгрузка данных выполняется с помощью трех процедур: Выгруз- каДанных() (листинги 1.67, 1.68), ЗаписатьДанныеО (листинг 1.69) и НоменклатураЗаписатьХМЬО (листинг 1.70). Пример можно посмотреть на приложенном диске, конфигурация «Интег- рация с другими информационными системами», обработка «Pa6oTaCXML». Процедура «ВыгрузкаДанных()»
Процедура «ЗаписатьДанныеО» Процедура «НоменклатураЗаписатьХМЦ)»
Порядок взаимодействия данных процедур можно проиллюстрировать следу- ющей схемой (рис. 1.9). Взаимодействие процедур при записи данных В процедуре ВыгрузкаДанныхО (см. листинг 1.68) производится перебор выгружаемых данных. Данные для выгрузки определяются в табличной части ВыгружаемыеДанные. У табличной части один реквизит табличной части СсылкаНаОбъект (набор типов Любая ссылка). В процедуре ЗаписатьДанныеО (см. листинг 1.69) проверяется: если запи- сываемый объект является элементом справочника Номенклатура, то вызы- вается специализированная процедура для его записи НоменклатураЗа- писатьХМЬО (см. листинг 1.70), в противном случае запись производится с помощью метода системы ЗаписатьХМЬО. В процедуре НоменклатураЗаписатьХМЬО производится «ручное» формирование элемента CatalogObject.Номенклатура.Вручную (начиная с записи начала элемента и заканчивая записью конца элемента). При выгрузке двух элементов, первый из которых представляет собой элемент справочника Контрагенты, а второй --- элемент справочника Номенклатура, полученный XML-документ будет иметь следующий вид (листинг 1.71).
Листинг 1.71. Пример сформированного XML-документа Загрузка данных из XML-документа может быть осуществлена с помощью следующих процедур и функций: ЗагрузкаДанныхО (листинги 1.72, 1.73), ВозможностьЧтенияДанныхО (листинги 1.74), Прочитать Данные () (листинг 1.75) и НоменклатураПрочитатьХМЬО (листинг 1.76). Процедура «ЗагрузкаДанныхО»
Процедура «ЧтениеДанныхХМЦ)» Функция «ВозможностьЧтенияДанных()»
Функция «ПрочитатьДанныеО» Функция «НоменклатураПрочитатьХМЦ)»
Порядок взаимодействия процедур можно представить в виде следующей схемы (рис. 1.10). Взаимодействие процедур при чтении данных В процедуре ЗагрузкаДанныхО (см. листинг 1.73) производится выборка (последовательный обход) элементов, содержащих данные. Для каждого элемента в функции ВозможностьЧтенияДанныхО (см. листинг 1.74) проверяется возможность чтения. Причем если имя типа равно Cata- logObject.Номенклатура.Вручную, возвращается значение Истина, в противном случае вызывается «штатный» метод «1С:Предприятия» ВозможностьЧтенияХМЬО для выполнения этой проверки для других типов. Чтение данных из элемента производится в функции ПрочитатьДанныеО (см. листинг 1.75). Если читается элемент CatalogObject. Номенклату- ра. Вручную, то тогда для чтения вызывается специализированная функция НоменклатураПрочитатьХМЬО (см. листинг 1.76), в противном случае чтение осуществляется с помощью «штатного» метода ПрочитатьХМЬО. Следует обратить внимание на тот факт, что в данном случае потребовалась «ручная» отработка изменений, как на стороне выгрузки, так и на стороне загрузки. Может возникнуть вопрос: что делать, если в объекте приемника добавлен (по сравнению с объектом источника) дополнительный реквизит. Стоит ли вносить изменения как на стороне выгрузки, так и на стороне загрузки? Разберем этот вопрос последовательно. Да, можно выгрузить объект как есть, но при этом в XML-элементах, подчиненных элементу объекта,
не будет данных о типах свойств, реквизитов. В итоге их загрузка (универ- сальная) будет затруднена. Скорее всего, в этом случае придется прописывать очень жесткие механизмы (если этот элемент имеет имя Картинка, значит, его тип ХранилищеЗначения и т. п.). Единственным случаем, когда можно обойтись без изменения процедуры загрузки, это когда в объекте приемника меньше реквизитов, чем в источнике. В этом случае можно «подделать» структуру элемента так, чтобы метод ПрочитатьХМЬО его воспринял. При решении задач обмена может потребоваться передача довольно боль- шого объема данных, как посредством каких-либо интернет-технологий, так и другими средствами. В связи с объемом этих данных может возникнуть необходимость в их сжатии перед передачей и распаковкой после приема. Платформа «1С:Предприятие» предоставляет возможности работы с ZIP- архивами. Для этого в системе существуют объекты Запись г1РФайла (ответственный за запись) и Чтениег1РФайла (ответственный за чтение архивов). Для того чтобы записать файлы в ZIP-архив, необходимо выполнить несколько простых действий: • создать архив с необходимыми параметрами, в который будут помещаться файлы; • поместить в архив необходимые файлы; • записать архив. Рассмотрим эти действия на следующем примере (листинг 1.77). Пример можно посмотреть на приложенном диске, конфигурация «Интеграция с другими информационными системами», обработка «Рабо- TaCZIP Архивами». 1.77. Пример записи файла в ZIP-архив
Создание объекта Записьг1РФайла можно осуществить двумя путями: • создать инициализированный объект (см. листинг 1.77); • создать неинициализированный объект и вызвать у него метод Открыть () (файл архива не должен существовать в этом случае), листинг 1.78. Пример использования неинициализированного объекта «Запись2!РФайла» При создании нового архива (либо при создании конструктором, либо методом Открыть ()) требуется указать: • Имя файла, куда будет записан архив. Этот параметр является обяза- тельным. Если такой файл уже существует на диске, он будет перезаписан (в момент вызова метода Записать ()). • Пароль доступа к архиву. Если этот параметр пропущен или равен пустой строке, то шифрование производиться не будет. • Комментарий к архиву. • Метод сжатия файлов в архиве. На выбор предоставляется возможность скопировать файлы в архив без сжатия или сжать их. По умолчанию файлы сжимаются. • Уровень сжатия файлов в архиве. Можно выбирать между минимальным, оптимальным и максимальным сжатием. По умолчанию используется оптимальное сжатие. • Метод шифрования. Можно защитить архив методом шифрования ZIP20, совместимым с большинством программ, или с помощью шифрования на основе новейшего стандарта AES с различной длиной ключа (128, 192 и 256 бит). Однако следует помнить, что данный метод может быть не совместим с некоторыми программами архивирования старых версий. После создания объекта необходимо добавить в него сжимаемые файлы. Для этой цели используется метод Добавить (). У него 3 параметра: • Полное имя файла или маска. • Режим сохранения путей к файлу. Можно сохранять полные пути, не сохранять пути совсем или сохранять пути относительно каталога. • Режим обработки подкаталогов. Можно обрабатывать подкаталоги рекур- сивно или не обрабатывать их. Параметр имеет смысл, если в качестве имени указана маска.
После того как все необходимые файлы добавлены, можно записать архив на диск, воспользовавшись методом Записать(). Важно понимать, что до выполнения этого метода никаких реальных дейс- твий по созданию архива не происходит. После записи архива на диск объект закрывает его, и для работы со следующим архивом необходимо выполнить метод Открыть (). Особенности упаковки файлов по маске Остановимся подробнее на особенностях упаковки файлов по маске. Предположим, что у нас есть следующие файлы: c:\ZIP\filel.xls c:\ZIP\file2.xls c:\ZIP\file.doc c:\ZIP\Test\file3.xls c:\ZIP\Test\file4.xls Для упаковки всех этих файлов в архив можно воспользоваться следующим кодом (листинг 1.79). Пример добавления файлов в ZIP-архив Следует отметить, что относительные пути актуальны только при задании маски (значение СохранятьОтносительныеПути системного перечис- ления РежимСохраненияПутейг1Р). В архив файлы попадут следующим образом: c:\ZIP\filel.xls \file3.xls \file4.xls Добавить файлы в архив можно и другим способом (листинг 1.80). Пример добавления файлов в ZIP-архив
В результирующий архив попадут следующие файлы: \filel.xls \file2.xls При создании архива можно включать файлы во вложенных каталогах (листинг 1.81). Пример добавления файлов из вложенных каталогов в ZIP-архив В результирующий архив попадут следующие файлы: \filel.xls \file2.xls \Test\file3.xls \Test\file4.xls Особенности работы метода «ДобавитьО» Упаковать файлы в архив можно несколькими способами в зависимости от того, какой результат необходим. Упаковать некоторые файлы в папку ZIP с сохранением структуры ката- логов. Предположим, что у нас есть следующие файлы: c:\ZIP\filel.xls c:\ZIP\Test\file3.xls Добавить их в архив можно, вызывая для каждого метод ДобавитьО с указанием требуемых параметров (листинг 1.82). Пример добавления файлов в ZIP-архив В архив файлы попадут следующим образом: \ZIP\filel.xls \ZIP\Test\file3.xls
Упаковать все файлы в папку ZIP без сохранения структуры каталогов. Предположим, что у нас есть следующие файлы: c:\ZIP\filel.xls c:\ZIP\Test\file3.xls Для добавления всех файлов передадим в метод Добавить () маску для поиска всех файлов (*.*), скажем, что нет необходимости сохранять пути для файлов, и укажем, что требуется производить поиск в подпапках (листинг 1.83). Пример добавления файлов в ZIP-архив В архив файлы попадут следующим образом: \-filel.xls \file3.xls При этом следует помнить, что если в разных папках будут файлы с одинако- выми именами, то операция выполнена не будет из-за того, что фактически мы попытаемся добавить в архив файлы с одинаковыми именами. Упаковать все файлы в папку ZIP с сохранением относительных путей. Предположим, что у нас есть следующие файлы: c:\ZIP\filel.xls c:\ZIP\Test\file3.xls Для добавления всех файлов передадим в метод Добавить () маску для поиска всех файлов (*.*), скажем, что необходимо сохранять отно- сительные пути для файлов, и укажем, что требуется производить поиск в подпапках. При этом следует помнить, что относительные пути будут начи- наться от папки, в которой начался поиск (листинг 1.84). Пример добавления файлов в ZIP-архив В архив файлы попадут следующим образом: \filel.xls \Test\file3.xls
На приемной стороне при получении архива возникает задача его чтения. С точки зрения объекта Чтениег1рФайла необходимо выполнить два действия: • открыть полученный архив; • распаковать файлы (извлечь их из архива). Создание объекта Чтениег1рФайла может производиться двумя способами: • создать инициализированный объект (листинг 1.85); я создать неинициализированный объект (листинг 1.86). Пример можно посмотреть на приложенном диске, конфигурация «Интеграция с другими информационными системами», обработка «Рабо- TaCZIP Архивами». Пример использования объекта «Чтение71рФайла» Пример использования объекта «Чтениег1рФайла» Извлечение файлов из архива может осуществляться двумя методами: я метод ИзвлечьВсе() (листинг 1.87); • метод Извлечь () (каждый файл по отдельности), листинг 1.88. Листинг 1.87. Пример извлечения файлов из ZIP-архива Пример извлечения файлов из ZIP-архива При взгляде на приведенный код может возникнуть вопрос: зачем же указы- вать пароль для расшифровки, если мы уже указали его при открытии? Суть этого в том, что формат ZIP-архива позволяет указать произвольный пароль для любого файла, и многие популярные программы архивирования
поддерживают такую возможность. При указании индивидуального пароля распаковки будет использоваться он. А если индивидуальный пароль не указан, то пароль, указанный при открытии архива. После извлечения файлов для прекращения работы с архивом необходимо выполнить метод Закрыть (). Приведем пример распаковки файлов из архива (листинг 1.89). Пример распаковки файлов из ZIP-архива При работе с большими объемами данных могут возникнуть проблемы при пересылке архивных файлов. Типичной такой проблемой является ограничение некоторых почтовых серверов на размер сообщения - если письмо превышает некий заранее установленный размер, оно отбрасыва- ется сервером. Применительно к «1С:Предприятию» такая ситуация может возникнуть при пересылке больших сообщений обмена данными. Для решения этих проблем можно использовать функции глобального контекста РазделитьФайл () и ОбъединитьФайлы(). Функция РазделитьФайл () предназначена для разбиения файла на несколько частей указанного размера. Функция ОбъединитьФайлыО, наоборот, позволяет из нескольких томов собрать один файл. Пример использования функции РазделитьФайл () приведен в листинге 1.90.
Пример можно посмотреть на приложенном диске, конфигурация «Интеграция с другими информационными системами», обработка «Рабо- TaCZIP Архи вами». Пример использования функции «РазделитьФайл()» Первый параметр функции содержит имя архива, во второй записывается размер каждой части файла в байтах, в третьем параметре указывается путь, по которому будут размещаться создаваемые файлы. Функция возвращает массив имен созданных файлов. Функцию ОбъединитьФайлыО можно использовать двумя способами: • указывая в первом параметре массив файлов, которые необходимо объеди- нить (листинг 1.91); • указывая в первом параметре шаблон, в соответствии с которым будет производиться объединение (листинг 1.92). 1.91. Пример использования функции «ОбъединитьФайлыО» 1.92. Пример использования функции «ОбъединитьФайлыО» Во втором параметре функции указывается полное имя создаваемого в резуль- тате объединения файла. Кроме этого способа существует также возможность объединить файлы в один с помощью команды операционной системы COPY. Для этого нужно воспользоваться ее возможностью конкатенации двоичных файлов (листинг 1.93). 1.93. Пример использования команды COPY
Использование интернет-технологии Прежде чем приступить к рассмотрению возможностей интернет-техно- логий, которые могут использоваться платформой «1С:Предприятие» для реализации различных механизмов интеграции с другими информацион- ными системами, рассмотрим основы работы этих технологий. Среди интернет-технологий распространена модель «Клиент-Сервер», разде- ляющая взаимодействующие стороны по функциональности клиента (запра- шивающего выполнение операции) и сервера (выполняющего запрошенную операцию). Взаимодействие клиента и сервера производится в соответствии с определенными правилами (протоколом). Схематично модель «Клиент- Сервер» можно изобразить следующим образом (рис. 1.11). Модель клиент-сервер Каждый компьютер в глобальной сети Интернет обладает неким уникальным идентификатором (IP-адресом). При организации любого взаимодействия учитываются IP-адреса, как клиента, так и сервера. Кроме IP-адресов допол- нительно используется такое понятие, как порт. Под портом понимается некая адресная точка (локально на компьютере), через которую и производится взаимодействие. Как на стороне сервера, так и на стороне клиента порт обслуживается какой-либо (специализированной) программой. Доступ клиента (это может быть программа Microsoft Internet Explorer и т. д.) из локальной сети в сеть Интернет может производиться как напрямую, так и через специализированную службу: прокси-сервер (некая служба- посредник). Задача службы --- выполнять запросы клиентов к серверу от сзоего имени, получать, выдавать, хранить (для повторной отправки) ответы серверов. При использовании этой службы клиент выполняет запрос не к серверу, а к прокси-серверу (с указанием данных сервера, содержащего запрашива- емый ресурс). Если такой запрос уже проходил через прокси-сервер и ответ
хранится в его базе данных (это определяется набором факторов, например таких, как «время жизни ответа», политика администратора сервера и т.п.), то запрос к серверу, содержащему запрашиваемый ресурс, не производится, ответ выбирается из базы данных. Использование такой службы позволяет экономить внешний (по отношению к локальной сети) трафик, более быстро получать ответы на часто задаваемые вопросы. Схематично этот процесс выглядит следующим образом (рис. 1.12). Прокси-сервер После рассмотрения принципов перейдем к рассмотрению конкретных технологий, которые могут использоваться механизмами, реализованными в «1С:Предприятие». Можно сказать, что HTML-документ представляет собой текстовый файл, имеющий определенную структуру, которому принудительно дано расши- рение НТМ или HTML. На самом деле более правильно говорить о языке HTML (язык разметки гипертекста). С этой точки зрения HTML-документ - это документ с текстовым содержимым, написанный на языке HTML. Структура HTML-документа задается с помощью так называемых «тегов» (выражений, заключенных в угловые скобки). Набор тегов и их свойств (значений свойств) зафиксирован. Изучение языка HTML сводится к изучению конечного множества тегов, свойств тегов и их значений. Если говорить о «задаче, решаемой языком HTML», то это форматирование отображаемых данных. В этом смысле теги можно разбить на «теги струк- туры документа», «теги форматирования» и «другие». Основные теги, задающие структуру HTML-документа, следующие (листинг 1.94).
В теле документа могут располагаться различные форматирующие теги. Пример таких тегов приведен в листинге 1.95. Пример форматирующих тегов Данные в HTML-документе можно организовывать в таблицы (листинг 1.96). Пример таблицы Для навигации (переходу к другим ресурсам) могут использоваться гипер- ссылки (листинг 1.97). Пример использования гиперссылки Следует отметить, что в данном разделе не ставится задача познакомить со всем множеством тегов - это удел специализированной литературы. Рассматриваем только основные понятия. Если собрать все продемонстрированные фрагменты и запустить полученный HTML-документ на просмотр в специализированной программе (например, Microsoft Internet Explorer), то получим, например, следующую картинку (рис. 1.13).
Пример HTML-документа В платформе «1С:Предприятие» существует специализированный вид поля формы, который позволяет просматривать HTML-документы. Функциональность поля формы вида ПолеНТМЬДокумента целиком зависит от установленной на локальном компьютере программы интернет-браузера (она ею обеспечивается). Для просмотра различных интернет-ресурсов, возвращающих ответ в виде HTML-документа (это не обязательно должны быть определенные в явном виде HTML-документы, также можно смотреть результат обращения к файлам *.asp, *.jsp и т.д.), нужно подставить адрес запрашиваемого ресурса в значение строкового реквизита, который отображается полем HTML-доку- мента (листинг 1.98). Пример можно посмотреть на приложенном диске, конфигурация «Интеграция с другими информационными системами», обработка «Pa6oTaCHTML». Поимео использования поля НТМ1_-документа Для работы с историей просмотренных страниц можно использовать методы Вперед () и Назад () (листинг 1.99). Пример использования методов «ВпередО» и «НазадО»
Поле HTML-документа, так же как и большинство специализированных программ, поддерживает работу с объектной моделью HTML-документа, которая зависит от установленной операционной системы и используемого интернет-браузера. Поэтому в каждом конкретном случае программная модель может быть разной. Например, ниже описана модель HTML-документа, используемая компанией «Майкрософт» в браузере Internet Explorer. Эту модель можно представить в виде набора взаимосвязанных объектов (каждый из которых определяется при помощи соответствующих тегов HTML). Схема фрагмента данной модели представлена на рис. 1.14. Фрагмент объектной модели HTML-документа Рассмотрим следующий HTML-документ (листинг 1.100). Пример HTML-документа
Визуально этот документ отображается следующим образом (рис. 1.15). Рис. 1.15. HTML-документ С точки зрения объектной модели его можно упрощенно представить следу- ющим образом (рис. 1.16). Рис. 1.16. Структура HTML-документа
Свойство Документ поля HTML-документа позволяет получить СОМОбъект, который содержит объект document, представленный в объектной модели. У поля формы вида Поле HTML документа существуют следующие события: • Событие ПриНажатии. Возникает при нажатии (с помощью мыши или клавиатуры) на любом элементе внутри окна поля HTML-документа. • Событие ДокументСформирован. Возникает, когда HTML-документ построен и готов к использованию. Если понадобится активно работать с объектной моделью, настоятельно рекомендуем использовать обработчик события поля HTML-документа ДокументСформирован. Событие возникает, когда документ загружен полностью (либо в ряде случаев, когда загружен пустой документ: blank). Этот момент можно использовать для начала попытки работы с объектной моделью. Протокол HTTP (hypertext transfer protocol) - это протокол обмена гипер- текстом (фактически обмен HTML-документами и их составляющими - картинками, flash-анимацией и т.д.). В качестве HTTP-сервера (программы, которая обслуживает нужный порт) может использоваться соответствующая служба Microsoft Internet Information Services. Для обращения к HTML-ресурсу нужно знать имя сервера и порт, который обслуживается нужной программой (обычно этот порт имеет номер 80). При настройке соединения для указания параметров доступа к прокси- серверу используется объект ИнтернетПрокси, для указания параметров доступа к HTTP-серверу - объект НТТРСоединение. Пример работы с объектами НТТРСоединение и ИнтернетПрокси приведен в листинге 1.102. Пример можно посмотреть на приложенном диске, конфигурация «Интег- рация с другими информационными системами», обработка «РаботаСНТТР». Для того чтобы заполнить анкету, загруженную в поле HTML-документа, можно воспользоваться следующим фрагментом кода (листинг 1.101). Пример заполнения анкеты
Пример работы с HTTP-соединением В рассмотренном механизме используются следующие «внешние» пара- метры: • СерверИсточник - параметр, указывающий сервер, где смотрим файлы, например, localhost или users.v8.lc.ru/Actual.aspx. • СтрокаПараметраПолучения - полное имя получаемого файла на сервере, например, /test/warning.gif.
• ИмяВходящегоФайла - полное имя сохраняемого файла на локальном компьютере, например, c:\test.gif. • ИмяПользователя - параметр, содержащий имя пользователя прокси- сервера. • ПарольПользователя - параметр, содержащий пароль на доступ к прокси- серверу; • ИспользуетсяПрокси - параметр, определяющий, используется ли прокси- сервер (тип Булево). То, что ни в каком из объектов явно не указываются порты обращения к серверам, говорит о том, что используются значения по умолчанию. После установки соединения с сервером файлы получаются с сервера методом Получить (). Работать с FTP-ресурсами (копировать на них или с них файлы) можно двумя способами: • основываясь на функциональности процедуры КопироватьФайл() (он может использоваться и для копирования файлов в локальной сети, и для работы по протоколу FTP). • используя специализированные объекты БТРСоединение, ЕТРФайл, ИнтернетПрокси. Рассмотрим оба варианта. Для копирования файла с FTP-сервера (или ресурса локальной сети) в локальный каталог компьютера можно использовать следующий фрагмент кода (листинг 1.103). Пример можно посмотреть на приложенном диске, конфигурация «Интег- рация с другими информационными системами», обработка «РаботаСНТТР». Пример использования процедуры «КопироватьФайл()»
Для доступа к FTP-серверам можно использовать специализированный объект РТРСоединение. Кроме этого может использоваться объект ИнтернетПрокси. Протокол FTP - это протокол обмена файлами. В качестве FTP-сервера (программы, которая обслуживает нужный порт) может использоваться соот- ветствующая служба Microsoft Internet Information Services. Для обращения к FTP-pecypcy нужно знать имя FTP-сервера и порт, который обслуживается нужной программой (обычно этот порт имеет номер 21). При настройке соединения для указания параметров доступа к прокси-серверу используется объект ИнтернетПрокси, для указания параметров доступа к FTP-серверу - объект РТРСоединение. Пример работы с объектами РТРСоединение и ИнтернетПрокси приведен в листинге 1.104. Пример можно посмотреть на приложенном диске, конфигурация «Интег- рация с другими информационными системами», обработка «РаботаСНТТР».
Листинг 1.104. Пример использования объекта «РТРСоединение»
В рассмотренном механизме используются следующие «внешние» пара- метры: • МаскаФайлов - параметр, содержащий маску для файлов загрузки. • ПутьНаСервере - содержит путь на FTP-сервере до нужных файлов, например, /setup/. • СерверИсточник - параметр, указывающий сервер, где смотрим файлы, например, ftp.v8.lc.ru. * Путь - параметр, определяющий каталог, куда перемещать файлы. • ИмяПользователя - параметр, содержащий имя пользователя прокси- сервера. • ПарольПользователя - параметр, содержащий пароль на доступ к прокси- серверу. • ИспользуетсяПрокси - параметр, определяющий, используется ли прокси- сервер (тип Булево). После установки соединения с сервером файлы получаются с сервера методом Получить О. С помощью объекта ИнтернетПочта можно организовывать прием, отправку писем. Объект ИнтернетПочта позволяет работать с почтовыми серверами напрямую по протоколам SMTP, РОРЗ. Прежде чем приступить к рассмотрению материала данного раздела, вспомним основные понятия, используемые при рассмотрении различных интернет-технологий. Для подключения к какому-либо серверу (в том числе и к почтовому) необходимо знать его адрес и порт, на котором обслуживаются запросы в соответствии с интересующим протоколом. Для работы с почтовым сервером объект ИнтернетПочта может использовать протокол SMTP (отправка сообщений, порт по умолчанию No 25) и РОРЗ (получение сообщений, порт по умолчанию No 110). Настройки обращения к почтовым серверам указыва- ются в специализированном объекте ИнтернетПочтовыйПрофиль. Рассмотрим пример, позволяющий отправлять почтовые сообщения (листинг 1.105). Пример можно посмотреть на приложенном диске, конфигурация «И нтеграция с другими информационными системами», обработка «РаботаСПочтой».
Пример отправки почтовых сообщений
В данном примере используются следующие входные параметры: • ИмяФайлаСообщения - полное имя отправляемого файла. • СервервМТР - имя сервера, например smtp.mail.ru. • ОтправительПочтовогоСообщения - полное имя отправителя сообщения, например, <логин>@таП.ги. • ПочтовыйАдресОбмена - почтовый адрес. • СерверРОРЗ - содержит адрес сервера, например pop3.mail.ru. • Пользователь, например, <логин>. а Пароль. В данном примере используется почтовый сервер mail.ru. Работа с ним имеет такую особенность: перед первой отправкой почты ее нужно сначала один раз получить с сервера. И обязательно требуется указать отправителя почтового сообщения. Прочитать сообщения можно, используя следующий фрагмент кода (листинг 1.106). Пример чтения почтовых сообщений
В примере используются следующие входящие данные: • СерверРОРЗ - содержит адрес сервера, например pop3.mail.ru; • Пользователь; • Пароль. У метода Выбрать () в данном случае определен один параметр (Ложь), озна- чающий, что письма с сервера не удаляются. Из всех писем, которые нахо- дятся на почтовом сервере, отбираются только те, у которых в теме определен префикс СообщениеОбмена. Остальные сообщения (считаем, что они личные) остаются на сервере. Обратите внимание, что при работе с объектом ИнтернетПочта отсутствует такое понятие, как «непрочитанные письма». В ряде случаев возникает необходимость оставлять находящиеся на сервере сообщения довольно длительное время (даже после прочтения). При большом потоке писем полная их загрузка может занимать много времени (такие потери времени могут быть крайне нежелательны). Для того чтобы решить эту проблему, существует возможность не загружать полностью все почтовые сообщения, а первоначально загружать только их конверты. Метод ПолучитьЗаголовки() объекта ИнтернетПочта позволяет полу- чать с сервера только заголовки сообщений. Благодаря этому, например, можно получить информацию о теме, отправителе и т. д. и решить, принимать ли это письмо, оставить его или сразу удалить. Данный метод возвращает массив объектов типа ИнтернетПочтовоеСо- общение. Каждый объект содержит информацию из заголовка сообщения. Вложения и тексты с сервера не принимаются. Например, требуется получить все заголовки почтовых сообщений (листинг 1.107). Пример получения заголовков почтовых сообщений
При просмотре можно заполнять новый массив заголовками сообщений, которые в дальнейшем можно попытаться получить полностью. Сам процесс получения может выглядеть следующим образом (листинг 1.108). Пример получения почтовых сообщений Используя метод ПолучитьЗаголовкиО, можно получать сообщения по одному. Кроме того, можно заключить процедуру получения в операторы Попытка ... Исключение, что позволит продолжить получение, если при приеме определенного сообщения произошла ошибка. Также можно помес- тить в форме индикатор для графического отображения процесса получения сообщений. Выше мы рассматривали пример, как с помощью почты передавать файлы обмена. Теперь рассмотрим вариант, когда тело сообщения формируется с помощью форматированного документа, в него помещается форматиро- ванный текст, картинки, ссылки, специальные символы. Затем это сообщение отправляется, принимается с помощью почтового сервера и отображается в форме обработки в HTML-документе. Для этого в обработку РаботаСПочтой нужно добавить реквизит типа Форма- тированныйДокумент и перетащить его в дерево элементов формы. Для отображения командной панели форматированного документа в форме нужно добавить над ним группу вида Командная панель и заполнить ее свойство Источник команд реквизитом формы, который будет содержать этот форматированный документ (рис. 1.17). Визуально при создании исходящего сообщения форматированный документ отображается следующим образом (рис. 1.18).
Отображение форматированного документа в форме Тело отправляемого сообщения
Для отправки сообщения, содержащего форматированный документ, можно использовать следующий фрагмент кода (листинг 1.109). Пример отправки почтовых сообщений
Для отправки содержимого форматированного документа сначала исполь зуется его метод ПолучитьНТМЬО, который получает HTML-составля- ющие форматированного документа - массив картинок и HTML-текст. Затем полученные картинки добавляются как вложения в почтовое сооб- щение и сопоставляются с текстом письма путем установки свойства Идентификатор объекта ИнтернетПочтовоеВложение. HTML-текст добавляется в массив текстов почтового сообщения с указанием типа текста ТипТекстаПочтовогоСообщения.НТМЬ. Остальная работа по отправке сообщения выполняется с помощью методов Подключиться () и Послать () объекта ИнтернетПочта. Для чтения сообщения, содержащего форматированный документ, можно использовать следующий фрагмент кода (листинг 1.110). Пример чтения почтовых сообщений
Для отображения содержимого полученного сообщения используется элемент формы ТекстНТМ1_ вида Поле HTML документа, связанный с соответс- твующим строковым реквизитом формы. В этот реквизит помещается HTML- текст прочитанного сообщения. Automation Технология Automation предназначена для программного использования объектов, чаще всего не имеющих визуального представления (исклю- чения составляют, например, объекты Microsoft Office Word.Application и Excel.Application, при этом они отображаются в отдельном окне, отличном от окна «1С:Предприятия»). Обычно задачи, которые решаются с помощью этой технологии, это запись и чтение данных в/из специфических (для других приложений) форматов, записи и чтения в какие-либо базы данных. «1С:Предприятие» может выступать как в роли Automation Server, так и в роли Automation Client.
Основное назначение Automation-сервера «1С:Предприятия» - управление приложением системы «1 С:Предприятие» из других приложений и выпол- нение действий, аналогичных интерактивным действиям. Automation-сервер «1С:Предприятие» предоставляет доступ ко всем свойствам и методам своего глобального контекста, имеет дополнительные свойства и методы для выполнения действий, специфичных для работы в режиме Automation. Для запуска системы «1С:Предприятие» в качестве Automation-cepeepa из внешнего приложения выполняется следующая последовательность действий: • создается СОМ-объект с идентификатором V82.Application (толстый клиент) или V82c.Application (тонкий клиент); • выполняется инициализация системы «1 С:Предприятие» методом ConnectO; • вызываются свойства и методы системы «1С:Предприятие» как Automation-сервера. Поставим задачу загрузить данные из листа программы MS Excel в базу данных «1С:Предприятие». В листе данные расположены следующим образом (рис. 1.19). Состав листа Excel Признаком конца табличной части является наличие в колонке «Номер» символа «#». Пример кода приведен в листинге 1.111. В данном примере создается СОМ-объект с идентификатором V82.Application, то есть запускается и инициализируется конфигурация «1С:Предприятие 8.2» в режиме толстого клиента с базой данных в каталоге c:\lnfoBases\Trade. Далее создается экземпляр документа РасходнаяНакладная. Из листа извлекаются данные документа и записываются в объект «1С:Предприятие». В конце алго- ритма открывается форма вновь созданного документа.
Аналогичные действия можно выполнять и в режиме тонкого клиента, когда создается объект V82c.Application. Однако в тонком клиенте недоступны методы прикладных объектов, невозможно обратиться к менеджерам справочников, Пример чтения данных из листа Excel в толстом клиенте
документов и т.п. Поэтому новый документ создается с помощью метода ПолучитьФорму (), обращение к его реквизитам происходит через основной реквизит полученной формы, а поиск ссылки на справочник выполняется в функции ПолучитьСсылкуНаСправочникО общего неглобального модуля РаботаСДанными (листинг 1.112). 1.112. Пример чтения данных из листа Excel в тонком клиенте
В конце алгоритма открывается форма вновь созданного документа, и данные в документ могут быть записаны интерактивно из формы. Объект Automation-сервер «1 С:Предприятия» в качестве своих свойств может иметь: • системные константы; • значения заданных в конфигураторе объектов, доступ к которым осущест- вляется с помощью менеджеров (например, константы, перечисления, справочники, документы, журналы документов, отчеты, обработки, планы видов характеристик, планы счетов, планы видов расчета, регистры); • переменные, объявленные в модуле приложения с ключевым словом Экспорт. Automation-сервер «1С:Предприятия» в качестве своих методов может иметь: • системные процедуры и функции; • процедуры и функции модуля приложения и общих модулей, объявленные с ключевым словом Экспорт; • два дополнительных метода-Connect() и NewObject(). Как и многие современные программные продукты, «1С:Предприятие» может выступать в роли клиентов Automation. Поэтому имеется возможность из системы «1С:Предприятие» обращаться к другой копии «1С:Предприятия» (например, к другой конфигурации) для обмена данными. Здесь также можно запускать «1С:Предприятие» в толстом клиенте (листинг 1.113) и в тонком клиенте (листинг 1.114). Пример можно посмотреть на приложенном диске, конфигурация «Интег- рация с другими информационными системами», обработка «Automation». Пример использования системы «1С:Предприятие» в качестве Automation Client (толстый клиент)
1.114. Пример использования системы «1С:Предприятие» в качестве Automation Client (тонкий клиент) Основное назначение Automation-клиента «1С:Предприятия» - управление другими приложениями из системы «1С:Предприятие» и выполнение действий, аналогичных интерактивным действиям. Можно сказать, что технология рекомендуется к применению, когда не тре- буется предоставлять пользователю интерфейс, выходящий за рамки возмож- ностей «1С:Предприятия», но в то же время требуется взаимодействие с «внешней функциональностью». В общем случае применение этой технологии состоит из двух частей - соз- дание объекта по его идентификатору и последующее использование объекта. Создание объекта выполняется оператором Новый СОМОбъект(Иденти- фикаторОбъекта). Использование созданного объекта ничем не отличается от использования остальных объектов «1С:Предприятия».
Дополнительные возможности предоставляет функция Полу- читьСОМОбъект(). С ее помощью можно создать Automation-объект из файла или подключиться к уже существующему в операционной системе экземпляру Automation-объекта. Пример работы с книгой программы MS Excel приведен в листинге 1.115. Пример можно посмотреть на приложенном диске, конфигурация «Интег- рация с другими информационными системами», обработка «Automation». Пример работы с книгой Excel Следует отметить, что для завершения работы с объектами Microsoft Office, имеющими метод Quito, его желательно вызывать в явном виде.
Внешнее соединение Основная задача, решаемая с помощью внешнего соединения, - обеспечение надежного и быстрого программного доступа к данным системы «1С:Пред- приятие» из внешних приложений. В общем и целом работа с системой «1С:Предприятие» через внешнее соединение подобна работе с системой «1С:Предприятие» в режиме Automation-сервера. Основные отличия заклю- чаются в следующем: • в случае Automation-сервера запускается полноценное приложение «1 С:Предприятия», а в случае внешнего соединения запускается относи- тельно небольшой внутрипроцессный СОМ-сервер; • при работе через внешнее соединение недоступны функциональные возможности, так или иначе связанные с организацией пользовательского интерфейса системы «1С:Предприятия»; • при работе через внешнее соединение не используется модуль приложения конфигурации «1С:Предприятия». Его роль при работе с внешним соеди- нением играет модуль внешнего соединения. При использовании внешнего соединения для доступа к данным системы «1С:Предприятие» имеются следующие преимущества по сравнению с использованием Automation-сервера: • более быстрая установка соединения, так как не требуется создания отдельного процесса операционной системы, а все действия производятся в рамках вызывающего процесса; • более быстрое обращение к свойствам и методам объектов системы «1С:Предприятие», так как для организации обращения не требуется орга- низации межпроцессной коммуникации; • меньший расход ресурсов операционной системы. Для организации доступа к данным системы «1 С:Предприятие» через внешнее соединение выполняется следующая последовательность действий: • создается менеджер СОМ-соединений, с помощью которого производится установка соединения; • через полученный объект внешнего соединения производится обращение к допустимым методам, свойствам и объектам базы данных, с которой установлено соединение. Поставим задачу загрузить данные из листа программы MS Excel в базу данных «1С:Предприятие» (посредством механизма СОМ). В листе данные расположены так же, как и в предыдущем примере (см. рис. 1.19). Признаком конца табличной части является наличие в колонке «Номер» символа «#».
Пример кода приведен в листинге 1.116. Пример чтения данных из листа Excel
В данном примере запускается и инициализируется конфигурация «^Пред- приятия» с базой данных в каталоге c:\lnfoBases\Trade. Далее создается экземпляр документа РасходнаяНакладная. Из листа извлекаются данные документа и записываются в объект «1С:Предприятие». В конце алгоритма документ сохраняется. Обязанности модуля приложения при работе через внешнее соединение выполняет модуль внешнего соединения. Данный модуль может иметь проце- дуры-обработчики событий, в которых могут быть размещены действия, выполняемые при инициализации и завершении соединения соответственно. Процедуры, функции и глобальные переменные, определенные в модуле внешнего соединения с ключевым словом Экспорт, становятся, как и в случае модуля приложения, частью глобального контекста. Внешнее соединение с информационной базой «1С:Предприятия» предо- ставляет полный доступ к глобальному контексту и в качестве своих свойств может иметь: • системные константы; • значения заданных в конфигураторе объектов, доступ к которым осущест- вляется с помощью менеджеров (например, константы, перечисления, справочники, документы, журналы документов, отчеты, обработки, планы видов характеристик, планы счетов, планы видов расчета, регистры); я переменные, объявленные в модуле внешнего соединения с ключевым словом Экспорт. В качестве своих методов внешнее соединение может иметь: • системные процедуры и функции; • процедуры и функции модуля внешнего соединения и общих модулей, объявленные с ключевым словом Экспорт; Открытые внешние соединения могут быть сохранены в пуле для их повтор- ного использования, что позволяет экономить ресурсы и ускорять работу пользователей, которые ранее уже подключались к данной информационной базе. Для управления пулом используются свойства менеджера СОМ- соединений: MaxConnections, PoolCapacity и PoolTimeout. После создания менеджера С-ОМ-соединений используются стандартные значения этих параметров - 0. Поэтому пул хотя и есть, но не используется. Чтобы «1 С:Предприятие» начало использовать пул, нужно установить значения, отличные от 0. Имеется возможность из системы «1С:Предприятие» обращаться к другой копии «1С:Предприятия» (например, к другой конфигурации) для обмена данными (листинг 1.117).
В ряде случаев может возникнуть задача организации связи какого-либо интернет-приложения (например, интернет-магазина) с базой системы «1С:Предприятия». Это может быть обусловлено необходимостью получения текущих остатков на складе, регистрации заказов и т. д. Архитектура веб-приложений может быть различной, но в рамках данного раздела будем рассматривать вариант, в котором приложение состоит из двух частей: • набор HTML, ASP-документов, находящихся в определенном виртуальном каталоге; • база данных, в которой находятся отображаемые данные, и данные, вводимые пользователями. Клиент, используя специальную программу (следует отметить, что очень часто под «клиентом» понимается именно программа отсылающая запрос, а не пользователь), посылает запрос на просмотр интересующего его ресурса. Этот ресурс находится на каком-либо сервере, под управлением специального программного обеспечения (для примера будем рассматривать Microsoft IIS). IIS может работать с так называемыми ASP-документами. Эти документы, как и HTML-документы, представляют собой текстовый файл, которому было дано расширение ASP. Основное отличие состоит в том, что ASP-документ Пример можно посмотреть на приложенном диске, конфигурация «Интег- рация с другими информационными системами», обработка «Automation». 1.117. Пример обращения к другой информационной базе «1С:Предприятия»
выполняется на сервере, и клиенту отсылается результат выполнения. Само «выполнение» возможно благодаря тому, что «asp» документ в общем случае представляет собой скрипт (описание команд на выполнение). Для написания скриптов используются две конструкции: <% код скрипта %> или набор тегов <script language= «имя языка» runat= «server»> и </script>. Первая конструкция используется для написания кода на первичном языке, вторая - на указанном в параметре language. На одной странице может быть несколько скриптовых конструкций. Порядок их выполнения довольно сложный. Для облегчения отслеживания порядка выполнения скриптов рекомендуется в конструкциях <script> помещать определение процедур, функций и вызывать их при использовании тегов <%%>. Только таким образом можно обеспечить однозначность последовательности исполнения скриптов. Для указания странице языка по умолчанию используется директива <%@ 1А1\Ю11А6Е=ИмяЯзыка%>, для указания кодовой страницы используется директива CODEPAGE и т. п. Из текста скрипта (документа ASP) можно создавать различные объекты, в том числе и использовать внешнее соединение с базой «1С:Предприятия», обращаться к специально определенным процедурам и т.д. Общая схема работы представлена на рис. 1.20. Общая схема рассматриваемого примера Клиент производит запрос ASP-документа. IIS получает этот запрос, выпол- няет данный документ. В процессе выполнения создается подключение (через внешнее соединение) к «1С:Предприятию», и, к примеру, выполняется функция, описанная в модуле внешнего соединения. При выполнении форми- руется HTML-документ (или XML, который потом преобразуется в HTML). Сформированный документ возвращается как результат выполнения функции в IIS. IIS, в свою очередь, «передает» ответ на запрос клиенту. Важно понимать, что языки скриптов это отдельные языки, требующие дополнительного изучения.
В контексте ASP-документов, помимо объектов, определяемых выбранным языком скриптов, существует шесть дополнительных объектов, которые предоставляют дополнительные возможности при работе с интернет-прило- жением. Это следующие объекты: • Application - с помощью данного объекта можно управлять всем приложением, создавать видимые во всем приложении объекты. • Ob jectContext - для введения или снятия транзакции. • Request - для приема данных. Поддерживает следующие методы: • Form() - прием данных, отосланных формой методом Post; • QueryStringO - прием данных, отосланных формой методом Get; • Cookies (). • Response - для вывода данных. Поддерживает следующие методы и свойства: • Write () - вывод данных (часто HTML-текст) в формируемый документ; • CacheControl --- контроль кеширования; • Charset - кодовая страница. • Server - объект, позволяющий управлять определенными параметрами сервера. Поддерживает метод CreateObject(). • Session - объект, позволяющий работать с текущей сессий. Поддержи- вает метод SessionID - получение идентификатора сессии. В данном перечне содержатся далеко не все свойства и методы объектов, поддерживаемых IIS. В задачу данного раздела их подробное рассмотрение и не входит. В рамках следующего материала будет использоваться только метод Write() объекта Response. Например, использование конструкции Response.Write("<Ь>Первое</Ь>") приведет к появлению в результи- рующем документе слова Первое, выделенного полужирным шрифтом. В этом примере используется демонстрационная конфигурация «Пример обмена», которая находится на приложенном диске. После установки шаблона этой конфигурации в каталог шаблонов будут скопированы все *.asp и *. xsl файлы, используемые в этом примере. Расположение каталога шаблонов на вашем компьютере можно посмотреть из режима Конфигуратор: Конфигурация - Поддержка - Шаблоны конфигураций и обновлений... Файлы будут находиться в этом каталоге в папке lc\82integration\ comconnector.
В каталоге, являющемся корневым для нашего веб-сервера, разместим два ASP-документа. Документ default.asp будет стартовым файлом веб-ресурса (листинг 1.118). default.asp Файл reflist.asp при обращении к нему (вызывается из файла по умолчанию) возвращает имена всех справочников, определенных в конфигурации (листинг 1.115). Корневой каталог веб-сервера определяется в свойствах веб-сервера по умолчанию в оснастке Internet Information Services (свойство Local Path), рис. 1.21.
Установка корневого каталога веб-сервера В данном документе (см. листинг 1.115) производится создание СОМ-объекта «1С:Предприятия», подключение к информационной базе. Производится установка экспортной переменной модуля внешнего соединения (опреде- ляется путь к файлам XSL преобразований). Вызывается функция getRefListO, которая возвращает HTML-текст, включаемый с помощью метода Write () в ответ сервера клиенту. В информационной базе, которая выступает в качестве СОМ-сервера для веб-приложения, в модуле внешнего соединения необходимо определить следующий текст (листинг 1.120). Фрагмент модуля внешнего соединения
Чтобы соединение с базой устанавливалось, в файловом варианте работы внешнего соединения нужно дать пользователю, от имени которого работает IIS, права на каталог информационной базы (в нашем случае c:/InfoBases/Trade). Для этого сначала необходимо открыть в обозревателе диалог Свойства папки и убедиться, что флажок Использовать простой общий доступ к файлам на закладке Вид снят (иначе закладка Безопасность при установке свойств конкретной папки не будет доступна), рис. 1.22.
Диалог обозревателя «Свойства папки» Затем нужно открыть свойства той папки, где находится информационная база, и на закладке Безопасность добавить пользователя, от имени которого работает IIS, и установить ему флажок прав Полный доступ (рис. 1.23). Свойства папки информационной базы
Преобразование, выраженное через XSLT, описывает правила преобразо- вания исходного дерева XML-документа в конечное дерево другого доку- мента. Преобразование строится путем сопоставления образцов и шаблонов. Образец сравнивается с элементами исходного дерева, а шаблон используется для создания частей конечного дерева. Структура конечного дерева может полностью отличаться от структуры исходного дерева. В ходе построения конечного дерева элементы исходного дерева могут подвергаться фильтрации и переупорядочиванию, также может быть добавлена новая структура. Разберемся в представленном механизме поэтапно. В результате работы объекта Писатель получаем XML-документ следую- щего вида (листинг 1.122). Файл стиля, используемого для проведения преобразования (файл reflist.xsl), показан в листинге 1.121. Листинг 1.121. Файл reflist.xsl
Изначально из файла стиля выбирается шаблон для корневого элемента XML-документа (можно сказать, что он размещается пока в пустом конечном документе), листинг 1.123. Шаблон для корневого элемента XML-документа Далее полученный документ анализируется, и в отведенное место (вместо <xsl:apply-templates select="reference"/>) записывается шаблон для узла reference. Результат представлен в листинге 1.124. Результат после записи шаблона Пример XML-документа
После полного применения преобразования получаем конечный HTML-доку- мент (листинг 1.125).
При желании просматривать формы списков каждого справочника в рассмат- риваемый пример необходимо добавить файл refone.asp (листинг 1.126), разместить в нужном каталоге дополнительный файл стиля refone.xsl (листинг 1.128) и добавить в модуль внешнего соединения функцию getRefOneO (листинг 1.127). Файл refone.asp Функция getRefOneQ
Файл стиля refone.xsl
Механизм работы добавленных файлов такой же, как и ранее рассматриваемый. При желании просматривать содержимое элемента каждого справочника в рассматриваемый пример необходимо добавить файл refitem.asp (листинг 1.129), разместить в нужном каталоге дополнительный файл стиля refitem.xsl (листинг 1.131) и добавить в модуль внешнего соединения функцию getRefltemO (листинг 1.130). Листинг 1.130. Функция getRefltem() Листинг 1.129. Файл refitem.asp
Файл стиля refitem.xsl
Механизм работы добавленных файлов такой же, как и ранее рассматрива- емый. ActiveDocument Технология ActiveDocument предназначена для редактирования документов внешними по отношению к «1С:Предприятию» редакторами. Эта технология позволяет в режиме Конфигуратор (в пользовательском режиме данная особенность недоступна) редактировать документы визуально (например, Word или Excel) непосредственно в окне «1С:Предприятия». При этом элементы пользовательского интерфейса (меню, панели команд и т.д.) заменяются на предоставляемые редактором. Документы могут быть предварительно отредактированы и сохранены в макетах конфигурации, а затем макеты могут использоваться пользователями как основы для создания окончательных версий документов. Для добавления в конфигурацию возможности работы с ActiveDocument необходимо для требуемого объекта (например, для документа РасходнаяНак- ладная) создать новый макет и при этом выбрать соответствующий тип макета (рис. 1.24). Эта технология применяется в случае, когда в конфигурации необходимо хранить данные, редактируемые другим приложением, - такие, например, как шаблоны для факсов или деловых писем, созданные в Microsoft Word, или Конструктор макета
шаблоны прайс-листов в Microsoft Excel. Такая необходимость возникает, как правило, при регламентировании формата документов (как во внут- реннем документообороте, так и при обмене документами со сторонними организациями и клиентами), однако при отсутствии ограничений на формат документа рекомендуется использовать существующие в «1С:Предприятии» возможности по оформлению электронных и печатных документов. Ниже (листинг 1.132) приведен пример кода, получающего из макета (имею- щего тип «Active document») заготовку документа программы Microsoft Word. Имя макета определено как Договор. Пример можно посмотреть на приложенном диске, конфигурация «Интеграция с другими информационными системами», обработка «Рабо- таС Acti veDocument». Пример использования макета Active Document
После получения производится поиск специальным образом определенных ключевых фраз и замена их на данные из информационной базы.
Внешние компоненты Технология создания внешних компонентов разработана для решения специ- альных задач интеграции, в которых требуется тесное взаимодействие между системой «1С:Предприятие 8» и другими программами. Процесс написания файла внешнего компонента описан в документации по созданию внешних компонентов. В данном разделе мы не будем касаться их внутреннего устройства, рассмотрим только способы использования готовых внешних компонентов в системе «1С:Предприятие». Внешние компоненты могут быть созданы по двум технологиям: • Native API --- рекомендуемая технология, появилась в версии «1 (^Предпри- ятие 8.2»; • СОМ - «старая» технология, существовавшая в версиях «^Предприя- тие 8.1» и младше. В версии 8.2 она поддерживается для совместимости со старыми компонентами. В зависимости от контекста исполнения могут использоваться внешние компоненты, созданные только по «новой» технологии или по любой из этих технологий: • Толстый и тонкий клиент могут использовать компоненты, созданные по обеим технологиям. • Веб-клиент может использовать любые компоненты Native API, а компо- ненты СОМ только в том случае, если веб-клиент работает в браузере под управлением ОС семейства Windows. • На сервере можно использовать только компоненты Native API. Внешний компонент представляет собой файл с расширением dll. Так как «1С:Предприятие» может работать на разных операционных системах с различной разрядностью, разработчикам внешних компонентов рекомен- дуется создавать комплект из четырех файлов: для ОС Windows 32 разряда, ОС Windows 64 разряда, ОС Linux 32 разряда, ОС Linux 64 разряда. Эти файлы могут поставляться: • В виде ZIP-архива (рекомендуемый способ для толстого клиента и сервера, а для тонкого клиента и веб-клиента --- это обязательный способ). Архив включает в себя четыре файла внешних компонентов и файл-манифест, описывающий назначение каждого из компонентов. • В виде отдельных файлов. Внешний компонент (либо набор внешних компонентов) может храниться: • на диске (только в виде отдельных файлов); • в макете «1С:Предприятия», содержащем двоичные данные (в виде отде- льных файлов или ZIP-архива);
• в информационной базе в реквизите с типом ХранилищеЗначения (в виде отдельных файлов или ZIP-архива). Ниже мы рассмотрим разные ситуации, в которых требуется подключать внешний компонент. Для подключения внешнего компонента на сервере или в толстом клиенте используется метод глобального контекста ПодключитьВнешнююКом- поненту (). Разберем примеры подключения внешнего компонента в зависимости от вариантов его хранения. Пример подключения внешнего компонента В рассмотренном примере (и далее) используются следующие входные данные: • ПроизвольноеИмя - произвольное имя, задаваемое разработчиком «1С:Предприятия»; • ComponentExtention - расширение, реализуемое компонентом. Это расширение должно быть описано в документации к этому внешнему компоненту. Пример подключения внешнего компонента
Пример подключения внешнего компонента Подключение внешнего компонента из базы данных (ZIP-архив) Пример подключения внешнего компонента Пример подключения внешнего компонента Для подключения внешнего компонента в тонком клиенте или веб-клиенте используются методы глобального контекста ПодключитьВнешнююКом- поненту() и УстановитьВнешнююКомпоненту () (причем метод Уста- новитьВнешнююКомпоненту () используется только тогда, когда внешний компонент расположен не на диске).
Разберем примеры подключения внешнего компонента в зависимости от вариантов его хранения. Данный вариант подключения возможен только в тонком клиенте (листинг 1.131). Пример подключения внешнего компонента Web-сервисы Механизм Web-сервисов позволяет использовать систему «1С:Предприятие» как набор сервисов в сложных распределенных и гетерогенных системах, а также позволяет интегрировать ее с другими информационными системами с использованием сервис-ориентированной архитектуры (SOA). Пример подключения внешнего компонента Пример подключения внешнего компонента
Сервис-ориентированная архитектура предлагает новый подход к созданию распределенных информационных систем, в которых программные ресурсы рассматриваются как сервисы, предоставляемые по сети. Конфигурация системы «1С:Предприятие» может экспортировать свою функциональность через Web-сервисы. Web-сервисы определяются в дереве объектов конфигурации и становятся доступны произвольным информаци- онным системам после их публикации на веб-сервере. Кроме того, система «1С:Предприятие» может обращаться к Web-сервисам сторонних производителей как через статические ссылки на Web-сервисы, определенные в дереве объектов конфигурации, так и с помощью динами- ческих ссылок на Web-сервисы, создаваемых с помощью встроенного языка. В основе сервисной архитектуры системы «1С:Предприятие» находится менеджер сервисов, который выполняет следующие функции: • управление пулом соединений с информационными базами; • поддержка WSDL описаний сервиса; • реализация протокола SOAP, сериализация сообщений, вызов соответс- твующего сервиса. Чтобы функциональность системы «1С:Предприятие» стала доступной внешним потребителям Web-сервисов, необходимо выполнить следующие действия: • Создать в конфигурации необходимые Web-сервисы. • Опубликовать эти Web-сервисы на веб-сервере с помощью специального инструмента конфигуратора (Администрирование • Публикация на веб- сервере...). Этот процесс подробно описан в книге «1С:Предприятие 8.2. Руководство администратора». Для создания Web-сервиса нужно: • Добавить в дерево конфигурации объект ТлГеЬСервис и описать основные свойства этого объекта: • URI пространства имен. Каждый Web-сервис может быть одно- значно идентифицирован по своему имени и URI пространства имен, которому он принадлежит. • Пакеты XDTO. Содержит перечень пакетов XDTO, типы которых могут использоваться для описания типов параметров и возвращаемых значений Web-сервиса. • Имя файла публикации. Содержит имя файла описания Web- сервиса, который расположен на веб-сервере.
• Описать операции, которые может выполнять данный Web-сервис. Основные свойства операций: • Тип возвращаемого значения. Содержит тип значения, которое возвращает операция Web-сервиса. Может являться типом значения XDTO или типом объекта XDTO. • Возможно пустое значение. Показывает, может ли значение, возвращаемое операцией, принимать неопределенное значение. п Имя метода. Содержит имя экспортируемой процедуры, располо- женной в модуле Web-сервиса, которая будет выполняться при его вызове. • Описать параметры выполняемых операций. Основные свойства пара- метров: • Тип значения. Содержит тип значения параметра операции Web- сервиса. Может являться типом значения XDTO или типом объекта XDTO. о Возможно пустое значение. Показывает, может ли параметр операции принимать неопределенное значение. • Направление передачи. Определяет направление передачи данных с помощью параметра. Входной параметр используется для передачи данных Web-сервису; Выходной - для получения данных от Web- сервиса; Входной-выходной может использоваться как для передачи данных, так и для их получения от Web-сервиса. • Создать модуль Web-сервиса и разработать в нем операции, определяющие его функциональность. Объект конфигурации WebCepenc содержит модуль, в котором создаются процедуры на встроенном языке, выполняемые при вызове тех или иных операций Web-сервиса. Типы параметров и возвращаемых значений этих операций описываются с помощью типов XDTO и могут представлять собой либо значения XDTO, либо объекты XDTO. Механизм XDTO представляет собой гибкое средство моделирования данных, которое широко используется в технологии Web-сервисов «^Предпри- ятия». Механизм XDTO позволяет определять объекты переноса данных, которые могут образовывать строгую иерархию и сериализоваться в XML. Эти свойства позволили использовать объекты XDTO в качестве параметров и возвращаемых значений операций Web-сервисов.
Основным понятием, на котором строится механизм XDTO, является фабрика XDTO. Фабрика XDTO содержит описание всех типов, с которыми оперирует система. В частности, при создании новой информационной базы «1С:Предприятия» автоматически создается глобальная фабрика XDTO, которая описывает все типы, используемые в конфигурации. Эта фабрика доступна через свойство глобального контекста ФабрикаХБГО. Серверная часть Web-сервиса может использовать глобальную XDTO фабрику для создания объектов и значений Web-сервиса. Все типы данных XDTO подразделяются на типы-значения и типы-объекты. Типы-значения позволяют определять простые типы, например, строки, числа, даты, булевы значения и т.д. Типы-объекты позволяют определять сложные типы, такие как структуры и массивы. ТипЗначенияХБТО и ТипОбъектаХБТО однозначно идентифицируются двумя свойствами - именем типа и URI пространства имен, которые образуют уникальный идентификатор типа. Рассмотрим более подробно, как задавать с помощью XDTO некоторые характерные типы. Строки Строки моделируются типами-значениями. Строковый тип имеет имя: {http://www.w3.org/2001/XMLSchema}string. В фигурных скобках здесь задается пространство имен типа. Для создания строкового значения нужно выполнить следующий фрагмент кода (листинг 1.141). Пример создания значения строкового типа Строка при передаче представляется в виде текста xml-тега (листинг 1.142). Фрагмент XML-документа Следует учесть, что строки конвертируются в UTF-8 при сериализации.
Целые числа Целые числа моделируются типами-значениями. Целочисленный тип имеет имя: {http://www.w3.org/2001/XMLSchemalint. Для создания целочисленного значения нужно выполнить следующий фрагмент кода (листинг 1.143). Пример создания значения целочисленного типа Число при передаче представляется в виде текста xml-тега (листинг 1.144). Фрагмент XML-документа И аналогично с другими простыми типами. Более подробно о представлении значений простых типов в XML-документе можно прочитать в разделе «Простые типы» на стр. 45. Структуры Перед тем как использовать структуру, необходимо создать пакет XDTO, описывающий тип-объект структуры. Для этого используются средства визуального конструирования, позволяющие добавлять пакеты XDTO в ветку дерева объектов конфигурации Общие • XDTO-пакеты. Пакет XDTO содержит описание некоторого множества типов, принадле- жащих одному пространству имен - пространству имен пакета. Структуры моделируются типами-объектами. Тип-объект может содержать свойства, которые соответствуют элементам структуры. Каждое свойство характеризуется уникальным именем и типом. Тип свойства может быть как типом-значением, так и типом-объектом. Например, для создания структуры Номенклатура из демоконфигурации «Web-сервисы» (ИТС) нужно выполнить следующий фрагмент кода (листинг 1.145). Пример создания объекта структурного типа
Структура при передаче представляется в виде xml-структуры (листинг 1.146). Фрагмент XML-документа Массив при передаче представляется в виде xml-структуры (листинг 1.148). Фрагмент XML-документа Массивы Массивы моделируются свойствами типов-объектов. Тип массива нельзя создать напрямую, но на определенном свойстве типа-объекта можно указать минимальное и максимальное количество элементов массива. Если оба значения равны 1, то это единичное свойство; если максимальное количество больше 1, то множественное свойство; если же максимальное количество равно -1, то количество элементов массива неограниченно. Свойства-массивы реализованы в XDTO через СписокХБТО. Например, для создания массива элементов номенклатуры, определенного в свойстве структуры из демоконфигу- рации «Web-сервисы» (ИТС) нужно выполнить следующий фрагмент кода (листинг 1.147).
Система «1С:Предприятие» может использовать Web-сервисы, предоставля- емые другими поставщиками, двумя способами: • с помощью статических ссылок, создаваемых в дереве объектов конфигу- рации; • с помощью динамических ссылок, создаваемых средствами встроенного языка. При использовании статической ссылки система «1С:11редприятие» получает описание Web-сервиса поставщика только один раз, при создании ссылки. За счет этого достигается большая скорость работы. При использовании динамической ссылки описание Web-сервиса получается каждый раз при вызове Web-сервиса. Скорость работы при этом уменьша- ется, но зато такой подход обеспечивает актуальность описания Web-сервиса поставщика. В случае же использования статических ссылок для получения актуального описания Web-сервиса требуется выполнить повторный импорт WSDL-описания средствами конфигуратора и затем сохранить измененную конфигурацию. Подробнее познакомиться с реализацией механизма Web-сервисов можно в демонстрационных конфигурациях «Web-сервисы» и «Web-сервисы (использование)», прилагающихся к книге на компакт-диске. Эти демонстрационные конфигурации иллюстрируют использование следу- ющих механизмов: • определение Web-сервиса; • определение схемы данных; • получение описания Web-сервиса; • динамическое создание прокси Web-сервиса; • статическое создание прокси Web-сервиса на основе WSCcbuiKH; • вызов операции Web-сервиса; • работа с объектами передачи данных (XDTO). В демонстрационной конфигурации «Web-сервисы» рассмотрен механизм предоставления функциональности системы «1С:Предприятие» через Web-сервисы другим информационным системам и использования ее внешними потребителями этих Web-сервисов (конфигурация «Web-сервисы (использование)»).
Конфигурация «Web-сервисы» демонстрирует создание и публикацию Web-сервиса, содержащего операцию, которая по переданным параметрам выполняет отчет, выгружает данные этого отчета в таблицу значений и возвращает эту таблицу. Конфигурация «Web-сервисы (использование)» демонстрирует возможность доступа к данному Web-сервису из системы «1С:Предприятие». После полу- чения описания Web-сервиса с помощью статических либо динамических ссылок вызывается его операция, в которую передаются параметры выпол- нения отчета, и назад возвращается таблица значений, содержащая данные отчета. Затем эта таблица выводится в таблицу значений. В файловом варианте работы, чтобы пример реализации механизма Web- сервиса корректно работал, нужно дать пользователю, от имени которого работает IIS (IUSR_<XXXX>, IWAM_<XXXX>), права на каталог информационной базы, из которой публикуется Web-сервис (см. рис. 1.23). В конфигурации «Web-сервисы», демонстрирующей первую часть примера, созданы и заполнены справочники Номенклатура, Склады, Контрагенты и документы ПриходнаяНакладная и РасходнаяНакладная. При проведении этих документов формируются движения в регистре накопления ОстаткиНоменк- латуры, который учитывает поступление и расход товаров в разрезе номенк- латуры и складов. На основе виртуальной таблицы остатков и оборотов этого регистра формируется отчет ОстаткиТоваров, который показывает остатки товаров по складам за период (рис. 1.25). Отчет имеет два параметра, задающих отчетный период, - ДатаНачала и ДатаОкончания. Итак, нам нужно создать Web-сервис, выполняющий данный отчет по заданным параметрам и возвращающий данные отчета в виде таблицы значений. Для описания типов параметров и возвращаемых значений Web- сервиса создадим пакет XDTO ДанныеОтчета с пространством имен http://localh.ost/wsreport. В свойстве URI пространства имен содержится http://localhost - адрес веб-сервера, установленного на локальном компьютере с помощью IIS, /wsreport --- каталог, в который будет опубликован Web-сервис. Пакет XDTO будет содержать следующие типы объектов XDTO (рис. 1.26).
Отчет «Остатки товаров» Структура пакета XDTO «ДанныеОтчета» • Номенклатура - для передачи данных элемента справочника Номенклатура. Этот тип объектов XDTO будет содержать свойство: • Наименование - тип string из пространства имен http://www.w3.org/2001/XMLSchema.
• Склад - для передачи данных элемента справочника Склад. Этот тип объектов XDTO будет содержать свойство: • Наименование - тип string из пространства имен http://www.w3.org/2001/XMLSchema. • СтрокаТаблицыОтчета - для передачи данных одной строки отчета. Этот тип объектов XDTO будет содержать следующие свойства: • Номенклатура - тип Номенклатура из пространства имен http://localhost/wsreport. Представляет собой ссылку на объект XDTO, определенный нами выше. • Склад - тип Склад из пространства имен http://localhost/ wsreport. Представляет собой ссылку на объект XDTO, опреде- ленный нами вып1е. о НачальныйОстаток --- тип int из пространства имен http://www.w3.org/2001/XMLSchema. • Приход - тип int из пространства имен http://www.w3.org/2001/XMLSchema. • Расход - тип int из пространства имен http://www.w3.org/2001/ XMLSchema. • КонечныйОстаток --- тип int из пространства имен http://www.w3.org/2001/XMLSchema. • ТаблицаОтчета - для передачи данных всех строк отчета. Этот тип объектов XDTO будет содержать единственное свойство: • Состав - тип СтрокаТаблицыОтчета из пространства имен http://localhost/wsreport. Представляет собой ссылку на объект XDTO, определенный нами выше. Для того чтобы это свойство могло содержать неограниченное множество значений, установим его свойство Максимальное количество в значение-1 (рис. 1.27).
Свойства Web-сервиса «ДанныеОтчета» • URI пространства имен - http://localhost/wsreport; • Пакеты XDTO - http://localhost/wsreport; • Имя файла публикации - wsreport.lcws. У созданного Web-сервиса определим операцию ПолучитьОтчет со следую- щими свойствами (рис. 1.29). Теперь, когда необходимые типы объектов XDTO созданы, добавим в конфи- гурацию «Web-сервис» ДанныеОтчета со следующими свойствами (рис. 1.28). Свойства операции «ПолучитьОтчет»
• Тип возвращаемого значения-ТаблицаОтчета из пространства имен http://localhost/wsreport; • Возможно пустое значение - установлен; • Имя метода - ПолучитьОтчет. У операции ПолучитьОтчет определим параметры ДатаНачала и ДатаОкончания со следующими свойствами (рис. 1.30). Эти параметры будут передаваться в процедуру, связанную с операцией Web-сервиса, для формирования отчета. Свойства параметров операции «ПолучитьОтчет» • Тип значения - тип date из пространства имен http://www.w3.org/2001/XMLSchema; • Возможно пустое значение - установлен; • Направление передачи --- Входной. После этого откроем модуль созданного Web-сервиса и поместим в нем экспортируемую функцию ПолучитьОтчет(), которая будет выполняться при его вызове (листинг 1.149). Функция «ПолучитьОтчет()»
Сначала в функции получается схема компоновки данных отчем а ОстаткиТоваров и соответствующие ей стандартные настройки. Затем
параметрам данных этих настроек присваиваются значения параметров ДатаНачала и ДатаОкончания, переданных в функцию. После этого создается макет компоновки данных отчета с учетом измененных настроек, отчет компонуется и выводится в таблицу значений ТаблицаРезуль- тата. Затем с помощью глобальной фабрики XDTO получаются типы объектов XDTO, ранее описанные нами в пакете XDTO ДанныеОтчета - Номенклату- раТип, СкладТип, СтрокаТаблицыОтчетаТип и ТаблицаОтчетаТип, на основе которого создается список значений XDTO ТаблицаОтчета. Затем коллекция значений ТаблицаРезультата, содержащая данные отчета, обходится в цикле. На каждом шаге этого цикла создается объект XDTO - СтрокаТаблицыОтчета и заполняются все его свойства - Номен- клатура, Склад, НачальныйОстаток и др. После этого СтрокаТабли- цыОтчета добавляется в список значений XDTO ТаблицаОтчета. В заключение функция возвращает объект XDTO ТаблицаОтчета. Тип этого объекта был описан в свойстве Тип возвращаемого значения операции ПолучитьОтчет созданного нами Web-сервиса ДанныеОтчета. Теперь осталось только опубликовать созданный Web-сервис на веб-сервере, например, расположенном на локальном компьютере http://localhost в каталоге /wsreport (рис. 1.31). . Диалог публикации на веб-сервере В конфигурации «Web-сервисы (использование)», демонстрирующей вторую часть примера, рассматривается возможность использования Web-сервиса
сторонних поставщиков путем получения описания Web-сервиса с помощью статических либо динамических ссылок. В конфигурации создана обработка ПолучитьОтчетПоТоварам с реквизитами ДатаНачала и ДатаОкончания, в которые будут вводиться значения параметров, задающих отчетный период для формирования отчета. По кнопке Сформи- ровать результат отчета будет выводиться в таблицу значений, отражающую данные реквизита ТЗРезультат (рис. 1.32). 1.32. Обработка «Получить отчет по товарам», получающая данные отчета через Web-сервис При нажатии кнопки Сформировать вызывается серверная процедура Сфор- мироватьОтчетО (листинг 1.150). Функция «СформироватьОтчет()»
В данной процедуре создается объект WSOnpeделения. который полу- чает определение Web-сервисов из WSDL файла. На основе определения Web-ссрвиса создается объект ИБПрокси и связывает его с точкой подклю- чения Web-сервиса. Затем выполняется операция Web-сервиса в которую передаются значения реквизитов и введенные в форме обработки. В результате отчет формируется и выгружается в таблицу значений, которая возвращается Web-сервисом в виде списка XDTO. Далее реквизит ТЗРезультат в цикле заполняется данными отчета и показыва- ется в форме обработки. Заметьте, что хотя в конфигурации «Web-сервисы (использование)» нет исходных данных для формирования отчета - документов, регистров накоп- ления и т.п., данные отчета становятся доступны благодаря использованию Web-сервиса стороннего поставщика, предоставившего подобную функцио- нальность путем создания и публикации Web-сервиса на веб-сервере. Использование динамической WS-ссылки В процедуре СформироватьОтчет () (см. листинг 1.150) использована динамическая WS-ссылка, когда объект WSIIpoKcn для подключения к Web- сервису получается на основании объекта 1лГ30пределения (листинг 1.151). Использование динамической WS-ссылки
Использование статической WS-ссылки Для использования статической WS-ссылки следует добавить в дерево объектов конфигурации объект WSCcbuiKa с именем ДанныеОтчета, ссылаю- щийся на опубликованный Web-сервис. Для этого нужно выполнить импорт WSDL-описания опубликованного Web-сервиса и в качестве URL указать http://localhost/wsreport/ws/wsreport.lcws?wsdl (рис. 1.33). Создание WS-ссылки После этого создание ЭДЭПрокси на основе статической WS-ссылки будет выглядеть следующим образом (листинг 1.152). Использование статической WS-ссылки
Глава 2. Обмен данными При решении различных задач может возникнуть необходимость в создании распределенной информационной системы (в силу территориальной распре- деленности организации, использования разнородного программного обеспе- чения для решения отдельных подзадач и т. п.). Технологическая платформа «1С:Предприятия» позволяет решать такие задачи, причем распределенные информационные системы могут строиться как на основе информационных баз «1С:Предприятия», так и с задействованием совершенно других систем. Одной из самых важных задач, которую необходимо решить при организации распределенных информационных систем, является задача обмена между ее составными частями. Обмен данными в системе «1С:Предприятие» реализуется благодаря исполь- зованию ряда средств технологической платформы, которые разработчик может применять как по отдельности, так и в различных комбинациях, в зави- симости от конкретной решаемой задачи. Такой подход позволяет обеспечить гибкость механизмов обмена и их настраиваемость на решение как можно большего круга задач. В состав средств платформы, используемых для построения схем обмена данными, входят: • объекты конфигурации План обмена; • базовые средства работы с XML; • средства XML-сериализации.
При помощи этих средств могут быть реализованы два механизма обмена данными: • универсальный механизм обмена данными; • механизм распределенных информационных баз. Универсальный механизм обмена данными позволяет создавать произвольные распределенные системы и практически не накладывает никаких ограничений на структуру создаваемой системы. Можно как связывать в единое целое базы «1С:Предприятия» с отличными друг от друга конфигурациями, так и осуществлять обмен с принципиально отличными информационными системами (базами данных). Механизм распределенных информационных баз, напротив, предназначен для обмена данными только с идентичными конфигурациями «^Предпри- ятия 8» и жестко регламентирует структуру создаваемой системы. Основные отличия механизма универсального обмена данными от механизма распределенных информационных баз можно проиллюстрировать следующей таблицей (табл. 2.1). Сравнение механизмов обмена данными В узлах плана обмена находятся Произвольные базы данных, в том числе информационные базы «1С: Предп риятия» Только информационные базы «1С:Предприятия 8» Конфигурации информационных баз Могут быть разные (применительно к информационным базам «1С:Предприятия») Только идентичные В сообщениях обмена передаются Только изменения данных Изменения данных, изменения конфигурации Направление передачи Произвольное, между двумя связанными узлами Изменения данных - произвольное, изменения конфигурации - от главного подчиненному узлу Формат файлов обмена Произвольный, чаще всего XML XML Создание распределенной базы и выполнение обмена Требуется написание кода (определение порядка разрешения коллизий, стратегии распространения данных, создания начальных выгрузок, решение задачи синхронизации данных) Может быть выполнено исключительно интерактивными средствами, без кодирования (действуют соглашения по умолчанию)
Структура распределенной системы Произвольная. Может отсутствовать понятие главный - подчиненный (отсутствовать иерархия) Древовидная. Любой узел (кроме корневого) имеет один главный и произвольное количество подчиненных узлов Перед тем как перейти к рассмотрению возможностей организации как универсального обмена, так и создания распределенных информационных баз «1СПредприятия», рассмотрим функциональность такого объекта плат- формы, как План обмена. Планы обмена При организации постоянного обмена может возникнуть ряд задач: • с кем будет производиться обмен (определение состава участников обмена); • какими данными будет производиться обмен (с одной стороны, это определение перечня типов объектов; с другой стороны, определение «экземпляров»); • определение регламента обмена (например, нумерация сообщений, адре- сация, процесс разрешения коллизий и т.п.). Все эти задачи в той или иной мере могут решаться с использованием функ- циональности планов обмена. Рассмотрим данный объект более подробно. Примеры, иллюстрирующие возможности обмена данными, можно посмот- реть в демонстрационной конфигурации «Пример обмена», которая находится на приложенном диске. Как объект конфигурации План обмена характеризуется составом рекви- зитов, табличных частей (составом реквизитов табличных частей), опре- деленными для него формами, макетами. У узла плана обмена существуют свойства Код, Наименование и т. п. В конфигурации может быть определено любое количество планов обмена. Элементами данных плана обмена являются узлы плана обмена, подобно тому, как элементами данных справочника являются элементы справочника. Каждый из узлов плана обмена обозначает участника обмена данными по данному плану обмена. Один из узлов (он является предопределенным) соответствует данной информационной базе, а остальные - другим учас- тникам, с которыми данная информационная база может обмениваться данными (рис. 2.1).
Узлы плана обмена Реквизиты и табличные части узла обмена могут использоваться для указания специфических данных по участнику обмена. С их помощью определяется порядок взаимодействия с данным участником, привязка его к другим объектам базы. Например, может указываться, что данный узел с точки зрения базы данных является «таким-то» складом (элементом справочника Склады), файл выгрузки данному получателю необходимо отправлять по «такому-то» FTP-адресу и т.п. (рис. 2.2). Пример узла плана обмена Данные переносятся между узлами с помощью сообщений. Средства работы с сообщениями образуют инфраструктуру сообщений. Каждое сообщение относится к определенному плану обмена, имеет определенный узел-отправи- тель и определенный узел-получатель. Сообщение не может быть отправлено
неизвестному узлу и не может быть принято от неизвестного узла. Каждое сообщение имеет свой собственный целочисленный номер. С точки зрения инфраструктуры сообщений у узла существуют два свойства: • номер отправленного сообщения; • номер принятого сообщения. Для предопределенного узла эти свойства смысла не имеют (база данных сама с собой данными не обменивается). Служба регистрации изменений предназначена для регистрации изменений данных, производимых «1С:Предприятием», чтобы при обмене данными иметь возможность передавать не все данные, а только новые, измененные и удаленные. Настройка состава объектов, для которых включается регистрация изменений, производится в режиме Конфигуратор, на закладке Основные объекта конфигу- рации ПланОбмена (необходимо нажать кнопку Состав), рис. 2.3.
Можно сказать, что объекты, для которых включается регистрация изме- нений, являются входными данными для службы регистрации изменений. Задача этой службы состоит в том, чтобы, опираясь на данный перечень объектов, отслеживать изменения объектов, их удаление и производить соот- ветствующие записи в таблицах регистрации изменений объектов. При этом отслеживаются ситуации повторного изменения (но об этом более подробно в разделе, посвященном именно службе регистрации изменений). Обобщив изложенный ранее материал, можно сказать, что планы обмена: • определяют состав участников обмена (любой узел, кроме предопределен- ного, соответствует какому-либо участнику обмена); • позволяют производить регистрацию изменений объектов (служба регист- рации изменений, как объектов, так и самой конфигурации); • реализуют инфраструктуру сообщений. Довольно сложно разделить службу регистрации изменений и инфраструк- туру сообщений - их функциональность тесно связана, но все же постара- емся рассмотреть особенности их работы по отдельности. Начнем со службы регистрации изменений. Целью регистрации изменений является получение списка измененных элементов данных, которые должны быть переданы в очередном сообщении тому или иному узлу, с которым производится обмен данными. При каждом изменении данных должно быть зарегистрировано, что имеются изменения, которые предстоит передать во все узлы, с которыми поддерживается обмен этими данными. При получении подтверждения приема сообщения, в котором были отправлены изменения, записи регистрации изменений должны быть удалены. Регистрация изменений может выполняться для следующих элементов данных: • КонстантаМенеджерЗначения.<имя>; • Объекты базы данных: • СправочникОбъект.<имя>; • ДокументОбъект.<имя>; • ПланСчетовОбъект.<имя>; • ПланВидовХарактеристикОбъект.<имя>; • ПланВидовРасчетаОбъект.<имя>; • БизнёсПроцесс0бъект.<имя>; о 3адача0бъект.<имя>;
• Наборы записей: • РегистрСведенийНаборЗаписей.<имя>; • РегистрБухгалтерииНаборЗаписей.<имя>; • РегистрНакопленияНаборЗаписей.<имя>; • ПоследовательностьНаборЗаписей.<имя>; • РегистрРасчетаНаборЗаписей.<имя>; • ПерерасчетНаборЗаписей.<имя>. Для каждого из приведенных элементов данных ведется своя таблица регис- трации изменений. Таблицы имеют разную структуру, в зависимости от того, для каких элементов данных регистрируются изменения, но все-таки струк- туры таблиц подобны. В структуре можно выделить три составляющих: • ключ элемента данных, для которого регистрируются изменения; • ссылка на узел, в который изменение должно быть передано; • номер сообщения, в котором изменение передано в первый раз. Следует отметить, что в конфигурации может быть определено несколько планов обмена. Для каждого из них может включаться регистрация изменений какого-либо объекта. Так вот, вне зависимости от количества планов обмена, в рамках которого регистрируются изменения какого-либо объекта, таблица регистрации изменений у объекта одна (можно сказать, что поле, содержащее ссылку на узел плана обмена, может иметь составной тип). Структуры таблиц регистрации изменений для разных данных отличаются ключом, так как ключи у разных данных разные: • Для константы ключом является идентификатор константы. ш Для объектов базы данных в качестве ключа используется ссылка на объект. • Для наборов записей, для которых определен регистратор, в качестве ключа используется ссылка на объект-регистратор. • Для набора записей регистра сведений, если регистратор не определен, в качестве ключа используется совокупность измерений, входящих в основной отбор. А если регистр сведений является периодическим и включен основной отбор по периоду, то в ключ входит еще и период. Основной отбор (для регистров сведений) позволяет определять логи- ческую единицу обмена данными. Рассмотрим это понятие более подробно (рис. 2.4).
Свойство «Основной отбор» Понятно, что физически минимальной единицей обмена является запись регистра сведений. Но всегда ли правильно обмениваться записями? Рассмотрим пример. Есть регистр сведений, в котором содержатся данные о дополнительных свойствах номенклатурных позиций. Речь идет именно о свойствах, которые четко характеризуют товарную позицию. Если для какого-то товара свойство имеет другое значение, то, значит, это другой товар. Например, такое свойство, как количество компрессоров холодильника. У данного регистра сведений два измерения: ссылка на номенклатуру и ссылка на свойство. Если обмен будет производиться по каждой записи отдельно, у одного учас- тника обмена добавили одно свойство, а у другого - другое, то в результате обмена у элемента номенклатуры появятся два свойства. Но в данном случае более правильно, чтобы свойства отдельно взятого товара представляли собой единое логическое целое (входили в некий логический квант данных). Как раз для того чтобы объединить несколько физических записей в один логический набор данных, и используется понятие Основной отбор. Если в приведенном примере для измерения Номенклатура (содержащего ссылку на номенклатурную позиций) установить свойство Основной отбор, то при изменении хотя бы одной физической записи обмен будет произво- диться всеми свойствами данной номенклатуры. В качестве примера рассмотрим следующие данные (наполнение регистра сведений), табл. 2.2.
Записи регистра сведений Атлант МХМ 1704-00 Количество компрессоров 2 Атлант МХМ 1704-00 Цвет Белый Ardo TL 1000 EX-1 Тип загрузки Вертикальная ArdoTL 1000 EX-1 Количество подшипников 1 Добавим в регистр запись табл. 2.3. о новом свойстве (выделена серым фоном), 2.3. В регистр сведений добавлена запись Атлант МХМ 1704-00 Количество компрессоров 2 Атлант МХМ 1704-00 Цвет Белый Атлант МХМ 1704-00 Отделов в морозильной камере 3 Ardo TL 1000 ЕХ-1 Тип загрузки Вертикальная Ardo TL 1000 ЕХ-1 Количество подшипников 1 В результате будут зарегистрированы следующие изменения (табл. 2.4). 2.4. Записи, попавшие в регистрацию изменений Атлант МХМ 1704-00 Количество компрессоров 2 Атлант МХМ 1704-00 Цвет Белый Атлант МХМ 1704-00 Отделов в морозильной камере 3 Если в основной отбор включить все измерения (если регистр сведений пери- одический, то включить в основной отбор и период), то логической единицей обмена будет отдельно взятая запись регистра сведений. Следует отметить тот факт, что при записи набора в регистр сведений состав этого набора определяется логикой работы конфигурации и не обязательно совпадает с набором, получаемым «при использовании» основного набора.
А при принудительной регистрации изменений для набора записей обяза- тельно должен быть установлен отбор, совпадающий с основным (иначе будет вызвано исключение). Такой порядок работы определяется тем, что основной отбор является специфической чертой именно механизма обмена данными. Исходя из сказанного выше, следует, что при изменении основного отбора необходимо будет менять и программный код, в котором производится принудительная регистрация записей регистра сведений (во всех вхождениях в конфигурацию). Изменение элемента данных должно быть зарегистрировано для всех узлов, в которые изменение должно быть передано. Таким образом, в резуль- тате изменения элемента данных в таблице регистрации изменений должно появиться N записей (наборов записей), где N - количество узлов, для которых регистрируются изменения (все узлы плана обмена, за исключе- нием предопределенного). В каждой из этих записей (наборе записей) указано одно и то же значение ключа элемента данных и различные значения ссылки на узел. Непосредственно после выполнения регистрации изменения номер сооб- щения имеет значение NULL. При первой отправке изменения в составе сообщения в данное поле помещается номер сообщения, в котором изменение отправлено. Рассмотрим приведенный алгоритм на примере. Считаем, что в плане обмена включена регистрация для документа РасходнаяНакладная. В плане обмена определено три узла: один - предопределенный, другие - с кодами Оптовый и Розничный. После включения регистрации было изменено два документа. В соответствии с этим таблица регистрации изменения примет следующий вид (табл. 2.5). Состав таблицы регистрации изменений ДокументСсылка.РасходнаяНакладная Узел Номер сообщения Расходная накладная No 1 от... Оптовый Null Расходная накладная No 1 от... Розничный Null Расходная накладная No 2 от... Оптовый Null Расходная накладная No 2 от... Розничный Null После этого было произведено формирование и отправка сообщения с номером 1 для узла Оптовый. Таблица приняла следующий вид (табл. 2.6).
Состав таблицы регистрации изменений Расходная накладная No 1 от... Оптовый 1 Расходная накладная No 1 от... Розничный Null Расходная накладная No 2 от... Оптовый 1 Расходная накладная No 2 от... Розничный Null Далее было зарегистрировано изменение еще одного документа (табл. 2.7). Состав таблицы регистрации изменений Расходная накладная No 1 от... Оптовый 1 Расходная накладная No 1 от... Розничный Null Расходная накладная No 2 от... Оптовый 1 Расходная накладная No 2 от... Розничный Null Расходная накладная No 3 от... Оптовый Null Расходная накладная No 3 от... Розничный Null После этого были сформированы и отправлены сообщения для узлов Оптовый и Розничный. Фактически были проведены две выгрузки (сформировано два сообщения). Для узла Розничный сообщение имело номер 1, для узла Оптовый - номер 2 (табл. 2.8). Состав таблицы регистрации изменений Расходная накладная No 1 от... Оптовый 1 Расходная накладная No 1 от... Розничный 1 Расходная накладная No 2 от... Оптовый 1 Расходная накладная No 2 от... Розничный 1 Расходная накладная No 3 от... Оптовый 2 Расходная накладная No 3 от... Розничный 1 После выгрузки для узла Оптовый запись в таблице для документа Расходная накладная No 3 отмечается номером сообщения 2 (первый раз изменение было передано именно в сообщении с таким номером), другие записи (для которых в поле НомерСообщения содержалось значение 1) остались без изменении (именно таким образом работает служба регистрации изменений).
Для узла Розничный все изменения были отнесены сообщением с номером 1. Предположим, что после выполнения вышеуказанных действий произошло повторное изменение документа Расходная накладная No 1. В этом случае таблица регистрации изменений будет иметь следующий вид (табл. 2.9). Состав таблицы регистрации изменений Расходная накладная No 1 от... Оптовый Null Расходная накладная No от... Розничный Null Расходная накладная No 2 от... Оптовый 1 Расходная накладная No 2 от... Розничный 1 Расходная накладная No 3 от... Оптовый 2 Расходная накладная No 3 от... Розничный 1 Продолжая разговор о службе регистрации изменений, следует отметить, что состав плана обмена распространяется на все узлы данного плана обмена. Поэтому, если, например, с разными узлами нужно обмениваться разным составом информации, необходимо создавать несколько планов обмена, в которых объединять узлы, обменивающиеся одинаковым составом инфор- мации. Например, если с одним узлом необходимо обмениваться изменениями в справочнике Номенклатура, а с другим изменениями - в документах Расход- наяНакладная, то не стоит создавать один план обмена, лучше создать план обмена ПоНоменклатуре (с соответствующей настройкой состава данных, по которым ведется регистрация изменений) и план обмена Расходные (с другим составом). При рассмотрении вышеприведенного примера акцент делался на заполнение таблицы регистрации изменений. Каким образом производилась регистрация, не учитывалось. Можно сказать, что рассматривалась функциональность службы регистрации изменений с учетом того, что для всех объектов вклю- чена авторегистрация изменений. Пришло время рассмотреть и этот аспект работы программного комплекса. При определении состава объектов, для которых производится регистрация изменений (кнопка Состав на закладке Основные объекта конфигурации План обмена), для каждого объекта можно определить свойство Авторегист- рация (рис. 2.5).
Свойство «Авторегистрация» Авторегистрацию можно разрешить или запретить. Если авторегистрация разрешена, то при изменении данных регистрация будет выполнена автома- тически. Если запрещена, то регистрацию изменения необходимо выполнять «вручную» (определив код на встроенном языке). Следует отметить, что можно «корректировать» результат регистрации и в том случае, если авто- регистрация объекта включена. Оба действия будут подробнее рассмотрены несколько позже. У каждого объекта конфигурации, входящего в состав плана обмена, имеется свойство ОбменДанными, имеющее тип ПараметрыОбменаДанными. Данное свойство может быть использовано только для чтения и предназначено как для управления различными параметрами при обмене данными, так и при реализации других механизмов, связанных с изменением объекта. Например, такое свойство, как Загрузка, может определять необходимость проведения (непроведения) каких-либо проверок в момент записи объекта (при записи в режиме загрузки можно отказаться от проверки номеров, кодов объектов, наличия каких-либо связанных с загружаемыми объектами данных и т.п., так как эти данные могут быть загружены после). Следует обратить внимание на тот факт, что значение данного свойства не хранится в базе данных. В соответствии с этим все изменения (опреде- ления различных коллекций, свойств), которые выполняются через данное свойство, «работают» только в течение существования объекта. У объекта ПараметрыОбменаДанными есть свойство Получатели, имеющее тип НаборУзлов. В данном свойстве хранится перечень узлов, для которых будет выполняться регистрация изменений при записи или удалении данных. Рассмотрим особенности регистрации изменений, как при автоматической регистрации изменений, так и в обратном случае.
Автоматическая регистрация изменений В случае если для объекта включена автоматическая регистрация изменений, этот список получателей (свойство Получатели) заполняется автоматически, перед тем как будет вызван обработчик события ПередЗаписью (при выпол- нении записи данных) или ПередУдалением (при выполнении удаления). Перед вызовом данных обработчиков событий список получателей предвари- тельно очищается. Исходя из этого, вносить изменения в список получателей (если для объекта включена автоматическая регистрация изменений) можно только в обработчиках ПередЗаписью (и/или ПередУдалением). При этом следует помнить, что список получателей может содержать только ссылки на узлы, относящиеся к планам обмена, в состав которых входит соответству- ющий объект конфигурации. В приведенном ниже примере обработчик ПередЗаписью исключает из списка получателей узел с кодом плана обмена (листинг 2.1). Пример обработчика события «ПередЗаписью» Следует вспомнить, что значение свойства ОбменДанными не хранится в информационной базе. Можно сказать, что данное свойство заполняется некими значениями по умолчанию при создании объекта (в оперативной памяти). Одним из таких свойств, которое в дальнейшем определяет порядок регистрации изменений, является свойство Автозаполнение. То есть, несмотря на тот факт, что при настройке состава регистрации изменений авторегистрация для объекта была включена, при создании объекта (при создании, получении из кода, при открытии формы объекта) это свойство можно переопределить. Пример реализации приведен в листинге 2.2. Пример изменения свойства <;Автозаполнение»
В этом случае автозаполнение отключается, и состав коллекции получателей можно определять в любом возможном месте (участке кода, отвечающего за работу с объектом). Но чтобы конфигурация была логически понятна и легко читаема, лучше это делать все в тех же обработчиках событий ПередЗаписью и/или ПередУдалением. Также следует напомнить, что в конфигурации может быть определено несколько планов обмена. В одном из них для объекта может быть включена автоматическая регистрация изменений, в другом она может быть отключена. Рассмотрим пример. План обмена УдаленныеОфисы (автоматическая регис- трация изменений для документа РасходнаяНакладная включена), состав непредопределенных узлов: • Центральный склад, • Офис на «Рублевке». План обмена УдаленныеСклады (автоматическая регистрация изменений для документа РасходнаяНакладная отключена), состав непредопределенных узлов: • Розничный склад, • Оптовый склад. Подобная настройка планов обмена может быть выполнена исходя из сооб- ражений, что документ РасходнаяНакладная должен присутствовать во всех офисах компании и при этом должен быть выгружен только на «свой» склад. При создании документа РасходнаяНакладная (изменении существующего) в таблице регистрации изменений данного документа появятся две записи, для узлов: • УдаленныеОфисы - Центральный склад; • УдаленныеОфисы - Офис на «Рублевке». Следует оговориться, что такое поведение системы наблюдается только в том случае, если не предпринимается никаких шагов по принудительной регистрации изменений. Кстати, свойство Автозаполнение в коллекции Получатели в данном примере установлено в значение Истина. «Ручная» регистрация изменений Если автоматическая регистрация изменений не производится, то перед вызовом обработчиков ПередЗаписью и ПриУдалении сброс и запол- нение списка получателей не осуществляются. Исходя из этого, заполнение данного списка может производиться в любом фрагменте кода, как показано в листинге 2.3.
Если автоматическая регистрация изменений для объекта отключена и в конфигурации нигде не встречаются строки кода, подобные тем, которые приведены выше (или будут рассматриваться ниже), экземпляры данного объекта никогда не попадут в таблицу регистрации изменений (для данного объекта она будет пустой). Вернемся к примеру с несколькими планами обмена (условия - в предыдущем разделе). Несмотря на тот факт, что в свойстве Автозаполнение коллекции Полу- чатели (свойства ОбменДанными) установлено значение Истина, для непредопределенных узлов, определенных в плане обмена УдаленныеСкпады, регистрация изменений не проводится. Но список получателей перед вызовом обработчиков событий ПередЗаписью и ПередУдалением очищается. Исходя из этого, для ручной регистрации изменений можно в модуле объекта (документа) определить следующий обработчик события (листинг 2.4). Пример обработчика события «ПередЗаписью»
В глобальном общем модуле определим следующую процедуру (листинг 2.5). Процедура «ВключитьРегистрациюО» Обе рассмотренные процедуры одновременно решают две задачи: • Регистрируют изменения для узла, у которого реквизит совпадает со складом, указанным в документе. • Производят проверку (для ранее существовавших документов), не изменился ли склад. Если склад изменился, то производится регист- рация изменения для узла, значение реквизита которого соответс- твует старому значению документа (хранимому на момент проверки в информационной базе). Далее в момент выгрузки изменений данная регистрация может быть «подменена» на объект УдалениеОбъекта, что приведет к удалению накладной, «не свойственной» узлу. Принудительная регистрация изменений В некоторых случаях может потребоваться принудительная регистрация изме- нений для какого-либо объекта, их списка (или всех объектов). Для этой цели может использоваться метод ЗарегистрироватьИзмененияО объекта ПланыОбменаМенеджер. Данный метод позволяет выполнять регистрацию изменений одиночных элементов данных или целых групп для одного или нескольких узлов.
Первый параметр данного метода - ссылка на узел плана обмена или массив ссылок на узлы, для которых выполняется регистрация изменений. Если первый параметр представляет собой одиночную ссылку на узел, то второй параметр может быть опущен. При этом выполняется регистрация изменений всех элементов данных, которые на данный момент присутствуют в базе данных и изменения которых могут быть зарегистрированы для данного узла (листинг 2.6). Регистрация изменений данных для указанного узла Данный вариант использования метода может быть полезен для организации начальной передачи данных вновь созданному узлу. Если же первый параметр представляет собой массив ссылок на узлы, то второй параметр обязательно должен быть указан (листинг 2.7). Регистрация изменений элемента данных для указанных узлов Впрочем, второй параметр может присутствовать и в том случае, если первый параметр - одиночная ссылка на узел. В зависимости от способа задания второго параметра можно зарегистрировать изменения одного элемента данных или же всех данных, относящихся к одному объекту конфигурации. Кроме этого, можно зарегистрировать удаление объекта (указав в качестве второго параметра объект типа УдалениеОбъекта). Для регистрации изменений одного элемента в качестве второго параметра может быть указан сам элемент данных, ссылка на объект базы данных или объект конфигурации. Пример регистрации изменений всех данных, относящихся к объекту конфи- гурации, приведен в листинге 2.8. Регистрация изменений данных, относящихся к объекту конфигурации
До сих пор ничего не говорилось об очистке таблицы регистрации изменений По большому счету существуют две основные стратегии выполнения данного действия: • Гарантированная доставка сообщений. В этом случае очистка таблиц регистрации изменений производится сразу же после того, как сообщение будет сформировано. • Ожидание квитанции. В этом случае очистка таблиц регистрации изме- нений производится при приеме сообщения, исходя из номера последнего полученного «от нас» сообщения (этот номер передается как квитанция в заголовке сообщения). Рассмотрим следующий пример. Считаем, что таблица регистрации изменений документа Расходная Накладная имеет следующее наполнение (табл. 2.10). Таблица регистрации изменений ДокументСсылка.РасходнаяНакладная Узел Номер сообщения Расходная накладная No 1 от... Оптовый 3 Расходная накладная No 1 от... Розничный Null Расходная накладная No 2 от... Оптовый 1 Расходная накладная No 2 от... Розничный 1 Расходная накладная No 3 от... Оптовый 2 Расходная накладная No 3 от... Розничный 1 Расходная накладная No 4 от... Оптовый 3 Расходная накладная No 4 от... Розничный Null Исходя из данных таблицы, можно сказать, что в узел Оптовый было отправ- лено три сообщения, в узел Розничный - одно. Используется стратегия ожидания подтверждающей квитанции, при этом от участника обмена Оптовый приходит сообщение, в котором указано, что последнее полученное от «нас» сообщение имело номер 2. Исходя из этой информации, можно удалить изменения, отправленные в сообщениях 1 и 2 (поле НомерСообщения таблицы регистрации изменений). Таблица примет следующий вид (табл. 2.11).
Таблица 2.11. Таблица регистрации изменений Расходная накладная No 1 от... Оптовый 3 Расходная накладная No 1 от... Розничный Null Расходная накладная No 2 от... Розничный 1 Расходная накладная No 3 от... Розничный 1 Расходная накладная No 4 от... Оптовый 3 Расходная накладная No 4 от... Розничный Null В случае гарантированной доставки таблица регистрации изменений очища- ется сразу после отправки сообщения. Например, таблица регистрации изме- нений имела следующий вид (табл. 2.12). Таблица 2.12. Таблица регистрации изменений ДокументСсылка.РасходнаяНакладная Узел Номер сообщения Расходная накладная No 1 от... Оптовый 3 Расходная накладная No 1 от... Розничный Null Расходная накладная No 2 от... Оптовый 1 Расходная накладная No 3 от... Оптовый 2 Расходная накладная No 4 от,.. Оптовый 3 Расходная накладная No 4 от... Розничный Null В узел Розничный формируется сообщение с номером 2. После того как сообщение сформировано, таблица регистрации будет иметь следующий вид (табл. 2.13). Таблица 2.13. Таблица регистрации изменений ДокументСсылка.РасходнаяНакладная Узел Номер сообщения Расходная накладная No 1 от... Оптовый 3 Расходная накладная No 1 от... Розничный 2 Расходная накладная No 2 от... Оптовый 1 Расходная накладная No 3 от... Оптовый 2 Расходная накладная No 4 от... Оптовый 3 Расходная накладная No 4 от... Розничный 2
Далее производится вызов метода по удалению записей в таблице pei ne i рации изменений (метод рассматривается чуть позже). Таблица регистрации изменений примет такой вид (табл. 2.14). Таблица 2.14. Таблица регистрации изменений ДокументСсылка.РасходнаяНакладная Узел Расходная накладная No 1 от... Оптовый 3 Расходная накладная No 2 от... Оптовый 1 Расходная накладная No 3 от... Оптовый 2 Расходная накладная No 4 от... Оптовый 3 Для удаления записей регистрации изменений у менеджера планов обмена имеется метод УдалитьРегистрациюИзменений(). В качестве первого параметра метода может использоваться ссылка на узел или массив таких ссылок. В качестве второго параметра может указываться ссылка на объект, УдалениеОбъекта, объект конфигурации, число (номер сообщения). Для удаления записей таблицы регистрации изменений с номерами сообщения не больше переданного (в примере с номерами 1 и 2) может использоваться фрагмент кода (листинг 2.9). Пример удаления записей таблицы регистрации Пример удаления записей регистрации изменений для всех данных, которые зарегистрированы для узла, приведен в листинге 2.10. Пример удаления записей таблицы регистрации Узел = ПланыОбмена.УдаленныеСклады.НайтиПоКоду("Оптовый"); ПланыОбмена.УдалитьРегистрациюИзменений(Узел); Можно удалить записи регистрации изменений конкретного элемента данных для одного или нескольких узлов (листинг 2.11).
Пример удаления записей таблицы регистрации Важнейшей составляющей инфраструктуры сообщений являются сами сооб- щения. Как уже отмечалось, сообщения передаются в рамках плана обмена от одного узла другому. То есть каждое сообщение точно ассоциировано с планом обмена, имеет одного отправителя и одного получателя. Рассмотрим, что такое сообщение. Сообщение оформляется как документ XML, имеющий определенную структуру. В качестве примера рассмотрим следующее сообщение (листинг 2.13). Пример сообщения обмена Также можно удалить записи регистрации изменений всех данных, относящихся к объекту конфигурации для одного или нескольких узлов (листинг 2.12). Пример удаления записей таблицы регистрации Все сообщение находится внутри элемента XML с именем Message, отно- сящимся к пространству имен http://v8.1c.ru/messages. Сообщение делится на заголовок Header и тело сообщения Body. Оба относятся к пространству имен http://v8.1c.ru/messages.
Структура заголовка жестко задана. Информация заголовка про i ставлена в нескольких элементах XML, вложенных в элемент Header. Все элементы, вложенные в элемент Header, относятся к пространству имен http://v8.1 c.ru/messages: • Элемент с именем ExchangePlan содержит имя плана обмена, к которому относится сообщение. • Элемент с именем From содержит код узла-отправителя. • Элемент с именем То содержит код узла, для которого предназначено сообщение. • Элемент с именем MessageNo содержит номер данного сообщения. Номер сообщения является положительным целым числом и присваивается узлом-отправителем. Номер каждого последующего сообщения равен номеру предыдущего отправленного сообщения плюс 1. • Элемент с именем ReceivedNo содержит максимальный номер сообщения, которое узел-отправитель данного сообщения принял от узла-получателя данного сообщения. Данное значение включено в состав заголовка сооб- щения для подтверждения приема сообщений. Тело сообщения содержится в элементе XML с именем Body, относящемся к пространству имен http://v8.1c.ru/messages. Данный элемент может иметь произвольное содержимое, определяемое прикладными потребностями. Инфраструктурой сообщений содержимое тела сообщения никак не регла- ментируется. Пример создания сообщения для выгрузки данных (листинг 2.14). Пример сообщения для выгрузки данных Выгрузка данных сопровождается созданием объекта с типом ЗаписьСо- общенияОбмена (переменная ЗаписьСообщения). Сразу после создания этот объект еще «не знает» своего номера, получателя и т.п. Вся подобная
информация указывается при выполнении метода НачатьЗапись(). В качестве первого параметра передается объект ЗаписьХМЬ, в качестве второго - ссылка на узел плана обмена (ссылка на получателя). При выполнении этого метода сообщению присваивается номер, опреде- ляемый как номер предыдущего отправленного сообщения, увеличенный на 1 (информация берется их узла-получателя). Производится запись в XML- документ заголовка сообщения, а также записывается начало элемента XML, соответствующего телу сообщения. Устанавливается блокировка на запись базы данных, соответствующая узлу плана обмена. Завершить запись сообщения можно с помощью двух методов объекта ЗаписьСообщенияОбмена: • ЗакончитьЗапись (), • ПрерватьЗапись(). Вызов метода ПрерватьЗаписьО прерывает запись сообщения, при этом оно считается неотправленным (счетчик отправленных сообщений в итоге не увеличивается). Неявный вызов этого метода происходит также в случае повторного вызова метода НачатьЗаписьО (без последующего вызова метода ЗакончитьЗапись ()) либо при разрушении (окончании времени жизни переменной, связанной с объектом) объекта ЗаписьСообще- нияОбмена. Метод ЗакончитьЗапись () осуществляет нормальное завершение записи сообщения. В этом случае в сообщение записывается конец элемента XML (представляющего тело сообщения). В узел плана обмена записывается номер сообщения обмена данными. С записи узла плана обмена снимается блокировка, и сообщение считается отправленным. Для чтения записанного в файл сообщения обмена в базе узла-получателя может использоваться следующий фрагмент кода (листинг 2.15). Пример чтения сообщения обмена
После открытия XML-документа, содержащего сообщение, создается объект ЧтениеСообщенияОбмена. Чтение данных начинается с выполнения метода НачатьЧтениеО объекта ЧтениеСообщенияОбмена. При этом производится чтение заголовка сообщения обмена данными, проверяются содержащиеся в заголовке данные. Если какие-либо данные указаны непра- вильно (задан неизвестный план обмена, указан узел, не входящий в план обмена, номер сообщения не соответствует ожидаемому), инициируется исключение. При начале чтения сообщения устанавливается блокировка на запись узла плана обмена. Используя второй параметр метода, можно установить вариант ожидаемого номера сообщения: • любой (фактически контроль номеров сообщения не производится); • очередной (строго больший на единицу, чем предыдущий); • больший. Следует обратить внимание на тот факт, что в приведенном фрагменте кода нет ни указания на используемый план обмена (их в конфигурации может быть несколько), ни указания на узел-отправитель. Данная информация полу- чается из заголовка сообщения (в случае невозможности определения, как и было сказано выше, возникает исключение). Завершить чтение сообщения можно с использованием двух методов: • ЗакончитьЧтение (); • ПрерватьЧтение(). Обращение к методу ПрерватьЧтениеО вызывает немедленное преры- вание чтения сообщения. Блокировка с записи узла плана обмена снимается. В соответствующий узел плана обмена не вносится никаких изменений (не изменяется номер последнего принятого сообщения). Этот же метод вызы- вается неявно при разрушении (окончании времени жизни переменной, связанной с данным объектом) объекта ЧтениеСообщенияОбмена или перед повторным вызовом метода НачатьЧтение (). Выполнение метода ЗакончитьЧтение () вызывает попытку нормального завершения чтения сообщения. При этом проверяется нормальное завер- шение сообщения (текущим элементом в объекте ЧтениеХМЬ является конец элемента, реализующего само сообщение). Номер принятого сообщения помещается в реквизит НомерПринятого узла плана обмена. Блокировка записи узла плана обмена снимается, и сообщение считается принятым.
Универсальный механизм обмена данными Универсальный механизм обмена данными может использоваться как вместе с механизмом распределенных информационных баз, так и по отдельности (для решения задач организации обмена данными информационных баз «1С:Предприятия 8» с различными программными системами). В качестве программных систем, с которыми может быть организован универ- сальный обмен данными, могут выступать другие информационные базы «1С:Предприятия», в том числе с отличающимися конфигурациями, совер- шенно другие программные комплексы (в этом и состоит отличие от меха- низма распределенных информационных баз, в рамках которого организуется обмен между базами данных с идентичными конфигурациями). К универсальному механизму обмена данными могут быть отнесены: • средства чтения и записи документов XML; • XML-сериализация; • планы обмена. Функциональность планов обмена была рассмотрена в предыдущих разделах данной главы. Возможности базовых средств чтения и записи XML-доку- ментов подробно рассматриваются в разделе «Работа с XML-документами» на стр. 30. При желании познакомиться с данными механизмами более подробно рекомендуем обратиться к соответствующим разделам книги. До данного момента рассматривались только механизмы регистрации и удаления регистрации изменений. Рассмотрим пример кода, реализующий (в рамках универсального обмена) полный цикл выгрузки данных (включает в себя выборку данных, для которых были зарегистрированы изменения). При этом в качестве файлов «носителей данных» будут использоваться документы XML. Следует отметить, что обмен данными может выполняться через файлы других форматов, но создать объекты ЧтениеСообщения и ЗаписьСообщения без указания в качестве параметра объектов ЧтениеХМЬ и ЗаписьХМЬ нельзя (листинг 2.16). Пример выгрузки данных
Для получения выборки данных, для которых зарегистрированы изменения, используется метод ВыбратьИзменения(). Для обхода полученных данных используется метод Следующий () выборки. В процессе выборки изменений в записи таблиц регистрации изменений (которые раньше не выгружались и у которых, соответственно, в поле таблицы НомерСообицения находится значение Null) проставляется номер сообщения обмена данными, в котором должны передаваться изменения. Представленный алгоритм выгрузки предполагает, что отправленные сообщения могут быть потеряны по тем или иным причинам. Если потерь сообщения не может быть в принципе (гарантированная доставка), то в конце алгоритма можно поместить следующую строку (листинг 2.17). Удаление регистрации изменений при гарантированной доставке В этом случае из таблицы регистрации изменений будут удалены записи, относящиеся к узлу, ссылка на который передана в качестве первого параметра метода. Причем будут удалены не все записи, а только те, в которых номер сообщения равен или меньше того значения, которое передано в качестве второго параметра метода. Это те записи, в которых была произведена первая отправка изменений. Фрагмент кода, в котором производится чтение сообщения, содержащего измененные данные, выглядит следующим образом (листинг 2.18).
В приведенных выше примерах чтения и записи сообщений не учитывалось, что при обмене данными может случиться так, что один и тот же элемент данных будет изменен одновременно в двух обменивающихся данными узлах. В этом случае непонятно, какое из изменений должно быть в конечном счете принято. Такая ситуация называется коллизией. Один из способов разрешить коллизию - определить, какой из узлов является главным, а какой - подчиненным. При этом должно быть принято изменение, сделанное в главном узле, а изменение, сделанное в подчиненном узле, должно быть отвергнуто. Для реализации этого при приеме сообщения перед записью данных необхо- димо установить, зарегистрировано ли изменение этих данных, и в зависи- мости от роли узла в данной паре получатель-отправитель принять решение: записывать или не записывать данные. Ниже (листинг 2.19) приведен пример реализации стратегии «главный - подчиненный» при чтении сообщения. Предполагается, что для хранения роли узла в плане обмена был определен реквизит имеющий тип Булево. Пример реализации стратегии главный - подчиненный Следует обратить внимание на необходимость установки у загружаемого элемента данных свойства Загрузка в значение Истина. В обработчиках событий записи объекта рекомендуется отслеживать данный режим и не делать каких-либо проверок на корректность заполнения, присутствие каких- либо связанных данных. Это обусловлено тем фактом, что на момент загрузки данного объекта другие объекты могут быть еще не загружены.
Рассмотрим пример реализации механизмов универсального обмена (факти- чески это выборочное описание механизмов, реализованных в демонстра- ционной конфигурации «Обмен данными», ее можно установить с диска «ИТС»). Считаем, что в некой конфигурации определен план обмена У данного плана обмена определены следующие реквизиты: (тип СправочникСсылка.Склады) - ссылка на склад, представ- ляющий данный узел; (тип Булево) - для реализации стратегии «главный - подчи- ненный»; • АдресОбмена (строка) - для указания ресурса, куда выгружаются сформи- рованные сообщения и откуда они загружаются. (строка) - содержит описание участника обмена; У плана обмена определены следующие узлы: • Центральный офис (предопределенный узел, код ЦентрОфис); • Склад розничный (код • Склад оптовый (код Опт). Свойство Главный не может быть установлено у предопределенного узла, соответствующего текущей информационной базе. Реквизит Склад узла ЦентрОфис содержит пустую ссылку. Следует отметить, что в реальной жизни для каждого узла (через реквизиты, табличные части плана обмена) можно указывать используемые способы доставки сообщений (электронная почта, ftp, MSMQ и т.п.). Особенности организации доставки сообщений разными способами рассматриваются в главе «Интеграция с другими информационными системами» на стр. 9. При желании познакомиться с данными механизмами поближе рекомендуем обратиться к данной главе. Состав плана обмена представлен на рисунке (рис. 2.6). Обратите внимание, что некоторые объекты (Документ.РасходнаяНак- ладная, РегистрНакопления.УчетНоменклатуры) входят в состав плана обмена, и при этом авторегистрация для них запрещена (при изменении соответствующих объектов список узлов получателей свойства ОбменДан- ными автоматически не заполняется). Это сделано, чтобы продемонстриро- вать ручное управление регистрацией изменений.
Состав плана обмена При решении задачи обмена следует принять во внимание следующие моменты: • При обмене каждая накладная должна уйти в свой узел (реквизит Склад узла плана обмена должен совпасть со складом, выбранном в документе). • Пользователям разрешается менять склад в документе. Если документ уже ушел в неправильный узел, он должен в нем удалиться и отправиться в правильный. Если у документа с помощью свойства будет включен режим то при программном создании этого документа необходимо самостоятельно зарегистрировать документ в нужных узлах. Для этого в модуле объекта разместим обработчик события ПередЗаписью (листинг 2.20). Обработчик события «ПередЗаписью» документа «РасходнаяНакладная»
КонецПроцедуры В данном обработчике (в случае включения режима Автозаполнение) производится проверка соответствия выбранного склада в объекте и записан- ного в информационной базе. В случае расхождения документ регистриру- ется как для нового узла (в соответствии с измененным складом), так и для старого. Процедура с аналогичным назначением определена в модуле набора записей регистра накопления УчетНоменклатуры (листинг 2.21). Обработчик события «ПередЗаписью» набора записей регистра «УчетНоменклатуры»
Обе эти процедуры используют процедуры ВключитьРегистрациюО и ВывестиРегистрацию(). Они определены общем модуле (листинги 2.22, 2.23). Процедура «ВывестиРегистрацию()» Процедура ВывестиРегистрациюО выводит в окно сообщений данные об объекте, регистрация которого произошла, и узлах-получателях, для которых эта регистрация произошла.
Задача процедуры ВключитьРегистрациюО --- определить всех возможных получателей регистрируемого изменения. В этот список попадут те узлы, у которых в реквизите Склад содержится ссылка на интересующий нас склад либо пустая ссылка (что расширяет функциональность решения). И, естес- твенно, этот получатель не должен быть предопределенным узлом данного плана обмена. Для осуществления обмена по плану обмена УдаленныеСклады создана обработка ОбменСУдаленнымиСкладами. Она позволяет решать следующие задачи: • полная регистрация изменений для выбранного узла; • удаление регистрации изменений для выбранного узла; • выполнение выгрузки данных в узел; • выполнение загрузки данных из узла. Рассмотрим реализацию данных механизмов. Процедура «ВключитьРегистрациюО»
Полная регистрация изменений для выбранного узла производится с использованием одноименной процедуры, определенной в общем модуле ОбменСУдаленнымиСкладами. У данной процедуры два параметра. В первый передается ссылка на узел, для которого необходимо выполнить регистрацию изменений. Во второй параметр передается значение типа Булево. Если это значение Истина, то для данного узла будет выполняться регистрация изме- нения всех объектов (невзирая на принадлежность данного узла к какому-либо определенному складу). Такой же вариант регистрации будет осуществлен, если в качестве первого параметра будет передан узел, у которого в реквизите Склад содержится пустая ссылка. Достигается полная регистрация всех объектов вызовом метода Заре- гистрироватьИзменения() без указания второго параметра (его значение по умолчанию Неопределено). При этом на отключенную авторегистрацию (для документов РасходнаяНакладная и наборов записей регистра накопления УчетНоменклатуры) внимания не обращается (листинг 2.24). Полная регистрация изменений для узла
Для осуществления данного действия в общем модуле ОбменСУдален- нымиСкладами определена процедура, текст которой приведен ниже. В качестве параметра передается ссылка на узел, для которого должна произойти очистка таблиц регистрации изменений (листинг 2.25). В случае если в качестве второго параметра передается значение Ложь, расходные накладные и записи регистра накопления регистрируются как измененные только в случае совпадения склада со складом, определенным в узле плана обмена. Все остальные данные регистрируются обычным образом.
В обработке выбирается узел обмена. Ссылка на выбранный узел сохраняется в реквизите обработки Узел, имеющем тип ПланОбменаСсылка.Удален- ныеСклады. Затем в процедуре выгрузки данных из этой ссылки получается объект ПланОбмена и вызывается метод ЗаписатьСообщенияСИзмене- ниями() этого объекта, реализующий, собственно, сам процесс выгрузки данных. Взаимосвязь основных процедур и функций, используемых для проведения выгрузки, можно проиллюстрировать следующей схемой (рис. 2.7). В процедуре ЗаписатьСообщенияСИзменениямиО, определенной в модуле плана обмена (листинг 2.27), производится вызов процедур и функций, которые решают следующие задачи: • получение имени файла по заранее установленным правилам (известным на принимающей стороне); Удаление регистрации изменений для узла Приведенная ниже процедура может являться обработчиком события нажатия кнопки либо гиперссылки. С помощью нее инициируется процесс выгрузки данных (листинг 2.26). Процедура, инициирующая выгрузку данных
я вызов функции, в которой производится запись сообщения в фай i с именем, переданным в качестве параметра; к вызов процедуры, осуществляющей доставку файла по указанному пути; • удаление сформированного файла. Взаимосвязь процедур и функций для выгрузки измененных данных Процедура «ЗаписатьСообщениеСИзменениямиО»
Функция ПолучитьИмяФайлаОбмена() (листинг 2.28), расположенная в общем модуле ОбменСУдаленнымиСкладами, собирает имя файла из ключе- вого слова Message, добавляя код узла источника и приемника. У файла опре- деляется расширение XML (листинг 2.28). Функция «ПолучитьИмяФайлаОбмена()» Листинг 2.29. Функция «ЗаписатьНовоеСообщениеО» В функции ЗаписатьНовоеСообщение() (листинг 2.29) в XML-файл с переданным в качестве параметра именем начинается запись данных. Для сокращения размера файла сообщения первоначально определяется соответс- твие используемым пространствам имен. Создается новое сообщение, произ- водится выборка изменений. Функция определена в модуле плана обмена, ссылка на узел-получатель получается из контекста выполнения функции (одноименное свойство Ссылка). Выбранные данные с помощью вызова функции НуженПереносДанныхО (листинг 2.30) проверяются на необходимость выгрузки. В случае если выгрузка производится, вызываются процедуры ЗаписатьДанныеО (листинг 2.31) и ВывестиДанные () (листинг 2.32). В противном случае вызывается процедура УдалениеДанныхО (листинг 2.33). Все моменты, связанные с интерфейсной частью механизма (вывод информационных сообщений), выполняются только на стороне клиента (отмечено директивами препроцессора).
Функция НуженПереносДанныхО (см. листинг 2.30) реализует стра- тегию распространения данных. Документы ПриходнаяНакладная и Расход- наяНакладная (и соответствующие им наборы записей регистра накопления) выгружаются только в случае, если значение реквизита Склад документом (и наборов записей регистра накопления) совпадают по значению с одно- именным реквизитом, определенным для узла получателя.
Для набора записей регистра накопления производится проверка на то, что во всех записях используется один склад. Данная проверка может и не прово- диться, если такая ситуация изначально не может встретиться. Функция «НуженПереносДанных()» Рассматриваемый механизм выгрузки данных относится в разряду универ- сальных и подразумевает, что обмен данных производится между конфигу- рациями, имеющими разную структуру. В процедуре Записать Данные () (см. листинг 2.31) производится разделение данных на те, которые выгружа- ются в индивидуальном порядке (в нашем случае это элементы справочника Номенклатура) и с помощью метода платформы ЗаписатьХМЬО. Процедура НоменклатураЗаписатьХМЬО рассматривается более подробно в разделе «Пример реализации обмена при разной структуре объектов конфигурации» на стр. 69.
Процедура «ЗаписатьДанные()» Текст процедуры, производящей вывод диагностических сообщений, приведен ниже (см. листинг 2.32). Процедура «ВывестиДанныеО» Если данные (полученные при выборке изменений) не подлежат выгрузке в текущий узел плана обмена, производится вызов процедуры Удале- ниеДанных() (см. листинг 2.33).
В данной процедуре для данных, имеющих объектную природу, создается объект УдалениеОбъекта. Этим достигается удаление в узле-прием- нике ранее неправильно отосланных данных. Наборы записей регистров очищаются. Процедура «УдалениеДанных()» С помощью процедуры ОпубликоватьФайлОбменаО (листинг 2.34) полученный в результате XML-документ может быть выложен на FTP- сервер либо на ресурс локальной сети. Имя ресурса определено в реквизите АдресОбмена. Для того чтобы была возможность отправлять файл, используя схемы FTP, HTTP, HTTPS, в пути приемника производится замена символов «\» на «/». Процедура «ОпубликоватьФайлОбменаО»
При публикации файла его имя формируется из слова Message, кода узла- отправителя (предопределенного узла (ПланыОбмена.УдаленныеСкла- ды.ЭтотУзел())), кода узла-получателя и номера отправляемого сообщения (номер представлен в формате целого числа из 10 цифр). Из вышеуказанной процедуры производится возврат в процедуру Запи- сатьСообщениеСИзменениямиО (см. листинг 2.27), после завершения которой процесс выгрузки завершается. Приведенная ниже процедура может являться обработчиком события нажатия кнопки либо гиперссылки. С помощью нее инициируется процесс загрузки данных (листинг 2.35). Процедура, инициирующая загрузку данных
В обработке выбирается узел обмена. Ссылка на выбранный узел сохраняется в реквизите обработки Узел, имеющем тип ПланОбменаСсылка.Удален- ныеСклады. Затем в процедуре выгрузки данных из этой ссылки получается объект ПланОбмена и вызывается метод ПрочитатьСообщенияСИзме- нениями() этого объекта, реализующий, собственно, сам процесс загрузки данных. Взаимосвязь основных процедур, рассматриваемых в данном разделе, пока- зана на схеме, представленной ниже (рис. 2.8). Взаимосвязь процедур и функций для загрузки измененных данных Следует отметить, что используется ряд процедур, рассмотренных в разделе «Выполнение выгрузки данных в узел» на стр. 190. В текущем разделе они повторно рассматриваться не будут (это касается функции ПолучитьИмяФайлаОбмена() (см. листинг 2.28) и процедуры Вывес- тиДанные() (см. листинг 2.32)). В процедуре ПрочитатьСообщениеСИзменениямиО (листинг 2.36), опре- деленной в модуле плана обмена, первоначально получаем имя файла. Это имя будет использоваться для создания временного документа, из которого будет впоследствии производиться считывание данных. Имя складывается из слова Message, кода узла приемника, кода узла-отправителя и постфикса R. Процедура расположена в модуле плана обмена, поэтому для получения ссылки узла-источника используется одноименное свойство (Ссылка).
Вызов функции ПолучитьФайлОбменаО (листинг 2.37) в случае уепсш ного получения файла записывает данные во временный файл с сформированным именем. Само чтение производится функцией Прочи- татьНовоеСообщение () (листинг 2.38). Данная функция возвращает номер полученного сообщения (он потом используется процедурой УдалитьФай лыОбменаО (листинг 2.41) для удаления сообщений с внешнего ресурса с данным и меньшими номерами). Процедура «ПрочитатьСообщениеСИзменениями()»
При получении файла обмена (см. листинг 2.37) считаем, что файл, который мы ожидаем, имеет имя, состоящее из слова Message, кода узла отправителя, кода узла получателя (предопределенного узла (ПланыОбмена.Удален- ныеСклады. ЭтотУзел ())) и номера, состоящего из 10 цифр. По сформи- рованной маске ищем сообщения с любым номером. Из всех найденных файлов выбираем тот, который обладает наибольшим номером. Исходя из стратегии очистки журнала регистрации данных «по получению квитанции», в сообщении с большим номером будет находиться наиболее полная порция данных для загрузки. После того как определились с файлом с помощью метода платформы КопироватьФайл (), копируем файл на локальную машину (в каталог вре- менных файлов). Функция «ПолучитьФайлОбменаО»
Чтение полученного сообщения (из временного файла) начинается в функции ПрочитатьНовоеСообщениеО (см. листинг 2.38). В качестве парамегра передается имя файла, куда будет произведено копирование сообщения. После того как создан объект ЧтениеСообщения и чтение начато, произ- водится очистка таблиц регистрации изменений данных (этим реализуется стратегия «ожидание квитанции»). Проверка возможности чтения очередной порции данных производится в функции ВозможностьЧтенияДанныхО (листинг 2.39), непосредс- твенно чтение производится с помощью функции Прочитать Данные О (листинг 2.40). Когда данные получены, анализируется возможность возникновения коллизий. При обнаружении коллизии принимается решение в пользу узла- приемника (они не принимаются), если в узле-отправителе реквизит Главный установлен в значение Ложь. Функция «ПрочитатьНовоеСообщениеО»
В функции ВозможностьЧтенияДанныхО (см. листинг 2.39) для данных с различающейся структурой (отрабатываемых по специальным алгоритмам) возвращается значение Истина. Остальные данные проверяются штатным методом платформы «1С:Предприятие». Считается, что конфигурации, учас- твующие в обмене, отличаются только структурой справочника Номенклатура. Для переноса изменений в данных этого справочника используется специ- альным образом определенный элемент CatalogObject.HoMeHKnaTypa.Вручную. Функция «ВозможностьЧтенияДанныхО» Функция ВозможностьЧтенияДанных{ЧтениеХМ1_) II Получаем тип данных XML, который может быть считан в данный момент TnnXML = ПолучитьХМ1_Тип(ЧтениеХМЦ; Если ТипХМ1_ = Неопределено Тогда Возврат Ложь; КонецЕсли;
Принципы построения функции (и пример) НоменклатураПрочи- татьХМЬО рассматриваются в разделе «Пример реализации обмена при разной структуре объектов конфигурации» на стр. 69. Процедура УдалитьФайлыОбменаО (см. листинг 2.41) производит очистку файлов - сообщений на внешнем ресурсе с номером сообщения, равным принятому или меньшему (получаем все файлы по маске, удаляем по условию). Функция Прочитать Данные () (см. листинг 2.40) для чтения элемента справочника из элемента XML-документа CatalogObject. Но- использует специальную функцию НоменклатураПро- читатьХМЬ(). Все остальные данные считываются стандартным методом подсистемы сериализации ПрочитатьХМЬО. Функция «ПрочитатьДанные()»
Процедура «УдаштьФайлыОбменаО» В рассматриваемом примере для документов ПриходнаяНакладная была включена автоматическая регистрация изменений. Если необходимо заре- гистрировать изменения для какого-либо определенного перечня узлов (отличного от формируемого при авторегистрации), можно воспользоваться двумя способами: определить обработчики события ПередЗаписью и ПередУдалением модуля объекта или воспользоваться следующими процедурами: ЗарегистрироватьПриходные () (листинг 2.42) и Запол- нитьНаборУзлов() (листинг 2.43).
Процедура «ЗарегистрироватьПриходныеО» Процедура ЗарегистрироватьПриходныеО в качестве параметра получает коллекцию узлов, для которых необходимо провести регистрацию изменений. В теле процедуры производится выборка всех документов Приход- наяНакладная. У каждого полученного объекта отключается автозаполнение, и набор получателей формируется самостоятельно (используется функция ЗаполнитьНаборУзлов () (см. листинг 2.43)). Процедура «ЗаполнитьНаборУзловО» У документа РасходнаяНакладная отключена автоматическая регистрация изменений. Ее можно включить, используя механизм, подобный приведен- ному (листинг 2.44). Процедура «ЗарегистрироватьРасходныеО»
Следует отметить тот факт, что в обработчике события ПередЗаписью данного документа установлена защита, которая не позволит зарегистри- ровать изменения документа для всех узлов. Эта процедура рассмотрена в начале раздела «Универсальный механизм обмена данными» на стр. 180. Чтобы проверить работу механизма универсального обмена данными на реальном примере, необходимо выполнить следующие шаги: • Создать один или несколько узлов обмена (путем загрузки конфигурации из файла), как описано в разделе «Создание узла из конфигурации» на стр. 218. • В центральной базе, в списке плана обмена, реализующего механизм универсального обмена (в нашем примере Удаленные склады), нужно установить для узла обмена реквизиты: Код, Наименование, Склад и Адрес обмена (например, для выгрузки данных обмена на локальный компьютер - с:\ (рис. 2.9). Установка реквизитов узла обмена в центральной базе • В базе узла обмена, которому нужно передать данные, в список плана обмена (в нашем примере Удаленные склады) необходимо внести узлы плана обмена с такими же кодами, как и в центральной базе. При этом узел, для которого создавалась база (например, с кодом Опт), нужно внести как предопределенный (помечен специальной пиктограммой в списке узлов), а узел центральной базы нужно отметить признаком Главный (для разре- шения коллизии «главный - подчиненный»). Также нужно указать рекви- зиты: Склад и Адрес обмена для непредопределенных узлов (рис. 2.10). • Для предотвращения конфликта записи объектов с одинаковыми номерами в базе каждого из узлов обмена требуется установить значение константы Префикс номеров. Подробнее об этом рассказывается в разделе «Подго- товка конфигурации к работе в распределенной информационной базе» на стр. 223.
Список узлов плана обмена для базы подчиненного узла • Для выгрузки данных в центральной базе нужно вызвать обработку Обмен с удаленными складами, выбрать узел, которому будут передаваться данные (например, Оптовый склад), и нажать кнопку Выполнить выгрузку (рис. 2.11). Выполнение выгрузки данных из центральной базы в удаленный склад • Для загрузки данных в базе узла, в который будут загружаться данные, нужно вызвать обработку Обмен с удаленными складами, выбрать узел, из которого данные были выгружены (например, Центральный офис), и нажать кнопку Выполнить загрузку (рис. 2.12). Выполнение загрузки данных в удаленный склад из центральной базы
Произойдет первоначальная загрузка данных из центральной базы во вновь созданный узел. В дальнейшем изменение данных можно производить в любом из узлов плана обмена и обмениваться данными в обе стороны. При этом обмениваться данными можно не только с узлом центральной базы, но и с любым другим узлом (например, между узлами Розничный склад и Оптовый склад), с той лишь разницей, что при приеме данных изменения, сделанные в главном узле, будут иметь больший приоритет. Подробнее познакомиться с реализацией механизма универсального обмена данными можно в демонстрационной конфигурации «Пример обмена», прилагающейся к книге на компакт-диске. В данном примере выполнен обмен данных между тремя парами узлов (Цент- ральный офис, Розничный склад и Оптовый склад) в произвольном порядке. Данные, созданные в каждом из узлов, имеют свой префикс нумерации. При этом документы Приходная накладная и Расходная накладная (и соот- ветствующие им наборы записей регистра накопления Учет номенклатуры) передавались только в случае, если значения реквизита Склад документов (и наборов записей регистра накопления) совпадали по значению с одно- именным реквизитом, определенным для узла-получателя. В случае пустой ссылки на склад документы передавались в полном объеме, например в узел Центральный офис. Распределенные информационные базы Распределенная информационная база представляет собой иерархическую структуру, состоящую из отдельных информационных баз «^Предприя- тия» - узлов распределенной информационной базы, между которыми орга- низован обмен данными с целью синхронизации конфигурации и данных. В основе механизмов распределенных информационных баз лежат универ- сальные механизмы обмена данными, но они содержат некоторые дополни- тельные возможности, не доступные через универсальные механизмы. Главное отличие распределенных информационных баз от универсальных механизмов обмена данными заключается в том, что универсальные меха- низмы обмена данными позволяют выстраивать достаточно произвольные схемы обмена данными, в то время как распределенные информационные базы имеют более узкую специализацию.
Распределенная информационная база - это совокупность информационных баз «1С:Предприятия» (узлов распределенной информационной базы), в которых поддерживается синхронизация конфигурации и данных. Распре- деленная информационная база имеет иерархическую структуру. У каждого узла распределенной информационной базы может быть один главный и произвольное число подчиненных узлов. «Самый главный узел» или узел, у которого нет главного узла, называется корневым узлом распределенной информационной базы. Каждый из узлов может обмениваться данными только со своими «соседями», то есть со своими главным и подчиненными узлами (рис. 2.13). Структура узлов распределенной информационной базы Изменения конфигурации допускаются только в корневом узле распре- деленной информационной базы с последующим ее распространением по иерархии от корневого узла к его подчиненным и т. д. Таким образом, меха- низм управления распределенными информационными базами обеспечивает наличие во всех узлах распределенной информационной базы одной и той же конфигурации. Изменение данных допускается в любом узле распределенной информаци- онной базы. Синхронизация данных достигается путем распространения изменений данных, произведенных в одном узле, во все структуры распреде- ленной информационной базы (рис. 2.14).
Миграция данных в распределенной информационной базе Если в рамках всей распределенной информационной базы поддержива- ется полная идентичность конфигурации, то полная идентичность данных не обязательна. Состав данных, изменения которых передаются в рамках распределенной информационной базы, может регулироваться как «по вертикали» (путем определения множества объектов конфигурации, данные которых участвуют в обмене), так и «по горизонтали» (путем задания условий на передачу и прием изменений на уровне отдельных элементов данных). Планы обмена занимают центральное место и в управлении распределенными информационными базами. Но для того чтобы тот или иной план обмена мог использоваться для организации распределенной информационной базы, у него при конфигурировании должно быть установлено свойство Распре- деленная информационная база. Данные в распределенной информационной базе переносятся с помощью сообщений, предоставляемых инфраструктурой сообщений. В отличие от универсальных механизмов обмена данными, содержимое сообщений, пере- даваемых между узлами распределенной информационной базы, не может быть произвольным, а является регламентированным протоколом обмена, принятым для распределенной информационной базы. Состав данных, изменениями которых будет производиться обмен в рамках распределенной информационной базы, определяется составом плана обмена. Вхождение объекта конфигурации в состав плана обмена показывает, что изменения данных, соответствующих объекту конфигурации, могут регист- рироваться для узлов данного плана обмена. Но в отличие от универсальных механизмов обмена данными, номенклатура данных, обмен которыми может производиться в рамках распределенной информационной базы, строго огра- ничена составом соответствующего плана обмена.
Для регистрации изменений данных в распределенной информационной базе задействована служба регистрации изменений. Элементы данных помещаются в сообщение с использованием механизмов XML-сериализации. Помимо изменений данных между узлами распределенной информационной базы передаются изменения конфигурации, а также некоторая дополни- тельная служебная информация. Регистрация изменений конфигурации и включение их в сообщение обмена в распределенной информационной базе осуществляются полностью автоматически и недоступны для пользователя и разработчика конфигураций. В отличие от универсальных механизмов обмена данными, формирование и прием сообщения обмена данными в распределенной информационной базе производятся «в одно действие», то есть все содержимое сообщения форми- руется путем вызова одного метода встроенного языка (листинг 2.45). Пример вызова метода «ЗаписатьИзменения()» Пример использования данных методов приведен в разделе «Запись и чтение сообщений обмена» на стр. 221. Для того чтобы управлять составом данных, помещаемых в сообщение, а также считываемых из сообщения и помещаемых в базу данных, на уровне отдельных элементов данных в модуле плана обмена могут быть определены обработчики событий: • ПриОтправкеДанныхПодчиненному; • ПриОтправкеДанныхГлавному; • ПриПолученииДанныхОтПодчиненного; • ПриПолученииДанныхОтГлавного. Таким образом, в распределенной информационной базе практически полно- стью задействованы универсальные механизмы обмена данными, но имеются и некоторые дополнительные возможности, не доступные вне распределенной информационной базы. ПланыОбмена.ПрочитатьИзменения(ЧтениеСообщения); Считывание содержимого сообщения производится также путем вызова одного метода (листинг 2.46). Пример вызова метода «ПрочитатьИзменения()»
Как было указано выше, у каждого из узлов распределенной информационной базы может быть один главный и произвольное число подчиненных узлов. Для своего главного узла узел является подчиненным, и, соответственно, для своих подчиненных - главным. Узел, у которого нет главного узла, является корневым узлом распределенной информационной базы. Корневой узел распределенной информационной базы --- это единственное место, где разре- шено вносить изменения в конфигурацию информационной базы. Распределенная информационная база может быть построена на основе нескольких планов обмена, с установленным свойством Распределенная информационная база. Взаимодействие в каждой паре узлов «главный - подчиненный» производится в соответствии с одним из определенных в конфигурации планов обмена. Никаких ограничений на использование того или иного плана обмена в том или ином узле распределенной информаци- онной базы не накладывается. Каждый из узлов распределенной информационной базы, как и в случае использования универсальных механизмов обмена данными, «знает» только своих «соседей», то есть свой главный и свои подчиненные узлы (рис. 2.15). Состав узлов распределенной информационной базы для узла «Розничный магазин»
Таким образом, полная схема распределенной информационной базы при наличии более чем двух уровней неизвестна никакому из узлов. Это является особенностью службы регистрации изменений: изменения регистрируются для всех непредопределенных узлов, если в каком-либо плане обмена указать все узлы распределенной базы, то это нарушит струк- туру подчинения баз данных. Для передачи изменений данных и конфигурации в распределенной инфор- мационной базе используются сообщения обмена данными, предоставляемые инфраструктурой сообщений. Если в случае применения универсальных механизмов обмена данными разработчик конфигурации сам определяет, что и как помещается в тело сообщения, то в случае распределенной информаци- онной базы структура и состав данных, помещаемых в тело сообщения, четко определены. Рассмотрим структуру сообщения обмена данными, используемого в распре- деленной информационной базе. В качестве примера рассмотрим следующее сообщение (листинг 2.47). Пример структуры сообщения обмена
Как видно из примера, ,вее особенности сообщения обмена данными, исполь- зуемого в распределенной информационной базе, сосредоточены в теле сооб- щения. Тело сообщения (элемент Body, относящийся к пространству имен http://v8.1c.ru/messages) содержит один-единственный элемент XML - Changes, относящийся к пространству имен http://v8.1c.ru/dataexchange. Внутри этого элемента сосредоточены все данные, передаваемые при обмене данными в распределенной информационной базе. Элемент Changes может содержать четыре вложенных элемента, относящихся к тому же пространству имен: • Элемент Signature содержит «подпись» плана обмена, в соответствии с которым получено сообщение. • Элемент Config содержит изменения конфигурации, а также данные, идентифицирующие состояние конфигурации. Необязательные элементы Metadata, вложенные в Config, содержат изменения отдельных объектов конфигурации. Если изменения конфигурации не передаются в сообщении, то элементы Metadata отсутствуют. Такие элементы могут присутствовать только в сообщениях, передаваемых от главного узла подчиненному. Элементы Digestl и Digest2 содержат цифровые подписи передаваемых в данном сообщении изменений конфигурации и всей конфигурации за вычетом изменений. Элементы Digestl и Digest2 присутствуют во всех сообщениях: передаваемых от главного узла подчиненному и наоборот. • Элемент Nodes может присутствовать только в сообщениях, передаваемых от главного узла подчиненному. Этот элемент содержит два вложенных элемента Node, первый из которых содержит данные главного узла (отпра- вителя), а второй - подчиненного (получателя). • И, наконец, элемент Data содержит измененные элементы данных, пере- даваемые в сообщении. Элементы данных помещаются в сообщение с помощью XML-сериализации.
Создание нового узла распределенной информационной базы в платформе «1С:Предприятие» можно выполнить несколькими способами: • создать начальный образ; • создать узел из конфигурации главного узла распределенной информаци- онной базы; • создать узел из копии информационной базы главного узла распреде- ленной информационной базы. Рассмотрим варианты подробнее. Данный вариант представляет собой наиболее простой способ создания нового узла распределенной информационной базы. Процедуру создания начального образа можно инициировать путем выполнения соответствующей интерфейсной команды Создать начальный образ. Также это можно сделать при помощи метода встроенного языка объекта ПланыОбменаМенеджер (листинг 2.48). Пример использования метода «СоздатьНачальныйОбраз()» Интерактивное создание начального образа Для того чтобы интерактивно создать начальный образ для узла плана обмена, необходимо открыть форму списка плана обмена или непосредственно форму узла плана обмена. Для выбранного (непредопределенного) узла плана обмена следует выполнить команду Создать начальный образ, которая доступна в командной панели формы, а также в меню Все действия (рис. 2.16). При этом на экране появится диалог создания начального образа, в котором будет предложено заполнить все необходимые параметры информационной базы - нового узла распределенной информационной базы. Структура диалога создания начального образа узла распределенной информационной базы аналогична структуре диалога создания новой информационной базы. После заполнения всех необходимых параметров платформа «1С:Предпри- ятие» выполнит создание начального образа: • Будет создана новая информационная база с указанными параметрами. • Конфигурация распределенной информационной базы будет перенесена во вновь созданную информационную базу.
• Будет выполнен перенос данных текущей информационной базы во вновь созданную, при этом для каждого элемента данных будет вызвана процедура узла плана обмена с предопределенным именем ПриОтправ- кеДанныхПодчиненному (т.е. будут перенесены только те данные, которые входят в состав соответствующего плана обмена, с учетом всех ограничений, фильтров, которые определены в обработчике события ПриОтправкеДанныхПодчиненному). • В новом узле распределенной информационной базы будут заполнены данные узла ЭтотУзел плана обмена данными узла данной информаци- онной базы, для которого создается начальный образ. Этот узел будет предопределенным для базы подчиненного узла. • В новом узле распределенной информационной базы будет создан элемент плана обмена, соответствующий данной информационной базе. Его данные будут перенесены. Затем ссылка на этот элемент будет уста- новлена в качестве значения главного узла в этой информационной базе. • Будут удалены все записи о регистрации изменений для узла, начальный образ которого был только что создан. Интерактивное создание начального образа Создание начального образа из встроенного языка Процесс создания начального образа при помощи метода СоздатьНачаль- ныйОбраз() менеджера планов обмена аналогичен интерактивной проце- дуре, за исключением того, что все параметры новой информационной базы, а также узел, для которого необходимо создать начальный образ, должны быть переданы в качестве параметров при вызове указанной процедуры (листинг 2.49).
В строковой переменной СтрокаСоединения указывается информационная база, в которой будет создан начальный образ подчиненного узла распреде- ленной информационной базы. Информационная база для создания началь- ного образа должна быть пустой или не должна существовать вовсе. Строка соединения представляет собой набор параметров, каждый из которых представляет собой фрагмент вида <Имя>=<Значение>, где имя <Имя> - имя параметра, а <3начение> - его значение. Фрагменты отделяются друг от друга символами «;». Если значение содержит пробельные символы, то оно должно быть заключено в двойные кавычки ("). Набор параметров определяется вариантом создаваемой информационной базы: файловый или клиент-серверный. Для файлового варианта определены следующие параметры: • File - каталог, в котором размещается файл информационной базы. я Locale - язык (страна), которые будут использованы при создании информационной базы. Допустимые значения такие же, как у параметра Форматная строка метода Формат (). Параметр Locale задавать не обязательно. Если этот параметр не задан, то будут использованы региональные установки текущей информаци- онной базы. Для клиент-серверного варианта определены следующие параметры: • Srvr - имя сервера «1С:Предприятия». Для обеспечения бесперебойной работы клиентских приложений возможно указание нескольких адресов кластера. Для этого: о Значением параметра Srvr может быть список адресов кластера через запятую, например: Srvr="Serverl,Server2" или Srvr= "Serverl: 1741, Server2:1741". • В диалоге добавления информационной базы в клиентском приложении значением свойства «Кластер серверов 1С:Предприятия» может быть список адресов кластера через запятую, например: Serverl, Server2 или Serverl:1741,Server2:1741. • Ref --- имя информационной базы на сервере «1С:Предприятия». Пример создания начального образа
• DBMS - тип используемого сервера баз данных: • MSSQLServer - Microsoft SQL Server; • PostgreSQL - PostgreSQL; • IBMDB2 - IBM DB2; • OracleDatabase - Oracle Database. • DBSrvr - имя сервера баз данных. • DB - имя базы данных в сервере баз данных. • DBUID - имя пользователя сервера баз данных. • DBPwd - пароль пользователя сервера баз данных. Если пароль для пользователя сервера баз данных не задан, то данный параметр можно не указывать. • SQLYOffs - смещение дат, используемое для хранения дат в Microsoft SQL Server. Может принимать значения 0 или 2000. Данный параметр задавать не обязательно. Если не задан, принимается значение 0. • Locale - язык (страна), аналогично файловому варианту. • CrSQLDB - создать базу данных в случае ее отсутствия (Y/N: "Y" - созда- вать базу данных в случае отсутствия, "N" - не создавать. Значение по умолчанию - N). • SchJobDn - в созданной информационной базе запретить выполнение регламентных заданий (Y/N). Значение по умолчанию - N. ш SUsr - имя администратора кластера, в котором должен быть создан начальный образ. Параметр необходимо задавать, если в кластере опреде- лены администраторы и для них аутентификация операционной системы не установлена или не подходит. • SPwd - пароль администратора кластера. Для всех вариантов определены параметры: • Usr - имя пользователя; • Pwd - пароль. Данный способ является альтернативным способом создания нового узла распределенной информационной базы. Он может применяться в случаях, когда, например, нет необходимости в операции переноса данных (происходящего при создании начального образа) во вновь создаваемую информационную базу. Во многом операции, которые необходимо выпол- нить для создания нового узла распределенной информационной базы
данным способом, совпадают с операциями, выполняемыми платформой «1С:Предприятие» при создании начального образа. Опишем данный способ подробнее: • В информационной базе - узле распределенной информационной базы, для которой необходимо создать подчиненный узел, создаем узел плана обмена, устанавливаем его код и заполняем все необходимые для него реквизиты. В случае если узел, для которого необходимо создать инфор- мационную базу, уже существует, данный пункт можно пропустить. • Сохраняем конфигурацию данной информационной базы в файл. • Создаем пустую информационную базу там, где необходимо создание узла распределенной информационной базы. • Загружаем конфигурацию из файла, созданную в пункте 2, во вновь созданную информационную базу. • Обновляем конфигурацию базы данных. • В режиме «1С:Предприятие» заполняем данные предопределенного узла ЭтотУзел плана обмена данными, соответствующими данным узла, для которого создается узел распределенной информационной базы, в исходной информационной базе (информационной базе главного узла). Коды указанных узлов должны совпадать. • Создаем узел плана обмена, который будет соответствовать информаци- онной базе главного узла, и заполняем его данными, соответствующими данным узла ЭтотУзел в исходной информационной базе. Коды указанных узлов должны совпадать. • При помощи метода УстановитьГлавныйУзел() менеджера планов обмена устанавливаем свойство ГлавныйУзел в значение ссылки на узел, созданный в предыдущем пункте (листинг 2.50). Установка главного узла После выполнения последнего пункта создание узла распределенной инфор- мационной базы считается законченным. Созданная информационная база может участвовать в обмене данными в рамках распределенной информаци- онной базы.
Стоит отметить, что в созданной таким образом информационной базе узла распределенной информационной базы полностью отсутствуют данные. Наполнение данными узла распределенной информационной базы должно выполняться самостоятельно. Для этого можно воспользоваться непосредс- твенно механизмом распределенной информационной базы: • в информационной базе главного узла распределенной информационной базы выполнить регистрацию данных, которые необходимо передать в новый узел (листинг 2.51); • выполнить процедуру обмена данными между главным узлом и созданным узлом распределенной информационной базы. Пример регистрации изменений данных для узла Под копией информационной базы в данном случае можно понимать полу- ченный тем или иным способом экземпляр информационной базы, полностью идентичный оригиналу. Так как конфигурация копии информационной базы идентична конфигурации оригинала, шаги, соответствующие синхронизации конфигураций, можно пропустить. Создание узла распределенной информа- ционной базы выполняется следующим образом: • В оригинале информационной базы - узле распределенной информаци- онной базы, для которой необходимо создать подчиненный узел, создаем узел плана обмена, устанавливаем его код и заполняем все необходимые для него реквизиты. В случае если узел, для которого необходимо создать информационную базу, уже существует, данный пункт можно пропустить. • В копии информационной базы удаляем все непредопределенные узлы соответствующего плана обмена. • Заполняем данные предопределенного узла ЭтотУзел значениями, анало- гичными содержащимся в узле, созданном в первом пункте. Значения кодов узлов должны совпадать. • Создаем узел плана обмена, который будет соответствовать информаци- онной базе главного узла, и заполняем его данными, соответствующими данным узла ЭтотУзел в базе оригинала. Коды указанных узлов должны совпадать. • При помощи метода УстановитьГлавныйУзел () менеджера планов обмена устанавливаем свойство ГлавныйУзел в значение ссылки на узел, созданный в предыдущем пункте (листинг 2.52).
Установка главного узла ГлавныйУзел = ПланыОбвдна.Мзгазины.НайтиПоКрдуС'ЦентрОфис"); ПланыОбмена.УстановитьГлавныйУзел{ГлавныйУзел); После выполнения последнего пункта создание узла распределенной инфор- мационной базы считается законченным. Созданная информационная база может участвовать в обмене данными в рамках распределенной информаци- онной базы. Состав данных полученного узла распределенной информационной базы полностью соответствует составу данных информационной базы оригинала (никакой фильтрации данных согласно составу мигрирующих объектов и в процедуре ПриОтправкеДанныхПодчиненному произведено не было). Состав данных, необходимый для правильной работы узла, должен быть скорректирован самостоятельно. Если план обмена используется в реализации механизма распределенных информационных баз, то в форме списка узлов данного плана обмена, в командной панели, а также в меню Все действия доступны две команды по записи и чтению сообщения обмена (рис. 2.17). Интерактивная запись и чтение изменений При выборе команды (например, записи изменений) открывается диалог, в котором указывается количество элементов данных, обрабатываемых в одной транзакции, и устанавливается флажок Сжимать сообщение (XML-документ будет упакован в архив ZIP), рис. 2.18.
Диалог записи сообщения обмена После нажатия кнопки Записать и сохранить в файл нужно указать имя файла сообщения. Если файл был упакован в архив ZIP, то при чтении сообщения обмена из этого файла архив будет распакован. К недостатку данного метода следует отнести тот факт, что в данном случае нет возможности отследить окончание как процесса выгрузки, так и процесса загрузки данных из сообщения обмена. Аналогичное действие можно реализовать и самостоятельно, используя для записи следующий фрагмент кода (листинг 2.53). Пример записи сообщения обмена Пример чтения сообщения обмена приведен в листинге 2.54. Пример чтения сообщения обмена
Данный подход позволяет отследить момент окончания процесса загрузки выгрузки и при необходимости выполнить какие-либо действия. При необходимости произвести упаковку полученного файла сообщений (или извлечение сообщения из архива) можно воспользоваться функцио- нальностью платформы по работе с ZIP-архивами, рассмотренной в разделе «Работа с ZIP-архивами» на стр. 78. Конфигурация, разработанная для обычной информационной базы, в боль- шинстве случаев требует адаптации для работы в распределенной информа- ционной базе. В этом разделе мы рассмотрим основные методы адаптации конфигурации к работе в распределенной информационной базе. Описанные методы не являются исчерпывающими, ими можно ограничиться, когда необ- ходимо обеспечить простой обмен данными. Например, разделение на два офиса с полным дублированием информации в них. Если же требуется реализация специфической схемы обмена, то может понадобиться реализация сложной архитектуры распределенного решения, влекущая за собой серьезную переработку конфигурации. Предположим, разрабатывается схема обмена, в которой данные из организаций холдинга должны передаваться в центральную информационную базу в виде сводных данных за определенный период. В этом случае требуется реализация в конфигурации соответствующих объектов для хранения детальной и сводной информации. Одной из особенностей работы в модели распределенной информационной базы является возможность создания в различных узлах объектов (доку- ментов, элементов справочника, видов характеристик и т.д.), обладающих одинаковыми номерами (кодами). Это может привести к возникновению в одной информационной базе объектов с одинаковыми номерами (кодами) и привести к определенным проблемам. Дело в том, что синхронизация объектов ведется по уникальному иденти- фикатору. При создании двух и более одинаковых объектов в различных информационных базах можно определить у них одинаковые значения рекви- зитов, одинаковые наборы данных в табличных частях, но при этом значения уникальных идентификаторов (если механизм назначения уникальных идентификаторов не менялся разработчиком конфигурации) у них разные. В процессе загрузки такие объекты будут считаться разными. И в этих случаях для справочника могут создаться элементы с одинаковым кодом, для доку- ментов могут создаться экземпляры с одинаковым номером в определенном периоде и т. д.
Когда назначение номера (кода) выполняется системой автоматически, для подобных объектов необходимо ввести префиксацию, идентифицирующую место создания объекта. Для объектов, чьи номера (коды) устанавливаются вручную, подобную префиксацию реализовывать не нужно (например, коды счетов назначаются пользователями вручную, добавление префикса для них является неправильным). Для объектов, требующих наличия префикса в номере (коде), необходимо: • Установить тип номера (кода) в значение Строка. • Добавить в конфигурацию объект конфигурации Константа, в котором будет установлено значение префикса номера (кода), однозначно иден- тифицирующее данный узел распределенной информационной базы (значение константы должно быть уникальным среди всех узлов распре- деленной информационной базы, сама константа не должна быть вклю- чена в состав плана обмена, на базе которого развернута распределенная информационная база). • Реализовать в модулях объектов предопределенные процедуры, выпол- няемые при установке номера (кода) - ПриУстановкеНовогоНо- мера (ПриУстановкеНовогоКода). Реализация должна использовать в качестве значения префикса значение описанной ранее константы, листинг 2.55. Пример назначения префикса Работа конфигурации в распределенной информационной базе подразуме- вает обмен данными между узлами распределенной информационной базы. В процессе обмена порядок следования данных в сообщениях обмена не опре- делен. При чтении данных могут возникать ситуации, при которых считанные данные ссылаются на несуществующие (возможно, еще не загруженные) данные. При записи считанных данных в информационную базу необхо- димо учесть возможность наличия неразрешенных ссылок в записываемых данных. Для этого в обработчиках событий ПередЗаписью, ПриЗаписи и ПередУдалением необходимо учитывать свойство Загрузка: при записи данных средствами механизма распределенной информационной базы данное свойство будет установлено в значение Истина. В указанных процедурах в режиме Загрузка не следует выполнять различные проверки, связанные с наличием тех или иных данных, участвующих в обмене (например, регис- тратор записываемого набора записей регистра накопления может быть еще
не прочитан из сообщения обмена), не рекомендуется также выполнять н (ме нение связанных данных. В данном режиме рекомендуется дать возможность системе записать прочи- танные данные. Контроль допустимости данных для данного узла распреде- ленной информационной базы может быть осуществлен в соответствующих обработчиках, вызываемых при чтении сообщения обмена (ПриПолуче- нииДанныхОтПодчиненного, ПриПолученииДанныхОтГлавного). Особое внимание следует уделить регистрам сведений, имеющим незави- симый режим записи (свойство Режим записи установлено в значение Независимый). Для данных регистров гранулой обмена является набор записей с отбором по измерениям, с установленным свойством Основной отбор. Необходимо проанализировать, будет ли соответствовать состав пере- даваемой информации логике работы конфигурации. Например, в регистре сведений хранится информация о характеристиках товаров. В основной отбор включены измерения: • Характеристика (идентифицирующее характеристику товара); • Товар (определяющее собственно товар). По логике работы конфигурации важно обеспечить целостность редактиро- вания характеристик товара - состав характеристик товара должен редакти- роваться целиком. Считаем, что ситуация, когда в одном узле исправляется одна характеристика, а в другом - другая, и через некоторое время (после обмена данными) в характеристиках происходит объединение исправлений, является недопустимой. В данном случае (когда все измерения регистра сведений входят в основной отбор) гранулой обмена данными выступает одна запись регистра сведений. И это может привести к ситуации, при которой состав характеристик товара будет состоять из различных характеристик, полученных из разных узлов распределенной информационной базы (мы можем считать эту ситуацию недопустимой). Для устранения подобных проблем следует внести коррективы в набор измерений, входящих в основной отбор регистра: исключить из основного отбора измерение, вносящее излишнюю гранулярность (характеристику из приведенного примера). Это позволит в процессе обмена передавать наборы записей, содержащие информацию, которая полностью соответствует логике работы конфигурации (все характеристики номенклатурной позиции явля- ются логической единицей обмена). Выполнение этих рекомендаций позволяет просто настроить обмен данными в рамках распределенной информационной базы. Дальнейшая адаптация конфигурации зависит от конкретной специфики обмена.
Чтобы проверить работу обмена данными в распределенной информационной базе на реальном примере, необходимо выполнить следующие шаги: • В центральной базе, в списке плана обмена, поддерживающего обмен данными в распределенной информационной базе (в нашем примере создать центральный узел плана обмена, установить его код и заполнить все необходимые для него реквизиты. • Создать подчиненный узел обмена (путем создания начального образа), как описано в разделе «Интерактивное создание начального образа» на стр. 215 (рис. 2.19). Создание подчиненного узла «Оптовый» путем создания начального образа При этом в базе подчиненного узла, в списке плана обмена (в нашем примере Магазины), узел, для которого создавалась база (например, с кодом Опт), будет внесен платформой как предопределенный (помечен специальной пиктограммой в списке узлов), а узел центральной базы будет добавлен в качестве главного узла обмена (помечен специальной пиктограммой в списке узлов), рис. 2.20. Список узлов плана обмена для базы подчиненного узла • Для предотвращения конфликта записи объектов с одинаковыми номерами в базе каждого из узлов обмена нужно установить значение конс- танты Подробнее об этом рассказывается в разделе
«Подготовка конфигурации к работе в распределенной информационной базе» на стр. 223. • После изменения данных в центральной базе, в списке узлов плана обмена, нужно выбрать подчиненный узел, которому будут передаваться данные (например, Оптовый), и нажать кнопку Записать изменения (рис. 2.21). Запись измененных данных из центральной базы в удаленный склад • В базе узла, в который будут загружаться данные, в списке узлов плана обмена нужно выбрать узел, из которого данные были выгружены (например, Центральный офис), и нажать кнопку Прочитать изменения (рис. 2.22). Чтение измененных данных из центральной базы в удаленный склад Произойдет загрузка данных из центральной базы, являющейся корневым узлом, в подчиненный узел обмена. В дальнейшем изменение данных можно производить в любом из узлов плана обмена и обмениваться данными в обе стороны. Но, в отличие от универсального обмена данными, в распреде- ленных информационных базах обмениваться данными можно только между парами узлов «главный - подчиненный», а не между подчиненными узлами. Изменения конфигурации возможны только в корневом узле и должны быть переданы по всем уровням иерархии. Подробнее познакомиться с реализацией обмена данными в распределенной информационной базе можно в демонстрационной конфигурации «Пример обмена», прилагающейся к книге на компакт-диске.
В данном примере выполнен обмен данными между двумя парами узлов (Центральный офис • Розничный склад и Центральный офис • Оптовый склад). Данные, созданные в каждом из узлов, имеют свой префикс нумерации. При этом изменения конфигурации выполнены в корневом узле Центральный офис и переданы подчиненному узлу Оптовый склад. Причем изменения конфигурации и изменения данных были переданы в одном сообщении обмена. В этом случае прочитать сообщение обмена в узле-получателе нужно дважды. Сначала будут получены изменения конфигурации. Затем нужно в режиме Конфигуратор обновить конфигурацию и выполнить чтение изменений еще раз. Теперь будут получены измененные данные. Обработчики событий ПриОтправкеДанныхПодчиненному, ПриОт- правкеДанныхГлавному, ПриПолученииДанныхОтПодчиненного, ПриПолученииДанныхОтГлавного в модуле плана обмена позволяют достаточно гибко управлять обменом данными в распределенной информа- ционной базе. С использованием этих обработчиков может быть построено большое разнообразие сценариев обмена данными. В этом разделе в качестве примера будет рассмотрена организация нескольких сценариев. Данный сценарий является наиболее простым и соответствует поведению распределенной информационной базы по умолчанию. Для этого сценария характерно следующее: • каждое изменение элемента данных, произведенное в любом из узлов распределенной информационной базы, стремится распространиться по всем узлам; • разрешение коллизий производится на основании отношения узлов «главный - подчиненный». Для реализации такого сценария все обработчики не должны изменять значения переданных им параметров, или же обработчики могут быть не определены вовсе. Данный сценарий подразумевает, что для некоторых элементов данных, для которых он реализуется, выполняется следующее: • вся совокупность элементов данных присутствует в главном узле;
• присутствие того или иного элемента данных в том или ином подчиненном узле определяется на основе сравнения значений некоторых реквизитов элемента данных с реквизитами подчиненного узла плана обмена; • разрешение коллизий производится на основании отношения узлов «главный - подчиненный». Для реализации данного сценария нужно обеспечить, чтобы при записи сооб- щения обмена данными в главном узле в сообщение не попадали элементы данных, которые не должны присутствовать в подчиненном узле. Кроме того, если значения реквизитов элемента данных могут быть изме- нены в подчиненном узле, то необходимо обеспечить, чтобы при получении сообщения обмена данными в главном узле производилась регистрация изменений для тех объектов, которых в соответствии со значениями их рекви- зитов в подчиненном узле быть не должно. Для более детального рассмотрения примера предположим, что в качестве типа элементов данных, для которых реализуется сценарий, выступает документ РасходнаяНакладная. У данного документа имеется реквизит Склад типа СправочникСсылка.Склады. Обмен данными организован в соответствии с планом обмена Магазины. У этого плана обмена также опре- делен реквизит Склад типа СправочникСсылка.Склады. В соответствии с этим планом обмена организована распределенная информационная база, в которой корневым узлом является центральный офис, а его подчиненными узлами - склады. У каждого из подчиненных узлов плана обмена значение реквизита Склад установлено так, чтобы обозначать, какому складу соответс- твует этот узел. Все документы РасходнаяНакладная должны присутствовать в корневом узле, а условием присутствия документов в подчиненных узлах является равенство значений реквизитов Склад в документе и узле плана обмена. В этом случае, для того чтобы документы РасходнаяНакладная не попадали в те подчиненные узлы, куда они попадать не должны, обработчик события ПриОтправкеДанныхПодчиненному в модуле плана обмена должен иметь следующий вид (листинг 2.56). Процедура «ПриОтправкеДанныхПодчиненномуО»
В приведенном примере обработчика анализируется тип элемента данных, и если он равен ДокументОбъект. РасходнаяНакладная, то значение реквизита Склад документа сравнивается со значением реквизита Склад узла плана обмена. Если значения реквизитов равны, то значение параметра ОтправкаЭлемента можно не изменять (при вызове параметр имеет значение Авто). При этом в сообщение будет помещено XML-представление документа. Если же значения реквизитов не равны, то параметру Отправ- каЭлемента присваивается значение Удалить. В этом случае в сообщение будет помещено XML-представление объекта УдалениеОбъекта, проиници- ализированного ссылкой на соответствующий документ РасходнаяНакладная. Может показаться странным, что в случае неравенства значений реквизитов Склад параметру ОтправкаЭлемента присваивается значение Удалить, а не Игнорировать, так как в случае значения Удалить XML-представление объекта УдалениеОбъекта будет помещаться в сообщения, отправляемые всем подчиненным узлам, кроме того узла, в который будет отправлен сам документ. Таким образом, в значительной части случаев УдалениеОбъекта будет отправлено тем узлам, где документа, который требуется удалить, никогда не было. Это действительно так, но в данном примере рассмотрен наиболее общий случай. Если же, например, известно, что значение реквизита Склад документа РасходнаяНакладная может быть установлено только при создании документа и в дальнейшем не может быть изменено, то параметру ОтправкаЭлемента в данном обработчике действительно могло бы быть присвоено значение Игнорировать. Если же значение реквизита Склад документа РасходнаяНакладная может быть изменено в подчиненном узле, то в модуле плана обмена необходимо определить обработчик события ПриПолученииДанныхОтПодчиненного следующего вида (листинг 2.57). Процедура «ПриПолученииДанныхОтПодчиненного()»
В приведенном примере обработчика анализируется тип элемента данных, и если он равен ДокументОбъект. РасходнаяНакладная, то значение реквизита Склад документа сравнивается со значением реквизита Склад узла плана обмена. Если значения реквизитов равны, то значения параметров ПолучениеЭлемента и ОтправкаНазад можно не изменять, обеспечив этим поведение по умолчанию при приеме элемента данных. Если же значения реквизитов не равны, то параметру ОтправкаНазад присваива- ется значение Истина. Тем самым гарантируется, что изменения документа будут зарегистрированы и при отправке сообщения подчиненному узлу будет отправлено УдалениеОбъекта, если, конечно, реквизит Склад документа не будет изменен в главном узле так, что он окажется равен значению рекви- зита Склад соответствующего узла плана обмена. Если же значение реквизита Склад документа РасходнаяНакладная не может быть изменено после создания документа, то обработчик ПриПолуче- нииДанныхОтПодчиненного можно не определять. На основе отношения «главный - подчиненный» в распределенной инфор- мационной базе организована типовая процедура разрешения коллизий, авто- матически выполняемая при приеме сообщения. Считается, что изменение элемента данных, произведенное в главном узле, имеет высший приоритет по отношению к изменению, произведенному в подчиненном узле. Таким образом, если сообщение, пришедшее от подчиненного узла, содержит элемент данных, изменения которого зарегистрированы в базе главного узла для этого подчиненного узла, то никаких действий предпринято не будет, то есть этот элемент данных не будет помещен в базу данных и запись регис- трации изменений не будет удалена. Если сообщение, пришедшее от главного узла, содержит элемент данных, изменения которого зарегистрированы в базе подчиненного узла для главного узла, то элемент данных будет записан в базу данных, а запись регистрация изменения будет удалена. В случае если данный сценарий не устраивает, можно реализовать прямо противоположный (принимаются изменения из нижестоящей базы). Данный сценарий подразумевает, что для некоторых элементов данных, для которых он реализуется, выполняется следующее: • каждое изменение элемента данных, произведенное в любом из узлов распределенной информационной базы, стремится распространиться по всем узлам; • разрешение коллизий производится на основании отношения узлов «главный - подчиненный», но более высокий приоритет имеет подчи ненный узел.
Для рассмотрения данного случая воспользуемся приведенным выше примером с документом РасходнаяНакладная и планом обмена Магазины. В данном случае требуется определить обработчики событий ПриПолуче- нииДанныхОтПодчиненного и ПриПолученииДанныхОтГлавного в модуле плана обмена. Обработчик ПриПолученииДанныхОтПодчинен- ного будет иметь следующий вид (листинг 2.58). Процедура «ПриПолученииДанныхОтПодчиненного()» Приведенный обработчик весьма прост: проверяется тип элемента данных, и если элемент данных относится к интересующему нас типу, то параметру ПолучениеЭлемента присваивается значение Принять, что приводит к безусловному приему элемента данных, независимо от того, зарегистриро- ваны его изменения или нет. Обработчик события ПриПолученииДанныхОтГлавного выглядит следу- ющим образом (листинг 2.59). Процедура «ПриПолученииДанныхОтГлавногоО» Этот обработчик несколько сложнее. Если элемент данных относится к интересующему нас типу, то производится проверка - зарегистрированы ли изменения элемента данных для узла-отправителя сообщения. Если изменения зарегистрированы, то параметру ПолучениеЭлемента присваи-
вается значение Игнорировать. В результате прочитанный элемент данных не записывается в базу данных, а регистрация изменений сохраняется, что позволит поместить элемент данных в сообщение, отправляемое главному узлу. В случае возникновения ситуации, при которой необходимо восстановить резервную копию информационной базы, работающую в рамках распреде- ленной информационной базы, можно воспользоваться следующими реко- мендациями. Напомним, что корневым узлом считается информационная база, у которой свойство ГлавныйУзел содержит значение Неопределено. Восстанов- ление корневого узла сводится к восстановлению резервной копии информа- ционной базы. После восстановления информационной базы корневого узла необходимо восстановить обмен данными в распределенной информационной базе. Для этого над всеми информационными базами - узлами распределенной информационной базы - необходимо выполнить действия, аналогичные реко- мендуемым при восстановлении информационной базы подчиненного узла. Процедуру восстановления информационной базы подчиненного узла можно разделить на несколько этапов: • Восстановление в информационной базе подчиненного узла конфигурации главного узла: • Отключение от распределенной информационной базы (осуществляется путем установки свойству ГлавныйУзел значения Неопределено) ПланыОбмена.УстановитьГлавныйУзел (Неопределено). • Загрузка конфигурации главного узла (для восстановления работы в распределенной информационной базе необходимо полное соответс- твие конфигураций главного и подчиненного узлов). Для выполнения этого условия необходимо загрузить конфигурацию (из файла *.ct), полученную из главного узла, в информационную базу подчиненною узла (режим объединения конфигураций в данном случае исполь швать нельзя).
• Синхронизация номеров сообщений между главным и подчиненным узлами. Для правильного обмена сообщениями в распределенной инфор- мационной базе необходимо, чтобы соблюдалось условие: номер прини- маемого сообщения должен быть больше номера, записанного в реквизите НомерПринятого узла, соответствующего информационной базе - источнику сообщения. Номер сообщения получается путем добавления единицы к номеру последнего принятого сообщения (значение рекви- зита НомерОтправленного узла, соответствующего информационной базе - приемнику сообщения). • Подключение к распределенной информационной базе. Для подключения информационной базы подчиненного узла обратно в распределенную информационную базу необходимо установить свойству ГлавныйУзел прежнее значение (листинг 2.60). Установка свойства «ГлавныйУзел» • Синхронизация данных главного и подчиненного узлов. Синхронизация данных может выполняться в обе стороны: от главного узла в подчи- ненный и от подчиненного узла в главный. В обоих случаях достаточно лишь выполнить регистрацию требуемых данных в службе регистрации изменений (для этого можно воспользоваться соответствующим методом менеджера плана обмена), листинг 2.61. Регистрация изменений для узла После выполнения описанных действий работа распределенной информаци- онной базы может продолжаться в обычном режиме. Для отслеживания правильного порядка проведения документов в «^Пред- приятии» служит механизм последовательностей документов. Этот механизм позволяет отслеживать порядок проведения документов и производить восстановление этого порядка. Для того чтобы документ оказался в после- довательности, он должен зарегистрироваться в последовательности, тогда механизм последовательностей будет учитывать его при своей работе.
При организации работы последовательности документов в распределенной информационной базе нужно учитывать, что участие документа в последо- вательности имеет смысл только в одном узле распределенной информаци- онной базы. Это может быть либо узел, в котором документ был создан, либо другой узел, но узел должен быть один. Нарушение данного принципа может привести к различным проблемам в процессе работы с системой, например, невозможности восстановления последовательности документов. Таким образом, документ, участвующий в последовательности, должен регистрироваться в последовательности только в одном узле информаци- онной базы. Для этого документ должен содержать информацию, по которой на момент записи документа можно сделать вывод, должен ли он в данном узле регистрироваться или нет. Для того чтобы документ мог это определить, все узлы информационной базы должны иметь уникальную идентификацию. Например, документ может содержать реквизит, в качестве значения которого содержится код узла плана обмена его информационной базы. Коды узлов информационных баз должны быть в этом случае уникальными. Этого можно добиться организационными методами. Основываясь на информации прина- длежности данному узлу распределенной информационной базы, документ должен при записи либо очистить набор записей регистрации в последова- тельности, либо, наоборот, его заполнить. Тем самым будет достигнута цель регистрации документа в последовательности только в собственном узле информационной базы. Пример очистки наборов записей в последовательностях (фрагмент кода размещается в обработке проведения документа) приведен в листинге 2.62. Пример очистки набора записей регистрации документа в последовательности Узел - реквизит документа, содержащий код узла, в котором он должен регис- трироваться в последовательностях. Как уже было сказано, документ может участвовать в последовательности только в одном узле информационной базы. Поэтому сами последователь ности документов не должны участвовать в обмене данных. Иначе занисн регистрации документа будут переданы в другой узел информационной базы, тем самым нарушив принцип регистрации документа в последовательное!и только в одном узле информационной базы.
Использование транзакций при организации обмена При реализации обмена, как посредством универсального механизма обмена, так и с использованием механизма распределенных информационных баз, одна из задач, которые требуют решения, - это обеспечение целостности и согласованности данных. Данная задача при использовании универсального обмена может решаться с использованием транзакций (листинг 2.63). Пример использования транзакций При выгрузке данных в механизме распределенных информационных баз используется метод ЗаписатьЙзмененияО менеджера планов обмена (листинг 2.64). Пример использования метода «ЗаписатьЙзмененияО» Второй параметр метода указывает количество элементов, записываемых в одной транзакции. Значение 0 указывает на то, что запись всех измененных данных производится в одной транзакции. Такой подход (когда вся выгрузка или загрузка осуществляется в одной тран- закции) обладает как определенными преимуществами, так и определенными недостатками. Преимущества такого подхода заключаются в том, что, например, в файловом варианте работы действия, сгруппированные в одну транзакцию, выпол- няются значительно быстрее (до определенного предела). Кроме этого, при выгрузке данных использование одной транзакции позволяет избежать несо- гласованности выгружаемых данных (например, когда после выгрузки доку- мента, но до выгрузки наборов записей регистров произошло перепроведение документа). Минусами такого подхода является снижение параллельности работы поль- зователей, так как выгружаемые данные будут заблокированы до окончания транзакции.
Кроме этого, необходимо учитывать объем изменений, выполняемых в о той транзакции. Например, в файловом варианте все изменения, произведенные транзакцией, накапливаются в оперативной памяти, что при записи больших объемов данных может привести к исчерпыванию свободной памяти. В клиент-серверном варианте такой опасности нет, но все-таки записывать большие объемы данных в одной транзакции не рекомендуется (из-за проблем параллельности блокировки тоже требуют ресурса сервера баз данных и т.п.). При обмене большими порциями данных имеет смысл использовать несколько транзакций при загрузке или выгрузке данных. Например, в алгоритме загрузки данных можно использовать следующий фрагмент кода, позволяющий разбивать процесс загрузки на несколько транзакций по 1 ООО элементов данных (в данном случае величина 1 ООО --- условная), листинг 2.65. Пример использования нескольких транзакций при выгрузке данных В случаях использования механизма распределенных информационных баз количество объектов указывается вторым параметром метода ЗаписатьИз- менения () (листинг 2.66). Пример указания количества элементов, записываемых в одной транзакции Следует отметить, что зачастую в каждом конкретном случае необходимо искать компромисс между скоростью и параллельностью работы пользова- телей.
Методика включения в сообщение обмена дополнительной информации В некоторых случаях обмен данными должен сопровождаться передачей в сообщении обмена служебной дополнительной информации. Передачу подобной информации можно осуществлять непосредственно в теле сооб- щения обмена. Дополнительную информацию можно размещать в теле сообщения, как при реализации универсального обмена, так и в случае работы с распределенными информационными базами. При универсальном обмене это делается довольно просто. При выгрузке данных (в любой момент: в начале сообщения, в середине, в конце) можно записать в тело сообщения специализированный элемент XML (с нужным наполнением), листинг 2.67. Пример записи служебной информации При чтении необходимо предусмотреть возможность чтения данного специа- лизированного узла (листинг 2.68). Пример чтения служебной информации При необходимости указания дополнительных данных при работе с распре- деленной информационной базой можно использовать следующий подход (листинг 2.69).
Листинг 2.69. Пример передачи дополнительной информации в сообщении распределенной информационной базы В результате выполнения получаем следующее сообщение (приведен начальный фрагмент), листинг 2.70. Фрагмент сообщения обмена
Обратите внимание, что после начала чтения сообщения объект ЧтениеХМЬ уже позиционирован на начале элемента info (можно сразу производить выборку атрибутов элемента). Следует отметить, что алгоритм как записи, так и чтения (в обоих вариантах обмена) зависит от структуры элемента, специализирующегося на «переносе» дополнительной информации. Чтение сообщения обмена, содержащего дополнительную информацию, может быть выполнено так, как показано в листинге 2.71. Пример чтения сообщения обмена
Организация одностороннего обмена В некоторых случаях нет необходимости организовывать полноценный обмен данными между двумя узлами - достаточно передавать данные в одном направлении (подобная задача может возникнуть как при органи- зации универсального обмена, так и в контексте распределенной информаци- онной базы). Однако для правильного функционирования механизмов обмена и инфраструктуры сообщений, в частности, необходимо получение ответных сообщений - сообщений, содержащих квитанции о доставке данных. Все механизмы по реализации одностороннего обмена можно разбить на две большие группы: • без ответных квитанций; • с ответными сообщениями, содержащими только квитанции. Для реализации одностороннего обмена без необходимости получения ответных сообщений можно воспользоваться схемой обмена с гарантиро- ванной доставкой. Суть этой схемы в следующем: после формирования сооб- щения обмена производится удаление регистрации изменений. Этим дейс- твием подтверждается, что данные (записанные в только что сформированное сообщение) будут гарантированно доставлены адресату (листинг 2.72). Пример удаления регистрации изменений В случае если данный механизм используется в распределенных базах данных, следует помнить, что метод УдалитьРегистрациюИзмененийО, не очищает изменения, связанные со структурой конфигурации. То есть если конфигурация изменяется (и используется распределенная информационная база), отказаться от передачи ответных квитанций не получится. Если рассматривать схемы, связанные с передачей ответного сообщения (содержащего только квитанцию), то можно выделить следующие варианты решения: • Отсутствие регистрации изменений данных в информационной базе, выступающей в роли узла-приемника --- сообщение обмена содержи! только квитанцию о доставке (данный вариант доступен только при реализации универсального обмена). • Фильтрация выгружаемых данных из информационной базы, высту- пающей в роли узла-приемника - сообщение обмена содержит только квитанцию о доставке (рекомендуется в случае использования распре к - ленных информационных баз, так как остается необходимость получать изменения конфигурации), листинг 2.73.
• Данные просто не включаются в сообщение (можно использовать в распре- деленных информационных базах, для уведомления о приеме изменений конфигурации в случае, если в источнике используется принудительная очистка таблиц регистрации изменений), листинг 2.74. В результате в файл обмена включается только заголовок сообщения (листинг 2.75). • Фильтрация принимаемых данных от информационной базы, высту- пающей в роли узла-приемника - при приеме отрабатывается только квитанция о доставке. Последний вариант является наименее предпочтительным, так как предпола- гает передачу фактически ненужных данных. Процедура «ЛриОтправкеДанныхПодчиненномуО»
Примеры реализации автоматического обмена данными В процессе использования механизмов обмена данными часто возникает необ- ходимость выполнять процедуру обмена автоматически (например, каждую ночь в определенные часы). В данном разделе мы рассмотрим несколько возможных вариантов организации автоматического обмена данными. Автоматический обмен может быть реализован при помощи регламентных заданий, которые выполняются платформой «1С:Предприятие» по опре- деленному расписанию. Допустим, каждый день в начале работы системы центральной базе необходимо обмениваться данными с узлом плана обмена Оптовый. Для этого в конфигурации центральной базы создадим объект Регла- ментноеЗадание с именем АвтоматическийОбменДанными. Установим его свойство Предопределенное и зададим расписание его выполнения - Выполнять: каждый день; с 8:00 один раз в день (рис. 2.23).
В свойстве Имя метода укажем процедуру общего неглобального модуля, которая будет вызываться при выполнении этого регламентного задания. Эту процедуру в общем модуле заполним следующим образом (листинг 2.76). Процедура «АвтоматическийОбменДанными()» В процедуре выполняется поиск узла обмена Оптовый и производится обмен данными с этим узлом в обе стороны с помощью методов плана обмена УдаленныеСклады ПрочитатьСообщениеСИзменениямиО и Запи- сатьСообщениеСИзменениями(). Эти методы были подробно рассмот- рены в разделе «Пример реализации универсального обмена» на стр. 183. Для клиент-серверного варианта работы «1С:Предприятия» больше не требуется предпринимать никаких действий для выполнения созданного регламентного задания в соответствии с указанным расписанием. Эту работу автоматически выполняет менеджер кластера серверов «1С:Предприятия». В файловом варианте работы (в котором и работает наша демонстрационная база «Пример обмена») для запуска регламентного задания требуется создать специальную обработку. Создадим форму этой обработки и ее событие ПриОткрытии. Заполним обработчик этого события следующим образом (листинг 2.77). Обработчик события формы «ПриОткрытии» А также в модуле формы поместим сам обработчик ожидания --- процедуру ОбработкаЗаданий () (листинг 2.78).
При открытии формы обработки выполняется подключение в качестве обработчика ожидания процедуры с именем 0бработка3аданий(). В свою очередь, процедура ОбработкаЗаданийО выполняет одно-единственное действие - вызывает метод ВыполнитьОбработкуЗаданий(). Этот метод проверяет, существуют ли задания, которые в соответствии с их расписанием должны быть выполнены. Если такие задания существуют, он запускает их на выполнение. Таким образом, в начале рабочего дня при соединении с центральной инфор- мационной базой, при открытии формы обработки АвтоматическийОбменДан- ными будет запускаться регламентное задание, организующее автоматический обмен данными с узлом плана обмена Оптовый. Автоматический обмен может быть реализован при помощи внешней программы, использующей возможности объекта СОМСоединение плат- формы «1С:Предприятие». Данный метод может быть использован в случае, когда изменение конфигурации (для внедрения кода поддержки автоматичес- кого обмена) по каким-либо причинам невозможно или нежелательно. Для примера напишем программу на языке Visual Basic для выполнения обмена, аналогичного описанному в разделе «Использование регламентных заданий» на стр. 241 (листинг 2.79). Пример процедуры обмена Обработчик ожидания В данном примере используются те же процедуры узлов плана обмена Удален- ныеСклады, что и в реализации обмена с использованием командной строки.
Полученный исполняемый модуль может быть поставлен в очередь плани- ровщика. Пример на языке JavaScript приведен в листинге 2.80. Пример постановки задания в очередь Данный код можно размещать в документах *.asp, *.aspx.
Глава 3. Web-расширение Роль Интернета в современной деловой и общественной жизни сложно пере- оценить. В связи с развитием интернет-технологий появились новые виды бизнеса (электронные аукционы, интернет-магазины и т.п.). Фактически уже считается стандартом, что любая компания имеет некое свое «представи- тельство» в Интернете, активно использует различные интернет-технологии для организации как внутрикорпоративного взаимодействия, так и взаимо- действия с огромной аудиторией клиентов, партнеров по бизнесу. Большое количество бизнес-задач уже решается с активным использова- нием этих технологий. С точки зрения автоматизации деятельности учета компаний интернет-технологии позволяют организовать удобный процесс обмена данными, организовать распределенные информационные системы, реализовать механизмы доступа огромного количества пользователей к данным компании. При разговоре о различных интернет-технологиях очень часто встречаются следующие понятия: • клиент, • сервер, я протокол.
Под сервером понимается некий ресурс глобальной сети, к которому можно обратиться для получения какой-либо информации, осуществления обра- ботки данных. Под клиентом обычно понимается программа, обращающаяся к серверу. Протокол - это правила, в соответствии с которыми происходит общение клиента и сервера. Рассмотрим эти понятия несколько подробнее. Предположим, возникло желание просмотреть новости на каком-либо сайте в Интернете. С точки зрения пользователя интернет-технологий мы для решения этой задачи выполняем следующую последовательность действий: • запускаем программу, позволяющую просматривать страницы в Интернете (к примеру, это может быть Internet Explorer); • в строке Адрес программы вводим название интересующего нас сайта (URL); • в основном окне программы просматриваем полученные данные. А вот как этот процесс выглядит изнутри (напоминаем, что рассмотрение производится довольно упрощенно). Каждый компьютер в глобальной сети Интернет обладает неким уникальным адресом (IP). При организации любого взаимодействия учитываются IP- адреса как клиента, так и сервера. Кроме IP-адресов дополнительно исполь- зуется такое понятие, как порт. Рассматривая схему взаимодействия клиента и сервера, можно провести следующую аналогию с реальной жизнью: на корабле нужно доставить груз в город N-ск. В общем случае довольно сложно представить себе корабль (если только это не судно на воздушной подушке), разгружающийся на центральной площади города. Для разгрузки судна (осуществления «взаимодействия» с городом) используется порт (некая точка взаимодействия). Саму разгрузку выполняет определенная «служба» (бригада грузчиков, крановщиков и т. п.). При обслуживании используются определенные «команды», понятные как экипажу корабля, так и сотрудникам порта («вира», «майна» и т. п.). То же самое происходит и при обработке данных как клиентом, так и сервером. С точки зрения Интернета любой компьютер в сети представляет собой некий «черный ящик» с определенным набором точек взаимодействия (аэропорт, порт, ж/д вокзал и т.п.). Каждая такая точка работает по своим правилам (протоколам). Для обслуживания порта может использоваться специализированная программа (рис. 3.1).
Взаимодействие клиента и сервера Вернемся к получению данных с интернет-сайта. В качестве клиента в данном случае выступает программа браузера (Internet Explorer). Когда пользователь вводит данные в поле Адрес, определяется IP-адрес компьютера, который содержит интересующий ресурс, т.е. IP-адрес сервера (для этой цели в Интернете существует специальная «служба»). Для просмотра интернет-страниц используется протокол HTTP (протокол обмена гипертекстом, также можно сказать, что это протокол обмена HTML- документами и их содержимым). По умолчанию работа в соответствии с этим протоколом ведется через порт с номером 80 (номер порта может быть изменен администратором, в этом случае при обращении он должен указы- ваться в явном виде). По полученному IP-адресу сервера (порт No 80) клиент формирует запрос на получение данных. Данный порт на сервере обслуживает специализированная программа: веб- сервер (к примеру, это может быть Internet Information Server, далее IIS). Эта программа получает запрос, выполняет его (это может сопровождаться выполнением какого-либо специализированного кода, из которого произво- дится обращение к определенным базам данных). Результат исполнения IIS отсылает на IP-адрес клиента. Получив ответ, программа браузера отображает его в виде, понятном пользователю. Следует отметить, что в данном примере не рассматривается порядок работы через «промежуточные» службы (прокси-сервера, сервера защиты). Теперь рассмотрим общие принципы работы Web-расширения. Задача Web-расширения заключается в том, чтобы организовать доступ к функ- циональности прикладных решений «1С:Предприятия» через Интернет.
Благодаря этому появляется возможность встраивать доступ к данным «1С:Предприятия» в существующие веб-сайты и создавать интернет-прило- жения, использующие данные информационных баз «1С:Предприятия». Web-расширение - это один из компонентов платформы. Оно поставляется в составе отдельного продукта - «1С:Предприятие 8. Web-расширение 1.1». В версии «1С:Предприятие 8.2» появилось новое приложение - веб-клиент, но не нужно его путать с Web-расширением. Веб-клиент - это клиентское приложение. Достаточно его запустить, и все прикладное решение будет само, автоматически, работать в браузере. А Web-расширение - это специальный компонент платформы, позволяющий на языке высокого уровня (например, С#) написать веб-приложение, которое будет работать в среде веб-браузера и взаимодействовать с информационной базой, предоставляя пользователю какую-часть ее функциональности. Или будет являться частью существую- щего веб-портала, умеющей получать, обрабатывать и изменять некоторые данные информационной базы. Общую схему взаимодействия клиента с информационной базой «1С:Пред- приятия» можно представить следующим образом (рис. 3.2). 3.2. Схема взаимодействия клиента с информационной базой «1С:Предприятия» Web-расширение предоставляет как пользовательский, так и программный интерфейс к данным информационной базы «1С:Предприятия». Другими словами, с помощью Web-расширения можно создавать веб-сайты и т.п., работая с которыми пользователь будет работать с информационной базой «1 С:Предприятия», не имея представления об этом. Работа будет вестись из программы по просмотру интернет-страниц (например, IE), без установленной на компьютере клиента платформы «1С:Предприятие».
Основные положения Web-расширение позволяет организовать доступ к информационным базам (функциональности платформы) «1С:Предприятия» из веб-приложении и веб-сервисов, реализованных на платформе .NET компании Microsoft. Основная идея, реализованная в данной платформе, - унифицировать работу распределенных вычислительных систем, сделать их независимыми от особенностей работы каждого отдельного приложения, сервиса. В данной платформе можно выделить две важные составляющие: • Visual Studio.Net - универсальная среда разработки для платформы .Net; • .Net Framework - многоязыковая инфраструктура исполнения приложений для платформы .Net. В свою очередь, .Net Framework также состоит из двух основных частей: • FCL (.Net Framework Class Library) - библиотека классов; • CLR (Common Language Runtime) - среда исполнения управляемых приложений. Можно выделить две основные технологии, которые реализуются классами FCL: • ADO.NET (ActiveX Data Objects .Net) - помогает устанавливать связь приложений с базами данных; • ASRNET (Active Server Pages .Net) - активные серверные страницы .Net, помогает создавать веб-приложения и веб-сервисы на основе веб-форм. Постараемся показать взаимосвязь основных технологий, используемых Web- расширением с помощью следующей схемы (рис. 3.3). Взаимосвязь используемых технологий
Библиотека FCL содержит более 7000 типов и разделена на различные модули, разделы (иерархические пространства имен). К примеру, в одном пространстве имен могут содержаться «кирпичики», с помощью которых можно работать с правами доступа, в другом --- все необходимое для орга- низации работы со специфическими элементами управления форм и т.п. Некоторые пространства имен могут подразделяться на более специфические пространства имен (так формируется их иерархия). Создание приложений с помощью .Net Framework означает написание программы (в общем случае на любом языке, поддерживаемом системой) посредством использования библиотеки FCL. В данной главе код будет целиком написан на С#, и в нем повсеместно будут использоваться возмож- ности .Net Framework. Для того чтобы написанное на С# приложение могло быть выполнено, его код необходимо преобразовать в язык, понятный операционной системе. Подобное преобразование называется компиляцией программы и выполня- ется компилятором. В .Net этот процесс состоит из двух этапов (оба этапа реализуются CLR): • Компиляция в промежуточный язык MSIL (Microsoft Intermediate Language). Этот код не является специфическим ни для какой операци- онной системы. • Компиляция в код, специфический для операционной системы и архи- тектуры используемого компьютера. Выполняется JIT-компиляторами (Just In Time, своевременный). В прошлом часто возникала необходимость транслировать написанную программу в несколько различных приложений, каждое из которых предна- значалось для конкретной операционной системы, архитектуры центрального процессора (одно приложение под Windows 9х, другое - под Windows NT и т. п.). Сейчас такая необходимость исчезла. Существует несколько JIT компи- ляторов, каждый из которых предназначается для определенного варианта архитектуры компьютера. Вызов нужного из них определяется условиями, в которых необходимо транслировать программу (из кода на языке MSIL) в машинный код. При таком подходе фактически можно забыть о системно-зависимых особен- ностях приложения и сконцентрироваться на его функционале. Использование CLR (среда исполнения управляемых приложений) не огра- ничивается компиляцией программы на MSIL и компиляцией в машинный код с помощью какого-либо JIT компилятора. Код, написанный с помощью .Net Framework, является управляемым на этапе выполнения (runtime). Это означает, что CLR отслеживает выполнение приложений, управляя
памятью, межъязыковой отладкой, обеспечением безопасности и т.п. При и> жения, выполняемые не под контролем CLR, называются неуправляемыми. Часто такую возможность используют для получения доступа к функциям нижнего уровня операционной системы. В качестве обобщения можно рассмотреть последовательность действий, необходимых для создания и выполнения приложения: • код приложения записывается на языке программирования, совместимом с .Net; • производится компиляция в промежуточный язык MSIL; • перед выполнением код компилируется соответствующим JIT компиля- тором; • полученный машинный код исполняется. Если взглянуть на Web-расширение с точки зрения рассмотренных техно- логий, то можно сказать, что оно фактически является расширением (дополнением) библиотеки FCL (добавляются компоненты как в ADO.NET, так и в ASP.NET). ADO.NET является технологией доступа к данным, позволяющей прило- жениям получить доступ к данным, хранящимся в различных источниках. Данная технология может применяться для доступа к данным не только в веб-приложениях, но и других приложениях, построенных на технологиях .NET. Основное ее отличие от множества аналогичных технологий доступа к данным - это возможность работы с данными без постоянного соединения с источником данных. Данные, полученные из базы данных, располагаются в объекте, известном как DataSet, после чего соединение с базой данных закрывается. Доступ и манипуляция данными, находящимися в DataSet, возможна без «живого» соединения с базой данных. После того как произведены необходимые изме- нения, DataSet может быть синхронизирован с базой данных средствами ADO.NET одной транзакцией. Подобная способность работать без постоянного соединения с базой данных является очень выгодной, эффективной и часто востребованной при работе в распределенных средах, таких как веб-приложения. Благодаря этому не требуется прилагать много усилий по сохранению соединения и полученных данных на сервере. К тому же это позволяет
создавать более масштабируемые и высокопроизводительные веб-прило- жения, так как минимизирует количество информации, хранящейся на сервере, и сервер более эффективно использует свои ресурсы. Основными классами FCL, реализующими технологию ADO.NET, являются классы Connection, Command, DataReader, DataAdapter и DataSet пространства имен System.Data. С помощью этого набора объектов осущест- вляется чтение, добавление, изменение и удаление данных. Объект Connection представляет собой соединение с источником данных. Посредством него остальные объекты осуществляют доступ к источнику данных. В Connection указываются параметры соединения с источником данных и сам источник данных. Для установления соединения с источником данных нужно открыть соединение. После выполнения требуемых действий соединение закрывается. Объект Command используется для извлечения и модифицирования данных, находящихся в источнике данных. Для указания, какие данные и в каком виде следует извлечь или изменить, используется текст команды. Обычно текст команды содержит запрос, написанный на соответствующем языке запросов. Для задания значений параметров запроса используются параметры команды. Параметры команды могут быть именованными или нет - это зависит от источника данных и языка запросов. Для указания источника данных, из которого следует извлечь данные, команде устанавливается Connection. Результат исполнения команды может быть прочитан с помощью объекта DataReader. Объект DataReader предназначен для чтения результата исполнения команды. Данный объект и возвращается при ее выполнении. Кроме чтения данных результата запроса, DataReader позволяет получить информацию о структуре результата, то есть получить информацию о количестве и составе колонок результата запроса. DataAdapter служит для преобразования данных, полученных с помощью команды, и заполнения этими данными объекта DataSet. DataSet служит универсальным хранилищем данных и играет ключевую роль при передаче данных между различными компонентами системы. Поэтому часто встает задача преобразования данных результата в DataSet и обратно. Эту задачу и решает DataAdapter. Этот объект содержит команды для чтения, добав- ления, изменения и удаления данных. Следует отметить, что после установки Web-расширения появляется возможность использования таких объектов, как V8DbConnection, V8DbCommand, V8DataAdapter, V8DataReader, V8DbSelectCommand, V8DbUpdateCommand, V8DbDeleteCommand, V8DbInsertCommand
использование которых упрощает процесс обращения к данным информа- ционной базы «1С:Предприятие 8». Описание данных классов находится в пространстве имен _1C.V8.Data. Примеры работы с этими объектами будут рассмотрены позже. В самом начале данной главы рассматривалась последовательность действий, выполняемых при желании клиента просмотреть какую-либо HTML-стра- ницу. Напомним эту последовательность: я по уникальному адресу ресурса в Интернете клиентом (например, программой Internet Explorer) производится запрос на получение данных (обращение идет к нужному порту системы); • этот порт на сервере обслуживает специализированная программа (Web- сервер), которая, приняв запрос, обрабатывает его; • результат запроса в виде HTML-документа возвращается браузеру и им отображается. Модель такого поведения называется «запрос-ответ», она является базовой в Интернете. Недостатком такой модели является то, что общение клиента с сервером происходит только в момент выполнения запроса (получения данных). После этого клиент живет своей «жизнью», сервер - своей. Технология ASP.NET позволяет использовать событийно-ориентированную программную модель. Суть этой модели заключается в том, что сервер «знает», что делает клиент. Для того чтобы понять, как это работает и какие преимущества это дает, проведем краткий экскурс в историю развития веб- технологий. Для размещения газетных публикаций в Интернете был разработан язык HTML (язык разметки гипертекста). Фактически его задачей было пред- ставление информации для пользователей Интернета с определенными функциями ее форматирования. Но страницы, описанные на этом языке, были статическими, никак не реагирующими на действия пользователя в программе-клиенте. Если говорить о функциях веб-сервера, то он просто, получив запрос, «брал» готовый HTML-документ и отсылал его клиенту. Начиная с 4-й версии языка HTML (так называемый DHTML, динамический HTML) появилась возможность выполнять фрагменты кода (скрипты) на стороне клиента. Они имитировали нажатие графических кнопок, с их помощью настраивалась анимация и т.д. В своей работе эти языки исполь- зовали объектную модель клиентской программы (браузера). С их помощью также можно было программно формировать запросы к серверу (запросы
GET, когда параметры запроса отражаются в строке URL страницы в формате иг1?параметр=значение). Ограничением этих языков было то, что они выполнялись на стороне клиента и, естественно, не обладали средствами по работе с базами данных на стороне сервера. Несколько позже (рассматриваем технологии компании Microsoft) появилась технология ASP (активные серверные страницы). Суть этой технологии заклю- чалась в том, что у сервера (точнее у программы веб-сервера Internet Information Server) появилась возможность исполнять ASP-документы (документы, внутри которых находился код на каком-либо допустимом языке программи- рования). Страницы «ожили». Появилась возможность формировать ответы клиенту (результирующий HTML-документ) в зависимости от каких-либо условий, в том числе от состояния базы данных, расположенной на сервере. Таким образом программный код стал исполняться и на стороне сервера. Но серверный сценарий никак напрямую не мог контактировать с клиентским сценарием, и наоборот. По-прежнему общение клиента и сервера произво- дилось при явном выполнении запроса или при отправке данных клиентом (в форме по кнопке Submit, OK или т.п.). Сервер получал запрос (данные) от клиента, выполнял файл и отсылал результат обратно. По-прежнему не было информации о том, что происходит на клиенте. Разработчикам интернет-приложений приходилось принуди- тельно (разными средствами) включать в запрос от клиента нужные данные (полученные в результате действий пользователя), потом (в случае возврата к ранее заполненным формам) определять механизмы восстановления введенных значений и т. п. С приходом технологии ASP.NET появились такие понятия, как веб-формы и серверные элементы управления, HTML-элементы управления. Суть в том, что если раньше (в технологии ASP) элементы управления создавались на стороне клиента (и модель их поведения также описывалась на стороне клиента), то теперь элементы управления могут создаваться на стороне сервера. И на сервере появилась возможность отслеживать события (и как следствие выполнять их обработку), связанные с работой пользователя с этими элементами управления. Это фактически и есть событийно-ориенти- рованная модель. Следует отметить, что несмотря ни на что событийная модель лежит поверх модели запрос-ответ, она ее использует. Но запросы к серверу могут выпол- няться без явной команды пользователя. Рассмотрим на примере, как же все это работает. В среде разработки Visual Studio .NET создадим новый проект (рис. 3.4).
Создание нового проекта Далее будет предложено выбрать шаблон проекта. На будущее (данная глава построена на сквозном примере) выберем шаблон V8 Web Application (хотя в данном случае могли выбрать Web Application). Шаблоны V8 Web Application и V8 Web Service появляются после установки Web-расширения (рис. 3.5). Создание нового приложения Отличием данного шаблона от Web application является то, что дополнительно в утилите импорта метаданных (она запускается автоматически) потребуется указать базу данных «1С:Предприятия 8», которая будет использоваться в веб- приложении по умолчанию (с точки зрения действий, которые производятся при выборе данного шаблона, отличий намного больше: копируются формы по умолчанию, картинки, настраивается ряд «конфигурационных» файлов и т. п.), рис. 3.6. После выбора базы требуется указать пользователя, в контексте которого будет осуществляться работа всего приложения с информационной базой «1 С:Предприятия». При обращении к объектам информационной базы (если иного не предусмотрено явным образом) будут использоваться права именно этого пользователя. В созданный проект добавим новую веб-форму (пункт меню Project • Add New Item), рис. 3.7.
Окно конструктора приложения 3.7. Конструктор «Web Form» Используя панель инструментов Toolbox (группа Web Form), разместим в диалоге формы четыре элемента управления TextBox, столько же элементов Label и две кнопки (элемент управления Button). Группы V8Web, V8Data появляются в данной панели инструментов после установки Web-расширения. Используя палитру свойств для каждого элемента управления, можно добиться следующего вида формы (рис. 3.8).
Пример формы У создаваемой формы есть два режима просмотра: • Design - показывается диалог формы таким, каким его будет видеть поль- зователь в программе-клиенте; ш HTML - показывается исходный код формы (содержащийся в файле с расширением aspx). В режиме HTML код созданной страницы выглядит следующим образом (листинг 3.1). HTML-код созданной страницы
Исходный текст формы включен не полностью, из него были удалены свойства элементов управления, связанные со стилем отображения (поло- жение, шрифт и т. п.), но были оставлены все моменты, существенные с точки зрения рассматриваемого материала. Первые две строки (в исходном тексте это была одна строка) занимает директива, в которой указано, что основным языком программирования для данной формы является язык С#, программная модель (исходный код формы) находится в файле LoginForm.aspx.cs. После этого до первого тега с префиксом asp (тегом называется некое выра- жение, заключенное в угловые скобки) идет, казалось бы, обычный HTML. Отличие, про которое необходимо знать, заключается в том, что хотя сам язык HTML допускает наличие открывающего тега без закрывающего, в данном случае желательно каждому открывающему тегу сопоставлять закрывающий тег. Закрывающий тег отличается от открывающего наличием символа «/» перед именем закрываемого тега. Обратите внимание на строку (листинг 3.2). Фрагмент HTML-кода созданной страницы Когда форма конструировалась в режиме Design, метод отправки для нее явно не определялся. Конструктор автоматически устанавливает метод отправки Post (данные формы отправляются во внутренних переменных запроса и не отображаются в строке URL браузера). Форма выполняется на сервере (обратите внимание: для того чтобы сделать форму клиентской, не нужно писать runat="client", следует просто убрать атрибут runat="server"). Те, кто работал с HTML или ASP, обратили внимание на тот факт, что в данной форме не определен обработчик высылаемых ею данных, т. е. после отправки данных на сервер они для обработки передаются этой же форме (производится отсылка самой себе). Внутри формы с помощью тегов с префиксом asp (этот префикс указывается для серверных элементов управления) определяются все визуально разме- щенные в них элементы управления. К примеру, в следующей строке указывается, что в форме определен элемент управления TextBox с уникальным идентификатором TextBoxl. Элемент управления является серверным (определяется наличием атрибута runat="server"), листинг 3.3. Фрагмент HTML-кода созданной страницы
Для того чтобы посмотреть, как эта форма ведет себя в пользовательском режиме, следует выполнить команду меню Project • Web Project • Set As Start Page (в рамках данного проекта страница станет стартовой). После этого нужно произвести компиляцию проекта и запустить его на исполнение. Это можно сделать одномоментно (действия будут выполняться по очереди, но как бы в пакетном режиме), запустив проект в режиме отладки (выполнив команду меню Debug • Start). Внешний вид формы будет точно таким же, как и в режиме Design. Следует отметить, что при использовании браузеров старых версий или других производителей внешний вид может отличаться. Кстати, одной из приятных особенностей ASP.NET является тот факт, что HTML-файл ответа, отсы- лаемый клиенту, подстраивается под возможности браузера клиента (для наиболее распространенных случаев). Если воспользоваться возможностью браузера просмотреть исходный код (пункт меню Вид • Источник) отображаемого документа, то можно увидеть следующее (листинг 3.4). Исходный код страницы
Если сравнить с исходным текстом веб-формы, то можно сказать, что: • представленный код является полностью «чистым» кодом HTML (без каких-либо директив, префиксов); • при описании формы HTML (тег form) появилось явное указание, что данные, введенные в нее, она же и будет обрабатывать (action="LoginForm.aspx"); • в данном тексте представлены обычные HTML-элементы формы, создава- емые на стороне клиента; • добавился тег input с типом hidden (скрытый) и «непонятным» значением. Фактически происходит следующее: при визуальном проектировании формы в ней размещаются серверные элементы управления. При обращении к данной форме для каждого элемента управления создается его HTML-пред- ставление, которое и отправляется в браузер. На самом деле браузер и может отображать только код HTML. Если бы ему был передан исходный код формы, то те фрагменты, которые ему не «понятны», не отобразились бы. Рассмотрим назначение скрытого тега input. При работе с технологией ASP при отправке данных из формы самой себе информация (состояние), введенная в элементы управления, сбрасывалась (форма как бы получалась заново, и в нее передавались данные запроса). Для того чтобы оставить введенные данные на месте (восстановить состояния элементов управления), разработчикам приходилось прописывать специфические механизмы. При использовании технологии ASP.NET в этом нет необходимости: рассмат- риваемое поле содержит все состояния и значения элементов управления, представленных на форме. Теперь займемся программной моделью поведения веб-формы. Для начала определим обработчик события Нажатие на кнопку «Очистить». Для этого произведем двойной щелчок на кнопке Очистить. Откроется дополнительное окно, показывающее содержимое файла LoginForm.aspx.cs (исходный программный код формы). В представленном коде уже будет сформировано определение функции, обработчика события Button2 Clickfobject sender, System.EventArgs e). Текст, который нужно определить в обработчике, будет ниже выделен серым фоном, а пока ознакомимся со всем представленным кодом (листинг 3.5). Программный код формы
Первоначально с помощью оператора using указываются используемые в данном коде пространства имен (каждое пространство имен содержит описание типов, решающее какую-либо определенную задачу). В новом пространстве имен определяется класс LoginForm, он наследуется от класса System.Web.Ul.Page (базовый класс для любой веб-формы). Любой элемент управления определяется как защищенный член создаваемого класса (из объявления видно, что определения серверных элементов управления находятся в пространстве имен System.Web.Ul.WebControls). При обращении к форме производится вызов функции Onlnit(Ev- ent Args е), из нее вызывается функция lnitializeComponent(). В функции lnitializeComponent() производится определение обработчиков событий: • начало загрузки страницы (Page_Load()); • нажатие кнопки Button2 (Button2_Click()). Для того чтобы функция могла выступать как обработчик события, она должна быть определена с двумя параметрами (листинг 3.6). Пример определения функции Параметр sender имеет тип object (базовый тип всех объектов) и характе- ризует объект, событие которого обрабатывается. Один обработчик события может обрабатывать однотипные события разных объектов, данный параметр может использоваться для уточнения или доступа к свойствам объекта источника. Второй параметр позволяет получить более подробные данные о произо- шедшем событии. После отработки процедуры Onlnit(EventArgs е) инициируется событие (соот- ветствующая функция начинает выполняться) Page_Load. После загрузки форма переходит к ожиданию отрабатываемых событий. При нажатии кнопки Очистить вызывается обработчик события Button2_Click, в котором очищаются все определенные в форме поля ввода (обращение производится к соответствующим защищенным членам класса). Что и проис- ходит в пользовательском режиме. Изменим пример. Определим обработчик события для элемента управ- ления TextBoxl (поле ввода, в которое пользователь вводит логин). Щелкнем два раза на выбранном элементе управления (в режиме Design), в открывшемся модуле в созданном обработчике события определим следу- ющий текст (листинг 3.7).
Заметьте, несмотря на то, что событие TextChanged возникает при любом изменении в поле ввода TextBoxl, запустив веб-приложение в режиме отладки, мы этого не увидим. Какие бы данные ни вводились бы в поле TextBoxl, изме- нений значений (текста) в полях TextBox2 и TextBox3 производиться не будет. И только при нажатии любой кнопки будет виден результат выполнения обработчика события TextChanged. Постараемся пояснить суть происходящего. Все события, которые происходят на форме, можно разделить на две большие группы: • Пассивные (связанные с движениями мыши, нажатием клавиш клавиа- туры). • Активные (нажатие кнопок, изменение текста и т.п.). Пассивных событий формируется огромное множество, отрабатывать их на стороне сервера нет необходимости (и возможности). Их отработка возла- гается на скрипты (сценарии), выполняемые на стороне клиента. Активные события отрабатываются на стороне клиента сервера (если для них определены обработчики событий). Но при этом не всякое событие приводит к его немедленной обработке на сервере. Часть событий может кешироваться на клиенте. В нашем случае событие TextChanged кешировалось. После того как произошло нажатие любой кнопки, например кнопки ОК, произошла отправка данных на сервер. Это можно увидеть, проанализировав текст источника HTML-кода в браузере. Пример обработчика события TextBox1_TextChanged Обратите внимание, что в функцию lnitializeComponent() была автоматически добавлена строка (определяющая, что добавленная функция будет являться обработчиком события), листинг 3.8. Объявление функции lnitializeComponent()
Тип кнопки установлен в значение submit. Это и определяет тот факт, что производится передача данных. В качестве получателя данных (для обработки) указана та же форма, это определено в теге form, в атрибуте action="LoginForm.aspx" (листинг 3.10). Фрагмент кода После передачи данных на сервер обработчики событий выполняются в порядке их возникновения. Последним обрабатывается событие, вызвавшее процесс отправки данных серверу. Если необходимо, чтобы событие TextChanged обрабатывалось на сервере сразу после возникновения, в палитре свойств серверного элемента управ- ления TextBoxl свойство AutoPostBack (немедленная отправка) нужно установить в значение True (рис. 3.9). Свойство «AutoPostBack» После установки данного свойства в исходном тексте формы (*.aspx) во фрагменте, описывающем серверный элемент управления, появился новый атрибут AutoPostBack="True" (листинг 3.11). Фрагмент кода Изменения произошли и в HTML-документе, получаемом программой- клиентом. Во-первых, был добавлен сценарий, выполняемый на стороне клиента (листинг 3.12). Кнопка определена следующим фрагментом кода (листинг 3.9). Фрагмент кода
В области действия тега script определена функция _doPostBack(eventTar- get, eventArgument). Основная задача этой функции - вызвать принудительную отсылку данных из HTML-формы на сервер. Вызов данной функции определен при описании HTML-элемента, ответс- твенного за прием данных о логине (листинг 3.13). Листинг 3.13. Фрагмент кода То, что эта функция будет задействована, определяется в свойстве onchange тега input. При возникновении необходимости определения собственных сценариев, выполняемых на стороне клиента, обращайте внимание на тот факт, что в зависимости от производителя программы клиента (браузера) придется по- разному отрабатывать какие-либо ситуации; реализация объектной модели браузера может различаться. Это наглядно видно по функции, представленной выше. Если в качестве браузера выступает программа компании Netscape, объект «Форма» получается с помощью следующей строки (листинг 3.14). Листинг 3.14. Пример для браузера Netscape Сценарий, выполняемый на стороне клиента
После, казалось бы, незначительной манипуляции (установка свойства AutoPostBack в значение True) нужный эффект был достигнут. После рассмотрения данного примера может возникнуть желание включать данное свойство для всех серверных элементов управления. На самом деле лучше этого не делать. Данное свойство лучше включать только в тех случаях, когда это действительно нужно, когда именно в этом и заключается функцио- нальность элемента управления. Необоснованное включение может привести к падению производительности создаваемой веб-формы. При этом не стоит думать, что эта производительность зависит от скорости работы персональ- ного компьютера или от скорости канала связи (хотя и не без этого). В первую очередь скорость выполнения запроса зависит от количества промежуточных узлов от клиента до сервера. Дело в том, что когда возникает необходимость отправить данные на сервер, как правило, старое соединение уже разрушено. Если так, то вначале произ- водится соединение с сервером, затем отсылка заголовков сообщений. После того как клиент и сервер поняли, что соединились удачно, клиент отправляет данные. После обработки сервер инициирует обратный процесс... Очевидно, что делать все это без необходимости совершенно не стоит. Если вернуться в палитре свойств Toolbox, становится очевидным, что помимо серверных элементов управления в диалоге можно размещать и обычные HTML-элементы. Это рекомендуется делать, если есть необходимость размес- тить какой-либо элемент и при этом нет смысла определять его на стороне сервера (хоть немного, но позволит сэкономить ресурсы сервера). Кстати, если при работе с серверными элементами управления возникнет необходимость просмотреть, какие обработчики события для них определены, можно воспользоваться палитрой свойств, переключив ее в режим просмотра событий (рис. 3.10). Палитра свойств В остальных случаях (Microsoft, Opera) он будет получен следующим образом (листинг 3.15). Пример для браузеров Microsoft,
Конструкторы Web-расширения для веб-приложений В состав средств разработки, поставляемых вместе с Web-расширением (помимо других средств), входят файлы шаблонов для мастера Microsoft Visual Studio Net 2003. Для знакомства с шаблонами, позволяющими создавать веб-приложения, необходимо первоначально создать новый проект с выбором шаблона V8 Application. После выбора данного шаблона будет предложено выбрать информационную базу «1С: Предприятия». В качестве такой базы пред- лагаем выбрать демонстрационную конфигурацию Обмен данными, входящую в состав информационно-технологического сопровождения (ИТС). Перед использованием конфигурации желательно (это понадобится в даль- нейшем) определить пользователя базы данных. Предварительно необходимо создать полный набор прав и только после этого добавить пользователя с этими правами (рис. 3.11). Создание нового пользователя информационной базы «1С:Предприятия» После добавления пользователя можно приступить к созданию нового веб-приложения. Для этого необходимо запустить среду разработки Visual Studio Net 2003 и создать новый проект. При создании нового проекта (пункт главного меню File • New • Project) нужно выбрать шаблон V8 Web Application. Данный шаблон доступен после установки Web-расширения на компьютере разработчика (рис. 3.12). В нижней части указывается путь к виртуальному каталогу создаваемого веб-приложения (строку localhost трогать не нужно). После нажатия кнопки ОК откроется окно утилиты генерации метаданных (запуск этой утилиты является особенностью шаблона V8 Web Application), рис. 3.13.
Создание нового веб-приложения Окно конструктора приложения В окне утилиты необходимо выбрать конфигурацию (базу данных), которая будет основной у создаваемого веб-приложения, указать параметры доступа к ней (имя пользователя и его пароль). После нажатия кнопки ОК будет создан ряд файлов, необходимых для работы всего приложения в целом, и будет открыта единственная (пустая) веб-форма (с именем WebForml.aspx). Просмотреть все созданные файлы можно, используя Solution Explorer (команда главного меню программы View • Solution Explorer), рис. 3.14. В результате выполнения команды откроется окно следующего вида (рис. 3.15).
Рис. 3.14. Вызов Solution Explorer Рис. 3.15. Окно Solution Explorer Если рассмотреть содержимое указанного окна, то можно увидеть, что внутри группы Images находятся ссылки на картинки, используемые при оформлении форм. Внутри группы References находятся ссылки на dll-файлы, отвечающие за реализацию ряда механизмов Web-расширения. Кроме этого, там нахо- дится ссылка на файл 1cv8.dll, в котором хранится информация о метаданных конфигурации, используемой веб-приложением. В корне MySite (так был назван виртуальный каталог приложения) определен ряд других файлов. Рассмотрим их назначение: • DefaultErrorForm - форма, отображающая ошибки исполнения; • DefaultFieldTreeForm - вызывается для отображения доступных полей при работе с объектом V8ReportBuilder;
• DefaultFilterForm - вызывается для установки отборов в списке; • DefaultlmageForm --- вызывается для отображения картинок; • DefaultLineForm - вызывается для редактирования строки табличной части (если указан режим редактирования в отдельной форме); • DefaultListForm - вызывается для отображения формы списка, формы выбора, формы выбора групп; • DefaultObjectForm - вызывается для отображения формы объекта или группы справочника; • DefaultRecordForm --- вызывается для редактирования констант и записи в списке регистра сведений с независимым режимом записи; • DefaultReportPrint - используется для вывода отчета на просмотр и печать; • DefaultTypeChoice --- вызывается для выбора типа в поле ввода; • DefaultTypelnfo - возвращает информацию о типах из метаданных; • DefaultValueList - используется для формирования подбора при вводе по строке; • Global.asax - является как бы глобальным модулем веб-приложения, в нем можно определять ряд обработчиков событий; • StyleSheet.ess - содержит стили оформления, применимые к веб-формам; • TableFormMap.xml --- содержит описания основных форм объектов; • Web.config - определяет настройки веб-приложения. Использование ряда этих файлов будет рассмотрено в следующих разделах данной главы. Познакомимся с конструктором V8 List Form на примере создания в прило- жении веб-формы, позволяющей просматривать (и выполнять ряд других стандартных действий) список номенклатурных позиций подключенной информационной базы. Для решения этой задачи включим в проект новый элемент (веб-форму). Сделать это можно, выполнив команду главного меню программы (Project • Add New Item...), рис. 3.16. Форму необходимо создать с использованием шаблона V8 List Form (для того чтобы не искать данный шаблон среди всех элементов пользовательского интерфейса, можно в левой части диалога сразу же выделить интересующую категорию V8), рис. 3.17.
3.16. Команда Add New Item... 3.17. Шаблон V8 List Form В нижней части диалога определяется имя создаваемой веб-формы. Данный шаблон может использоваться для создания веб-форм, которые по своей функциональности соответствуют формам списка любых объектов «1С :Предприятие». После открытия (кнопка Open) выбранного шаблона необходимо из списка выбрать таблицу базы данных, которая будет выступать источником данных для создаваемой веб-формы (рис. 3.18). Рис. 3.18. Выбор таблицы базы данных
На этом же этапе конструктора можно определять состав полей, которые будут отображаться в создаваемой форме списка справочника (рис. 3.19). Выбор состава полей Следует отметить тот факт, что при создании форм может возникнуть ситуация, когда имя реквизита совпадает с именем метода, существующего для объекта. К примеру, в справочнике может быть определен реквизит ПолноеНаименование. При создании формы списка (для объекта с таким реквизитом) и ее использовании проблем возникать не будет, но при попытке открыть из этой формы форму элемента справочника может быть выдано сообщение Member not found (при создании нового элемента, сразу при открытии формы элемента, при изменении существующего элемента, при попытке сохранения сделанных изменений). Внизу открытого диалога автоматически ставится флажок Записывать инфор- мацию в файл соответствия имен таблиц и форм. Если оставить этот флажок отмеченным, то тогда в файле проекта TableFormMap.xml будет размещен дополнительный элемент XML TableFormMap. Содержимое файла приведено ниже (листинг 3.16).
Элемент XML TableFormMap, представленный выше, описывает, что для таблицы Справочник.Номенклатура определена форма списка с именем nomenlist.aspx. Это приведет к тому, что при возникновении необходи- мости работы со списком указанной таблицы пользователь будет работать не с формой списка по умолчанию (DefaultListForm.aspx), а с данной формой, если иное действие не определено разработчиком явным образом. Например, он может явно указать, что для подбора номенклатуры из какого-либо доку- мента должна использоваться строго определенная форма и т. п. В результате добавления элемента по выбранному шаблону будет создана веб-форма следующего вида (рис. 3.20). Созданная веб-форма Для просмотра созданной формы в действии ее можно определить как стар- товую, используя команду главного меню программы (Project • Web Project • Set As Start Page), рис. 3.21. Содержимое файла TableFormMap.xml
Команда Set As Start Page После этого можно запустить приложение в режиме отладки (Debug • Start) и проверить работу созданной формы. Следует отметить, что установка формы в качестве стартовой действует только в режиме отладки. В готовом веб-приложении стартовая страница определяется в настройках веб-сервера (рис. 3.22). Указание стартовых страниц в настройках веб-сервера Для каждого веб-сервера эти настройки могут быть определены индивиду- ально администратором сервера (например, программы Microsoft IIS).
В результате работы конструктора в форме определено три объекта, их взаи- мосвязь можно показать схематически (рис. 3.23). Рис. 3.23. Взаимосвязь объектов Рассмотрение любой формы лучше начинать с источников. Источником данных для этой формы является объект V8ListDataSource (ID - ListDataSource). Одно из свойств объекта содержит указание на используемую таблицу базы данных (Справочник.Номенклатура). Если веб-приложение работает с несколькими информационными базами «1С:11редприятия», то псевдоним базы указывается в свойстве IBAlias (пустой псевдоним озна- чает, что используется база данных по умолчанию, которая была указана при создании веб-приложения). В диалоге определен серверный элемент управления V8Grid (элемент, пока- зывающий список). Этот элемент управления связан с источником данных посредством свойства ListDataSource. Элемент управления V8CommandPanel (командная панель) связан с нужным списком посредством свойства LinkedControl. Для просмотра кода созданной веб-формы (ее реализации на языке С#) можно воспользоваться командой главного меню программы View • Code (рис. 3.24). Код формы выглядит следующим образом (листинг 3.17).
Листинг 3.17. Код формы
Прокомментируем данный код. Оператор using определяет пространства имен библиотеки классов, которые используются в данной форме. Два последних из них: • _lC.V8.Data, • _ lC.V8.WebControls. Они являются специфическими для Web-расширения. Пространство имен _1C.V8.Data содержит определения классов, реализующих различные механизмы работы с информационными базами. Пространство имен _1C.V8.WebControls содержит определение элементов управления, специфи- ческих для Web-расширения, и их свойств. Далее в коде формы определяется пространство имен проекта MySite. В этом пространстве имен определяется единственный класс nomenlist, он наследу- ется от класса System.Web.UI.Page (базового класса для веб-форм). В качестве защищенных членов класса определяются заголовок формы (Title) и все объекты, размещенные в диалоге формы (источник, список, командная панель). Далее определяется функция инициализации класса (Onlnit(EventArgs е)). В данном обработчике производится вызов функции lnitializeComponent(), которая отвечает за определение функций (членов класса) как обработчиков каких-либо событий. Затем производится вызов метода I nit базового класса (System.Web.UI.Page). Далее по коду определяются две функции, которые функцией Initia- lizeComponent() были назначены как обработчики события инициализации и загрузки формы. Следует отметить, что любой обработчик события является защищенным членом класса, функцией, которая не возвращает значения (void). У данной функции определено два параметра. Первый параметр - это элемент, с кото- рого произошел вызов данной функции (объект, являющийся источником события), второй параметр содержит объект, описывающий детали возник- шего события. В функции - обработчике события Pagejnit производится настройка командной панели, определенной в форме (определяется состав кнопок). Первоначально анализируется возможный параметр запроса ControlName (Request.Params["ControlName"]). В случае если в этом параметре определено значение, отличное от NULL, это значит, что форма открывается как форма выбора. Тогда для элемента управления устанавливается режим выбора (при двойном щелчке форма будет закрыта, и выбранное значение будет передано форме, из которой производился запрос), в источнике
инициализируемой формы добавляется колонка Представление (для передачи в элемент управления, в который производится выбор значения). В противном случае пытаемся найти кнопку выбора (в командной панели) и сделать ее невидимой. Остальные кнопки устанавливаются в соответствии с правами пользователя, в контексте которого производится обращение к базе данных «1С:Предпри- ятия». В обработчике события Page_Load производится проверка прав пользо- вателя на просмотр списка (в противном случае формируется сообщение о нарушении прав доступа). Далее проверяется свойство IsPostBack. Свойство позволяет отследить «первую загрузку» формы (форма загружается не в связи с отработкой каких-либо «пользовательских» событий, т.е. не «повторно»). В случае если форма загружается впервые, устанавливается заголовок формы. Обратите внимание на тот факт, что инициализация формы и ее загрузка производятся каждый раз, как при ее первоначальной загрузке, так и при отработке каких-либо событий на стороне сервера. Если при работе в ранее созданной форме списка номенклатуры произвести двойной щелчок левой клавишей мыши, то откроется форма, содержащая данные о выбранном элементе справочника (рис. 3.25). Форма элемента справочника
Это происходит, несмотря на тот факт, что явно форма элемента справочника нами не создавалась. Дело в том, что в проект изначально включен набор форм по умолчанию (их перечень рассматривался ранее). И как раз в этом случае одна из этих форм и используется (DefaultObjectForm). Рассмотрим данный механизм более подробно. Начнем с самой формы DefaultObjectForm. В диалоге формы определен источник данных, без указания таблицы, с которой он связан, и два элемента управления: • таблица (обычный серверный элемент управления из пространства имен Sysytem.Web.UI.WebControls); • командная панель (элемент управления, специфический для Web-расши- рения). Фрагмент диалога формы показан на рисунке (рис. 3.26). Фрагмент диалога формы Состав коллекции кнопок
В командной панели определены три кнопки (OK, Save, Close). Состав коллекции кнопок и возможные варианты настройки показаны на рисунке рис. 3.27. Программная реализация формы на языке С# приведена ниже (листинг 3.18). Следует отметить, что данный код приводится в качестве примера формы, определяемой программно (на основании переданных параметров). Никто не гарантирует, что со временем реализация этой формы не будет меняться. 3.18. Программная реализация формы DefaultObjectForm
Если рассмотреть представленный код, то можно отметить, что структура кода совпадает со структурой кода любой веб-формы (в том числе веб-формы, позволяющей работать со списком номенклатуры). Отличительной особен- ностью является наполнение (код) обработчика события инициализации веб-формы (DefaultObjectFormJnit) и наличие дополнительной функции ConstructForm. Рассмотрим их назначение и особенности функционирования. Обработчик инициализации формы DefaultObjectFormJnit фактически произ- водит настройку источника данных (V80bjectDataSource objectDS). Производится опрос возможных параметров запроса к данной форме. Если Web-приложение работает с несколькими базами «1С:Предприятия», проверяется значение параметра IBAlias. Полученное значение устанавли- вается в свойство объекта источника данных. Далее (в нашем случае в параметре КеуТуре, получаемом с помощью вызова Request.Params ["КеуТуре"]) определяется значение Справочник.Номенк- латура (это значение в запрос к форме включается автоматически). Значение полученного параметра устанавливается как имя таблицы источника данных. Далее по коду делается ряд проверок, и осуществляется установка других (не менее важных) свойств источника. Практически в самом конце обработ- чика размещены следующие строки (листинг 3.19). Фрагмент кода В первой строке производится попытка получения формы, назначенной основной (используются данные, записанные в файле TableFormMap.xml). В случае если в результате выполнения метода GetUrlO не возвращается пустая строка либо имя формы по умолчанию, производится переход на данную (специфическую) форму (Server. Transfer (url)), путь к которой был получен. Если переход на другую форму не производится, то вызывается функция ConstructForm(). В тексте модуля данной функции можно выделить несколько основных моментов: • в самом начале производится проверка на наличие прав на редактирование объекта; • в соответствии с метаданными объекта создается набор элементов управ- ления, связанных со свойствами редактируемого объекта;
• в соответствии с метаданными объекта создается набор элементов управления V8EditGrid, определяется состав колонок (в соответствии с набором реквизитов соответствующих табличных частей). Поставим перед собой задачу: определить в веб-форме, позволяющей работать со списком номенклатуры, возможность просмотра и заполнения регистра сведений ЦеныНоменклатуры. Регистр сведений имеет два измерения: • Номенклатура, тип СправочникСсылка. Номенклатура; • ТипЦены, тип СправочникСсылка.ТипыЦен. Также регистр имеет ресурс Цена, тип Число. Регистр непериодический, режим записи Независимый. Вернемся к форме nomenlist.aspx. Добавим в форму списка новый источник (V8ListDataSource), в качестве таблицы (свойство TableName) укажем таблицу РегистрСведений.ЦеныНоменклатуры (рис. 3.28). Свойства источника данных V8ListDataSource При настройке свойств нового источника в свойство WhereClause потребу- ется записать условие (можно сказать, что описание условия в данном свойстве равнозначно описанию условия в разделе ГДЕ при построении запроса к указанной таблице). Если необходимо определить условие как параметр виртуальной таблицы, то используется коллекция ConditionClause. Так же как и при описании запроса, параметр описывается с помощью символа &, но, в отличие от работы с объектом Запрос «1 С:Предприятия 8», параметр должен быть еще и определен (не путать с присвоением параметру ,
значения). Определение параметров происходит при настройке коллекции WhereParameters (необходимо просто создать новый параметр и указать его имя - Ссылка). После настройки нового источника необходимо добавить еще один серверный элемент управления V8Grid. В свойство ListDataSource определить имя добавленного источника данных (рис. 3.29). Установка свойства ListDataSource Кроме этого, можно в свойство Width записать значение 100 % (это приведет к тому, что ширина табличного поля будет совпадать с шириной открыва- емой формы). После размещения элемента в диалоге можно определиться с составом отображаемых им колонок. Для этой цели сначала нужно выпол- нить команду контекстного меню Fill columns (заполнить колонки) добавлен- ного элемента управления V8Grid (рис. 3.30). Команда Fill columns
После выполнения указанной команды будет автоматически (в Соответствии с указанным источником) заполнена коллекция Columns табличного поля. Остается удалить из коллекции ненужные колонки (рис. 3.31). Настройка колонок списка Следующим действием будет назначение элементу управления V8Grid, ответственному за список номенклатуры, обработчика события SelectedlndexChanged (при изменении текущего индекса строки). Для этой цели в окне просмотра свойств необходимо переключиться в режим просмотра обработчиков событий (кнопка с молнией), установить курсор напротив события с именем V8Grid_SelectedlndexChanged (рис. 3.32) и нажать кнопку Enter на клавиатуре. Событие SelectedlndexChanged При этом выполнятся два действия. Во-первых, в функции InitializeCompo- nent() (ответственной за определение обработчиков событий) появится новая строка. Этой строкой новая функция Grid_SelectedlndexChanged() назначается обработчиком события SelectedlndexChanged для элемента управления V8Grid (табличное поле, созданное конструктором формы и позволяющее работать со списком номенклатуры). Добавленная строка выделена серым фоном (листинг 3.20).
3.20. Функция InitializeComponent Во-вторых, в коде описан заголовок функции Grid_SelectedlndexChanged(). Остается определить внутри функции следующие строки кода (листинг 3.21). 3.21. Функция Grid_SelectedlndexChanged В данной функции производится получение ключевого поля (мы определили в качестве ключевого поля ссылку на номенклатуру) по текущему (новому) индексу записи в списке номенклатуры. Полученная ссылка устанавлива- ется в значение первого параметра (обращение к параметрам производится по индексу, первый параметр, а он у нас и единственный, в коллекции пара- метров имеет индекс, равный нулю). Далее источник V8ListDataSource1, связанный с регистром сведений, принуди- тельно перечитывает данные в соответствии с новым значением параметра. После этого у табличного поля (V8Grid1) вызывается метод, инициирующий получение данных у источника. При проверке реализованного механизма можно убедиться, что требуемый результат достигнут (рис. 3.33). Пример созданной формы
Схематически весь процесс можно представить следующим образом (рис. 3.34). Схема взаимодействия связанных списков У рассмотренного механизма есть один недостаток. При первоначальном открытии окна табличное поле, связанное с регистром сведений (V8Grid) данными, не заполняется. Это происходит по той причине, что событие SelectedlndexChanged не возникает при открытии формы. Для решения этой проблемы необходимо выполнить несколько действий. Сначала следует изменить обработчик загрузки веб-формы (добавить строки), листинг 3.22. Обработчик события Page Load
При первой загрузке страницы производится программное чтение данных в источник, связанный с номенклатурой. Далее производится получение данных соответствующим табличным полем и после этого производится принудительный вызов функции - обработчика события Selectedln- dexChanged. Затем у обоих элементов управления - источников данных - нужно устано- вить свойство InitByRequest в значение False (рис. 3.35). Свойство InitByRequest Установка данного свойства необходима для исключения двойного считы- вания данных (так как теперь данные считываются и программно). Для создания веб-формы, которая бы отображала данные какого-либо объекта (элемента справочника, документа и т.п.), необходимо выбрать шаблон V8 Item Form (рис. 3.36). После определения имени создаваемой формы открываем шаблон.
Для начала необходимо определиться с объектом, для которого будет созда- ваться веб-форма. Будем считать, что необходимо создать форму документа Поступление товаров (рис. 3.37). Окно конструктора формы элемента Выбор реквизитов табличной части
После выбора таблицы необходимо определиться с составом реквизитов. Следует отметить, что в данном случае желательно выбирать все рекви- зиты (кроме предопределенных), если вы не создаете форму только для просмотра). После нажатия кнопки Вперед необходимо будет выбрать табличную часть, которая будет размещена в веб-форме, и определиться с составом отобража- емых реквизитов табличной части документа. Заметьте, несмотря на то, что есть возможность для табличной части выбрать ссылку и номер строки (как показано на рисунке), делать это совсем не обязательно (рис. 3.38). После нажатия кнопки Готово интересующая нас форма будет создана. Позна- комимся с этой формой поближе. В рассматриваемой веб-форме можно увидеть несколько элементов управ- ления: • V80b j ectDataSource - является источником данных (в его настройках указывается таблица, из которой будут извлекаться данные для формы). В качестве ключевого поля данного элемента выступает ссылка на загру- женный элемент. • V8TextBox - предназначен для отображения (и обработки) реквизитов шапки документа. • V8EditGrid - предназначен для вывода табличной части документа (на каждую табличную часть по элементу). • V8CommandPanel - реализует командную панель (как для экземпляра документа в целом, так и для каждой табличной части). Взаимосвязь элементов управления в упрощенном виде можно изобразить в виде следующей схемы (рис. 3.39). Взаимосвязь элементов управления
Внутри каждого объекта указаны свойства, посредством которых настраива- ется взаимосвязь указанных элементов управления. Программная реализация веб-формы строится по стандартной схеме и имеет следующий вид (листинг 3.23). 3.23. Программная реализация веб-формы
В пространстве имен проекта определяется новый класс. Все элементы управления определены как защищенные члены класса. Далее по коду опре- деляются обработчики событий. При работе с документом, созданным в предыдущем разделе, становится очевидным одно неудобство: сумма по строке табличной части не считается, цена не подбирается. Данные механизмы уже давно относятся к обяза- тельным. Рассмотрим пример реализации расчета суммы по строке по введенному количеству и сумме. В самом начале потребуется включить в проект новую форму (используя шаблон Web Form). В диалоге разместить несколько элементов управления: • V8LineDataSource (имя lineDS, в качестве источника указана табличная часть документа); • V8TextBox (по одному элементу управления на каждый реквизит табличной части); ш надписи (обычные HTML-элементы); • V8CommandPanel, командная панель, связанная с объектом lineDS. Приблизительный вид формы (рис. 3.40).
Внешний вид веб-формы Для элементов управления V8TextBox, связанных с реквизитами табличной части Количество и Цена, можно определить обработчик события ValueChanged. Текст всей формы приведен ниже (листинг 3.24). Программная реализация веб-формы
He следует забывать тот факт, что если не предпринимать никаких допол- нительных шагов, обработка события (изменения количества и цены) будет производиться только после явной отправки формы. Для того чтобы вызов функции происходил именно при изменении (а не квитировался), необходимо свойство AutoPostBack установить в значение True. Следует отметить, что не нужно (без особой необходимости) устанавливать данное свойство для всех элементов управления. Рекомендуется это делать только в тех случаях, когда действительно нужна немедленная обработка данных (факти- чески после проведения изменений производится отсылка формы серверу), рис. 3.41. Теперь, после того как форма (ответственная за редактирование строки) готова, остается в веб-форме, ответственной за редактирование документа, установить нужным образом свойства объекта V8EditGrid (рис. 3.42).
3 . Свойство AutoPostBack 3.42. Свойство EditlnSeparateWindow В свойстве EditlnSeparateWindow указывается, что редактирование строки табличной части будет производиться в отдельном окне. И в качестве этого окна будет использоваться вновь созданная форма строки табличной части. При необходимости включения в создаваемое веб-приложение каких-либо отчетных форм можно воспользоваться шаблоном V8 Report Form. Создадим отчет, с помощью которого можно будет просматривать остатки номенклатурных позиций по складам. Для начала включим в проект новую форму. При создании выбираем шаблон V8 Report Form (рис. 3.43). После открытия шаблона (указания имени создаваемой формы) определяем текст запроса (рис. 3.44). Следует отметить, что получаемая отчетная форма будет обладать функци- ональностью, похожей на функциональность выходной формы, созданной с использованием возможностей построителя отчета. Исходя из этого, в тексте запроса в обязательном порядке должен быть определен раздел ИТОГИ.
Шаблон V8 Report Form Пример запроса Кроме этого, важно в текст запроса включать поля представлений ссылочных полей, которые потом потребуется показывать в отчете. Если этого не сделать, то в выходной форме будут отображаться уникальные идентификаторы ссылок на объекты (что, скорее всего, огорчит пользователя).
Определение группировок строк и колонок На следующем шаге необходимо указать ряд настроек, важных с точки зрения размещения данных в отчетной форме (рис. 3.47). На следующем шаге необходимо предварительно нажать кнопку Заполнить (рис. 3.45). Окно конструктора формы отчета При определении полей запроса поля представлений автоматически (по нажатию кнопки Заполнить) не заполняются. Их необходимо настроить (добавить) вручную. При этом форма конструктора должна выглядеть так же, как представленная на рисунке выше. Настройку списка выбранных полей не изменяем (не нужно вносить в этот список поля представлений, добавля- емых в список полей запроса) Следующим шагом может быть определение группировок строк и колонок. В нашем случае оставим все без изменений (рис. 3.46).
Установка группировок Далее потребуется указать режим отображения отчета, определить количество строк, отображаемых на странице. Не рекомендуется делать данную величину очень большой, т. к. это затрудняет как получение данных, так и их просмотр (рис. 3.48). Настройка вывода отчета На последней странице конструктора отмечается необходимость размещения дополнительных закладок, существенно расширяющих функциональность создаваемого веб-отчета. Можно сказать, что данные закладки реализуют такую же функциональность, как и табличные части построителя отчета в «1 С:Предприятии 8». Назначение каждой закладки совпадает с одноименными табличными частями объекта «1С:Предприятие 8» ПостроительОтчета (рис. 3.49). Выбор состава закладок
После последовательного выполнения всех указанных шагов будет создана необходимая веб-форма. Рассмотрим полученную веб-форму более подробно. Основу механизма веб-отчетов составляет элемент управления V8ReportSource. Элемент управления содержит свойства, аналогичные свойствам построителя отчета «1С:Предприятия 8»: • Order - порядок; • Filter - управление отбором; • ColumnGroup - измерения колонок; • RowGroup - измерения строк; • SelectedFields - выбранные поля. Эти свойства могут быть интерактивно настроены пользователем, для чего в форме на каждое свойство определено по элементу управления V8EditGrid (аналог табличного поля «1С:Предприятия»). Для отображения результата запроса служит объект V8ReportViewer. Связанный с ним элемент управления V8CommandPanel позволяет осуществлять навигацию по полученному результату запроса (напоминаем, что в общем случае данные отображаются по указанному количеству строк). Состав и взаимосвязь элементов управления, расположенных на форме, можно схематически представить следующим образом (рис. 3.50). Рис. 3.50. Взаимосвязь объектов формы Элемент управления V8ReportSource решает несколько задач: • анализ текста запроса и выдача доступных полей для настроек параметров отчета;
а взаимодействие с кешем отчета; в разбиение результата отчета на группы и страницы. Можно сказать, что этот элемент управления является своего рода сервисной оболочкой, которая избавляет разработчика от работы с деталями реали- зации механизма веб-отчетов. Однако при желании можно отказаться от использования данного объекта и воспроизвести его функциональность, работая с его составляющими. Дело в том, что объект V8ReportSource для своей работы использует несколько других объектов и механизмов. Основными из них являются: • V8ReportBuilder, используется для получения данных; • V8ReportData, обработка полученных данных; • механизм кеширования результата отчета; • V8ReportFormatter, производит форматирование данных. В упрощенном виде взаимодействие перечисленных объектов можно пред- ставить следующей схемой (рис. 3.51). . Взаимосвязь объектов Коротко схему можно пояснить следующим образом. Элемент управления V8ReportSource создает объект V8ReportBuilder и передает ему все параметры и настройки, указанные пользователем (внесенные в соот- ветствующие элементы управления V8EditGrid). В соответствии с этими параметрами (и текстом запроса отчета) объект V8ReportBuilder извле- кает данные из информационной базы «1С:Предприятия 8» и возвращает их в виде объекта V8ReportData. Эти данные помещаются в кеш отчета, основанный на стандартном механизме кеширования ASP.NET. Из кеша данные извлекаются по мере необходимости, оформляются с помощью объекта V8ReportFormatter и передаются элементу управления V8ReportViewer.
В ряде случаев при работе с полученными отчетными данными может потре- боваться получение дополнительных (связанных с отображаемыми) данных. К примеру, при просмотре остатков товаров нужно открыть форму элемента справочника. Может потребоваться из одного отчета перейти в другой. Например, работая с оборотно-сальдовой ведомостью, в которой каждая строка содержит данные об остатках по счету, приходу и расходу, по щелчку в строке желательно перейти в отчет, показывающий более детальную инфор- мацию по данному счету. Механизм получения таких дополнительных данных можно реализовать с помощью расшифровок. Расшифровки можно разделить на два типа: • простые - когда необходимо получить форму объекта по представляемой ссылке; • сложные - когда из одного отчета необходимо перейти в другой отчет (с передачей нужных параметров). Оба варианта реализуются с помощью свойств Details и FieldFormat объекта V8ReportSource. Какой вариант используется --- зависит от способа заполнения этих свойств. Рассмотрим их реализацию более подробно. Считаем, что настраиваем расшифровки у отчета, который создавался в предыдущем разделе. Простые расшифровки Добьемся того, чтобы после формирования отчета из него можно было открыть форму элемента как справочника Номенклатура, так и справочника Склады. Начать настройку расшифровок рекомендуется с настройки свойства Details объекта V8ReportSource. Необходимо создать новый элемент коллекции и настроить его так, как пока- зано на рис. 3.52. Коллекцию DetailsParameters настраивать (для простых расшифровок) нет необходимости. В свойстве KeyFieldForElement выбирается поле (из полей отчета), содержащее ссылку объекта, форму элемента которого будем получать. В свойстве Name указываем имя расшифровки (его будем использовать при работе со свойством FieldFormat). С помощью свойства URLTarget определяем вариант получения формы элемента. После настройки свойства Details переходим к определению свойства FieldFormat. Заполнение этого свойства приведет к тому, что данные,
выводимые в указанном поле, будут представлены в виде гиперссылки. Это свойство необходимо заполнить, как показано на рис. 3.53. Коллекция элементов свойства Details Коллекция элементов свойства FieldFormat В свойстве Details устанавливаем флажок использования расшифровки. В следующем поле из списка (предварительно должно быть определено свойство Details объекта V8ReportSource) выбираем нужную расшиф- ровку. Для какого поля эта расшифровка, определяется полем Name. Расшифровка (была показана настройка расшифровки по номенклатуре) готова, осталось только откомпилировать приложение.
Сложные расшифровки Механизм сложных расшифровок позволяет настроить взаимосвязь сущес- твующих в веб-приложении отчетов. С его помощью можно значительно увеличить гибкость системы отчетности, используемой в приложении. Рассмотрим пример реализации связи отчета по остаткам товара с отчетом (его необходимо будет создать), показывающим движения выбранного товара понедельно. При создании нового отчета используется следующий запрос (листинг 3.25). Запрос, используемый для создания отчета о движениях товара Так же как и для простых расшифровок, определение сложных производится с помощью свойств Details и FieldFormat объекта V8ReportSource. Начнем с настройки свойства Details (рис. 3.54). Коллекция Details В созданном элементе коллекции определяется его имя (оно будет использо- вано при определении свойства FieldFormat). С помощью свойства URL указывается путь к форме открываемого отчета. Для указания связи параметров вызывающего отчета с параметрами вызыва- емого используется свойство DetailsParametrs. Его настройка показана на рис. 3.55.
3.55. Коллекция DetailsParametrs Выбирается вариант сравнения Equal (равенство), определяется имя пара- метра отчета, значение выбирается из выпадающего списка. Для того чтобы механизм заработал, остается настроить свойство FieldFormat (рис. 3.56). Коллекция FieldFormat В свойстве Details устанавливаем флажок использования расшифровки. В следующем поле из списка (предварительно должно быть определено свойство Details объекта V8ReportSource) выбираем нужную расшиф- ровку. Для какого поля эта расшифровка, определяется полем Name.
Особенности реализации расшифровок Рассмотрим действие механизма расшифровок. Рассматривать будем на примере сложных расшифровок, определяемых в предыдущем разделе (реализация этого механизма как для простых, так и для сложных расшиф- ровок строится по одному принципу). Сформируем отчет по остаткам номенклатуры (рис. 3.57). Сама функция имеет следующий вид (листинг 3.28). Пример отчета по остаткам номенклатуры Товар в данном отчете отражается в виде гиперссылок. С точки зрения исходного HTML-кода каждая ячейка таблицы (в которой отражается номенк- латурная позиция) имеет следующую реализацию (листинг 3.26). Фрагмент HTML-кода При щелчке мышью по такой ячейке вызывается функция JavaScript doDetailsClick, определенная в js файле. Подключение этого файла определя- ется следующей строкой HTML-кода (листинг 3.27). Фрагмент HTML-кода
Данная процедура на основании полученных через параметры данных программно генерирует запрос к серверу (для сервера формируется событие Details, которое им в дальнейшем и обрабатывается). Табличные данные отчета могут быть представлены графически, с помощью диаграмм. Для этого Web-расширение предоставляет возможность создания веб-диаграмм, использующих в качестве своей основы механизм веб- отчетов. Шаблон V8 Chart Form как раз и предназначен для создания веб-форм, показы- вающих данные в виде диаграммы. Последовательность выполняемых шагов при создании веб-диаграммы идентична последовательности (и особенностям заполнения) по созданию формы на основании шаблона V8 Report Form. Поэтому она в данном случае специально не рассматривается. В указанной функции производится проверка заполненности необходимых параметров вызова и производится вызов функции doPostBack, опреде- ленной в HTML-коде страницы (листинг 3.29). Фрагмент HTML-кода
Единственной особенностью (кроме того факта, что выбирается другой шаблон) является необходимость выбора вида диаграммы на одном из этапов создания формы (рис. 3.58). Выбор вида диаграммы Основа механизма веб-диаграмм - элемент управления V8ChartSource. Свойства, управляющие настройкой запроса, аналогичны свойствам V8ReportSource и табличным частям объекта ПостроительОтчета «1С:Предприятие 8»: • Order - порядок; • Filter - управление отбором; • ColumnGroup - измерения колонок; • RowGroup - измерения строк; • SelectedFields - выбранные поля. Эти свойства могут быть интерактивно настроены пользователем в форме, для чего в ней располагается соответствующее количество (на каждое свойство по одному) элементов управления V8EditGrid. Для отображения полученных данных служит элемент управления V8ChartViewer и связанный с ним элемент управления V8CommandPanel (позволяющий в том числе выбирать вид диаграммы).
Взаимосвязь элементов управления, расположенных в форме веб-диаграммы, представлена на следующей схеме (рис. 3.59). Схема взаимодействия объектов формы Элемент управления V8ChartSource решает задачи, связанные с построе- нием данных отчета: ш анализ текста запроса и выдача доступных полей для настроек пара- метров отчета (эта функциональность реализована в базовом элементе V8ReportBuilder); • формирование и кеширование изображения диаграммы. Так же как и объект V8ReportSource, объект V8ChartSource для своей работы использует ряд других объектов. В упрощенном виде их схема взаи- модействия выглядит следующим образом (рис. 3.60). Схема взаимодействия объектов
При создании диаграммы элементу управления V8ChartSource устанавли- вается: • текст запроса; • описание взаимосвязей полей запроса; • отображаемый ресурс; • серии - группировки строк; • точки - группировки колонок; • настройка упорядочивания и отбор; • тип диаграммы; • графический формат диаграммы; • размер изображения. Элемент управления V8ChartSource, используя механизм отчетов, полу- чает результаты выполнения запроса в объекте V8ReportData. С помощью объекта V8ChartFormatter, с учетом настроек оформления диаграммы, эти данные преобразуются в описание диаграммы. Это описание переда- ется объекту V8Cha гt Irr.ageCrcator, который формирует изображение диаграммы. Сформированное изображение помещается в кеш диаграммы, основанный на стандартном механизме кеширования ASP.NET. Для отображения диаграммы элемент управления V8ChartViewer размещает на веб-странице ссылку на форму по умолчанию для вывода изображений, которая извлекает изображение диаграммы из кеша по идентификатору, полученному от V8ChartSource. Кроме этого, объект V8ChartImageCreator формирует карту областей изображений (ImgMap), которая служит для поддержки механизма расшифровок и подсказок. Каждая область соответствует определенному элементу изображения (например, подписи или сектору круговой диаграммы), к которому могут быть привя- заны определенные параметры расшифровки и подсказка. Расшифровки диаграммы определяются точно таким же образом, как и для отчета. Доступ к данным через ADO.NET С помощью ADO.NET компонента можно организовывать различную обра- ботку данных: получение, изменение, удаление данных из информационной базы данных «1С:Предприятие 8». Рассмотрим эти возможности на ряде простых примеров. Необходимо помнить, что рассматриваемые объекты (посредством которых будет организовываться доступ и модификация данных) в основном являются специфическими для Web-расширения (определены в пространстве имен _1C.V8.Data).
Также следует отметить, что приводимые ниже примеры (после соответс- твующей корректировки) позволят адаптировать уже готовые веб-формы (созданные без использования Web-расширения) к работе с информационной базой «1С:Предприятия 8» (по этой причине ни в одном из примеров не задействован ни один серверный элемент управления из пространства имен _1C.V8.WebControls). Получить данные из информационной базы «1С:Предприятия 8» (из веб- формы) можно двумя способами (на самом деле это просто два варианта определения одного и того же объекта VBDbSelectCommand): • по запросу; • с указанием одной таблицы. Несмотря на наличие двух способов, общая схема (порядок использования объектов) получения данных для них одна и та же. Ее можно представить в следующем виде (рис. 3.61). Алгоритм получения данных Для чтения в общем случае используются три объекта: • V8DbConnection - предназначен для указания параметров подключения к базе данных и проведения этого подключения;
• V8DbSelectCommand - предназначен для указания параметров выборки и проведения выборки данных, получения объекта V8DataReader; • V8DataReader - предназначен для получения данных и их обхода. Перейдем к рассмотрению реальных примеров. Поставим перед собой задачу: получить и отобразить в форме остатки номенклатуры. Предварительно необходимо создать новую веб-форму. При создании выбрать шаблон Web Form. В диалоге формы необходимо разместить элемент управления Table (он расположен в панели Toolbox, в группе Web Forms). Из этой же группы необходимо добавить в диалог элемент управления Button (кнопку). В модуле формы необходимо добавить еще одно используемое пространство имен -_1C.V8. Data. Остается следующим образом определить обработчик нажатия кнопки (следует отметить, что переход к обработчику события кнопки можно осущес- твить по двойному щелчку по самой кнопке), листинг 3.30. Обработчик события Click
При создании подключения (V8DbConnection) помимо пути к базе данных указывается имя и пароль пользователя, в контексте которого необходимо обращаться к базе данных. В рассматриваемом случае эти данные указыва- ются явно в коде формы (что не рекомендуется). Как это сделать по-другому, будет рассмотрено в следующем примере. При создании объекта V8DbSelectCommand указывается тип команды: CommandType.Text. В этом случае в свойство CommandText данного объекта можно записать текст запроса. При необходимости получить данные с каким-либо отбором условие отбора определяется непосредственно в тексте запроса (параметр определяется с помощью символа «&»). При использовании параметров в условиях необходимо помнить: • параметрам необходимо присваивать значения (<объект>.Parame- ters .Add(<Имя>, <3начение>); • типы данных «1С:Предприятия» и .Net могут различаться и требовать явного преобразования. У созданного объекта V8DbSelectCommand через свойство Connection устанавливается созданный объект V8DbConnection.
Далее в коде производится работа с объектом Table. Отдельно создается строка табличной части (row), отдельно ячейка (cell). Манипулируя данными объектами, определяется объект «Таблица». Сам процесс получения данных начинается с установления подключения (напомним, что одной из важных особенностей ADO.NET является отсутс- твие необходимости поддерживать постоянное подключение). В конструкции try (попытка) производится получение данных. Причем при создании объекта V8DataReader (при выполнении метода ExecuteReader ()) используется конструкция using (по окончании блока кода все ресурсы будут гарантированно освобождены). Обход результата происходит в цикле. По окончанию обхода соединение закрывается. С помощью рассмотренной модели можно одновременно получать данные из разных таблиц, но полученные таким образом данные нельзя модифици- ровать. Поставим перед собой задачу: отображать данные документа Приходная накладная по введенному в форме номеру документа. Данный пример очень похож на предыдущий. Так же нужно создать новую веб-форму. В диалог формы необходимо поместить элемент управления TextBox (он расположен в панели Toolbox, в группе Web Forms). Из этой же группы необходимо добавить в диалог элемент управления Table (вывод данных будем производить именно в этот элемент управления) и Button (кнопка). В коде не забыть дописать использование пространства имен _1C.V8.Data. Обработчик события нажатия кнопки будет уже определен несколько по- иному (листинг 3.31). Обработчик события Click
Рассмотрим отличия данного обработчика от приведенного ранее. При создании подключения имя пользователя и его пароль не прописываются явно, а выбираются из параметров пользовательской сессии (объект Session[<Имя параметра>1). За запись этих значений несет ответствен- ность сама система, но при желании подобную возможность можно исполь- зовать и в своих целях (более подробно это рассмотрено в разделе «Полезные средства .NET Framework» на стр. 349). У объекта V8DbSelectCommand определен тип команды: CommandTy- pe.TableDirect. Исходя из этого, состав полей для выборки определен в свойстве Fields (указываются как реквизиты шапки документа, так и реквизиты вложенных таблиц). При необходимости наложить какой-либо отбор на данные, получаемые из таблицы, можно использовать свойство WhereClause (аналог раздела ГДЕ языка запросов «1С:Предприятия»), Значение параметра берется из элемента управления TextBox, размещен- ного в диалоге. Следует обращать внимание на типы полей. В нашем случае документ Приходная накладная имеет строковый номер. При попытке пере- дать числовое значение ошибки бы не происходило, но к нужному результату (успешному нахождению документа) это не приводило бы. Последней особенностью является открытие подчиненной выборки для обхода данных табличной части документа. Поставим перед собой задачу - реализовать возможность добавления нового элемента в справочник Номенклатура. При добавлении данных работа ведется со следующими объектами: • V8DbConnection --- предназначен для указания параметров подключения к базе данных и проведения этого подключения; • V8DbInsertCommand - предназначен для указания добавляемых данных и проведения самой операции добавления. Перейдем к рассмотрению примера. Необходимо создать новую веб-форму (используя при этом шаблон Web Form). В диалоге формы нужно разместить три элемента управления TextBox (для кода, наименования и закупочной цены номенклатуры). Также следует доба-
При создании объекта V8DbInsertCommand в качестве типа команды можно использовать только CommandType.TableDirect. В свойство Text записывается имя таблицы. Добавляемые данные должны соответствовать полям таблицы и определяются как параметры. После установки подключения производится выполнение метода ExecuteNonQuery () (метод ничего не возвращает). При успешном выпол- нении данные будут добавлены в базу данных «1С:Предприятия 8». вить в диалог кнопку (Button). При открытии формы необходимо заполнить текстовые поля и нажать определенную кнопку. После добавления данные в текстовых полях должны очиститься. В код формы нужно включить возможность использования пространства имен _1C.V8.Data. Для кнопки определим следующий обработчик события (листинг 3.32). Обработчик события Click
Обратите внимание, что при обращении к элементу управления TextBox получаем значение типа Строка. Для его преобразования к числу (для заку- почной цены) используется объект Convert. В самом конце функции в текст полей ввода записываются пустые строки. Обратите внимание, что в данной реализации полностью отсутствует реали- зация «защиты от дурака» (попытка добавить объект повторно, попытка добавить объект с незаполненными полями). В реальной жизни подобные проверки крайне желательно реализовывать. Поставим перед собой очередную задачу: необходимо «исправить» движения документа Приходная накладная (по указанному номеру документа) по регистру накопления Учет номенклатуры. «Исправление» будет заключаться в том, что в ресурс «Количество» будет записываться значение единицы (независимо от реального наполнения документа). Для изменения данных (а речь идет именно об изменении существующих данных) используются следующие объекты: • V8DbConnection - предназначен для указания параметров подключения к базе данных и проведения этого подключения; • V8DbSelectCommand - предназначен для указания параметров выборки и проведения выборки данных, получения объекта V8DataReader; • V8DataReader - предназначен для получения данных и их обхода; • V8DbUpdateCommand - предназначен для выполнения обновления данных. Схематично порядок работы при изменении данных можно показать следу- ющим образом (рис. 3.62). Как и в предыдущих примерах, определим веб-форму. В диалоге разместим элемент управления TextBox (для ввода номера документа), кнопку (для запуска процесса изменения). Определим возможность использования пространства имен _1C.V8.Data. Обработчик нажатия кнопки имеет следующий вид (листинг 3.33).
Алгоритм изменения данных 3.33. Обработчик события Click
После создания объекта V8DbConnection производится определение и создание объекта DataTable. Дело в том, что изменения, которые по условию задачи необходимо провести, связаны с обработкой табличных данных (записей регистра накопления). В объекте DataTable будем накап- ливать набор записей, который в дальнейшем будет записан в базу данных «1С:Предприятия 8». Структура этого объекта совпадает с составом полей таблицы регистра накопления УчетНоменклатуры. Не считая работу с объектом DataTable, первая часть обработчика очень похожа на пример с получением данных. Это и понятно: данные, перед тем как будут изменены, должны быть прочитаны. После того как будущий набор записей сформирован, создается объект V8DbUpdateCommand (возможен только тип команды CommandType .Tab- leDirect). При настройке параметров для набора записей регистра накопления (и ряда других регистров) необходимо обязательно указывать регистратор. Опять же для регистров добавляемый набор записей должен записываться в параметр с предопределенным именем DataSet.
С помощью вызова метода ExecuteNonQuery () соответствующей команды выполняется изменение данных. В рассматриваемом примере будем удалять элементы справочника Номенкла- тура по введенному в текстовое поле коду. Функция, отвечающая за удаление элемента справочника, имеет следующий вид (листинг 3.34). Листинг 3.34. Обработчик события Click
После определения параметров подключения производится получение данных. Важно при операции чтения (в рассматриваемом случае) получить ссылку на удаляемый объект. Так как ожидается получение одного значения, оно получается выполнением метода ExecuteScalar (). После получения ссылки создается и настраивается объект V8DbDele- teCommand. Удаление производится при вызове метода Execu- teNonQuery (). Следует отметить, что если объект, попытка удаления которого производится, заблокирован, то выполнение метода приведет к ошибке. Web-сервисы Отличие Web-сервиса от веб-приложения заключается в том, что веб- приложение предназначено для организации пользовательского интерфейса с использованием веб-браузера, в то время как Web-сервис предназначен для организации программного доступа со стороны произвольных программных систем. С помощью Web-сервиса можно организовать доступ к механизмам «1С:Предприятия», отсутствующим в других частях распределенной системы. С точки зрения использования Web-сервис представляет собой некоторое множество методов, обращение к которым может быть организовано из любой программной системы, выступающей в качестве клиента Web-сервиса. В принципе создать на основе ASP.NET Web-сервис, осуществляющий доступ к информационной базе «1С:Предприятия 8», не слишком сложно. Но средства, предоставляемые Web-расширением, еще более упрощают эту задачу. Познакомимся с данной возможностью на примере создания Web-сервиса, который возвращает сумму в рублях прописью, а также возвращает курс валюты по переданному коду валюты. Для начала создадим новый проект. При этом в качестве шаблона будем использовать V8 Web Service (рис. 3.63).
Шаблон V8 Web Service Web-сервис будет создан в виртуальном каталоге MyService. После нажатия кнопки ОК автоматически стартует утилита загрузки метаданных (рис. 3.64). Утилита импорта метаданных Необходимо указать конфигурацию, которая будет использоваться сервисом, и параметры доступа (имя пользователя конфигурации и его пароль). В результате работы конструктора по выбранному шаблону будет создан ряд файлов (просмотреть их можно, используя Solution Explorer). Файл, содер- жащий методы сервиса, имеет имя Servicel .asmx. Исходный программный текст этого файла приводится ниже (листинг 3.35).
3.35. Пример файла Servicel.asmx
Метод RublesInWords () получает в качестве параметра число. Далее с помощью обращения к методу ЧислоПрописью () глобального контекста «1С:Предприятия 8» получает представление этого числа как суммы прописью в рублях на русском языке. Внутри самого метода первоначально производится установка соединения с базой данных. Вызов метода глобального контекста производится методом Call(). Параметры метода ЧислоПрописью() передаются массивом, который создается и инициализируется прямо в методе CallQ. Добавим в код реализацию метода, который будет по переданному коду (в соответствии со стандартным классификатором) возвращать курс валюты. Код метода приводится ниже (листинг 3.36). Метод GetKursQ
Следует отметить, что функциональность метода основана на функции Полу- читьКурс(), определенной в модуле внешнего соединения информационной базы «1С:Предприятие 8» (листинг 3.37). Функция «ПолучитьКурсО» Перед тем как приступить к компиляции, рекомендуется определить пространство имен сервиса (листинг 3.38). Определение пространства имен
Для того чтобы получить возможность работать с Web-сервисом из созда- ваемого веб-приложения, необходимо первоначально добавить ссылку на данный сервис. Для этой цели нужно выполнить команду главного меню Project • Add Web Reference (рис. 3.65). В открывшемся после этого окне указать путь к файлу сервиса (в данном случае указывается путь к сервису, существующему на локальной машине). Далее следует нажать кнопку Go. Результат выполнения операции будет выведен в ту же форму (рис. 3.66). Добавление веб-ссылки В поле ввода Web Reference Name можно определить произвольное имя добав- ляемой веб-ссылки. Для обращения метода к сервису можно использовать код, подобный приве- денному (листинг 3.39). Пример обращения к Web-сервису
Вызов процедур, функций. Преобразование типов При создании (адаптации) веб-приложений и Web-сервисов может возникнуть необходимость в использовании ряда ресурсов «1С:Предприятия 8»: • работать с глобальными переменными (определенными в модуле внешнего соединения с использованием ключевого слова Экспорт); • осуществлять вызов процедур, функций, определенных с использова- нием ключевого слова Экспорт как в модуле внешнего соединения, так и в общих модулях (с установленным флажком Внешнее соединение). Следует помнить, что очень часто при использовании указанных ресурсов будет возникать необходимость в конвертации данных из типов .NET в типы «1С:Предприятия 8», и наоборот. Для осуществления преобразования можно использовать два метода (у каждого из них есть несколько вариантов вызова): • ConvertValueNetToV8 - преобразование типов .NET в типы «^Пред- приятия 8»; в ConvertValueV8ToNet - преобразование типов «1С:Предприятия 8» в типы .NET. Предположим, что модуль внешнего соединения «1С:Предприятия» выглядит следующим образом (листинг 3.40). Пример модуля внешнего соединения
Следует отметить, что при знакомстве (через встроенную подсказку) с какими-либо методами нужно внимательно смотреть на тип используемого объекта connection. В качестве параметров может указываться connection с типом V8DbConnection и connection с типом ComObject. Рассмотрим примеры обращения к переменным, функциям, объявленным в представленном модуле внешнего соединения. Начнем с напоминания о том, что для обращения к базе данных необхо- димо произвести подключение к ней. Это можно сделать, создав объект V8DbConnection (листинг 3.41). Подключение к информационной базе «1С:Предприятия» Если в веб-форме определен какой-либо источник (специфический для Web-расширения, например), то подключение может выглядеть следующим образом (листинг 3.42). Установление соединения с информационной базой «1С:Предприятия»
Можно сказать, что объект V8DbConnection определяет параметры подключения (и производит открытие подключения). У данного объекта существует свойство Connection, которое (после выполнения метода Ореп()) и содержит ComObject. Для чтения значения переменной модуля внешнего соединения гпПользо- ватель можно использовать следующий метод (листинг 3.43). Пример чтения значения переменной Пример обращения к функции Рассмотренная ранее функция ВозвращаемСтроку() не имела параметров. В том случае если они есть (и параметр не один), для передачи значений в параметры можно использовать массив. Рассмотрим пример вызова функции, у которой определено два параметра (листинг 3.45). Пример вызова функции с двумя параметрами Считаем, что в переменной connection находится объект типа V8DbCon- nection. Для обращения к функции ВозвращаемСтроку() можно использовать следу- ющий код (листинг 3.44). Первоначально формируется массив параметров args. При определении сразу же производится его инициализация. Первым значением будет значение ссылки на номенклатуру, преобразованное к типу «1С:Предприятия 8» (подобное значение можно получить при обращении к элементу управления V8TextBox с установленным соответствующим типом). Второй элемент массива ничего не содержит (null). Далее (с помощью метода Call О) производится вызов указанной функции (имя указывается вторым параметром). Третьим параметром передается созданный ранее массив.
Функция определена как возвращающая значение типа Булево (если цена номенклатуры найдена, то возвращается значение Истина, не найдена - Ложь). Кроме этого, возврат значения цены производится через массив параметров (параметры передаются по ссылке). После получения значения цены его необходимо преобразовать из типа «1С:Предприятия 8» в тип .NET. Полученное значение отображается в элементе управления Label2. Настройка прав доступа Для контроля прав доступа к данным информационной базы «1С:Предпри- ятия» предназначен класс V8Rights пространства имен _1C.V8.Data. Обра- щение к свойствам и методам данного класса позволяет проверить наличие разрешения на выполнение стандартных действий с данными информаци- онной базы. К примеру, такая проверка автоматически добавляется в функцию-обработчик загрузки формы, созданной на основе шаблона V8 Item Form (листинг 3.46). Обработчик события Page Load Следует отметить, что сами разрешения настраиваются в режиме Конфигу- ратор информационной базы «1С:Предприятие» (настройкой ролей пользо- вателей). Какие роли действуют - определяется пользователем, в контексте которого производится обращение к базе данных. Существует и более универсальная возможность проверки прав пользо- вателя. Она предоставляется методом AccessRight () класса V8Right. В качестве параметров этому методу передается строка с названием действия (например: Read, Edit, Posting и т.д.), таблица (объект V8TableInfo), в отно- шении которой предлагается выполнение действия, и соединение (объект V8DbConnection).
Идентификация пользователя Информационная база данных «1С:Предприятия 8» может не предусмат- ривать никакой авторизации (что бывает, скорее всего, в исключительных ситуациях). В этом случае контроль прав доступа не производится, и задача идентификации пользователя на стороне веб-приложения/сервиса, как правило, не возникает. Если авторизация в информационной базе присутствует, то с точки зрения веб-приложения/сервиса есть два варианта работы с ней: • доступ к базе в контексте одного (как правило, специально созданного) пользователя; • каждый посетитель ресурса проходит авторизацию и фактически может работать под личным логином (с индивидуальным набором прав). Недостатком первого варианта является явное «обезличивание» (с точки зрения базы данных) всех пользователей веб-приложения/сервиса. Второй вариант требует определения всех пользователей в самой информа- ционной базе, что в случае большого количества пользователей может быть неприемлемо. На практике могут использоваться смешанные варианты. Тогда ресурс делится на две части. К одной доступ осуществляется в контексте какого- либо «общего» пользователя, а к закрытой области (в которую может быть допущено намного меньше пользователей) требуется персональная иденти- фикация. Следует отметить, что при обращении к веб-сервисам может использоваться вариант, когда параметры доступа указываются в качестве параметров вызы- ваемой функции. Рассмотрим настройки веб-приложения/сервиса, связанные с правами доступа пользователей. Данные настройки распределены по нескольким файлам веб- приложения. Следует отметить, что при желании организовать идентификацию на основе форм следует произвести настройку всех указанных файлов. В случае если идентификация пользователей не производится либо не используется принудительная авторизация на основе форм, в этом файле определены следующие XML-элементы (листинг 3.47).
Как видно, помимо имени пользователя и пароля в этом же разделе определен путь к информационной базе данных. В качестве отдельного варианта можно реализовать принудительную аутен- тификацию на основе форм. Особенность данного механизма заключается в том, что после его определения первое обращение к абсолютно любому ресурсу приведет к открытию формы, ответственной за идентификацию. Для того чтобы при таком варианте аутентификации организовать возмож- ность гостевого входа (случайный пользователь тоже смог бы обратиться к ресурсу), непосредственно в форме авторизации можно в явном виде пропи- сывать гостевой логин. Листинг 3.47. Фрагмент файла Web.config В данном варианте к веб-приложению могут обращаться любые пользователи, к веб-серверу разрешен анонимный доступ. Но даже при анонимном доступе обращение веб-приложения к информационной базе может осуществляться в контексте одного или нескольких пользователей. Контроль прав доступа к информационной базе данных (при необходимости) осуществляется обычно в обработчике события Load веб-форм. При этом проверяются права доступа к запрашиваемым данным именно с точки зрения пользователя, пара- метры которого указаны в разделе appSetting (или явно определены другим образом). Раздел appSettings имеет следующий вид (листинг 3.48). Листинг 3.48. Фрагмент кода
При настройке авторизации на основе форм разделы файла выглядят следу- ющим образом (листинг 3.49). Фрагмент кода Обратите внимание на тот факт, что для реализации аутентификации на основе форм недостаточно внести изменения в файл web.config. Потре- буется еще создать форму, в которой будет осуществляться аутентификация пользователя, и внести изменения в файл global.asax. Настройка данного файла (можно сказать, что он используется в качестве «глобального модуля») необходима в случае реализации механизма автори- зации на основе форм. Имеется в виду, что в других вариантах авторизации обычно этого не требуется (но работа с самим файлом может осуществляться для решения других задач). В определение используемых пространств имен следует добавить следующие строки (листинг 3.51). Определение пространств имен Также следует определить обработчик события AuthenticateRequest (листинг 3.52).
Обработчик события AuthenticateRequest При любом запросе будет вызываться вышеописанный обработчик события. В нем и производится проверка: была ли успешно осуществлена авторизация текущего пользователя или нет (используется механизм cookie --- возможность сервера записывать на стороне клиента какие-либо значения, характеризу- емые именем, сроком жизни и т. п.). Предположим, что существует форма с именем logon.aspx, отвечающая за авторизацию пользователей. В форме определены два текстовых поля ввода (TextBox) и кнопка, по нажатию которой производится проверка коррект- ности авторизации пользователя. Обработчик нажатия кнопки имеет следующий вид (листинг 3.53).
3.53. Обработчик события Click
Следует отметить, что если механизм авторизации на основе форм не исполь- зуется (но все приложение работает в контексте одного пользователя), запись имени пользователя и его пароля в параметры объекта Session производится сервером автоматически. А если быть точнее --- в файле global.asax определен следующий обработчик события, ответственный за это (листинг 3.54). 3.54. Обработчик события Start Работа с метаданными Для того чтобы обрабатывать данные «1С:Предприятия», Web-расширение строит структуру метаданных информационной базы и создает описание типов, соответствующих данным, хранящимся в конкретной информаци- онной базе. Этот процесс выполняется автоматически при создании нового проекта из шаблонов V8 Web Application или V8 Web Service. Если впоследствии конфи- гурация информационной базы будет изменена, следует вручную запустить генерацию метаданных для веб-приложения или Web-сервиса. Для этого используется команда главного меню Tools • Импорт метаданных. После выполнения команды откроется диалог следующего вида (рис. 3.67). В поле Каталог следует указать подкаталог /bin каталога, в котором находится веб-приложение. Результатом генерации метаданных является файл 1су8<псевдоним ИБ>.сШ, содержащий описание типов, присущих конкретной информационной базе. Одно веб-приложение может использовать несколько информационных баз. Каждая информационная база имеет в веб-приложении свой уникальный псевдоним. Именно он указывается в поле Псевдоним ИБ при генерации мета- данных. Эти псевдонимы также используются для указания связи с элементами управ- ления, расположенными в форме (свойство IBAlias).
Рис. 3.67. Импорт метаданных Доступ к структуре метаданных информационной базы предоставляется классом V8Metadata пространства имен _1C.V8.Data. Следует отметить, что метаданные конфигурации по умолчанию определя- ются в файл 1cv8.dll. При работе с Visual Studio данная библиотека подгру- жается системой. Если одновременно идет работа с разными проектами, но с одинаковыми именами данной библиотеки (в каждом веб-приложении, построенном с помощью Web-расширения, обязательно будет библиотека с таким именем), может возникнуть «наложение» метаданных, которое приведет к ошибкам в создаваемом приложении. В связи с этим при переходе от одного проекта (построенного на одних мета- данных) к другому рекомендуется полностью закрывать предыдущий проект. Пул соединений В процессе обращения к данным информационной базы создаются внешние соединения с «1 С:Предприятием». Это происходит при использовании элементов управления --- источников данных или при непосредственной работе с объектом V8DbConnection. Создание каждого такого соединения зани- мает определенную часть ресурсов сервера и требует некоторого времени. Поэтому для ускорения работы Web-расширение может поддерживать пул соединений, в котором будут находиться уже открытые соединения.
Разработчик имеет возможность настраивать пуп соединений, указывая максимальное количество соединений, одновременно находящихся в пуле, и период, в течение которого соединение будет удерживаться в пуле. Настройка (инициализация) перечисленных параметров выполняется в файле Global.asax (листинг 3.55). Пример настройки пула соединений
Свойство PoolTimeout определяет период в секундах, в течение которого соединение будет удерживаться в пуле для возможного повторного использо- вания. Алгоритм работы пула следующий: • когда пользователь закрывает соединение с базой данных, оно (если значение PoolCapacity отличается от нуля) помещается в пул; • если при этом пул был заполнен (в пуле находилось максимальное коли- чество соединений), то будет вытеснено то соединение, которое дольше всего находится в пуле; • повторно использовать соединение может только тот же пользователь, в контексте которого оно было создано; • по окончании времени существования в пуле (свойство PoolTimeout) соединение удаляется из пула (либо оно вытесняется каким-либо новым соединением). Следует отметить, что в данном случае, когда говорится о каком-либо поль- зователе, подразумевается пользователь, в контексте которого производится подключение к информационной базе «1С:Предприятия 8». В связи с этим использование пула соединений особенно эффективно, когда все веб- приложение работает в контексте одного пользователя (указанного в файле web.config). Свойство PoolCapacity задает максимальное количество внешних соеди- нений, одновременно находящихся в пуле. Значение данного свойства опре- деляется в файле Web.config, в приведенном ниже разделе (листинг 3.56). Фрагмент файла Web.config
Свойство MaxConnection определяет максимальное число одновременно существующих внешних соединений. Данное число соединений включает также число соединений, находящихся в пуле. Значение по умолчанию равно 0 (без ограничений). Это свойство можно использовать при желании ограничить количество лицензий платформы «1С:Предприятие 8», которые будут использоваться веб-приложением. Рассмотрим все это на примере. Пусть установлены следующие значения свойств: • MaxConnection = 4; • PoolTimeout = 60; • PoolCapacity = 2. При таком значении параметров веб-приложение будет использовать максимум 4 лицензии, при этом в пуле максимально будут находиться два соединения. Соединение из пула будет удаляться либо по истечении 60 секунд после последнего его использования, либо при освобождении другого (созданного позже) соединения, которое не расположено в пуле (оно вытеснит из пула самое старое соединение). Полезные средства .NET Framework В данной главе рассмотрим ряд объектов (входящих в контекст ASP.NET), которые довольно часто используются при создании как веб-приложений, так и Web-сервисов. Данный раздел ни в коем случае не претендует на полное описание. При возникновении такой необходимости рекомендуем обращаться к специализированной литературе. Данный объект позволяет серверу поддерживать связь с клиентом. Например, для включения в HTTP вывода произвольных данных (произвольного фраг- мента HTML) можно использовать метод Wtite () (листинг 3.57). 3.57. Пример использования метода WtiteQ Метод Wtite () в качестве параметра может принимать только строковые значения.
С помощью объекта Response можно управлять буферизацией вывода данных. Поясним понятие буферизации. Веб-формы (файлы aspx) фактически представляют собой программы, написанные (в нашем случае) на языке С#. При обращении к такой форме вызывается какая-либо функция, в результате работы которой формируется HTTP-ответ клиенту. Так вот, при включенной буферизации ответ не будет отправлен клиенту, пока не закончится испол- нение формы. При отключенной буферизации данные отправляются по мере их формирования. Какой из вариантов использовать, определяется в каждом случае индивидуально. Для запрета буферизации можно использовать следующую конструкцию (листинг 3.58). Пример запрета буферизации Следует помнить, что если в HTTP-отклик уже помещены какие-либо данные, попытка отключения (или включения) буферизации приведет к ошибке. Методы объекта, позволяющие управлять буферизацией, перечислены в листинге 3.59. Методы, позволяющие управлять буферизацией Объект может использоваться для перенаправления пользователей. К примеру, вы хотите, чтобы при первом обращении к ресурсу пользователь отправлялся на определенную стартовую страницу (независимо от запрашиваемого ресурса). С этой целью в файле global.asax можно определить обработчик события (листинг 3.60). Пример перенаправления
Объект может использоваться для записи cookie (значений, записываемых на стороне клиента), листинг 3.61. Пример использования cookie Данный объект позволяет под держивать связь клиента с сервером. С помощью данного объекта можно производить чтение значений cookie (листинг 3.62). Пример чтения cookie Также можно получать значения параметров, переданных в запросе. К примеру, обращение к ресурсу могло производиться следующим образом (листинг 3.63). 3.63. Пример обращения к ресурсу Для извлечения значения параметра TableName можно использовать следу- ющий подход (листинг 3.64) 3.64. Пример получения значения параметра Данный объект предназначен для хранения контекста работы пользователя. Дело в том, что протокол HTTP не поддерживает возможности хранения состояния работы с пользователем (с его помощью нельзя хранить состояние пользовательской корзины, хранить значения, определяющие специфику работы данного пользователя и т.п.). Объект Session как раз и решает эти задачи.
При первом обращении к любому ресурсу приложения для каждого поль- зователя создается объект сессии (каждый такой объект характеризуется неким уникальным идентификатором, защищенным от повторения). Как при старте сессии, так и при ее завершении инициируются события, обработчики которых могут быть определены в файле global.asax. Завершение сессии (и освобождение всех занятых ее ресурсов) можно вызвать принудительно (листинг 3.65). Пример завершения сессии Также завершить сессию можно по истечении определенного промежутка времени после последнего запроса. Этот промежуток времени устанавлива- ется в параметрах веб-сервера (рис. 3.68). Настройка параметров веб-сервера Кроме этого, в объекте Session можно хранить значения, индивидуальные для каждого пользователя (листинг 3.66). Пример записи и чтения значения Подготовка веб-приложения к работе До сих пор, для того чтобы проверить, как работает та или иная созданная веб-форма, рекомендовалось установить ее как стартовую и запустить проект в режиме отладки. Когда все формы приложения будут готовы (а скорее всего, намного раньше), необходимо подумать о навигации по созданному
приложению. Т.е. должен быть определен механизм, позволяющий пользова- телю спокойно переходить от одной формы к другой (без знания имен форм и путей до них). Реализация подобного механизма может строиться по- разному. Но чаще всего в основе лежит возможность использования гипер- ссылки. Примеры использования (код HTML) приведены в листинге 3.67. Фрагмент HTML-кода Обращаем внимание на тот факт, что вторая гиперссылка определяет вызов формы списка справочника Контрагенты и при этом используется форма по умолчанию. В ходе создания веб-приложения в виртуальном каталоге были созданы: • Каталог Images, он содержит картинки, используемые для оформления форм. Данный каталог необходимо оставить в готовом решении. • Каталог bin, он содержит ряд файлов (этот каталог также в обязательном порядке должен включаться в работающее решение). В каталоге содер- жится dll-файл проекта и dll-файлы, содержащие описание метаданных используемых конфигураций.
• В корне виртуального каталога (если иное не определено явно) распо- лагаются файлы *.aspx, *.aspx.cs. Файлы *.aspx.cs в рабочее решение можно не включать (но терять их не рекомендуется, т. к. они потребуются в случае возникновения необходимости исправления функционала, пере- компиляции веб-приложения). Параметры автоформ Веб-приложение, созданное при помощи различных шаблонов в среде Visual Studio .NET, содержит несколько автоформ (форм по умолчанию). Они используются приложением, когда происходит обращение к данным, для которых разработчик не создал собственных форм, при отработке некоторых стандартных действий. Управление работой автоформ осуществляется при помощи параметров, которые передаются либо в строке запроса, либо как переменные формы. Разработчик веб-приложения может явно использовать автоформы для выполнения необходимых действий, определяемых логикой приложения. Указать, какие действия должна выполнить автоформа, можно при помощи ее параметров, передавая значения следующим образом (листинг 3.68). Пример передачи параметров в автоформу Чтение переданных таким образом параметров осуществляется (в коде формы webform) с помощью объекта Request. Ниже приводится список параметров некоторых автоформ. DefaultListForm используется для отображения записей таблицы базы данных в виде списка. Также DefaultListForm применяется для выбора значений из списка записей. Эта форма имеет следующие параметры: • IBAlias --- имя информационной базы. Используется в том случае, если приложение работает с несколькими информационными базами данных. Значение по умолчанию - пустая строка. • TypeName - имя типа. Задает таблицу базы данных, которая будет отоб- ражаться в списке. Вместо TypeName может использоваться параметр TableName.
• TableName - имя таблицы. Задает таблицу базы данных, которая будет отображаться в списке. Вместо TableName может использоваться пара- метр TypeName. • ChoiceMode - режим выбора для иерархических таблиц. Допустимые значения: • Items, • Folders, • FoldersAndltems. Если передано значение Folders, в списке будут отображаться только группы элементов. • ControlName - идентификатор элемента управления, вызвавшего форму списка для выбора. Если передан параметр ControlName, форма пере- ходит в режим выбора из списка. • TypeDescriptionNeeded - указывает на необходимость считывания описания типов для поддержки связи по типу. Возможные значения: • true, • false. • SelectionName<N>, SelectionValue<N>, SelectionType<N> - отборы и параметры критериев отбора. В случае одного элемента отбора используется форма SelectionName, SelectionValue, SelectionType. Если установлено несколько отборов, то они задаются в параметрах SelectionNamel, SelectionValuel, SelectionTypel, SelectionName2, SelectionValue2, SelectionType2 и т. д. Нуме- рация начинается с единицы. • SelectionName - имя поля; п SelectionValue - значение отбора; • SelectionType - тип значения. Используется в случае составного типа. • Assortment - задает режим подбора. В этом режиме после выбора значения форма остается открытой, предоставляя возможность продол- жения выбора. Должен быть задан параметр ControlName. Допустимое значение - true. • InitialValue - начальное значение. Содержит значение ключа записи. Если параметр задан, то список позиционируется на переданное значение.
DefaultObjectForm используется для добавления, редактирования, копирования или ввода на основании записи объектной таблицы. Режим формы определяется следующим образом: • если передан параметр Key Value, то форма переходит в режим редакти- рования; • если передан параметр CopyKeyValue и задаваемая им таблица совпадает с таблицей из параметра TableName (или КеуТуре), то форма переходит в режим копирования; • если передан параметр CopyKeyValue и задаваемая им таблица не совпадает с таблицей из параметра TableName (или КеуТуре), то форма переходит в режим ввода на основании; ш если параметры KeyValue и CopyKeyValue не заданы, то форма пере- ходит в режим добавления записи. Эта форма имеет следующие параметры: • IBAlias - имя информационной базы. Используется в том случае, если приложение работает с несколькими информационными базами данных. Значение по умолчанию - пустая строка. • КеуТуре - тип значения ключевого поля. Используется для определения таблицы, запись которой будет редактироваться (или в которую будет добавлена новая запись). • KeyValue - значение ключевого поля. Задает значение ключа редактиру- емой записи. • TableName - имя таблицы. Задает таблицу базы данных, запись которой будет редактировать в форме (будет добавлена при помощи формы). Вместо TableName может использоваться параметр КеуТуре. • CopyKeyType, CopyKeyValue - тип значения ключевого поля и значение ключевого поля копируемой записи. Передача этих параметров задает режим копирования. • IsFolder - параметр ЭтоГруппа. Определяет режим редактирования (создания) группы. • MasterName<N>, MasterValue<N>, MasterType<N> - предуста- новленные значения полей. Используется, например, для задания поля Владелец для подчиненных таблиц. В случае одного значения использу- ется форма MasterName, MasterValue, MasterType. Если передано
несколько значений, то они задаются в параметрах MasterNamel, MasterValuel, MasterTypel, MasterName2, MasterValue2, MasterType2 и т.д. Нумерация начинается с единицы. • MasterName --- имя поля. • MasterValue - значение. п MasterType - тип значения. Используется в случае составного типа. • ControlName - идентификатор элемента управления, вызвавшего форму. Используется для обновления списка записей после записи изменений в форме. • Parent - значение поля Родитель для иерархических таблиц. DefaultRecordForm используется для редактирования, создания новой или копирования существующей записи регистра. Режим формы определяется следующим образом: • если передан параметр KeyValue<N>, то форма переходит в режим редактирования; • если передан параметр CopyKeyValue<N>, то форма переходит в режим копирования; • если параметры KeyValue<N> и CopyKeyValue<N> не заданы, то форма переходит в режим добавления записи. Эта форма имеет следующие параметры: • IBAlias - имя информационной базы. Используется в том случае, если приложение работает с несколькими информационными базами данных. Значение по умолчанию - пустая строка. • TableName - имя таблицы регистра. Задает регистр, запись которого будет редактироваться в форме (будет добавлена при помощи формы). я ControlName - идентификатор элемента управления, вызвавшего форму. Используется для обновления списка записей после записи изменений в форме. • KeyName<N>, KeyValue<N>, KeyType<N> - значения ключевых полей редактируемой записи. В случае одного значения используется форма KeyName, KeyValue, КеуТуре. Если для таблицы задано несколько ключевых полей, то их значения задаются в параметрах KeyNamel, KeyValuel, KeyTypel, KeyName2, KeyValue2, KeyType2 и т.д. Нумерация начинается с единицы. • KeyName - имя ключевого поля.
• KeyValue --- значение ключевого поля. • КеуТуре - тип значения ключевого поля. Используется в случае составного типа. • CopyKeyName<N>, CopyKeyValue<N>, CopyKeyType<N> - значения ключевых полей копируемой записи. В случае одного значения исполь- зуется форма CopyKeyName, CopyKeyValue, СоруКеуТуре. Если для таблицы задано несколько ключевых полей, то их значения задаются в параметрах CopyKeyNamel, CopyKeyValuel, CopyKeyTypel, CopyKeyName2, CopyKeyValue2, CopyKeyType2 и т.д. Нумерация начинается с единицы. • CopyKeyName - имя ключевого поля. • CopyKeyValue - значение ключевого поля. • СоруКеуТуре - тип значения ключевого поля. Используется в случае составного типа. DefaultLineForm предназначена для редактирования (добавления) строки табличной части. Эта форма имеет следующие параметры: • IBAlias - имя информационной базы. Используется в том случае, если приложение работает с несколькими информационными базами данных. Значение по умолчанию --- пустая строка. • TableName - имя табличной части. • ColumnsList - разделенный точкой с запятой список отображаемых полей строки табличной части. • HiddenColumnsList - разделенный точкой с запятой список неотобра- жаемых полей строки табличной части. • ControlName - идентификатор элемента управления, вызвавшего форму для редактирования (добавления) строки табличной части. Используется для обновления отображения табличной части после записи изменений в форме.