Как получить объект формы существующего документа или справочника в 1С:Предприятии 8.3 для программной работы с ней перед открытием?

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

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

Получение формы существующего объекта: метод ПолучитьФорму()

Наиболее эффективный и рекомендуемый способ получения формы существующего объекта для её последующей программной обработки — это использование метода глобального контекста ПолучитьФорму(). Этот метод позволяет нам получить объект формы, с которым мы можем взаимодействовать, прежде чем она будет открыта и показана пользователю.

Для того чтобы получить форму существующего объекта, нам необходимо передать в метод ПолучитьФорму() два ключевых параметра:

  1. Полное имя формы: Строка, указывающая на конкретную форму объекта. Например, "Документ.СборкаТоваров.ФормаОбъекта".
  2. Структура параметров: Объект типа Структура, содержащий параметры для инициализации формы. Ключевым параметром здесь является Ключ, в котором мы передаём ссылку на наш существующий объект.

Давайте посмотрим на пример кода, который решает нашу основную задачу:


Перем СсылкаНаОбъект; // Предполагаем, что эта переменная уже содержит ссылку на существующий объект

// Создаем структуру параметров для передачи в форму
ПараметрыФормы = Новый Структура("Ключ", СсылкаНаОбъект);

// Получаем объект формы
ФормаОбъекта = ПолучитьФорму("Документ.СборкаТоваров.ФормаОбъекта", ПараметрыФормы);

// Теперь у нас есть объект формы, и мы можем с ним работать
// Например, изменить какой-либо реквизит формы перед открытием
// ФормаОбъекта.МойРеквизит = "НовоеЗначение";

// После всех необходимых изменений, мы можем открыть форму
ФормаОбъекта.Открыть();

Как мы видим из примера, после выполнения ПолучитьФорму(), переменная ФормаОбъекта будет содержать экземпляр формы. Это даёт нам полный контроль над её содержимым и поведением до того, как пользователь её увидит. Например, мы можем программно заполнить какие-либо поля формы, установить значения видимости элементов или выполнить другую предварительную настройку.

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

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


Перем ВходящийДокументСсылка; // Ссылка на элемент справочника ВходящиеДокументы

// Для конфигурации "Документооборот 8 ПРОФ 2.1"
ПараметрыДляФормы = Новый Структура("Ключ", ВходящийДокументСсылка);
ФормаВходящегоДокумента = ПолучитьФорму("Справочник.ВходящиеДокументы.Форма.ФормаЭлемента", ПараметрыДляФормы);

// Теперь можем работать с ФормаВходящегоДокумента
// ...
ФормаВходящегоДокумента.Открыть();

Почему важно получить форму перед её открытием?

Ключевая причина, по которой мы можем захотеть получить объект формы перед её непосредственным открытием, заключается в необходимости отредактировать некоторые параметры формы объекта или её данные до того, как она станет доступна пользователю. Если мы просто откроем форму, у нас будет меньше возможностей для её динамической настройки "на лету" без взаимодействия с пользователем или сложных обходных путей.

Получив объект формы, мы получаем доступ к её реквизитам, элементам, командам и другим свойствам. Это позволяет нам:

  1. Предварительно заполнить поля формы на основе какой-либо логики.
  2. Изменить видимость или доступность элементов формы.
  3. Установить дополнительные параметры, которые будут влиять на поведение формы после её открытия (например, режим сохранения, режим подбора и т.д.).
  4. Инициировать специфические действия в форме, которые должны произойти до взаимодействия пользователя.

Метод ПолучитьФорму() в управляемом приложении также инициирует событие ПриСозданииНаСервере для получаемой формы, что является важным моментом для инициализации данных формы и её параметров.

ПолучитьФорму() vs ОткрытьЗначение(): в чем разница и когда что использовать?

В платформе 1С:Предприятие 8.3 существуют два основных подхода к открытию форм объектов по ссылке: ПолучитьФорму() и ОткрытьЗначение(). Давайте разберем их различия и области применения, чтобы мы могли выбрать наиболее подходящий метод для наших задач.

ОткрытьЗначение()

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

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


Перем СсылкаНаОбъект; // Предполагаем, что эта переменная уже содержит ссылку на существующий объект

ОткрытьЗначение(СсылкаНаОбъект);

Преимущества ОткрытьЗначение():

  1. Простота: Легко использовать, если не требуется сложная предварительная настройка.
  2. Автоматизация: Платформа сама определяет, какую форму открыть для данного типа объекта (например, форму элемента для справочника, форму документа для документа).

Недостатки ОткрытьЗначение():

  1. Ограниченный контроль: Мы не получаем объект формы для программной работы до её открытия.
  2. Меньшая универсальность: Не позволяет передавать пользовательские параметры в форму.
  3. Дополнительные серверные вызовы: В некоторых случаях платформа может выполнять дополнительные обращения к серверу (например, для определения типа элемента в иерархических справочниках), что может сказаться на производительности.

Этот метод подходит, когда нам нужно просто "показать" объект пользователю, и нет нужды вмешиваться в процесс инициализации формы.

ПолучитьФорму()

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

Преимущества ПолучитьФорму():

  1. Полный программный контроль: Мы получаем доступ к объекту формы до её открытия, что позволяет нам манипулировать её реквизитами, элементами и поведением.
  2. Передача параметров: Возможность передавать как системные (например, Ключ, ЗначениеКопирования), так и пользовательские параметры в форму.
  3. Обработка ПриСозданииНаСервере: Вызов этого события при получении формы позволяет инициализировать данные и логику формы на сервере.

Когда использовать какой метод?

Редактирование параметров формы перед открытием

Возможность редактировать параметры формы до её открытия является одним из ключевых преимуществ использования ПолучитьФорму(). Мы можем передавать в форму различные параметры через структуру при её получении, а затем эти параметры будут доступны внутри формы.

Системные и пользовательские параметры

Различают два вида параметров формы:

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

Обработка параметров в форме:

Основное место для обработки переданных параметров внутри формы — это событие ПриСозданииНаСервере(). В этом событии мы можем получить доступ к коллекции Параметры и использовать переданные значения для инициализации реквизитов формы, настройки её элементов и выполнения другой логики.


// Пример кода в модуле формы (событие ПриСозданииНаСервере)
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
    // Проверяем наличие параметра "МойПользовательскийПараметр"
    Если Параметры.Свойство("МойПользовательскийПараметр") Тогда
        ЭтотОбъект.МойРеквизитФормы = Параметры.МойПользовательскийПараметр;
        // Если параметр не ключевой и нужен для дальнейшей работы, его стоит сохранить
        // например, в реквизите формы
    КонецЕсли;
    
    // Системный параметр Ключ будет обработан платформой автоматически,
    // он используется для чтения данных объекта в форму.
    Если Параметры.Свойство("Ключ") Тогда
        // Мы можем получить ссылку из ключа, если это необходимо для какой-либо логики
        СсылкаНаОбъект = Параметры.Ключ;
    КонецЕсли;

    // ... другая логика инициализации формы
КонецПроцедуры

Важный момент: Пользовательские параметры (неключевые), которые передаются в форму, существуют только в момент её создания и удаляются после вызова ПриСозданииНаСервере. Если эти параметры нам нужны для дальнейшей работы с формой (например, для обработки событий по нажатию кнопок), мы должны сохранить их в реквизитах самой формы.

Получение имени формы без "хардкода"

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

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


Перем СсылкаНаОбъект; // Ссылка на любой объект (документ, справочник и т.п.)

// Получаем путь к основной форме объекта по умолчанию
НужныйПутьКФормеЧерезМетаДанные = СсылкаНаОбъект.Метаданные().ПолноеИмя + ".ФормаОбъекта";

// Пример: Для Документ.СборкаТоваров это будет "Документ.СборкаТоваров.ФормаОбъекта"
// Для Справочник.Организации это будет "Справочник.Организации.ФормаОбъекта"

// Теперь мы можем использовать эту строку для получения формы
ПараметрыФормы = Новый Структура("Ключ", СсылкаНаОбъект);
Форма = ПолучитьФорму(НужныйПутьКФормеЧерезМетаДанные, ПараметрыФормы);

Этот подход делает наш код более универсальным и устойчивым к изменениям, так как он не жестко привязан к конкретному типу документа или справочника, а адаптируется к типу объекта, на который указывает ссылка. Если же нам нужна конкретная форма с нестандартным именем, её имя все равно придется указывать явно.

Работа с ДанныеФормыСтруктура

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

  1. Получаем текущее значение объекта из формы: Используем метод РеквизитФормыВЗначение("Объект", Тип("ДокументОбъект.ИмяДокумента")) (или СправочникОбъект и т.д.) для преобразования ДанныеФормыСтруктура обратно в объект базы данных.
  2. Модифицируем объект: Вносим необходимые изменения в полученный объект.
  3. Записываем объект: Сохраняем измененный объект в базе данных (например, ОбъектДокумента.Записать()).
  4. Обновляем данные формы: Преобразуем модифицированный объект обратно в реквизит формы, используя метод ЗначениеВРеквизитФормы(ОбъектДокумента, "Объект"), чтобы изменения отразились в форме.

Пример:


// В модуле формы
&НаКлиенте
Процедура МодифицироватьОбъектНаФорме()
    // Получаем объект документа из реквизита формы "Объект"
    ДокументОбъект = РеквизитФормыВЗначение("Объект", Тип("ДокументОбъект.СборкаТоваров"));

    // Модифицируем объект
    ДокументОбъект.Комментарий = "Комментарий изменен на клиенте.";
    // ... другие изменения

    // Записываем объект в базу данных
    ДокументОбъект.Записать();

    // Обновляем реквизит формы "Объект", чтобы форма отобразила изменения
    ЗначениеВРеквизитФормы(ДокументОбъект, "Объект");
КонецПроцедуры

Важно: Если мы просто откроем форму по ссылке и *отдельно* модифицируем объект в базе данных, данные в открытой форме могут не синхронизироваться с актуальными данными в базе, так как форма работает со своей копией объекта (ДанныеФормыСтруктура), а не напрямую с данными базы. Поэтому важно всегда обновлять реквизит формы после записи объекта.

Контекст "На клиенте" и особенности работы

Все рассмотренные нами методы — ПолучитьФорму(), ОткрытьФорму(), ОткрытьЗначение() — доступны и работают в клиентском контексте (т.е. могут быть вызваны из клиентского кода). Однако, необходимо помнить о следующих нюансах:

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

Таким образом, мы выяснили, что для получения объекта формы существующего документа или справочника в 1С:Предприятии 8.3 для программной работы с ней перед открытием, наиболее подходящим методом является ПолучитьФорму() с передачей ссылки на объект через параметр Ключ. Этот подход обеспечивает необходимый контроль и гибкость, позволяя нам настроить форму в соответствии с нашими требованиями до того, как она будет показана пользователю.

← На главную