При разработке внешних обработок в среде управляемого приложения 1С, особенно в таких сложных конфигурациях, как Комплексная автоматизация (КА) или ERP, программисты часто сталкиваются с проблемой: параметры в форму передаются, но при попытке сохранить их в реквизиты формы они «исчезают». Это происходит из-за непонимания жизненного цикла параметров и специфики серверных вызовов. В данной статье мы подробно разберем, почему данные могут пропадать и как реализовать стабильную передачу данных между документом и внешней обработкой.
Прежде всего, проанализируем ситуацию. В управляемых формах 1С параметры, которые мы передаем в функцию ОткрытьФорму(), попадают в специальную структуру Параметры. Эта структура доступна только в момент создания формы на сервере. Рассмотрим основные причины потери данных:
Параметры.ИмяПараметра внутри процедуры ПриСозданииНаСервере, но не присвоили его реквизиту формы (который отображается в дереве реквизитов справа в редакторе), то при первом же обращении к серверу (например, при нажатии кнопки или изменении поля) структура Параметры будет пустой, и данные потеряются.ЭтотОбъект (реквизиты самой обработки), забывая, что форма и объект — это разные сущности. Для сохранения состояния между клиент-серверными вызовами данные должны находиться именно в Реквизитах формы.ДокументОбъект, нужно сохранять ДокументСсылка).Рассмотрим стандартный и самый надежный способ передачи данных. Сначала создадим в форме обработки реквизит (например, ДокументСсылка с соответствующим типом ссылки на документ). Далее в модуле формы документа пропишем открытие обработки:
&НаКлиенте
Процедура ВыполнитьЗаполнение(Команда)
ПараметрыФормы = Новый Структура;
ПараметрыФормы.Вставить("СсылкаНаДокумент", Объект.Ссылка);
ОткрытьФорму("ВнешняяОбработка.МояОбработка.Форма.Форма", ПараметрыФормы, ЭтаФорма);
КонецПроцедуры
Теперь самое важное: в форме самой обработки мы должны «поймать» этот параметр и явно присвоить его реквизиту формы, чтобы он сохранился в памяти формы.
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
// Проверяем наличие параметра и записываем его в реквизит формы
Если Параметры.Свойство("СсылкаНаДокумент") Тогда
ДокументСсылка = Параметры.СсылкаНаДокумент;
КонецЕсли;
КонецПроцедуры
После выполнения этого кода переменная ДокументСсылка будет доступна в любых других процедурах формы (и на клиенте, и на сервере), пока форма открыта.
Если обработка открывается непосредственно из формы документа, мы можем обратиться к данным документа через свойство ВладелецФормы. Это позволяет не передавать параметры явно, а считывать их «на лету». Рассмотрим, как это реализовать на сервере в модуле формы обработки:
&НаСервере
Процедура ПолучитьДанныеИзВладельца()
// Проверяем, что владельцем является форма
Если ТипЗнч(ЭтаФорма.ВладелецФормы) = Тип("УправляемаяФорма") Тогда
// Получаем данные объекта владельца
ДанныеДокумента = ЭтаФорма.ВладелецФормы.Объект;
СсылкаНаОбъект = ДанныеДокумента.Ссылка;
// Теперь мы можем работать с данными документа напрямую
КонецЕсли;
КонецПроцедуры
Важный нюанс: Этот метод сильно связывает обработку с конкретной формой документа. Если вы попытаетесь открыть обработку из другого места, код может выдать ошибку.
Часто задача стоит не просто передать ссылку в обработку, но и вернуть результат (например, заполненную таблицу) обратно в документ. Для этого идеально подходит механизм ОписаниеОповещения. Выясним, как это работает по шагам.
Шаг 1. В документе вызываем форму обработки и указываем процедуру, которая примет результат:
&НаКлиенте
Процедура ЗаполнитьИзОбработки(Команда)
Оповещение = Новый ОписаниеОповещения("ПослеЗаполнения", ЭтотОбъект);
ПараметрыФормы = Новый Структура("ТекущийДокумент", Объект.Ссылка);
ОткрытьФорму("ВнешняяОбработка.ЗаполнениеТЧ.Форма", ПараметрыФормы, ЭтаФорма, , , , Оповещение, РежимОткрытияОкнаФормы.БлокироватьВесьИнтерфейс);
КонецПроцедуры
&НаКлиенте
Процедура ПослеЗаполнения(Результат, ДополнительныеПараметры) Экспорт
Если Результат <> Неопределено Тогда
// Обрабатываем структуру "Результат", пришедшую из обработки
Для Каждого СтрокаТЧ Из Результат.ТаблицаТоваров Цикл
НоваяСтрока = Объект.Товары.Добавить();
ЗаполнитьЗначенияСвойств(НоваяСтрока, СтрокаТЧ);
КонецЦикла;
КонецЕсли;
КонецПроцедуры
Шаг 2. В форме обработки, после того как пользователь закончил работу, вызываем закрытие с передачей данных:
&НаКлиенте
Процедура КнопкаОк(Команда)
РезультатЗаполнения = Новый Структура;
РезультатЗаполнения.Вставить("ТаблицаТоваров", ПолучитьТаблицуНаСервере());
Закрыть(РезультатЗаполнения);
КонецПроцедуры
В конфигурациях вроде 1С:Комплексная автоматизация внешние обработки часто подключаются через механизм «Дополнительные отчеты и обработки» (БСП). В этом случае система сама передает параметры в форму обработки. Проанализируем структуру этих параметров:
ОбъектыНазначения — массив ссылок на документы, для которых вызвана обработка.ДополнительнаяОбработкаСсылка — ссылка на саму обработку в справочнике.Чтобы данные не терялись при использовании БСП, в методе ПриСозданииНаСервере обязательно нужно извлечь ссылку из массива ОбъектыНазначения:
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
Если Параметры.Свойство("ОбъектыНазначения") И Параметры.ОбъектыНазначения.Количество() > 0 Тогда
// Сохраняем первую ссылку в реквизит формы
ОбъектОснование = Параметры.ОбъектыНазначения[0];
КонецЕсли;
КонецПроцедуры
Для того чтобы параметры внешней обработки не «пропадали», придерживайтесь следующих правил:
ПриСозданииНаСервере обязательно перекладывайте данные из структуры Параметры в созданные реквизиты формы.Закрыть(Результат) в паре с ОписаниеОповещения.Перем, не сохраняют свои значения между вызовами сервера. Пользуйтесь только реквизитами формы.Используя эти подходы, вы обеспечите стабильную работу своих внешних обработок и исключите ошибки потери данных при взаимодействии с основными объектами системы.