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

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

При разработке функциональности в 1С часто возникает необходимость открыть вспомогательное окно: форму подбора, диалог изменения статусов, окно указания причин разблокировки или ввода дополнительных параметров. Если для объекта создается не стандартная форма документа, а произвольная форма, разработчики сталкиваются с вопросом: как корректно передать в нее данные исходного документа и получить его ссылку?

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

В чем разница между формой документа и произвольной формой

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

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

Рассмотрим основные способы передачи ссылки и контекста документа в произвольную форму в обычном приложении.

Способ 1. Передача ссылки через реквизит произвольной формы

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

  1. В дереве реквизитов произвольной формы добавим реквизит (например, ДокументСсылка) с типом ДокументСсылка.ИмяВашегоДокумента.
  2. При открытии формы из основного документа передадим значение ссылки в этот реквизит.

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


// Получаем произвольную форму по имени
ФормаВспомогательная = Документы.АдресноеХранение.ПолучитьФорму("ФормаРазблокировки");

// Заполняем реквизит произвольной формы ссылкой на текущий документ
ФормаВспомогательная.ДокументСсылка = ЭтотОбъект.Ссылка;

// Открываем форму
ФормаВспомогательная.Открыть();

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

Способ 2. Использование свойства «ВладелецФормы»

В обычном приложении при вызове метода ПолучитьФорму() можно передать форму документа в качестве владельца. В этом случае внутри открытой произвольной формы автоматически становится доступным свойство ВладелецФормы.

Проанализируем пример передачи контекста через владельца:


// В модуле формы документа передаем "ЭтаФорма" вторым параметром
ФормаВспомогательная = Документы.АдресноеХранение.ПолучитьФорму("ФормаРазблокировки", ЭтаФорма);
ФормаВспомогательная.Открыть();

В модуле произвольной формы теперь можно обращаться к реквизитам и методам исходной формы без создания лишних реквизитов:


// Получаем ссылку или реквизиты документа через владельца формы
СсылкаНаДокумент = ВладелецФормы.ДокументОбъект.Ссылка;
ТекущаяОрганизация = ВладелецФормы.ДокументОбъект.Организация;

Способ 3. Модальный вызов формы с возвратом структуры параметров

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

Посмотрим на программный код вызова произвольной формы и обработки результата:


ФормаДиалога = Документы.АдресноеХранение.ПолучитьФорму("ФормаРазблокировки");

// Заполняем контекстные параметры для диалога
ТекДанные = ЭлементыФормы.ТабличнаяЧастьТовары.ТекущиеДанные;
Если ТекДанные <> Неопределено Тогда
    ФормаДиалога.Сектор = ТекДанные.Сектор;
    ФормаДиалога.Ряд    = ТекДанные.Ряд;
    ФормаДиалога.Паллет = ТекДанные.Паллет;
    
    ВозвращенныеДанные = ФормаДиалога.ОткрытьМодально();
    
    // Если пользователь нажал кнопку подтверждения и форма вернула структуру
    Если ТипЗнч(ВозвращенныеДанные) = Тип("Структура") Тогда
        ТекДанные.Разблокирован = ВозвращенныеДанные.Разблокирован;
        ТекДанные.Причина       = ВозвращенныеДанные.Причина;
    КонецЕсли;
КонецЕсли;

В самой произвольной форме при нажатии кнопки подтверждения сформируем структуру и закроем форму с передачей значения:


Процедура КнопкаРазблокироватьНажатие(Кнопка)
    
    Результат = Новый Структура;
    Результат.Вставить("Разблокирован", Истина);
    Результат.Вставить("Причина", РеквизитПричина);
    
    // Закрываем форму и возвращаем результат
    Закрыть(Результат);
    
КонецПроцедуры

Важные архитектурные правила и ограничения

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

  1. Проверка на новый документ. Если документ еще не записан в базу данных (ЭтоНовый() = Истина), его ссылка является пустой (Ссылка.Пустая() = Истина). Попытка записать такую ссылку в регистр сведений приведет к созданию битой ссылки. Перед открытием вспомогательных окон или выполнением записей в регистры необходимо убедиться, что документ записан, либо инициировать его запись.
  2. Недопустимость интерактивных действий в транзакции проведения. Нельзя открывать произвольные формы, показывать предупреждения или запрашивать действия пользователя из обработчика ОбработкаПроведения модуля документа. Интерактивные проверки должны выполняться на клиенте перед проведением (например, в событии ПередЗаписью формы документа с проверкой режима проведения).
  3. Оповещение об изменении данных. Если произвольная форма выполняет прямую запись в регистр сведений, основная форма документа не обновит свои данные автоматически. Для синхронизации вызывается метод Оповестить("СтатусИзменен", ПараметрыСобытия), а в форме документа переопределяется процедура ОбработкаОповещения для перечитывания актуальных статусов.
← На главную