Часто разработчики и системные администраторы сталкиваются с необъяснимым поведением платформы 1С:Предприятие. Одна из таких загадок — ситуация, когда в консоли запросов реквизит документа заполнен, но при попытке получить этот документ как объект (или посмотреть его в отладчике через Shift+F9) реквизит оказывается абсолютно пустым. Из-за этого документы могут перестать проводиться, выдавая ошибки о незаполненных полях. Разберем эту проблему подробно на примере документа ЗаказКлиента и его реквизита ОбъектРасчетов в конфигурации 1С:Комплексная автоматизация (КА) 2.5.
Проанализируем ситуацию: документ не проводится, ругаясь на пустой объект расчетов. Запрос к базе данных честно возвращает значение для ОбъектРасчетов, но программное обращение к объекту возвращает пустоту. Почему так происходит? Посмотрим на механизмы платформы.
В актуальных версиях Комплексной автоматизации 2.5 (как и в 1С:ERP) разработчики серьезно переработали архитектуру взаиморасчетов. Ранее реквизит ОбъектРасчетов мог иметь тип ссылки на КлючиАналитикиПоПартнерам, а теперь для него используется новый тип — СправочникСсылка.ОбъектыРасчетов.
Разберем по шагам, что происходит на уровне базы данных SQL и на уровне серверного кэша 1С:
ПолучитьОбъект(), платформа 1С строго валидирует все считываемые данные на соответствие текущим типам метаданных.Чаще всего такая грабля вылезает после обновления типовой конфигурации. Рассмотрим подробнее механизм перехода на новые релизы. В современных конфигурациях 1С используется отложенное обновление. Это значит, что структура метаданных обновляется сразу, а сами данные конвертируются фоновыми заданиями уже в процессе работы пользователей.
В системе существует специальный регистр сведений ОбработчикиОбновления. Именно там регистрируются процедуры, которые должны пройти по всем документам и конвертировать старые ключи аналитики в новые ОбъектыРасчетов. Если обработчик споткнулся об ошибку или фоновое задание еще не выполнилось до конца, мы получаем рассинхронизацию: структура новая, а данные внутри документов старые.
Выясним причину глубже. Не только платформа на уровне ядра может затирать невалидные типы. Посмотрим на события объектной модели. При получении объекта или его открытии в форме всегда отрабатывают платформенные события, например, ПриЧтенииНаСервере, а также многочисленные подписки на события.
В типовых решениях разработчики 1С добавляют проверки: если система видит, что аналитика документа устарела или неактуальна, она программно сбрасывает "невалидный" реквизит, ожидая, что он будет перезаполнен пользователем или алгоритмом проведения. В консоли запросов эти модули просто не исполняются, поэтому вы видите "призрак" старого значения.
Если вы обновили базу, но забыли адаптировать расширения, ждите беды. Проанализируем ситуацию с расширениями: если в каком-то расширении у документа ЗаказКлиента тип реквизита ОбъектРасчетов был переопределен, возникает жесткий конфликт структур. Объектная модель накладывает типы из расширения поверх основной конфигурации, из-за чего значение не читается.
Также не забываем про кэш 1С, который может хранить устаревшие описания структур данных. В таких случаях всегда рекомендуется выполнять чистку серверного и клиентского кэша.
Рассмотрим, что нужно сделать, чтобы диагностировать и устранить неисправность:
ОбъектыРасчетов или взаиморасчетами. Если статус не выполнен или есть ошибки — запустите их принудительно и добейтесь успешного завершения.ТИПЗНАЧЕНИЯ, чтобы проверить, какой именно тип сейчас лежит в базе для проблемного документа.ПриЧтенииНаСервере или ОбработкаПолученияДанныхВыбора).Посмотрим на пример запроса, который поможет вывести текущий тип проблемного реквизита:
ВЫБРАТЬ
ЗаказКлиента.Ссылка КАК Ссылка,
ЗаказКлиента.ОбъектРасчетов КАК ОбъектРасчетов,
ТИПЗНАЧЕНИЯ(ЗаказКлиента.ОбъектРасчетов) КАК ТипЗначенияРеквизита
ИЗ
Документ.ЗаказКлиента КАК ЗаказКлиента
ГДЕ
ЗаказКлиента.Ссылка = &Ссылка
Выполнив этот запрос, вы сразу увидите, если в поле ОбъектРасчетов застряла ссылка старого типа (например, КлючиАналитикиПоПартнерам) или битая ссылка (со статусом "Объект не найден"). Зная точную причину, вы сможете либо дождаться окончания отложенного обновления, либо написать небольшую обработку для принудительного перезаполнения реквизита актуальными значениями.