К статье
Практический материал

Разработка и Конфигурация · 9 мин

Что такое экземпляр объекта в 1С

Что такое экземпляр объекта в 1С: разница между типом и экземпляром, примеры кода, ссылки и объекты, типичные ошибки разработчиков и проверка результата.

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

Простая аналогия: тип — это чертёж, экземпляр — построенное по нему здание. По одному чертежу можно построить сколько угодно зданий, и каждое будет отдельным объектом со своим адресом. Так же в 1С: по описанию справочника «Номенклатура» создаются тысячи элементов, и каждый из них — отдельный экземпляр со своим кодом, наименованием и ссылкой.

Путаница возникает потому, что термин «экземпляр объекта» в 1С употребляется в двух смежных смыслах. В прикладном смысле это конкретная запись в базе данных — например, элемент справочника или документ. В программном смысле это значение встроенного языка, созданное в памяти: объект типа «СправочникОбъект», «ДокументОбъект», структура, массив, COM-объект. Ниже разберём оба смысла и покажем, как они связаны.

Тип и экземпляр: в чём разница

Тип — это описание. Например, «СправочникСсылка.Номенклатура» говорит платформе: значение этого типа указывает на элемент справочника «Номенклатура» и имеет предопределённый набор свойств. Сам тип нельзя «заполнить» или «записать» — он только определяет правила.

Экземпляр — это значение, существующее в памяти или в базе данных. Когда вы создаёте новый элемент справочника в режиме предприятия, вы создаёте экземпляр. Когда в коде выполняется Новый Структура — тоже создаётся экземпляр, только не прикладного объекта, а объекта встроенного языка.

Проверить тип значения можно функцией ТипЗнч(): она возвращает тип переданного экземпляра. Это стандартный приём в условиях, когда поведение кода зависит от того, какой именно объект пришёл на вход.

Экземпляры прикладных объектов: ссылка и объект

Ключевая тонкость 1С: у прикладного объекта (справочника, документа) экземпляр существует в двух формах — ссылка и объект. Ссылка (СправочникСсылка, ДокументСсылка) — это лёгкий идентификатор записи в базе. Она позволяет читать реквизиты, но не менять их. Объект (СправочникОбъект, ДокументОбъект) — это редактируемое представление записи в памяти, которое можно изменить и записать.

Получить объект из ссылки можно методом ПолучитьОбъект(). При этом платформа загружает данные из базы в память и создаёт новый экземпляр объекта. Два вызова ПолучитьОбъект() для одной ссылки дадут два разных экземпляра в памяти — изменения в одном не появятся в другом автоматически.

ЭлементОбъект = СсылкаНаЭлемент.ПолучитьОбъект();

ЭлементОбъект.Наименование = "Новое наименование";

ЭлементОбъект.Записать();

После Записать() состояние объекта переносится в базу данных. До записи все изменения существуют только в памяти и будут потеряны при завершении сеанса.

Экземпляры объектов встроенного языка

Кроме прикладных объектов, экземпляры создаются для типов встроенного языка: структуры, соответствия, массивы, таблицы значений, запросы, построители отчётов, COM-объекты. Они существуют только во время выполнения кода и не сохраняются в базе сами по себе.

Создание такого экземпляра обычно выполняется конструктором Новый:

Данные = Новый Структура("Имя, Возраст", "Иван", 30);

Список = Новый Массив;

Таблица = Новый ТаблицаЗначений;

Каждый вызов Новый создаёт независимый экземпляр. Две структуры с одинаковым содержимым — это два разных объекта в памяти. При присваивании переменной Б = А для таких типов копируется ссылка на тот же экземпляр, а не его содержимое: изменив Б, вы измените и А. Это частая причина неочевидных ошибок.

bsl
А = Новый Структура("Количество", 1);
Б = А; // Б указывает на тот же экземпляр
Б.Количество = 5;
// А.Количество теперь тоже равно 5

Как создать экземпляр: типовые сценарии

Новый элемент справочника или документ

Для создания новой записи используется менеджер объекта: Справочники.Номенклатура.СоздатьЭлемент() или Документы.РеализацияТоваровУслуг.СоздатьДокумент(). Метод возвращает экземпляр объекта в памяти, который ещё не существует в базе — у него нет ссылки до первой записи.

Порядок действий
  1. 1
    Вызовите метод создания: Справочники.Имя.СоздатьЭлемент() или Документы.Имя.СоздатьДокумент()
  2. 2
    Заполните обязательные реквизиты и табличные части полученного объекта
  3. 3
    Вызовите Записать() — для документа при необходимости Записать(РежимЗаписиДокумента.Проведение)
  4. 4
    Проверьте, что у объекта появилась ссылка: объект.Ссылка больше не пустая

Экземпляр по описанию типа

Иногда тип известен только в виде строки или значения типа — например, при универсальных обработках. Тогда экземпляр создаётся через Новый(Тип) или через менеджеры, полученные по имени: Справочники[ИмяСправочника]. Это позволяет писать код, работающий с любым объектом метаданных без жёсткой привязки.

Как проверить, что работа идёт с нужным экземпляром

Основные инструменты проверки — ТипЗнч(), сравнение ссылок и отладчик. В отладчике видно, какой именно экземпляр находится в переменной, какие у него значения свойств и совпадает ли ссылка с ожидаемой записью в базе.

Контрольные точки

Как проверить результат

Тип значения переменной
Норма

ТипЗнч() возвращает ожидаемый тип, например СправочникОбъект.Номенклатура

Тревожный признак

Тип не совпадает — например, вместо объекта пришла ссылка или Неопределено

Ссылка после записи
Норма

объект.Ссылка заполнена и находится в базе через поиск

Тревожный признак

Ссылка пустая — объект не был записан

Изменения в базе
Норма

После Записать() данные видны при повторном чтении из базы

Тревожный признак

Изменения есть только в памяти и пропадают после завершения кода

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

Типичные ошибки при работе с экземплярами

Типичные ошибки
01
Попытка изменить реквизиты через ссылку: Ссылка.Наименование = ... вызовет ошибку, потому что ссылка доступна только для чтения
02
Присваивание объектов встроенного языка без понимания, что копируется ссылка на тот же экземпляр — изменения затрагивают обе переменные
03
Многократный вызов ПолучитьОбъект() для одной ссылки и запись разных экземпляров — конфликты блокировок и потеря данных
04
Использование объекта после того, как транзакция отменена: состояние в памяти может не соответствовать базе

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

Сравнение подходов: ссылка, объект, запрос

ПодходЧтение данныхИзменение данныхНагрузка
СсылкаДа, обращение через точкуНетМинимальная
Объект (ПолучитьОбъект)ДаДа, с Записать()Высокая при массовом использовании
ЗапросДа, выборочноНетНизкая, оптимальна для выборок

Выбор зависит от задачи. Нужно прочитать пару реквизитов у одной записи — достаточно ссылки. Нужна выборка по условию — запрос. Нужно изменить запись с контролем прав и вызовом обработчиков событий — только объект.

Итог

Что важно запомнить

Экземпляр объекта — конкретное значение, созданное по описанию типа. Прикладные объекты существуют в форме ссылки (чтение) и объекта (изменение и запись). Объекты встроенного языка создаются через Новый и живут только в памяти. Присваивание таких объектов копирует ссылку на экземпляр, а не его содержимое.

Частые вопросы

Чем экземпляр объекта отличается от объекта метаданных?

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

Можно ли изменить данные через ссылку, не получая объект?

Нет, ссылка предназначена только для чтения. Для изменения нужно получить объект методом ПолучитьОбъект(), внести изменения и вызвать Записать(). Альтернатива без объекта — прямая работа с данными через запросы в особых сценариях, но она обходит обработчики событий и используется редко.

Почему после присваивания двух переменных меняются обе?

Для объектов встроенного языка (структур, массивов, таблиц значений) присваивание копирует ссылку на тот же экземпляр в памяти, а не его содержимое. Чтобы получить независимую копию, нужно создать новый экземпляр и перенести данные — например, для таблицы значений есть метод Скопировать().

Что происходит с экземпляром объекта, если не вызвать Записать()?

Объект существует только в памяти сеанса. После завершения выполнения кода все изменения теряются, а в базе данных ничего не появляется. Новый элемент, созданный через СоздатьЭлемент() и не записанный, не получит ссылку и не будет виден пользователям.

Как узнать тип экземпляра в коде?

Используйте функцию ТипЗнч(Значение) — она возвращает тип переданного значения. Для сравнения с конкретным типом применяется конструкция Тип("СправочникСсылка.Номенклатура") или проверка через ТипЗнч(Значение) = Тип("...").

Опасно ли вызывать ПолучитьОбъект() в цикле?

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