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