Как работает автоматическое заполнение документов на основании в 1С:ERP и почему метод Заполнить() не всегда заполняет реквизиты

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

При разработке в крупных прикладных решениях, таких как 1С:ERP 2.4 или Комплексная автоматизация, программисты часто сталкиваются с ситуацией, когда в модуле объекта документа в процедуре ОбработкаЗаполнения нет явного присвоения значений реквизитам (например, ЭтотОбъект.Договор = Основание.Договор). Однако при создании документа на основании в пользовательском режиме все поля оказываются заполненными. Попытка же вызвать метод Объект.Заполнить(Основание) программно иногда не дает ожидаемого результата. Давайте разберем этот механизм «магии» платформы и выясним, как правильно управлять процессом заполнения.

Механизм платформы «Заполнять из данных заполнения»

Первое, на что нам стоит обратить внимание — это свойства реквизитов документа в конфигураторе. У каждого реквизита существует свойство «Заполнять из данных заполнения». Если этот флаг установлен, платформа берет на себя значительную часть работы по инициализации нового объекта.

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

  1. При вводе на основании вызывается событие ОбработкаЗаполнения(ДанныеЗаполнения, СтандартнаяОбработка).
  2. В качестве параметра ДанныеЗаполнения обычно передается ссылка на документ-основание (например, ДокументСсылка.РеализацияТоваровУслуг).
  3. В типовых конфигурациях внутри этого обработчика код часто преобразует ссылку в Структуру. Платформа позволяет переопределить переменную ДанныеЗаполнения, записав в нее структуру с ключами, имена которых совпадают с именами реквизитов вашего документа.
  4. Если по завершении процедуры параметр СтандартнаяОбработка остается равным Истина, платформа выполняет автоматическое сопоставление: она берет все значения из структуры ДанныеЗаполнения и записывает их в одноименные реквизиты документа.

Именно поэтому в коде вы можете видеть заполнение структуры, но не видеть прямого изменения реквизитов ЭтотОбъект. Платформа сделает это сама «за кулисами» сразу после выхода из процедуры.

Анализ типового кода в ERP

Проанализируем ситуацию на примере документа «Счет на оплату». В модуле объекта мы часто видим вызов процедур типа ЗаполнитьПоРеализацииТоваров. Посмотрим, что происходит внутри таких процедур:


Процедура ЗаполнитьПоРеализацииТоваров(Знач Основание, ДанныеЗаполнения)
    // Здесь создается структура, если она еще не создана
    Если ТипЗнч(ДанныеЗаполнения) <> Тип("Структура") Тогда
        ДанныеЗаполнения = Новый Структура;
    КонецЕсли;

    // В структуру помещаются данные из реализации
    ДанныеЗаполнения.Вставить("Организация", Основание.Организация);
    ДанныеЗаполнения.Вставить("Валюта", Основание.Валюта);
    ДанныеЗаполнения.Вставить("Договор", Основание.Договор);
    
    // Заполнение табличных частей часто идет напрямую в объект, 
    // но шапка может заполняться через структуру.
КонецПроцедуры

Важно помнить: если вы изменили тип переменной ДанныеЗаполнения со ссылки на структуру внутри процедуры, то для того, чтобы автоматика сработала, нельзя устанавливать СтандартнаяОбработка = Ложь.

Почему программный вызов Заполнить() может не работать

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


ДокументОбъект = РеквизитФормыВЗначение("Объект");
ДанныеЗаполнения = Объект.ДокументОснование;
ДокументОбъект.Заполнить(ДанныеЗаполнения);
ЗначениеВРеквизитФормы(ДокументОбъект, "Объект");

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

В ERP ситуация осложняется тем, что многие реквизиты зависят от контекста. Например, при изменении Организации или Партнера должны пересчитываться параметры налогообложения, соглашения и т.д. Метод Заполнить() в модуле объекта — это серверный метод, который не вызывает событий формы (таких как ПриИзменении). В результате данные в объекте могут появиться, но форма не «подхватит» связанные изменения или не обновит визуальные состояния.

Как правильно реализовать перезаполнение

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

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

Разберем пример правильного программного перезаполнения в форме документа:


&НаСервере
Процедура ПерезаполнитьНаОснованииСервер()
    
    ТекущийОбъект = РеквизитФормыВЗначение("Объект");
    Основание = ТекущийОбъект.ДокументОснование;
    
    // 1. Очищаем ТЧ, если это необходимо по логике
    ТекущийОбъект.ЭтапыГрафикаОплаты.Очистить();
    
    // 2. Вызываем стандартное заполнение
    // Внимание: внутри ОбработкаЗаполнения ERP может менять ДанныеЗаполнения
    ТекущийОбъект.Заполнить(Основание);
    
    // 3. Если платформа не заполнила реквизиты из структуры автоматически 
    // (актуально для некоторых версий платформы при работе с существующим объектом),
    // можно принудительно вызвать логику заполнения из модуля менеджера
    // Документы.СчетНаОплатуКлиенту.ЗаполнитьСчетПоРеализации(ТекущийОбъект, Основание);
    
    ЗначениеВРеквизитФормы(ТекущийОбъект, "Объект");
    
    // 4. Обязательно вызываем серверные обработчики изменения ключевых реквизитов,
    // чтобы обновились зависимые данные формы (цены, налоги, видимость полей)
    ПроверитьЗаполнениеЭлементовФормы(); 
    
КонецПроцедуры

Подписки на события: скрытый слой заполнения

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

Проанализируем порядок выполнения:

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

Резюме

Для успешной работы с заполнением в ERP необходимо понимать, что ДанныеЗаполнения — это не просто ссылка-основание, а транспортный контейнер (часто структура), который платформа использует для инициализации реквизитов. Если при программном вызове Заполнить() автоматика не срабатывает, проверьте наличие свойства «Заполнять из данных заполнения» у реквизитов и убедитесь, что вы не подавляете стандартную обработку в коде.

← На главную