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