Как получить реквизит документа в модуле произвольной формы в 1С 8.3

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

При разработке управляемых форм часто возникает задача: в произвольной форме, созданной внутри ветки конкретного документа, получить значение одного из его реквизитов. Начинающие разработчики нередко предполагают, что если форма создана внутри метаданных документа, платформа 1С автоматически связывает её с конкретным документом базы данных и позволяет обращаться к его реквизитам напрямую.

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

Почему нельзя получить данные документа без передачи контекста

Проанализируем разницу между структурой метаданных и экземпляром данных в базе:

  1. Метаданные конфигурации: Расположение формы внутри ветки конкретного документа в дереве метаданных лишь указывает логическую принадлежность формы к данному типу объектов. Через объект Метаданные можно узнать только типы, состав реквизитов и табличных частей, но не конкретные значения в базе данных.
  2. Данные конкретного экземпляра: Конкретный документ — это отдельная запись в базе данных со своим уникальным идентификатором (ссылкой). Форма сама по себе не знает, с каким именно из тысяч созданных документов пользователь работает в текущий момент, пока мы явно не передадим ссылку на этот документ или сам объект.

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

Способ 1. Использование параметров формы (рекомендуемый вариант)

Рассмотрим стандартный и наиболее гибкий механизм — передачу ссылки или конкретного значения реквизита при открытии формы через параметры.

Разберем по шагам, как это реализовать:

  1. В редакторе произвольной формы на вкладке «Параметры» добавим новый параметр, например, СсылкаНаДокумент с типом ссылки нужного документа.
  2. При вызове произвольной формы из внешней процедуры или другой формы передадим параметр в структуре открытия:

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

ОткрытьФорму("Документ.ЗаказКлиента.Форма.ФормаЗадач", ПараметрыФормы, ЭтотОбъект);
  1. В модуле открываемой формы в серверном обработчике ПриСозданииНаСервере прочитаем переданный параметр и используем его:

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

Способ 2. Назначение основного реквизита формы

Если произвольная форма предназначена для полноценной работы с данными одного документа, оптимально сделать её форму аналогичной типовой форме документа.

Посмотрим на порядок действий:

  1. В окне реквизитов формы создаем реквизит Объект с типом ДокументОбъект.ИмяВашегоДокумента.
  2. Устанавливаем для созданного реквизита свойство «Основной реквизит» (выделяется жирным шрифтом).
  3. При назначении основного реквизита платформа автоматически активирует встроенный параметр Ключ. Теперь форму можно открывать стандартным образом:

ПараметрыОткрытия = Новый Структура("Ключ", СсылкаНаДокумент);
ОткрытьФорму("Документ.ЗаказКлиента.Форма.ФормаЗадач", ПараметрыОткрытия);

В этом случае в модуле формы обращение к реквизитам документа становится доступным напрямую через реквизит Объект.ИмяРеквизита, так как платформа сама считает данные документа из базы при инициализации формы.

Способ 3. Получение данных через владельца формы

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

Разберем пример:

  1. При открытии формы передаем текущую форму документа в качестве параметра ВладелецФормы:

ОткрытьФорму("Документ.ЗаказКлиента.Форма.ФормаЗадач", , ЭтотОбъект);

  1. В открытой подчиненной форме на клиенте доступно свойство ЭтаФорма.ВладелецФормы. Через него можно прочитать значения реквизитов формы-владельца без необходимости повторного обращения к базе данных, что особенно полезно, если документ еще не записан в базу.

Способ 4. Оптимизированное чтение реквизитов на сервере

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

Посмотрим на пример оптимального чтения реквизита с помощью запроса на сервере:


&НаСервере
Функция ПолучитьРеквизитДокумента(СсылкаНаДокумент)
    Запрос = Новый Запрос;
    Запрос.Текст = 
        "ВЫБРАТЬ
        |   Док.Контрагент КАК Контрагент
        |ИЗ
        |   Документ.ЗаказКлиента КАК Док
        |ГДЕ
        |   Док.Ссылка = &Ссылка";
    
    Запрос.УстановитьПараметр("Ссылка", СсылкаНаДокумент);
    Выборка = Запрос.Выполнить().Выбрать();
    
    Если Выборка.Следующий() Тогда
        Возврат Выборка.Контрагент;
    КонецЕсли;
    
    Возврат Неопределено;
КонецФункции

Если в конфигурации используется «Библиотека стандартных подсистем» (БСП), для быстрого и компактного чтения реквизитов рекомендуется использовать функцию ОбщегоНазначения.ЗначениеРеквизитаОбъекта(Ссылка, "ИмяРеквизита").

← На главную