При настройке обмена данными между конфигурациями 1С, особенно с использованием «1С:Конверсия данных 2.1», разработчики часто сталкиваются с трудноуловимыми ошибками, которые проявляются не сразу, а лишь при определенных условиях в данных. Одной из таких классических проблем является ошибка «Значение не является значением объектного типа». В этой статье мы подробно разберем ситуацию, возникшую при обмене справочником Договоры контрагентов из системы БИТ.ФИНАНС в Бухгалтерию предприятия, выясним причины её возникновения и разработаем надежный алгоритм защиты кода в правилах обмена (ПКС).
Представим сценарий: созданы правила обмена, которые успешно работают через обработку «Универсальный обмен данными в формате XML». Задача состоит в том, чтобы при выгрузке договора транслировать в базу-приемник ставку НДС, которая хранится не в самом договоре напрямую, а в связанном с ним объекте бит_ПроектДоговора. Проблема заключается в том, что после обновлений базы или изменения структуры справочника выгрузка начинает прерываться с фатальной ошибкой при обращении к реквизиту через «точку».
Разберем типичный код, который вызывает падение системы в обработчике ПКС ПередВыгрузкой:
Значение = Источник.бит_ПроектДоговора.СтавкаНДС;
На первый взгляд код кажется логичным, но он содержит в себе «мину замедленного действия». Проанализируем, почему 1С выдает ошибку объектного типа.
Справочник Договоры контрагентов почти всегда является иерархическим. В нем существуют как элементы (сами договоры), так и группы (папки). Это ключевой момент, который часто упускают при написании правил обмена.
Когда обработка обмена перебирает объекты для выгрузки, она заходит в каждую папку. У объекта типа «Группа» отсутствуют реквизиты, которые добавлены разработчиками для «Элементов». В системе БИТ.ФИНАНС реквизит бит_ПроектДоговора назначен справочнику, но для группы он всегда будет иметь значение Неопределено. Следовательно, попытка обратиться к .СтавкаНДС у значения Неопределено и вызывает ту самую ошибку.
Даже если мы обрабатываем элемент (не группу), реквизит бит_ПроектДоговора может быть не заполнен. В 1С обращение через точку к пустой ссылке (если тип строго определен) обычно возвращает пустое значение этого типа. Однако, если реквизит имеет составной тип или если в базе данных возникла ситуация «битой ссылки», обращение к вложенному свойству приведет к остановке процесса обмена.
Чтобы точно определить, на каком объекте спотыкается обмен, рекомендуется использовать методы отладки через сообщения. Разберем, как это сделать правильно в контексте правил обмена:
Сообщить("Обработка объекта: " + Источник);
Сообщить("Тип проекта договора: " + ТипЗнч(Источник.бит_ПроектДоговора));
Если Источник.ЭтоГруппа Тогда
Сообщить("Это группа, пропукаем выполнение логики");
КонецЕсли;
Проанализировав вывод этих сообщений, мы увидим, что для групп справочника Источник.бит_ПроектДоговора возвращает пустоту, а попытка получить СтавкаНДС становится критической.
Для того чтобы правила обмена работали стабильно, необходимо внедрить несколько уровней проверок в обработчик ПередВыгрузкой. Рассмотрим правильный алгоритм написания кода.
Шаг 1: Исключение групп. Это обязательное условие для любых иерархических справочников, если вы обращаетесь к специфическим реквизитам элементов.
Шаг 2: Проверка заполненности ссылки. Никогда не обращайтесь через точку к реквизитам, если не уверены, что ссылка заполнена.
Шаг 3: Оптимизация запроса. Помните, что конструкция Источник.бит_ПроектДоговора.СтавкаНДС порождает дополнительный запрос к базе данных (разыменование ссылки). При больших объемах данных (тысячи договоров) это существенно замедлит обмен.
Рассмотрим эталонный вариант реализации логики в ПКС (Правило Конвертации Свойств) для реквизита СтавкаНДС:
// Инициализируем значение по умолчанию
Значение = "";
// 1. Проверяем, что объект не является группой
Если Не Источник.ЭтоГруппа Тогда
// 2. Проверяем, заполнена ли ссылка на проект договора
Если ЗначениеЗаполнено(Источник.бит_ПроектДоговора) Тогда
// 3. Безопасно получаем ставку НДС
Значение = Источник.бит_ПроектДоговора.СтавкаНДС;
Иначе
// Опционально: логика, если проект договора не указан
// Например, можно установить ставку "Без НДС"
// Значение = Перечисления.СтавкиНДС.БезНДС;
КонецЕсли;
КонецЕсли;
При работе с расширениями и отраслевыми решениями, такими как БИТ.ФИНАНС, важно учитывать следующие технические нюансы:
СтавкаНДС на Ставка_НДС).СтавкаНДС в договоре существует. В типовой БП 3.0 ставка НДС обычно не хранится в договоре. Если вам нужно передать это значение «в никуда» для последующей обработки, используйте Параметры или дополнительные свойства.Мы выяснили, что причина ошибки заключалась в игнорировании иерархической структуры справочника. Группы договоров не обладают теми же свойствами, что и элементы. Использование простой проверки ЭтоГруппа = Ложь и контроля заполнения ссылки ЗначениеЗаполнено() полностью решает проблему и делает ваш обмен данными надежным и профессиональным.