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