При разработке внешних обработок заполнения табличных частей (ТЧ) часто возникает необходимость вызвать промежуточное диалоговое окно. Например, это может быть форма для выбора файла Excel, указания дополнительных параметров распределения суммы или уточнения настроек загрузки. Одной из типовых проблем, с которой сталкиваются разработчики, является «потеря» связи с исходным документом: в форме диалога реквизиты документа оказываются недоступны, а ВладелецФормы возвращает Неопределено.
В данной статье мы подробно разберем, как правильно передать контекст документа в форму диалога, обеспечив при этом сохранность данных между серверными вызовами, и выясним, почему обычные переменные модуля для этого не подходят.
Проанализируем ситуацию: когда мы открываем форму диалога из основной формы обработки, нам нужно передать ссылку на объект, который мы заполняем. Часто разработчики пытаются использовать переменные модуля, объявленные через ключевое слово Перем в верхней части модуля формы. Однако в управляемом приложении 1С переменные модуля формы на сервере не сохраняют свои значения между вызовами. Как только выполнение кода на сервере завершается и управление возвращается на клиент, значения таких переменных очищаются. При следующем серверном вызове они снова будут инициализированы значениями по умолчанию (как правило, Неопределено).
Также важно понимать механизм работы ВладелецФормы. Если при вызове метода ОткрытьФорму не указан третий параметр (владелец), то система не будет знать, какая форма инициировала открытие, и контекст владельца будет пуст.
Для того чтобы данные попали в открываемую форму диалога, их необходимо поместить в структуру параметров. Рассмотрим правильный способ вызова формы диалога из основной формы обработки или из кода команды заполнения.
Проанализируем пример кода на клиенте:
&НаКлиенте
Процедура ВызватьДиалогЗаполнения()
// Определяем объект, который будем заполнять (ссылка на документ)
ОбъектЗаполнения = Объект.Документ;
// Формируем структуру параметров для передачи в форму диалога
ПараметрыОткрытия = Новый Структура;
ПараметрыОткрытия.Вставить("ОбъектЗаполнения", ОбъектЗаполнения);
// Описание оповещения для обработки результата после закрытия диалога
ОписаниеОповещения = Новый ОписаниеОповещения("ПослеЗакрытияДиалога", ЭтаФорма);
// Открываем форму диалога.
// Обратите внимание на третий параметр - передаем 'ЭтаФорма' как владельца
ОткрытьФорму("ВнешняяОбработка.ИмяВашейОбработки.Форма.ФормаДиалога",
ПараметрыОткрытия,
ЭтаФорма,
,,,,
ОписаниеОповещения);
КонецПроцедуры
Как мы уже выяснили, использование Перем не подходит для хранения ссылки на документ внутри формы диалога, если планируются серверные вызовы. Вместо этого необходимо использовать Реквизиты формы. Реквизиты формы сериализуются и передаются между клиентом и сервером в составе состояния формы, что гарантирует их сохранность.
Выполним следующие действия:
ОбъектЗаполнения.ДокументСсылка.ЗаказПокупателя) или универсальный тип ЛюбаяСсылка, если обработка предназначена для разных видов документов.Теперь в модуле формы диалога перехватим переданный параметр при создании формы на сервере:
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
// Проверяем наличие параметра и записываем его в РЕКВИЗИТ формы
Если Параметры.Свойство("ОбъектЗаполнения") Тогда
ЭтаФорма.ОбъектЗаполнения = Параметры.ОбъектЗаполнения;
КонецЕсли;
КонецПроцедуры
Теперь значение ОбъектЗаполнения будет доступно в любой серверной процедуре формы диалога через обращение ЭтаФорма.ОбъектЗаполнения или просто ОбъектЗаполнения.
Если вам нужно получить значения конкретных реквизитов документа (например, организацию, склад или валюту) для использования в логике диалога, вы можете обращаться к ним через полученную ссылку. Рассмотрим пример получения данных на сервере:
&НаСервере
Процедура ВыполнитьРасчетНаСервере()
// Получаем данные из документа-основания
ДанныеДокумента = ОбщегоНазначения.ЗначенияРеквизитовОбъекта(ОбъектЗаполнения, "Организация, Валюта, Склад");
// Используем полученные данные в алгоритме
Если ДанныеДокумента.Валюта = Справочники.Валюты.НайтиПоКоду("643") Тогда
// Логика для рублей...
КонецЕсли;
КонецПроцедуры
Рассмотрим часто задаваемый вопрос: можно ли прикрепить вызов обработки к кнопке «Заполнить» непосредственно над табличной частью, а не в общем меню командной панели формы?
При использовании стандартного механизма БСП (Библиотека стандартных подсистем) для подключения внешних обработок заполнения, кнопка автоматически помещается в подменю «Заполнить» командной панели всей формы. Это стандартное поведение, которое обеспечивает единообразие интерфейса.
Однако, если стоит задача поместить кнопку именно в командную панель конкретной таблицы, возможны следующие варианты:
ПриСозданииНаСервере можно программно создать элемент формы (кнопку) и связать её с командой. Но этот метод требует изменения кода конфигурации, что лишает внешнюю обработку её главного преимущества — автономности.Подведем итоги нашего анализа. Для корректной работы диалога во внешней обработке необходимо:
ОткрытьФорму.Соблюдение этих правил позволит вам создавать надежные и функциональные инструменты для автоматизации работы пользователей в среде 1С:Предприятие 8.3.