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