При интеграции сторонних систем с 1С через SOAP/HTTP веб-сервисы разработчики нередко сталкиваются с ситуацией, когда попытка вызвать метод объекта документа или справочника (например, функцию печати или заполнения) приводит к критической ошибке: «Ошибка инициализации модуля» или сообщению о том, что глобальные переменные и функции не определены. Проанализируем причины этой ошибки и разберем по шагам правильные архитектурные способы её устранения.
Для понимания проблемы выясним, в каком именно окружении исполняется код веб-сервиса в платформе «1С:Предприятие»:
Сервер). Сеанс веб-сервиса не является внешним соединением (COM-соединением), поэтому директива препроцессора #Если ВнешнееСоединение для него не срабатывает.Предупреждение(), Вопрос(), вызовы методов форм) или обращения к общим модулям, у которых выключен флажок «Сервер», компилятор 1С выдает ошибку инициализации модуля, даже если вызываемый метод не использует эти проблемные участки.Рассмотрим первый вариант решения, когда требуется быстро адаптировать существующий модуль объекта без масштабного рефакторинга. Для этого изолируем все клиентские и интерактивные вызовы с помощью директив препроцессора.
Разберем пример: если в модуле объекта содержатся функции отображения диалогов или работы с интерфейсом, заключим их в соответствующие блоки:
#Если Клиент Тогда
Процедура ПоказатьДиалогПользователю()
Предупреждение("Операция завершена успешно!");
КонецПроцедуры
#КонецЕсли
Если конфигурация работает в режиме обычного приложения, используем директиву:
#Если ТолстыйКлиентОбычноеПриложениеКлиент Тогда
Процедура ИнтерактивнаяПроверка()
// Клиентский код, недоступный в веб-сервисе
Предупреждение("Проверьте заполнение реквизитов");
КонецПроцедуры
#КонецЕсли
Важно: проверку синтаксиса в конфигураторе необходимо выполнять с включенным флажком «Сервер» (меню Сервис — Параметры — Модули — Проверка), а не только в режиме «Внешнее соединение».
Посмотрим на более правильный с точки зрения стандартов разработки «1С:Предприятия 8» подход. Модули объектов предназначены для обеспечения целостности данных самого объекта (обработчики событий ПередЗаписью, ПриЗаписи, ОбработкаПроведения). Процедуры печати, отчетов и формирования табличных документов рекомендуется размещать в модуле менеджера объекта.
Преимущества модуля менеджера:
Ссылка.ПолучитьОбъект(), что снижает нагрузку на серверную память и исключает блокировки.Разберем пример переноса функции печати в модуль менеджера документа:
// В модуле менеджера документа (например, Документ.РеализацияТоваровУслуг)
Функция СформироватьПечатнуюФорму(МассивСсылок, ОбъектыПечати) Экспорт
ТабличныйДокумент = Новый ТабличныйДокумент;
Макет = Документы.РеализацияТоваровУслуг.ПолучитьМакет("Печать");
// Заполнение табличного документа данными
Для Каждого ТекСсылка Из МассивСсылок Цикл
ОбластьШапка = Макет.ПолучитьОбласть("Шапка");
ОбластьШапка.Параметры.Номер = ТекСсылка.Номер;
ОбластьШапка.Параметры.Дата = ТекСсылка.Дата;
ТабличныйДокумент.Вывести(ОбластьШапка);
КонецЦикла;
Возврат ТабличныйДокумент;
КонецФункции
Проанализируем процесс вызова метода и передачи сформированного табличного документа через веб-сервис клиенту. Создадим или используем серверный общий модуль (с установленными свойствами «Сервер» и «Вызов сервера»).
В методе веб-сервиса формируем ТабличныйДокумент, сохраняем его в двоичные данные (например, в формате PDF) и возвращаем клиенту:
Функция ПолучитьПечатнуюФормуPDF(ИдентификаторДокумента) Экспорт
СсылкаНаДокумент = Документы.РеализацияТоваровУслуг.ПолучитьСсылку(Новый УникальныйИдентификатор(ИдентификаторДокумента));
МассивСсылок = Новый Массив;
МассивСсылок.Добавить(СсылкаНаДокумент);
// Вызываем метод печати из модуля менеджера
ТабДок = Документы.РеализацияТоваровУслуг.СформироватьПечатнуюФорму(МассивСсылок, Неопределено);
// Сохраняем табличный документ во временный файл и получаем двоичные данные
ИмяВременногоФайла = ПолучитьИмяВременногоФайла("pdf");
ТабДок.Записать(ИмяВременногоФайла, ТипФайлаТабличногоДокумента.PDF);
Результат = Новый ДвоичныеДанные(ИмяВременногоФайла);
УдалитьФайлы(ИмяВременногоФайла);
Возврат Результат;
КонецФункции
Если ошибка сообщает о недоступности глобальных функций, которые определены в конфигурации разработчиком, обязательно проверим свойства соответствующих общих модулей:
Глобальный) установлен флажок «Сервер». Если флажок снят и стоит только «Клиент (управляемое приложение)», в сеансе веб-сервиса данный модуль и его процедуры будут недоступны.