Как программно заполнить реквизит Грузоотправитель в форме Реквизиты печати заказа клиента?

Программист 1С v8.3 (Управляемые формы) 1С:Управление торговлей Управленческий учет Торговля и дистрибуция
← На главную

При работе с типовыми конфигурациями на платформе 1С:Предприятие 8.3 (Управляемые формы), такими как Управление торговлей 11, ERP 2 или Комплексная автоматизация, разработчики часто сталкиваются с задачей автоматического заполнения данных для печати. Одной из таких задач является подстановка Грузоотправителя в зависимости от подразделения или других условий. Сложность заключается в том, что реквизиты печати часто вынесены в отдельную вспомогательную форму, и простое присваивание значения переменной в коде не всегда приводит к желаемому результату.

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

Анализ архитектуры хранения данных для печати

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

Если реквизит Грузоотправитель присутствует в самом объекте ЗаказКлиента, то его заполнение должно происходить в контексте этого объекта. Если же он существует только как реквизит формы РеквизитыПечати, нам потребуется механизм передачи параметров при открытии этой формы.

Шаг 1. Получение данных из регистра сведений

Рассмотрим пример получения данных из нетипового регистра сведений УчетнаяПолитикаПодразделений. Нам нужно найти Грузоотправителя, привязанного к конкретному подразделению документа. Для этого напишем запрос или воспользуемся методом менеджера регистра.


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

Шаг 2. Заполнение реквизита в основной форме документа

Многие разработчики совершают ошибку, пытаясь «записать» форму. В 1С Записать() — это метод объекта или набора записей. Чтобы данные сохранились, они должны попасть в Объект. Рассмотрим, как правильно присвоить значение в модуле формы документа:


&НаСервере
Процедура ЗаполнитьГрузоотправителяНаСервере()
    // Получаем значение из нашего регистра
    НайденныйГрузоотправитель = ПолучитьГрузоотправителяПоПодразделению(Объект.Подразделение);
    
    Если ЗначениеЗаполнено(НайденныйГрузоотправитель) Тогда
        // Присваиваем значение реквизиту объекта
        Объект.Грузоотправитель = НайденныйГрузоотправитель;
        
        // Если нужно сразу зафиксировать изменения в базе данных:
        // Объект.Записать(); 
        // ВАЖНО: Вызов Записать() в форме может привести к конфликту, 
        // если пользователь сам редактирует документ.
    КонецЕсли;
КонецПроцедуры

Шаг 3. Взаимодействие с формой РеквизитыПечати

Если Грузоотправитель должен заполняться именно в момент открытия формы РеквизитыПечати, нам нужно использовать обработчик ПриСозданииНаСервере этой самой формы. Выясним, как данные попадают в эту форму. Обычно это происходит через параметры открытия.

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

  1. Перехватить создание формы: В модуле формы РеквизитыПечати прописать логику заполнения в процедуре ПриСозданииНаСервере.
  2. Использовать Оповещение: Если форма открывается интерактивно пользователем, можно использовать механизм ОповеститьОВыборе для возврата выбранного значения в основную форму.

Пример кода в модуле формы РеквизитыПечати:


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

Типичные ошибки и их решение

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

Рекомендация по использованию ПолучитьОбъект()

В некоторых сообщениях форума предлагается использовать конструкцию Ссылка.ПолучитьОбъект().Записать(). Рассмотрим подробнее, почему это может быть опасно. Если вы вызываете этот код внутри формы того же самого документа, вы рискуете получить ошибку блокировки. Правильнее работать напрямую с данными формы через Объект.ИмяРеквизита = Значение. Метод ПолучитьОбъект() лучше оставить для внешних обработок или регламентных заданий, где форма документа не открыта.

Таким образом, для успешного заполнения грузоотправителя необходимо:

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