Работа с формами в 1С:Предприятие — одна из самых востребованных задач среди разработчиков и администраторов системы. Часто требуется передать в форму значения из других объектов конфигурации: справочников, документов, регистров или даже других форм. Без правильной техники передачи данных формы становятся статичными и бесполезными, а бизнес-процессы тормозятся.
Эта статья охватывает все актуальные способы передачи значений в формы 1С 8.3 и 8.2 — от базовых параметров открытия до программного манипулирования реквизитами и обмена данными между формами. Мы разберём не только синтаксис, но и типичные ошибки, которые приводят к потере данных при передаче или некорректному отображению информации. Особое внимание уделено нюансам работы с управляемыми и обычными формами, а также передаче сложных типов данных (табличные части, коллекции, объекты).
1. Базовый способ: передача параметров при открытии формы
Самый простой и универсальный метод — передача значений через параметры метода ОткрытьФорму(). Этот подход работает как для управляемых, так и для обычных форм, но имеет ограничения по типам передаваемых данных.
Синтаксис метода:
ОткрытьФорму("ИмяФормы", ЭтотОбъект, , , , Параметры);
Где Параметры — это структура, содержащая пары "ключ-значение". Например, чтобы передать в форму документа номер и дату:
Параметры = Новый Структура();
Параметры.Вставить("НомерДокумента", "ДОГ-000123");
Параметры.Вставить("ДатаДокумента", ТекущаяДата());
ОткрытьФорму("Документ.РеализацияТоваровУслуг.ФормаОбъекта", ЭтотОбъект, , , , Параметры);
- 📌 Плюсы: простота реализации, не требует изменений в форме-приёмнике.
- ⚠️ Минусы: нельзя передавать объекты конфигурации (только примитивные типы и структуры).
- 🔄 Нюанс: в управляемых формах параметры доступны через свойство
Параметрыобъекта формы.
2. Работа с реквизитами формы: прямой доступ и программная установка
Если значения нужно передать в конкретные реквизиты формы (поля ввода, флажки, списки), удобнее работать напрямую с объектом формы. Этот метод требует знания имени реквизита, но даёт больше контроля над процессом.
Пример для управляемой формы:
// Получаем форму документа
Форма = ПолучитьФорму("Документ.ЗаказПокупателя.ФормаОбъекта");
// Устанавливаем значения реквизитов
Форма.Элементы.Номер.Значение = "ЗК-00456";
Форма.Элементы.Дата.Значение = ТекущаяДата() + 3; // Через 3 дня
Форма.Элементы.Контрагент.Значение = Справочники.Контрагенты.НайтиПоНаименованию("ООО Ромашка");
// Открываем форму
Форма.Открыть();
⚠️ Внимание: При работе с обычными формами (тонкий клиент, толстый клиент) доступ к элементам осуществляется через коллекциюЭлементыФормы, а неЭлементы. Путаница между этими коллекциями — частая причина ошибок типа "Неопределённое свойство".
Для передачи табличных частей используйте метод Загрузить():
ТабличнаяЧасть = Форма.Элементы.Товары;
ТабличнаяЧасть.Загрузить(Выборка); // Выборка — результат запроса или таблица значений
Имя реквизита указано верно (с учётом регистра)|
Тип передаваемого значения совпадает с типом реквизита|
Форма ещё не открыта (иначе изменения не применятся)|
Для справочников передаётся ссылка, а не строка-->
3. Передача объектов конфигурации: ссылки vs. копии
Одна из самых распространённых ошибок — попытка передать в форму объект конфигурации (документ, справочник, регистр) "как есть". В большинстве случаев это приводит к ошибкам сериализации или потере связи с базой данных.
Правильные подходы:
- 🔗 Передача ссылок: вместо объекта передавайте его ссылку (например,
ДокументСсылка.Ссылка). В форме потом можно получить объект по ссылке. - 📋 Копирование данных: если нужны только данные (без привязки к БД), скопируйте их в
СтруктуруилиТаблицуЗначений. - 🔄 Обмен через параметры: для сложных объектов используйте механизм параметров с предварительной конвертацией в JSON (требует подключения библиотеки для работы с JSON).
Пример передачи ссылки на документ:
Параметры = Новый Структура();
Параметры.Вставить("СсылкаНаДокумент", Документ.Ссылка);
ОткрытьФорму("Документ.ПоступлениеТоваров.ФормаВыбора", ЭтотОбъект, , , , Параметры);
В форме-приёмнике объект восстанавливается так:
Если Параметры.Свойство("СсылкаНаДокумент") Тогда
ДокументОбъект = Параметры.СсылкаНаДокумент.ПолучитьОбъект();
КонецЕсли;
⚠️ Внимание: При передаче ссылок между разными сеансами (например, через HTTP-сервисы или фоновые задания) ссылка может стать невалидной. В таких случаях передавайте уникальные идентификаторы (GUID или код+дату) и восстанавливайте объект запросами.
4. Обмен данными между формами: события и обработчики
Когда нужно передать данные между уже открытыми формами (например, из формы списка в форму элемента), используйте механизм Оповещения или Публичные методы.
Способы организации обмена:
| Метод | Применимость | Пример кода | Ограничения |
|---|---|---|---|
| Оповещения | Управляемые формы | Оповестить("ИмяСобытия", Параметры); |
Требует подписки на событие в форме-приёмнике |
| Публичные методы | Обычные и управляемые формы | ФормаПриемник.ПринятьДанные(Данные); |
Нужно знать имя формы-приёмника |
| Глобальные переменные | Все типы форм | ГлобальныйКонтекст.Вставить("TempData", Данные); |
Небезопасно при многопользовательской работе |
Пример с оповещениями:
// В форме-отправителе:
Оповестить("ПередатьДанныеВФормуЭлемента", Новый Структура("Код,Наименование", ТекКод, ТекНаим));
// В форме-приёмнике (в модуле формы):
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
ПодписатьсяНаОповещение("ПередатьДанныеВФормуЭлемента", ЭтотОбъект, "ОбработатьПереданныеДанные");
КонецПроцедуры
Процедура ОбработатьПереданныеДанные(Данные) Экспорт
ЭлементыФормы.Код.Значение = Данные.Код;
ЭлементыФормы.Наименование.Значение = Данные.Наименование;
КонецПроцедуры
ЗаписьЖурналаРегистрации("Оповещение отправлено", УровеньЖурнала.Информация,, Данные);
Это поможет отследить, доходят ли данные до формы-приёмника.-->
5. Передача сложных данных: таблицы, деревья, коллекции
Когда нужно передать в форму табличные данные (например, остатки товаров или структуру подчинённости контрагентов), обычные параметры не подходят. Здесь помогают:
- 📊 ТаблицаЗначений: универсальный формат для передачи табличных данных. Поддерживает колонки разных типов.
- 🌳 ДеревоЗначений: для иерархических данных (например, структура подразделений).
- 🗃️ Массив/СписокЗначений: для передачи наборов однотипных данных.
Пример передачи ТаблицыЗначений с остатками товаров:
ТаблицаОстатков = Новый ТаблицаЗначений;
ТаблицаОстатков.Колонки.Добавить("Товар", Новый ОписаниеТипов("СправочникСсылка.Номенклатура"));
ТаблицаОстатков.Колонки.Добавить("Количество", Новый ОписаниеТипов("Число"));
ТаблицаОстатков.Колонки.Добавить("Склад", Новый ОписаниеТипов("СправочникСсылка.Склады"));
// Заполняем данными (например, из запроса)
Запрос = Новый Запрос;
Запрос.Текст = "ВЫБРАТЬ
| ОстаткиТоваров.Номенклатура КАК Товар,
| ОстаткиТоваров.КоличествоОстаток КАК Количество,
| ОстаткиТоваров.Склад
|ИЗ
| РегистрНакопления.ОстаткиТоваров КАК ОстаткиТоваров";
Результат = Запрос.Выполнить();
ТаблицаОстатков.Загрузить(Результат);
// Передаём в форму
Параметры = Новый Структура("Остатки", ТаблицаОстатков);
ОткрытьФорму("Справочник.Номенклатура.ФормаСписка", ЭтотОбъект, , , , Параметры);
В форме-приёмнике таблицу можно вывести в ДинамическийСписок или ТабличноеПоле:
Если Параметры.Свойство("Остатки") Тогда
ЭлементыФормы.СписокОстатков.Значение = Параметры.Остатки;
КонецЕсли;
Как передать данные из формы в отчёт?
Для передачи данных из формы в отчёт используйте механизм ПараметрыОтчёта. Сначала формируйте структуру с данными в форме, затем передавайте её в метод СкомпоноватьРезультат() отчёта:
ПараметрыОтчёта = Новый Структура("ДатаНачала,ДатаОкончания,ФильтрПоСкладу",
НачалоПериода, КонецПериода, ТекущийСклад);
Отчёт.СкомпоноватьРезультат(ПараметрыОтчёта);
6. Типичные ошибки и их решение
Даже опытные разработчики сталкиваются с проблемами при передаче данных в формы. Вот самые распространённые ошибки и способы их исправления:
- 🚫 "Неопределённое свойство 'Параметры'": возникает, если пытаетесь получить параметры в обычной форме через
Параметры(вместоПараметрыФормы). - 🔄 Данные не обновляются: если форма уже открыта, изменения реквизитов не применяются автоматически — нужно вызывать
Обновить(). - 🗑️ "Тип не совпадает": при передаче ссылок на объекты убедитесь, что в форме-приёмнике реквизит имеет совместимый тип (например,
СправочникСсылка.Контрагенты, а не простоСправочникСсылка). - 🔒 Блокировки при работе с объектами: если передаёте объект (не ссылку!) между формами, он может быть заблокирован другим пользователем. Используйте
ПолучитьОбъект()с флагомЛожьдля чтения без блокировки.
Пример исправления ошибки с типами:
// Неверно (может вызвать ошибку типов):
Форма.Элементы.Контрагент.Значение = Справочники.Контрагенты.НайтиПоКоду("001");
// Правильно (явное приведение типа):
Форма.Элементы.Контрагент.Значение = СправочникСсылка.Контрагенты(Справочники.Контрагенты.НайтиПоКоду("001"));
⚠️ Внимание: При передаче данных между разными базами (например, через HTTP-сервисы или обмен данными) нельзя передавать объекты конфигурации или ссылки. Используйте универсальные форматы:JSON,XMLилиТаблицаЗначенийс примитивными типами.
Если Параметры.Свойство("ИмяПараметра") Тогда ...
Это предотвратит ошибки, если параметр не был передан.-->
FAQ: Частые вопросы по передаче данных в формы 1С
Как передать в форму данные из внешнего источника (Excel, JSON, XML)?
Для передачи данных из внешних источников:
- Считайте данные в
ТаблицуЗначенийилиСтруктуру(например, черезЧтениеJSONилиЗагрузитьДанныеИзТабличногоДокумента()). - Передайте полученную структуру в форму через параметры или реквизиты.
- В форме преобразуйте данные в нужный формат (например, загрузите в табличную часть).
Пример для JSON:
ДанныеJSON = Новый ЧтениеJSON;
ДанныеJSON.УстановитьСтроку(ТекстJSON);
ТаблицаДанных = ПрочитатьJSON(ДанныеJSON);
Параметры = Новый Структура("ВнешниеДанные", ТаблицаДанных);
ОткрытьФорму("Обработка.ИмпортДанных.Форма", ЭтотОбъект, , , , Параметры);
Можно ли передать в форму объект запроса (РезультатЗапроса)?
Нет, РезультатЗапроса нельзя передавать напрямую, так как он привязан к сеансу. Преобразуйте его в ТаблицуЗначений:
Результат = Запрос.Выполнить();
Таблица = Результат.Выгрузить();
Параметры.Вставить("ДанныеЗапроса", Таблица);
Как обновить данные в форме после их передачи?
Если данные в форму переданы, но не отображаются:
- Для управляемых форм вызовите
Обновить():
Форма.Обновить();
Форма.ЭлементыФормы.ИмяЭлемента.Обновить();
Что делать, если при передаче ссылок возникает ошибка "Объект не найден"?
Ошибка означает, что ссылка стала невалидной. Проверьте:
- Не удалён ли объект в базе данных.
- Не изменилась ли конфигурация (например, был переименован справочник).
- Передаётся ли ссылка между разными базами (в этом случае используйте
УникальныйИдентификатор()).
Решение: передавайте не ссылку, а УникальныйИдентификатор() и восстанавливайте объект запросом:
УИД = Параметры.СсылкаНаОбъект.УникальныйИдентификатор();
Объект = Справочники.Номенклатура.НайтиПоУникальномуИдентификатору(УИД);
Как передать данные в форму из фонового задания?
Фоновые задания выполняются в отдельном сеансе, поэтому:
- Сохраните данные в
РегистрСведенийили временный справочник с пометкой "ДляФона". - Передайте в форму только идентификатор записи (например, код или GUID).
- В форме загрузите данные из регистра по идентификатору.
Пример:
// В фоновом задании:
Данные = Новый Структура("Код,Дата", "123", ТекущаяДата());
Запись = РегистрыСведений.ВременныеДанныеФона.СоздатьМенеджерЗаписи();
Запись.Идентификатор = Новый УникальныйИдентификатор();
Запись.Данные = Данные;
Запись.Записать();
// В основной форме:
УИД = Параметры.ИдентификаторДанных;
Данные = РегистрыСведений.ВременныеДанныеФона.ПолучитьПоследниеДанные(УИД);