Ошибки при выполнении обмена данными в распределенных информационных базах (РИБ) — одна из самых трудоемких задач для администратора и программиста 1С. Ситуация осложняется тем, что база может быть полностью типовой, а ошибка возникает внезапно, прерывая процесс синхронизации. Рассмотрим одну из самых распространенных проблем, связанную с обращением к реквизитам через «точку», когда объект еще не загружен или вовсе отсутствует в базе.
Обычно ошибка выглядит следующим образом: Ошибка при выполнении обработчика - 'ПередЗаписью': {ОбщийМодуль.ПроцедурыОбменаСРозничнойТорговлей.Модуль(1138)}: Значение не является значением объектного типа (Склад). Разберем, что происходит в этот момент внутри системы. Проанализируем строку кода, на которую указывает конфигуратор:
Склад = Регистратор.СкладОрдер.Склад;
В данном случае программа пытается получить значение реквизита Склад у объекта СкладОрдер, который, в свою очередь, является реквизитом документа Регистратор. Ошибка «Значение не является значением объектного типа» означает, что часть этой цепочки (либо Регистратор, либо СкладОрдер) не является ссылкой на существующий объект, а содержит Неопределено или ссылку на несуществующий объект (так называемую «битую ссылку»).
Выясним причину, по которой в периферийной базе появляются битые ссылки. В РИБ-системах данные передаются пакетами. Рассмотрим основные сценарии возникновения конфликта:
ОбменДанными.Загрузка = Истина, некоторые обработчики ПередЗаписью в типовых конфигурациях все равно могут содержать код, обращающийся к данным регистратора для определения аналитики.Прежде всего, нам необходимо понять, какой именно документ вызывает сбой. Для этого в периферийной базе следует включить отладку. Настроим остановку по ошибке и запустим процесс обмена. Когда выполнение прервется, проанализируем переменную Регистратор.
Если в табло отладчика мы видим <Объект не найден> (116:80f6a02...), это подтверждает теорию о битой ссылке. Нам нужно найти этот ГУИД (уникальный идентификатор) в центральной базе. Воспользуемся консолью запросов или стандартной обработкой «Поиск ссылок в объекте», чтобы понять, что это за документ (например, «Возврат товаров от покупателя» №001 от 01.10.2018).
Проанализируем ситуацию: почему регистратор не пришел в базу? Проверим состав плана обмена в Центральной базе:
Важный нюанс: Часто в розничной торговле «Чеки ККМ» не передаются из магазина в магазин, но движения по ним могут «цепляться» за другие документы. Если «Возврат» ссылается на «Чек», которого нет в базе, возникнет ошибка при попытке прочитать Регистратор.СкладОрдер.Склад.
Если ошибка блокирует работу, а искать причину в коде некогда, применим метод принудительной синхронизации объектов. Посмотрим, как это сделать правильно:
Склады в состав обмена или принудительно зарегистрировать все элементы этого справочника к выгрузке. Это восстановит целостность НСИ (нормативно-справочной информации).Если вы имеете возможность вносить изменения в конфигурацию (снята с поддержки или используются расширения), стоит защитить код от подобных падений. Рассмотрим пример безопасного извлечения склада:
// Вместо Склад = Регистратор.СкладОрдер.Склад;
// Используем проверку на наличие объекта
Если Регистратор = Неопределено Тогда
Склад = Справочники.Склады.ПустаяСсылка();
ИначеЕсли Регистратор.Метаданные().Реквизиты.Найти("СкладОрдер") <> Неопределено И ЗначениеЗаполнено(Регистратор.СкладОрдер) Тогда
// Проверяем тип СкладОрдер, если это составной тип
Если ТипЗнч(Регистратор.СкладОрдер) = Тип("СправочникСсылка.Склады") Тогда
Склад = Регистратор.СкладОрдер;
Иначе
// Пытаемся получить склад через точку только если ссылка не битая
Склад = ?(Регистратор.СкладОрдер.ПолучитьОбъект() = Неопределено,
Справочники.Склады.ПустаяСсылка(),
Регистратор.SkladOrder.Sklad);
КонецЕсли;
КонецЕсли;
Такой подход гарантирует, что даже при отсутствии объекта в базе система не «вылетит» с фатальной ошибкой, а просто запишет пустую аналитику или пропустит обработку.
Многие администраторы пытаются решить проблему через ТИИ с параметром «Создавать объекты при наличии ссылок». Рассмотрим, почему это временная мера:
СкладОрдер.Регистратор.СкладОрдер.Склад система получит Неопределено.Склад и снова выдаст ту же самую ошибку.Вывод: Единственный верный способ — обеспечить наличие реального объекта-регистратора в базе данных либо через корректировку правил обмена, либо через ручную синхронизацию недостающих данных.
Чтобы минимизировать появление таких ошибок в будущем, проанализируем следующие рекомендации:
ПередЗаписью — частая причина сбоев.Таким образом, системный подход к поиску битых ссылок и понимание механизмов работы РИБ позволяют быстро устранить ошибку и восстановить нормальную работу торговых точек.