Как передать и прочитать параметр при открытии обычной формы 1С

Программист 1С v8.3 (Обычные формы) IT и автоматизация бизнеса
← На главную

Разработка на платформе 1С:Предприятие 8 в режиме обычного приложения существенно отличается от работы с управляемыми формами. Одной из наиболее частых проблем для разработчиков, привыкших к современному интерфейсу "Такси", является отсутствие стандартного расширения Параметры у объекта формы. Если в управляемых формах мы просто передаем структуру в метод ОткрытьФорму(), то в обычных формах этот механизм требует более детального подхода.

В данной статье мы разберем, как правильно передать данные из одной формы в другую, рассмотрим различные способы их обработки и выясним, какие события формы лучше всего использовать для установки отборов. Проанализируем ситуацию на конкретных примерах кода.

Метод 1. Использование реквизитов формы и прямое обращение к объекту

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

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


Процедура ПодгруппаОСНачалоВыбора(Элемент, СтандартнаяОбработка)
    // Отменяем стандартное открытие, так как будем открывать форму программно
    СтандартнаяОбработка = Ложь;

    // Шаг 1: Получаем объект формы без её открытия
    // Используем ПолучитьФорму, где вторым параметром можно передать владельца
    ФормаВыбора = Справочник.ПодгруппыОС.ПолучитьФорму("ФормаВыбора", Элемент);

    // Шаг 2: Напрямую записываем данные в реквизиты формы. 
    // Предполагается, что в ФормеВыбора создан реквизит "ГруппаОСОтбор"
    ФормаВыбора.ГруппаОСОтбор = ГруппаОС;
    
    // Также можно установить начальное значение, чтобы курсор сразу встал на нужный элемент
    ФормаВыбора.НачальноеЗначениеВыбора = ПодгруппаОС;

    // Шаг 3: Теперь открываем форму
    ФормаВыбора.Открыть();
КонецПроцедуры

Теперь проанализируем, что должно происходить внутри открываемой формы. Чтобы переданный параметр применился, нам нужно обработать его в событии ПриОткрытии или ПередОткрытием:


Процедура ПриОткрытии()
    // Проверяем, заполнено ли наше свойство, переданное извне
    Если ЗначениеЗаполнено(ГруппаОСОтбор) Тогда
        // Устанавливаем отбор в списке справочника
        СправочникСписок.Отбор.ГруппаОС.Использование = Истина;
        СправочникСписок.Отбор.ГруппаОС.Значение = ГруппаОСОтбор;
        СправочникСписок.Отбор.ГруппаОС.ВидСравнения = ВидСравнения.Равно;
    КонецЕсли; 
КонецПроцедуры

Метод 2. Использование экспортных переменных (без создания реквизитов)

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

Выясним, как это выглядит в коде модуля открываемой формы:


// В самой верхней части модуля, до процедур
Перем КонтекстВызова Экспорт;

Процедура ПередОткрытием(Отказ, СтандартнаяОбработка)
    Если КонтекстВызова = "СпециальныйРежим" Тогда
        // Выполняем особую логику инициализации
        ЭтаФорма.ТолькоПросмотр = Истина;
    КонецЕсли;
КонецПроцедуры

Такой подход позволяет передавать произвольные данные, не меняя структуру конфигурации в части реквизитов формы. Это "чище" с точки зрения архитектуры, если параметр нужен только один раз в момент запуска.

Метод 3. Программная установка отбора без участия кода внутри формы

Если ваша задача — просто установить фильтр в списке, можно даже не писать код внутри открываемой формы. Рассмотрим ситуацию, когда мы управляем объектом СправочникСписок (или ДокументСписок) непосредственно из вызывающего кода. Посмотрим на пример:


Процедура ОткрытьСписокСОтбором()
    Форма = Справочники.Номенклатура.ПолучитьФормуВыбора();
    
    // Обращаемся к реквизиту формы, который содержит данные списка
    // По умолчанию в формах списков это "СправочникСписок"
    Отбор = Форма.СправочникСписок.Отбор;
    
    Если Отбор.Найти("ВидНоменклатуры") <> Неопределено Тогда
        Отбор.ВидНоменклатуры.Установить(Справочники.ВидыНоменклатуры.Товар);
    КонецЕсли;
    
    Форма.Открыть();
КонецПроцедуры

Важный нюанс: метод Установить() является сокращенным способом включения использования отбора и присвоения ему значения. Это избавляет от написания трех строк кода (Использование, Значение, ВидСравнения).

Разберем разницу между событиями ПередОткрытием и ПриОткрытии

При работе с параметрами и отборами критически важно выбрать правильную точку входа. Проанализируем два основных события:

  1. ПередОткрытием: Вызывается до того, как форма будет отрисована и данные начнут считываться из базы. Это идеальное место для установки отборов. Если вы установите фильтр здесь, система сразу сделает запрос к БД с учетом ваших условий, что предотвратит "мерцание" интерфейса (когда сначала загружаются все данные, а потом они резко исчезают из-за примененного фильтра).
  2. ПриОткрытии: Форма уже существует как визуальный объект. Здесь лучше выполнять действия, связанные с интерфейсом — например, активизировать конкретный элемент управления или вывести информационное сообщение пользователю на основании переданных параметров.

Доступ к владельцу формы как альтернатива параметрам

Иногда передавать параметр вовсе не обязательно. В обычных формах объект формы всегда имеет свойство Владелец. Рассмотрим ситуацию, когда форма выбора открывается из формы документа. В открытой форме выбора мы можем напрямую "заглянуть" в контекст вызывающей формы:


Процедура ПередОткрытием(Отказ, СтандартнаяОбработка)
    // Проверяем, что владельцем является форма
    Если ТипЗнч(ЭтаФорма.Владелец) = Тип("Форма") Тогда
        // Читаем значение реквизита "Организация" из вызвавшей формы
        Попытка
            ТекОрганизация = ЭтаФорма.Владелец.Организация;
            // Устанавливаем отбор на основе полученных данных
            СправочникСписок.Отбор.Организация.Установить(ТекОрганизация);
        Исключение
            // Владелец не имеет реквизита Организация
        КонецПопытки;
    КонецЕсли;
КонецПроцедуры

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

Резюме по лучшим практикам

Подводя итог, для работы с обычными формами рекомендуется придерживаться следующего алгоритма:

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

← На главную