Разработка и Конфигурация · 11 мин
Как получить текущий объект в 1С
Как получить текущий объект в 1С: ЭтотОбъект в модуле формы, ТекущиеДанные в таблице, ПолучитьОбъект по ссылке, типичные ошибки и примеры кода.
Получение текущего объекта — одна из самых частых задач при доработке конфигураций 1С: нужно записать изменённый документ, прочитать реквизиты элемента справочника из формы или обратиться к строке табличной части, которую сейчас редактирует пользователь. Проблема в том, что «текущий объект» в 1С — не одно понятие, а несколько разных механизмов в зависимости от контекста: модуль объекта, модуль формы, клиентская процедура, обработчик таблицы.
Новички часто путают ЭтотОбъект, Объект, ТекущиеДанные и Ссылка.ПолучитьОбъект(), из-за чего получают ошибки «Метод объекта не обнаружен» или, что хуже, теряют данные при записи. В управляемых формах ситуация усложняется разделением клиентского и серверного контекста: часть операций доступна только на сервере.
Ниже разобраны все основные способы получить текущий объект в 1С 8.3: где какой метод применять, какие ограничения есть у каждого и как проверить, что вы работаете именно с тем экземпляром данных.
Что такое «текущий объект» в 1С и почему контекст решает всё
В платформе 1С нет единой универсальной команды «дай текущий объект». Код выполняется в конкретном контексте: модуль объекта, модуль формы, общий модуль, обработчик события элемента формы. В каждом из этих мест «текущий объект» означает разное и получается по-разному.
Важно различать ссылку и объект. Ссылка — это лёгкий идентификатор записи в базе, через неё можно только читать реквизиты. Объект — это полноценная структура данных в памяти, которую можно изменять и записывать. Большинство ошибок возникает именно из-за попытки изменить данные через ссылку или записать ссылку вместо объекта.
ЭтотОбъект в модуле объекта
Если код находится в модуле объекта (например, в обработчиках ПередЗаписью, ПриЗаписи, ОбработкаПроведения), текущий объект доступен напрямую через ключевое слово ЭтотОбъект. Это и есть тот самый экземпляр, который сейчас записывается или проводится.
Обращаться к реквизитам можно и без явного указания ЭтотОбъект — в модуле объекта реквизиты доступны по имени. Однако явное обращение полезно, когда нужно передать объект целиком в процедуру общего модуля или сравнить с другим экземпляром.
Процедура ПередЗаписью(Отказ, РежимЗаписи, РежимПроведения)
Если ЭтотОбъект.ЭтоНовый() Тогда
ЭтотОбъект.Комментарий = "Создан автоматически";
КонецЕсли;
КонецПроцедурыТипичный приём — проверка ЭтотОбъект.ЭтоНовый() для действий, которые должны выполняться только при создании документа, и ЭтотОбъект.ПометкаУдаления для контроля снятия пометки. Помните: в ПередЗаписью данные ещё не в базе, поэтому запросы к базе по этой ссылке могут вернуть старые значения.
Реквизит Объект в модуле формы
В модуле формы элемента справочника или документа текущий объект доступен через основной реквизит формы — обычно он называется Объект. К нему обращаются как Объект.Наименование, Объект.Товары и т.д. В управляемых формах это данные формы, а не настоящий объект базы: платформа хранит их в специальном представлении.
Из-за этого в клиентских процедурах управляемой формы нельзя вызвать методы объекта вроде Записать() или ПолучитьОбъект() — доступны только чтение и изменение реквизитов. Для серверной логики данные формы преобразуют в настоящий объект вызовом РеквизитФормыВЗначение("Объект"), а после изменений возвращают обратно через ЗначениеВРеквизитФормы.
&НаСервере
Процедура ПересчитатьНаСервере()
ДокОбъект = РеквизитФормыВЗначение("Объект");
ДокОбъект.СуммаДокумента = ДокОбъект.Товары.Итог("Сумма");
ЗначениеВРеквизитФормы(ДокОбъект, "Объект");
КонецПроцедурыТекущиеДанные в табличных частях и динамических списках
Когда пользователь редактирует строку табличной части на форме, текущая строка доступна через Элементы.ИмяТаблицы.ТекущиеДанные. Это самый частый способ получить «текущий объект» строки в обработчиках ПриИзменении, ПриНачалеРедактирования, ПередУдалением.
ТекущиеДанные — это структура данных строки, доступная и на клиенте. Через неё можно читать и менять поля строки: ТекущиеДанные.Сумма = ТекущиеДанные.Цена * ТекущиеДанные.Количество. Если строка не выбрана (таблица пустая или фокус снят), ТекущиеДанные возвращает Неопределено — это нужно проверять всегда.
&НаКлиенте
Процедура ТоварыКоличествоПриИзменении(Элемент)
ТекущиеДанные = Элементы.Товары.ТекущиеДанные;
Если ТекущиеДанные = Неопределено Тогда
Возврат;
КонецЕсли;
ТекущиеДанные.Сумма = ТекущиеДанные.Цена * ТекущиеДанные.Количество;
КонецПроцедурыТекущая строка динамического списка
В форме списка Элементы.Список.ТекущаяСтрока возвращает ссылку на выделенный элемент, а не объект. Чтобы изменить его программно, потребуется получить объект на сервере через ПолучитьОбъект(), изменить и записать — после чего оповестить список вызовом ОповеститьОбИзменении(Ссылка), чтобы интерфейс обновился.
Получение объекта из ссылки в произвольном коде
В общих модулях, обработчиках и регламентных заданиях текущего объекта как такового нет — есть ссылка, с которой нужно работать. Переход от ссылки к объекту выполняется методом Ссылка.ПолучитьОбъект(). После изменений обязателен вызов Объект.Записать(), иначе изменения не попадут в базу.
Метод ПолучитьОбъект() возвращает Неопределено, если запись удалена или ссылка битая. Поэтому безопасный шаблон выглядит так: проверить ссылку на пустоту, получить объект, проверить результат, изменить, записать. Для документов при записи указывайте режим: Записать(РежимЗаписиДокумента.Проведение) или РежимЗаписиДокумента.Запись.
- 1Проверьте, что ссылка не пустая: ЗначениеЗаполнено(Ссылка)
- 2Получите объект: Объект = Ссылка.ПолучитьОбъект()
- 3Проверьте, что объект получен (не Неопределено)
- 4Измените нужные реквизиты объекта
- 5Вызовите Объект.Записать() с нужным режимом
- 6При работе из формы списка вызовите ОповеститьОбИзменении(Ссылка)
Для записи в транзакции с обработкой ошибок оборачивайте Записать() в попытку: при исключении откатывайте транзакцию и фиксируйте текст ошибки в журнале регистрации. Это особенно важно в фоновых заданиях, где ошибка иначе пройдёт незамеченной.
Текущий объект в обработчиках событий и подписках
В подписках на события (ПередЗаписью, ПриЗаписи документов и справочников) текущий объект передаётся первым параметром обработчика — обычно он называется Источник. Это тот же самый объект, который записывается, и изменения в нём учитываются при записи (в ПередЗаписью) или уже отражены в базе (в ПриЗаписи).
В обработчиках ПриКопировании, ОбработкаЗаполнения, ОбработкаПроверкиЗаполнения в модуле объекта текущий объект — снова ЭтотОбъект. Важный нюанс: в ПриЗаписи объект уже записан, и повторный вызов Записать() внутри него приведёт к рекурсии — для дозаписи данных используйте ПередЗаписью или отдельные механизмы вроде ДополнительныеСвойства.
Сравнение способов и типичные ошибки
| Контекст | Способ | Можно изменять | Ограничение |
|---|---|---|---|
| Модуль объекта | ЭтотОбъект | Да | Только внутри модуля объекта |
| Модуль формы | Объект (реквизит формы) | Да, через данные формы | Нет методов объекта на клиенте |
| Таблица формы | Элементы.Таблица.ТекущиеДанные | Да | Неопределено, если строка не выбрана |
| Форма списка | Элементы.Список.ТекущаяСтрока | Нет (только ссылка) | Изменение через ПолучитьОбъект на сервере |
| Любой серверный код | Ссылка.ПолучитьОбъект() | Да | Требует Записать(), может вернуть Неопределено |
Как проверить результат
ТипЗнч возвращает ДокументОбъект или СправочникОбъект — можно изменять
Тип Ссылка — попытка присвоения реквизита ни к чему не приведёт
После Записать() данные видны в базе и в открытой форме списка
Изменения пропадают после закрытия — Записать() не вызван или отменён
Код корректно завершается при ТекущиеДанные = Неопределено
Ошибка «Поле объекта не обнаружено» при пустой табличной части
Что важно запомнить
Способ получения текущего объекта определяется контекстом: ЭтотОбъект — в модуле объекта, Объект — в форме, ТекущиеДанные — в таблицах, ПолучитьОбъект() — из ссылки. Ссылка только читается, объект изменяется и требует Записать().
Частые вопросы
Чем ЭтотОбъект отличается от Объект в форме?
ЭтотОбъект доступен в модуле объекта и ссылается на сам записываемый экземпляр. Объект — это реквизит управляемой формы, содержащий данные редактируемой записи; в клиентском контексте он не поддерживает методы объекта, для серверной обработки его преобразуют через РеквизитФормыВЗначение.
Почему Ссылка.ПолучитьОбъект() возвращает Неопределено?
Чаще всего запись физически отсутствует в базе: удалена напрямую, это битая ссылка после удаления без контроля целостности или результат обмена. Перед использованием результата всегда проверяйте его на Неопределено.
Как получить текущий объект в обычной (неуправляемой) форме?
В обычных формах реквизит формы содержит настоящий объект, поэтому методы вроде Записать() и ПолучитьОбъект() доступны напрямую, без преобразований РеквизитФормыВЗначение. Механика ТекущиеДанные для таблиц работает аналогично.
Можно ли получить текущий объект на клиенте в управляемой форме?
Полноценный объект — нет, на клиенте доступны только данные формы (реквизит Объект) и ТекущиеДанные таблиц. Для операций, требующих методов объекта, вызывайте серверную процедуру с директивой &НаСервере.
Как узнать, что запись в форме новая и ещё не сохранена?
В модуле объекта — ЭтотОбъект.ЭтоНовый(). В управляемой форме — проверка Параметры.Ключ.Пустая() в обработчике ПриСозданииНаСервере или проверка Объект.Ссылка.Пустая() в любой серверной процедуре.
Что делать, если изменения объекта не видны в открытом списке?
После программной записи объекта вызовите ОповеститьОбИзменении(Ссылка) — открытые формы списков и элементов получат оповещение и обновят отображение. Без этого список покажет устаревшие данные до ручного обновления.