Передача данных между формами в 1С:Предприятие 8.3 — одна из самых востребованных задач при разработке конфигураций. Без этого механизма невозможно создать сложные интерфейсы с логической связью между окнами, передачей выбранных значений или результатов обработки. Однако начинающие программисты часто сталкиваются с проблемами: данные теряются при закрытии формы, не обновляются в реальном времени или передаются в некорректном формате.

В этой статье мы разберём 5 основных способов обмена данными между формами — от элементарных параметров до продвинутых техник с использованием ВнешнихОбработок и ГлобальныхПеременных. Каждый метод проиллюстрирован практическим примером кода, который можно адаптировать под свои задачи. Особое внимание уделено типичным ошибкам (например, передача объектных ссылок вместо значений приводит к ошибке "Объект не найден") и способам их избежать.

1. Передача данных через параметры формы

Самый простой и безопасный способ — использование параметров формы. Он подходит для разовой передачи данных при открытии формы (например, передача ID выбранного документа или фильтра для списка). Параметры задаются в методе ОткрытьФорму() и доступны только на момент создания формы.

Основные преимущества метода:

  • ✅ Простота реализации — достаточно 2-3 строк кода
  • ✅ Нет риска утечек памяти (данные не хранятся после закрытия формы)
  • ✅ Подходит для передачи примитивных типов (Число, Строка, Дата) и ссылок на объекты

Пример кода для передачи ID документа из формы списка в форму элемента:

// В форме списка (источник)

Процедура ОткрытьДокумент(Команда)

ПараметрыФормы = Новый Структура("IDДокумента", ТекущийЭлемент.Ссылка.УникальныйИдентификатор());

ОткрытьФорму("Документ.РеализацияТоваровУслуг.ФормаЭлемента", ПараметрыФормы);

КонецПроцедуры

// В форме элемента (приёмник)

Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)

Если Параметры.Свойство("IDДокумента") Тогда

ДокументОбъект = Параметры.IDДокумента.ПолучитьОбъект();

ЗаполнитьФорму(ДокументОбъект);

КонецЕсли;

КонецПроцедуры

⚠️ Внимание: Если передаёте ссылку на объект (например, документ или справочник), убедитесь, что она не станет недействительной после записей транзакций. Используйте УникальныйИдентификатор() вместо прямой ссылки, если форма может оставаться открытой долго.
💡

Для передачи нескольких параметров используйте Структура вместо отдельных аргументов — это упрощает поддержку кода при добавлении новых данных.

2. Использование реквизитов формы

Реквизиты формы позволяют хранить данные в течение всего времени её работы и обновлять их динамически. Этот метод удобен, когда нужно передавать данные между родительской и дочерней формами (например, при выборе значения в модальном окне).

Ключевые особенности:

  • 🔄 Данные сохраняются пока форма открыта (в отличие от параметров)
  • 📎 Можно использовать для обратной связи (дочерняя форма меняет реквизит родительской)
  • 🚫 Не подходит для передачи между независимыми формами

Пример: передача выбранного контрагента из формы выбора в основную форму документа.

// В основной форме (родитель)

Процедура ВыбратьКонтрагента(Команда)

ФормаВыбора = ОткрытьФормуМодально("Справочник.Контрагенты.ФормаВыбора");

Если ФормаВыбора.ВыбранноеЗначение <> Неопределено Тогда

ЭлементыФормы.Контрагент.Значение = ФормаВыбора.ВыбранноеЗначение;

КонецЕсли;

КонецПроцедуры

// В форме выбора (дочерняя)

Перем ВыбранноеЗначение Экспорт;

Процедура ПриВыборе(Элемент)

ВыбранноеЗначение = Элемент.Значение;

Закрыть();

КонецПроцедуры

Метод Когда использовать Ограничения
Параметры формы Разовая передача при открытии Не обновляются динамически
Реквизиты формы Двусторонний обмен между связанными формами Требует явной привязки форм
Глобальные переменные Обмен между любыми формами Риск конфликтов имён
📊 Какой метод передачи данных вы используете чаще?
Параметры формы
Реквизиты формы
Глобальные переменные
Внешние обработки
Другой

3. Глобальные переменные и общие модули

Для передачи данных между независимыми формами (например, из формы справочника в форму отчёта) удобно использовать глобальные переменные или общие модули. Этот метод гибкий, но требует осторожности: неконтролируемое использование глобальных переменных может привести к утечкам памяти и конфликтам.

Рекомендации по использованию:

  • 🌍 Объявляйте переменные в ОбщемМодуле с ключом Экспорт
  • 🧹 Очищайте переменные после использования (например, в обработчике ПриЗакрытии)
  • 🔒 Для критичных данных используйте БлокировкаДанных

Пример с общим модулем ОбменДаннымиМеждуФормами:

// В общем модуле

Перем мТекщийКонтрагент Экспорт;

// В форме-отправителе

Процедура УстановитьКонтрагента(Значение)

ОбменДаннымиМеждуФормами.мТекщийКонтрагент = Значение;

КонецПроцедуры

// В форме-получателе

Процедура ПолучитьКонтрагента()

Возврат ОбменДаннымиМеждуФормами.мТекщийКонтрагент;

КонецПроцедуры

⚠️ Внимание: Глобальные переменные не сохраняются между сеансами 1С. Для долговременного хранения используйте ХранилищеЗначения или регистры сведений.
Что будет если не очистить глобальную переменную?

Неочищенные глобальные переменные остаются в памяти сеанса до его завершения. Это может привести к:

1) Утечкам памяти при частых операциях

2) Конфликтам данных, если переменная используется в разных сценариях

3) Ошибкам типа "Объект заблокирован", если переменная содержит ссылку на удалённый объект

4. Внешние обработки как посредники

Если нужно передать сложные структуры данных (таблицы значений, деревья, коллекции объектов), удобно использовать внешние обработки. Они позволяют инкапсулировать логику обмена и избежать загромождения основного кода.

Преимущества метода:

  • 📦 Поддержка сложных типов данных (например, ТаблицаЗначений с иерархией)
  • 🔧 Легко модифицировать логику без изменения форм
  • 🔄 Можно использовать для асинхронного обмена

Пример: передача таблицы товаров между формами через обработку ОбменДанными.epf.

// В форме-отправителе

Процедура ПередатьТовары(Команда)

Обработка = ВнешниеОбработки.Создать("ОбменДанными");

Обработка.УстановитьДанные(ЭлементыФормы.Товары.Значение);

ОткрытьФорму("Документ.ЗаказПокупателя.ФормаЭлемента");

КонецПроцедуры

// В обработке "ОбменДанными"

Перем мДанные Экспорт;

Процедура УстановитьДанные(Данные) Экспорт

мДанные = Данные;

КонецПроцедуры

Функция ПолучитьДанные() Экспорт

Возврат мДанные;

КонецФункции

// В форме-получателе

Процедура ПриОткрытии()

Обработка = ВнешниеОбработки.Создать("ОбменДанными");

Если Обработка.ПолучитьДанные() <> Неопределено Тогда

ЭлементыФормы.Товары.Значение = Обработка.ПолучитьДанные();

КонецЕсли;

КонецПроцедуры

Создать обработку с реквизитом для хранения данных|Экспортировать методы доступа к данным|Добавить обработку в список внешних обработок конфигурации|Проверить права доступа к обработке-->

5. Обмен через временные хранилища

Для передачи данных между формами в разных сеансах (например, в веб-клиенте или при работе с расширениями) подходит механизм ХранилищеЗначения. Он позволяет сохранять данные в базе и извлекать их по уникальному идентификатору.

Особенности метода:

  • 💾 Данные сохраняются в базе (доступны после перезапуска 1С)
  • 🔐 Требуется контроль за очисткой устаревших записей
  • 📡 Подходит для обмена между тонким и толстым клиентом

Пример использования:

// Сохранение данных

Хранилище = Новый ХранилищеЗначения();

Идентификатор = Хранилище.Поместить(ДанныеДляПередачи);

// Извлечение данных

ВосстановленныеДанные = Хранилище.Получить(Идентификатор);

⚠️ Внимание: Хранилище значения не является транзакционным. Если данные критичны, используйте регистры сведений с пометкой удаления.

6. События и подписки (продвинутый уровень)

Для реального времени обмена данными (например, обновление списка при изменении в другой форме) можно использовать механизм событий. Этот метод требует глубокого понимания архитектуры 1С, но обеспечивает максимальную гибкость.

Сценарии применения:

  • 🔄 Синхронизация данных между открытыми формами
  • 📢 Уведомления об изменениях (например, "Документ проведён")
  • 🤝 Координация действий в распределённой системе

Пример с использованием ПодпискаНаСобытие():

// В модуле управляемого приложения

Перем мПодписки;

Процедура ПодписатьсяНаОбновлениеДанных(Форма)

Если мПодписки = Неопределено Тогда

мПодписки = Новый Соответствие;

КонецЕсли;

мПодписки.Вставить(Форма, Истина);

ПодписатьсяНаСобытие("ОбновлениеДанных", Форма, "ОбновитьДанные");

КонецПроцедуры

Процедура ОбновлениеДанных(Данные) Экспорт

Для Каждого Форма Из мПодписки Цикл

Если Форма.Ссылка.Существует() Тогда

Форма.ОбновитьДанныеНаСервере(Данные);

КонецЕсли;

КонецЦикла;

КонецПроцедуры

💡

События — единственный способ обмена данными между формами в реальном времени без явного обращения к методам.

FAQ: Частые вопросы по передаче данных между формами

Можно ли передавать объекты 1С (документы, справочники) напрямую через параметры?

Да, но это не рекомендуется. При передаче объекта по ссылке он может стать недействительным после записей в базу (например, если документ проведён или удалён в другой транзакции). Лучше передавать УникальныйИдентификатор() и восстанавливать объект в форме-получателе методом ПолучитьОбъект().

Как передать данные из обычной формы в управляемую?

Используйте ПараметрыФормы при открытии управляемой формы или глобальные переменные. Для обычных форм также доступен метод ОткрытьЗначениеВНовойФорме(), но он имеет ограничения по типам данных.

Пример:

// В обычной форме

Параметры = Новый Структура("Данные", ТаблицаТоваров);

ОткрытьФорму("УправляемаяФорма.МодульОбмена", Параметры);

Почему после передачи таблицы значений в другую форму она становится пустой?

Это типичная ошибка при передаче по ссылке. Таблица значений передаётся как объект, и если исходная таблица очищается, изменения отразятся и в форме-получателе. Решения:

  1. Клонируйте таблицу перед передачей: НоваяТаблица = Таблица.Скопировать().
  2. Сериализуйте данные в JSON/XML и десериализуйте в форме-получателе.
Как передать данные между формами в веб-клиенте?

В веб-клиенте не работают глобальные переменные модулей. Используйте:

  • ХранилищеЗначения для временного хранения,
  • ПараметрыСеанса (если данные нужны в течение сеанса),
  • Внешние обработки с сохранением в базу.

Пример с ПараметрамиСеанса:

ПараметрыСеанса.Вставить("ТекущийКонтрагент", Контрагент.Ссылка);

// В другой форме:

Контрагент = ПараметрыСеанса.Получить("ТекущийКонтрагент");

Можно ли передавать данные между формами разных баз 1С?

Нет, стандартными средствами — нельзя. Для обмена между базами используйте:

  • Внешние файлы (JSON, XML, Excel),
  • Веб-сервисы (HTTPСервис),
  • Обмен через промежуточную базу (например, 1С:Консолидация).

Пример обмена через HTTP:

// Отправка данных

HTTPЗапрос = Новый HTTPЗапрос("http://другая-база/hs/обмен/принять");

HTTPЗапрос.УстановитьТелоИзСтроки(СериализоватьJSON(Данные));

Ответ = HTTPЗапрос.Выполнить();

// Приём данных (в другой базе)

Функция ПринятьДанные(Запрос) Экспорт

Данные = ДесериализоватьJSON(Запрос.ТелоКакСтроку);

// Обработка данных...

КонецФункции