Почему ТекущийОбъект отображается как Объект не найден в событии ПослеЗаписиНаСервере

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

В практике разработки на платформе 1С:Предприятие 8.3 программисты часто сталкиваются с загадочным поведением системы: в обработчике ПослеЗаписиНаСервере значение параметра ТекущийОбъект в окне отладки отображается как <Объект не найден>. При этом в файловой базе код может работать абсолютно корректно, а в клиент-серверном варианте вызывать исключения. Разберем детально, почему это происходит и как правильно организовать работу с данными в этот момент.

Особенности визуализации в отладчике

Первое, что нам необходимо сделать — это выяснить, имеем ли мы дело с реальным отсутствием объекта или с особенностью работы конфигуратора. Проанализируем ситуацию: в серверном вызове состояние <Объект не найден> часто является «ложным» представлением. Это происходит потому, что текстовое представление ссылки формируется на стороне сервера, и в момент остановки на точке останова механизм получения этого представления может давать сбой.

Для проверки выполним следующие действия в окне «Вычислить выражение»:

  1. Попробуем обратиться к любому реквизиту объекта напрямую, например: ТекущийОбъект.Номер или ТекущийОбъект.Дата.
  2. Если значения отображаются, значит, структура объекта в памяти (UUID ссылки) верна, и проблема носит чисто визуальный характер в отладчике.
  3. Если же обращение к реквизитам вызывает ошибку «Объект не найден», значит, проблема глубже и связана с правами доступа или состоянием транзакции.

Проблема использования метода ПолучитьОбъект() в обработчиках формы

Рассмотрим фрагмент кода, который часто становится причиной падения системы в серверных базах:


Процедура ПослеЗаписиНаСервере(ТекущийОбъект, ПараметрыЗаписи)
    Если ЗначениеЗаполнено(ТекущийОбъект.ДоговорКонтрагента) Тогда
        // Опасный участок кода
        Форма.ЗначениеВРеквизитФормы(ТекущийОбъект.ДоговорКонтрагента.ПолучитьОбъект(), "ДоговорОбъект");
    КонецЕсли;
КонецПроцедуры

Проанализируем, что здесь происходит. Метод ПолучитьОбъект() инициирует чтение данных из базы данных. Если ДоговорКонтрагента — это ссылка, которая была изменена или создана в рамках текущей транзакции (например, при сложной цепочке связанных записей), база данных в клиент-серверном варианте может наложить блокировку. В результате метод вернет Неопределено, что приведет к ошибке при попытке выполнения ЗначениеВРеквизитФормы.

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

Влияние механизмов RLS (права на уровне записей)

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

  1. У пользователя есть права на создание документа.
  2. В системе настроен RLS, который запрещает видеть документы, если, например, в них не указано подразделение пользователя.
  3. При записи объект создается (транзакция проходит успешно), но в момент возникновения события ПослеЗаписиНаСервере основная транзакция завершается.
  4. Система пытается повторно прочитать объект для отображения, но механизм RLS скрывает его от пользователя, так как объект перестал соответствовать условиям видимости.

В этом случае платформа вернет <Объект не найден>. Проверьте поведение системы под пользователем с Полными правами. Если под ними ошибка исчезает — ищите причину в настройках ограничений доступа.

Очистка серверного кэша и сеансовых данных

Если код не менялся, права в порядке, а ошибка появилась внезапно только на одной из серверных баз, велика вероятность сбоя кэша метаданных. Посмотрим, как это лечится:

Во-первых, выполните очистку локального кэша пользователя. Во-вторых, если это не помогло, требуется очистка серверного кэша. На сервере приложений 1С за это отвечает папка snccntxt (внутри рабочего каталога службы). Удаление временных файлов и перезапуск службы rphost часто решают проблемы с «невидимостью» только что записанных объектов.

Корректная работа с данными формы

Вместо того чтобы пытаться запихнуть целый СправочникОбъект или ДокументОбъект в реквизит формы типа ДанныеФормыСтруктура через ПолучитьОбъект(), воспользуемся более надежным способом. Если ваша задача — просто обновить отображение связанных данных, лучше передавать ссылку и заполнять реквизиты формы точечно.

Разберем правильный подход:


// Вместо прямого преобразования объекта
// Используем копирование данных, если типы совместимы
КопироватьДанныеФормы(ИсточникОбъект, РеквизитФормыПриемник);

Или, если нужно передать данные из одного объекта в другой на форме:


// На сервере
ДокументОбъект = ДанныеФормыВЗначение(Объект, Тип("ДокументОбъект.ПриходнаяНакладная"));
// Выполняем действия
ЗначениеВДанныеФормы(ДокументОбъект, Объект);

Важный момент: использование реквизитов формы с типом «Объект» (например, СправочникОбъект) внутри формы другого объекта — это архитектурно спорное решение. Это часто приводит к конфликтам блокировок в серверном режиме, так как 1С пытается управлять состояниями двух независимых транзакционных объектов в одном контексте формы.

Подведем итоги

Ситуация, когда ТекущийОбъект превращается в <Объект не найден>, обычно сводится к трем факторам:

  1. Особенности отладчика: объект на самом деле есть, просто его представление недоступно.
  2. Права RLS: объект записан, но пользователь потерял право на его чтение сразу после записи.
  3. Неверная работа с контекстом: попытка вызвать ПолучитьОбъект() там, где нужно работать с данными формы напрямую.

Соблюдение стандартов разработки 1С и использование методов ЗначениеВДанныеФормы вместо прямых манипуляций с объектами через ссылки позволит избежать подобных проблем в клиент-серверной архитектуре.

← На главную