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