Как программно заполнить реквизиты при вводе на основании из формы списка и формы документа в 1С?

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

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

Разберем причину: разнообразие типов параметра ДанныеЗаполнения

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

  1. ДокументСсылка: Передается, когда мы открываем документ-основание и нажимаем кнопку «Создать на основании». В этом случае ДанныеЗаполнения — это прямая ссылка на объект.
  2. Массив: Часто встречается при работе с динамическими списками или когда в механизме ввода на основании предусмотрен множественный выбор. В массив попадают ссылки на выбранные документы.
  3. Структура: Передается в случаях, когда заполнение инициировано сложным программным кодом, передающим набор параметров.
  4. Неопределено: Если документ создается просто кнопкой «Создать», а не на основании чего-либо.

Когда вы пишете код вида Расш1_ВнутреннийКурс = ДанныеЗаполнения.Расш1_ВнутреннийКурс;, он срабатывает только для первого варианта (ссылки). Если в параметре пришел массив, платформа не может найти у него реквизит Расш1_ВнутреннийКурс, и заполнение не происходит.

Реализация универсального заполнения через расширение

Для того чтобы наше расширение работало корректно в любых условиях, нам необходимо проверить тип входящих данных. Рассмотрим правильный шаблон процедуры ОбработкаЗаполнения в модуле объекта документа:


&После("ОбработкаЗаполнения")
Процедура Расш1_ОбработкаЗаполнения(ДанныеЗаполнения, ТекстЗаполнения, СтандартнаяОбработка)
    
    // Проверяем, что данные заполнения вообще переданы
    Если ДанныеЗаполнения = Неопределено Тогда
        Возврат;
    КонецЕсли;
    
    // Определяем основание в зависимости от типа
    Основание = Неопределено;
    
    Если ТипЗнч(ДанныеЗаполнения) = Тип("ДокументСсылка.СчетНаОплатуПокупателю") Тогда
        Основание = ДанныеЗаполнения;
    ИначеЕсли ТипЗнч(ДанныеЗаполнения) = Тип("Массив") И ДанныеЗаполнения.Количество() > 0 Тогда
        // Берем первый элемент массива, если это ввод на основании из списка
        Если ТипЗнч(ДанныеЗаполнения[0]) = Тип("ДокументСсылка.СчетНаОплатуПокупателю") Тогда
            Основание = ДанныеЗаполнения[0];
        КонецЕсли;
    КонецЕсли;
    
    // Если основание найдено, заполняем наш реквизит
    Если Основание <> Неопределено Тогда
        ЭтотОбъект.Расш1_ВнутреннийКурс = Основание.Расш1_ВнутреннийКурс;
    КонецЕсли;
    
КонецПроцедуры

Использование безопасного метода ЗаполнитьЗначенияСвойств

Проанализируем еще один подход, который считается более «чистым» в среде профессиональной разработки. Метод ЗаполнитьЗначенияСвойств позволяет копировать значения реквизитов с одинаковыми именами из одного объекта в другой, не вызывая ошибок при отсутствии реквизита или несоответствии типов. Это избавляет от необходимости жестких проверок на тип Массив в некоторых сценариях.

Однако помните: если ДанныеЗаполнения — это массив, метод ЗаполнитьЗначенияСвойств не сможет извлечь данные напрямую. Поэтому проверка типа все равно остается лучшей практикой.


// Пример использования безопасного заполнения для одиночной ссылки
Если ТипЗнч(ДанныеЗаполнения) = Тип("ДокументСсылка.СчетНаОплатуПокупателю") Тогда
    ЗаполнитьЗначенияСвойств(ЭтотОбъект, ДанныеЗаполнения, "Расш1_ВнутреннийКурс");
КонецЕсли;

Почему данные могут «затираться» после заполнения?

Если вы внедрили код с проверкой типа, но реквизит все равно пустой при открытии формы документа, причина может крыться в логике самой конфигурации «Бухгалтерия предприятия 3.0» (БП 3.0) или БСП (Библиотека стандартных подсистем). Выясним возможные факторы:

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

Рекомендации по работе в БП 3.0

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

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

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

← На главную