При разработке обработок в системе 1С:Предприятие 8.3 программисты часто сталкиваются с ситуацией, когда необходимо программно заполнить реквизит табличной части, имеющий составной тип данных. Типичный сценарий: мы находим нужную строку табличной части, пытаемся присвоить значение реквизиту, но в результате в ячейке по-прежнему остается Неопределено или пустая ссылка, хотя визуально в конфигураторе тип разрешен. Рассмотрим подробно, почему это происходит и как правильно диагностировать и устранить подобную проблему на примере конфигурации 1С:ERP.
Разберем ситуацию, когда в документе Поступление безналичных денежных средств (в ТЧ "Расшифровка платежа") нужно заполнить реквизит Основание платежа. Этот реквизит является составным. Если при попытке прямого присвоения Строка.ОснованиеПлатежа = СсылкаНаОбъект; значение не меняется, это может свидетельствовать о нескольких причинах:
ДанныеФормыКоллекция. В этом контексте поведение составных типов может иметь свои нюансы.Документ.РеализацияТоваровУслуг в поле, которое ожидает Справочник.ОбъектыРасчетов, приведет к неудаче.Прежде чем вносить изменения в конфигурацию, нам необходимо убедиться, что система вообще "знает" о том типе данных, который мы пытаемся передать. Проанализируем ситуацию с помощью обращения к метаданным. Для этого воспользуемся методом СодержитТип. Рассмотрим пример кода, который поможет проверить, допустим ли тип нашей ссылки для конкретного реквизита:
// СсылкаНаРасчет — это объект, который мы хотим записать (например, Реализация или Объект расчетов)
// Получаем описание типов реквизита из метаданных документа
ОписаниеТиповРеквизита = Метаданные.Документы.ПоступлениеБезналичныхДенежныхСредств.ТабличныеЧасти.РасшифровкаПлатежа.Реквизиты.ОснованиеПлатежа.Тип;
// Проверяем, разрешен ли тип нашей ссылки в этом реквизите
Если ОписаниеТиповРеквизита.СодержитТип(ТипЗнч(СсылкаНаРасчет)) Тогда
Сообщить("Тип разрешен, можно выполнять присвоение.");
Иначе
Сообщить("Тип НЕ разрешен в метаданных. Присвоение невозможно!");
КонецЕсли;
Если в результате проверки мы получаем сообщение о том, что тип не разрешен, то никакие программные ухищрения не заставят платформу записать это значение. Платформа 1С строго контролирует типизацию данных в базе.
Часто программисты пытаются манипулировать типами через элементы управления формы, используя свойство ОграничениеТипа. Однако важно понимать разницу: ОграничениеТипа — это свойство элемента формы (визуального компонента), а не самой строки данных. Если вы работаете в коде обработки (на сервере), у вас нет доступа к элементам управления формы документа, вы работаете напрямую с данными.
Рассмотрим ошибочный подход, который часто встречается в попытках решения:
// ОШИБОЧНЫЙ КОД
лТипЗначения = Новый ОписаниеТипов("Документ.РеализацияТоваровУслуг");
лСтрока.ТипЗначения = лТипЗначения; // Ошибка: у строки ТЧ нет свойства ТипЗначения!
Вместо этого следует использовать метод ПривестиЗначение. Это позволяет корректно преобразовать значение к разрешенному типу, если он присутствует в описании типов реквизита. Выясним, как это реализовать правильно:
// Правильный подход через приведение типа
ОписаниеТиповРеквизита = Метаданные.Документы.ПоступлениеБезналичныхДенежныхСредств.ТабличныеЧасти.РасшифровкаПлатежа.Реквизиты.ОснованиеПлатежа.Тип;
СтрокаТЧ.ОснованиеПлатежа = ОписаниеТиповРеквизита.ПривестиЗначение(СсылкаНаРасчет);
В современных конфигурациях 1С:ERP и Комплексная автоматизация поле Основание платежа (или аналогичные) часто перестает принимать прямые ссылки на документы (Заказы, Реализации). Вместо этого система требует ссылку на элемент справочника Объекты расчетов. Это критический момент, который часто упускают из виду.
Если вы пытаетесь подставить ДокументСсылка.РеализацияТоваровУслуг, а в метаданных указан только СправочникСсылка.ОбъектыРасчетов, то значение будет сброшено в Неопределено. Проанализируем, как в этом случае найти или создать нужный объект расчетов. В типовых конфигурациях для этого существуют общие модули, например ДенежныеСредстваСервер или РасчетыСКлиентами.
Если в ходе анализа (см. Шаг 1) выяснилось, что нужного типа действительно нет в метаданных (например, из-за ошибки в релизе поставщика), единственным верным способом будет добавление этого типа. Чтобы не снимать конфигурацию с поддержки, используем механизм расширений:
ПоступлениеБезналичныхДенежныхСредств) и его табличную часть.ОснованиеПлатежа.СправочникСсылка.ОбъектыРасчетов или ДокументСсылка.РеализацияТоваровУслуг).После этого программное присвоение Строка.ОснованиеПлатежа = НужнаяСсылка; начнет работать автоматически без дополнительного кода.
Для успешного изменения типа составного реквизита в табличной части необходимо соблюдать следующую последовательность действий:
ПривестиЗначение для безопасного преобразования типов.Таким образом, мы выяснили, что проблема "неприсвоения" значения чаще всего кроется не в ошибке кода, а в несоответствии типов данных на уровне метаданных системы.