Почему в 1С запрос показывает реквизит заполненным, а в объекте он пустой?

Программист 1С v8.3 (Управляемые формы) 1С:Комплексная автоматизация IT и автоматизация бизнеса
← На главную

Часто разработчики и системные администраторы сталкиваются с необъяснимым поведением платформы 1С:Предприятие. Одна из таких загадок — ситуация, когда в консоли запросов реквизит документа заполнен, но при попытке получить этот документ как объект (или посмотреть его в отладчике через Shift+F9) реквизит оказывается абсолютно пустым. Из-за этого документы могут перестать проводиться, выдавая ошибки о незаполненных полях. Разберем эту проблему подробно на примере документа ЗаказКлиента и его реквизита ОбъектРасчетов в конфигурации 1С:Комплексная автоматизация (КА) 2.5.

Суть проблемы и архитектурные изменения

Проанализируем ситуацию: документ не проводится, ругаясь на пустой объект расчетов. Запрос к базе данных честно возвращает значение для ОбъектРасчетов, но программное обращение к объекту возвращает пустоту. Почему так происходит? Посмотрим на механизмы платформы.

В актуальных версиях Комплексной автоматизации 2.5 (как и в 1С:ERP) разработчики серьезно переработали архитектуру взаиморасчетов. Ранее реквизит ОбъектРасчетов мог иметь тип ссылки на КлючиАналитикиПоПартнерам, а теперь для него используется новый тип — СправочникСсылка.ОбъектыРасчетов.

Разберем по шагам, что происходит на уровне базы данных SQL и на уровне серверного кэша 1С:

  1. Физически в таблице СУБД хранится GUID (уникальный идентификатор) ссылки.
  2. Запрос 1С читает данные напрямую из таблицы. Если там лежит GUID, запрос его вернет, даже если тип этого GUID уже не соответствует текущим метаданным (в конфигураторе тип сменился, а в данных остался старый GUID).
  3. Когда мы вызываем метод ПолучитьОбъект(), платформа 1С строго валидирует все считываемые данные на соответствие текущим типам метаданных.
  4. Обнаружив в поле GUID старого справочника (который больше не входит в состав типов реквизита), платформа автоматически игнорирует невалидное значение и инициализирует реквизит как пустой.

Незавершенные обработчики обновления

Чаще всего такая грабля вылезает после обновления типовой конфигурации. Рассмотрим подробнее механизм перехода на новые релизы. В современных конфигурациях 1С используется отложенное обновление. Это значит, что структура метаданных обновляется сразу, а сами данные конвертируются фоновыми заданиями уже в процессе работы пользователей.

В системе существует специальный регистр сведений ОбработчикиОбновления. Именно там регистрируются процедуры, которые должны пройти по всем документам и конвертировать старые ключи аналитики в новые ОбъектыРасчетов. Если обработчик споткнулся об ошибку или фоновое задание еще не выполнилось до конца, мы получаем рассинхронизацию: структура новая, а данные внутри документов старые.

Программная очистка при чтении

Выясним причину глубже. Не только платформа на уровне ядра может затирать невалидные типы. Посмотрим на события объектной модели. При получении объекта или его открытии в форме всегда отрабатывают платформенные события, например, ПриЧтенииНаСервере, а также многочисленные подписки на события.

В типовых решениях разработчики 1С добавляют проверки: если система видит, что аналитика документа устарела или неактуальна, она программно сбрасывает "невалидный" реквизит, ожидая, что он будет перезаполнен пользователем или алгоритмом проведения. В консоли запросов эти модули просто не исполняются, поэтому вы видите "призрак" старого значения.

Влияние расширений конфигурации и кэша

Если вы обновили базу, но забыли адаптировать расширения, ждите беды. Проанализируем ситуацию с расширениями: если в каком-то расширении у документа ЗаказКлиента тип реквизита ОбъектРасчетов был переопределен, возникает жесткий конфликт структур. Объектная модель накладывает типы из расширения поверх основной конфигурации, из-за чего значение не читается.

Также не забываем про кэш 1С, который может хранить устаревшие описания структур данных. В таких случаях всегда рекомендуется выполнять чистку серверного и клиентского кэша.

Как найти и исправить проблему

Рассмотрим, что нужно сделать, чтобы диагностировать и устранить неисправность:

  1. Проверка обработчиков: Откройте регистр «Обработчики обновления». Найдите процедуры, связанные со справочником ОбъектыРасчетов или взаиморасчетами. Если статус не выполнен или есть ошибки — запустите их принудительно и добейтесь успешного завершения.
  2. Анализ типов в запросе: Выполните в консоли специальный запрос с использованием функции ТИПЗНАЧЕНИЯ, чтобы проверить, какой именно тип сейчас лежит в базе для проблемного документа.
  3. Проверка подписок и расширений: Запустите глобальный поиск по конфигурации и расширениям, чтобы найти места, где реквизит очищается (события ПриЧтенииНаСервере или ОбработкаПолученияДанныхВыбора).

Посмотрим на пример запроса, который поможет вывести текущий тип проблемного реквизита:


ВЫБРАТЬ
    ЗаказКлиента.Ссылка КАК Ссылка,
    ЗаказКлиента.ОбъектРасчетов КАК ОбъектРасчетов,
    ТИПЗНАЧЕНИЯ(ЗаказКлиента.ОбъектРасчетов) КАК ТипЗначенияРеквизита
ИЗ
    Документ.ЗаказКлиента КАК ЗаказКлиента
ГДЕ
    ЗаказКлиента.Ссылка = &Ссылка

Выполнив этот запрос, вы сразу увидите, если в поле ОбъектРасчетов застряла ссылка старого типа (например, КлючиАналитикиПоПартнерам) или битая ссылка (со статусом "Объект не найден"). Зная точную причину, вы сможете либо дождаться окончания отложенного обновления, либо написать небольшую обработку для принудительного перезаполнения реквизита актуальными значениями.

← На главную