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

Чтобы понять разницу, представьте библиотеку. Ссылка — это библиографическая карточка с названием книги и её местоположением на полке. Она легковесная, её можно быстро передать другому читателю. Объект — сама книга со всеми страницами, закладками и пометками. Его нужно нести осторожно, а изменения в нём отразятся на оригинале. Теперь перенесём эту аналогию в : когда вы работаете со ссылкой, вы манипулируете только "адресом" данных, а при работе с объектом — загружаете все его свойства и реквизиты в оперативную память.

В этой статье мы разберём:

  • 🔹 Техническую основу ссылок и объектов в платформе 1С
  • 🔹 Когда и почему нужно использовать каждый из них
  • 🔹 Типичные ошибки, ведущие к утечкам памяти и зависанию базы
  • 🔹 Примеры кода с пояснениями для разных версий платформы

📊 Как часто вы сталкиваетесь с путаницей между ссылками и объектами в 1С?
Постоянно
Иногда
Раньше путался, теперь разобрался
Никогда не путаю
Не работаю с 1С

1. Что такое ссылка в 1С: определение и внутренняя структура

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

  • 📌 Типа объекта (например, СправочникСсылка.Номенклатура)
  • 📌 Уникального идентификатора (UID) — внутреннего кода, присваиваемого платформой
  • 📌 Ссылки на базу данных (для распределённых информационных баз)

Главное преимущество ссылок — их минимальное потребление памяти. Когда вы передаёте ссылку в параметре функции или сохраняете её в реквизите, платформа копирует только этот идентификатор, а не все данные объекта. Например, при выборке 10 000 позиций номенклатуры из справочника в массив ссылок расход памяти будет в десятки раз меньше, чем при загрузке полных объектов.

Ссылки делятся на два типа:

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

⚠️ Внимание: Ссылки на удалённые объекты (помеченные на удаление) остаются валидными до момента физического удаления из базы. Проверяйте их актуальность через метод ЭтоУдаленный() перед использованием.

2. Объект в 1С: когда данные "материализуются"

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

  • 📄 Все реквизиты (включая составные типы)
  • 📄 Табличные части с детализацией
  • 📄 Динамические списки и связанные коллекции
  • 📄 Модули объекта (если применимо)

Объекты создаются:

  • 🛠️ Явно — через Справочники.Номенклатура.СоздатьЭлемент() или Документы.ЗаказПокупателя.СоздатьДокумент()
  • 🛠️ Неявно — при вызове ПолучитьОбъект() у ссылки или при выборке данных с флагом ЗагружатьОбъекты = Истина

Работа с объектами требует больше ресурсов, но даёт полный контроль над данными. Например, только через объект можно:

  • 🔧 Изменить реквизит: Объект.Наименование = "Новое значение"
  • 🔧 Добавить строку в табличную часть: Объект.Товары.Добавить()
  • 🔧 Вызвать метод модуля: Объект.РассчитатьСумму()

💡

Если вам нужно только прочитать значение реквизита, используйте ссылку с методом ПолучитьРеквизит("Наименование") — это в 3-5 раз быстрее, чем загрузка полного объекта.

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

3. Ключевые отличия: когда что использовать

Выбор между ссылкой и объектом зависит от цели операции. Вот чек-лист для принятия решения:

Используйте ССЫЛКУ, если:|Нужно передать идентификатор объекта в функцию|Требуется только чтение данных без изменений|Работаете с большими выборками (оптимизация памяти)

Используйте ОБЪЕКТ, если:|Нужно изменить реквизиты или табличные части|Вызываете методы модуля объекта|Работаете в транзакции с последующей записью-->

Типичные сценарии использования ссылок:

  • 🔍 Поиск и фильтрация данных (например, в отчётах)
  • 🔍 Передача параметров между функциями
  • 🔍 Хранение связей в реквизитах других объектов

Примеры, когда объекты необходимы:

  • 📝 Создание новых документов или элементов справочников
  • 📝 Модификация существующих данных
  • 📝 Выполнение расчётов с использованием методов объекта

Почему нельзя изменять данные через ссылку?

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

1. Консистентность данных (проверка заполнения обязательных реквизитов)

2. Возможность отката при ошибках (транзакции)

3. Выполнение триггеров и обработчиков событий.

4. Производительность: что быстрее и почему

Разница в производительности между ссылками и объектами становится критичной при работе с большими объёмами данных. Рассмотрим тестовый сценарий: выборка 10 000 элементов справочника Номенклатура.

При использовании ссылок:

Запрос = Новый Запрос;

Запрос.Текст = "ВЫБРАТЬ Ссылка КАК Ссылка ИЗ Справочник.Номенклатура";

Результат = Запрос.Выполнить().Выгрузить(); // ~0.5 секунды

Платформа возвращает только массивы UID, без загрузки реквизитов.

При загрузке объектов:

Запрос = Новый Запрос;

Запрос.Текст = "ВЫБРАТЬ Ссылка КАК Ссылка ИЗ Справочник.Номенклатура";

Результат = Запрос.Выполнить();

Выборка = Результат.Выбрать();

Пока Выборка.Следующий() Цикл

Объект = Выборка.Ссылка.ПолучитьОбъект(); // ~15-20 секунд

КонецЦикла;

Каждый вызов ПолучитьОбъект() инициирует чтение всех реквизитов из базы.

⚠️ Внимание: В клиент-серверном варианте работы 1С загрузка объектов по ссылкам вызывает дополнительные сетевые запросы к серверу. Это может стать узким местом при медленном соединении.

5. Типичные ошибки и как их избежать

Ошибка №1: Загрузка объектов в цикле без необходимости

Антипример:

Для Каждого Строка Из ТаблицаТоваров Цикл

Товар = Справочники.Номенклатура.НайтиПоНаименованию(Строка.Наименование).ПолучитьОбъект(); // Лишняя загрузка!

Сообщить(Товар.Артикул);

КонецЦикла;

Исправление: Используйте ПолучитьРеквизит("Артикул") напрямую у ссылки.

Ошибка №2: Хранение объектов в коллекциях

Если вы сохраняете объекты в Массив или Структура на длительное время, это приводит к:

  • 🗑️ Утечкам памяти (объекты остаются в памяти даже после использования)
  • 🗑️ Конфликтам блокировок (если объекты не освобождены правильно)
Решение: Храните ссылки, а объекты получайте по мере необходимости.

Ошибка №3: Игнорирование транзакций при работе с объектами

Пример опасной операции:

Док = Документы.ЗаказПокупателя.СоздатьДокумент();

Док.Контрагент = Справочники.Контрагенты.НайтиПоНаименованию("ООО Ромашка");

Док.Записать(); // Без транзакции!

Риск: При сбое после записи документ останется в базе в некорректном состоянии. Исправление: Оберните в транзакцию:
НачатьТранзакцию();

Попытка

Док = Документы.ЗаказПокупателя.СоздатьДокумент();

Док.Контрагент = Справочники.Контрагенты.НайтиПоНаименованию("ООО Ромашка");

Док.Записать();

ЗафиксироватьТранзакцию();

Исключение

ОтменитьТранзакцию();

ВызватьИсключение;

КонецПопытки;

💡

Всегда освобождайте объекты после использования, особенно в циклах! Используйте конструкцию Объект = Неопределено; или ОчиститьОжидание(); для принудительной очистки памяти.

6. Практические примеры: от простого к сложному

Пример 1. Получение данных без загрузки объекта

Задача: Вывести наименование и артикул номенклатуры в отчёт, не загружая полный объект.

Запрос = Новый Запрос;

Запрос.Текст =

"ВЫБРАТЬ

| Номенклатура.Ссылка КАК Ссылка,

| Номенклатура.Наименование КАК Наименование,

| Номенклатура.Артикул КАК Артикул

|ИЗ

| Справочник.Номенклатура КАК Номенклатура";

Результат = Запрос.Выполнить().Выгрузить();

Здесь мы получаем все нужные данные одним запросом, без дополнительных обращений к базе.

Пример 2. Массовое создание документов

Задача: Создать 100 заказов покупателя на основе данных из файла. Неправильно:

Для Каждого Строка Из ДанныеИзФайла Цикл

Док = Документы.ЗаказПокупателя.СоздатьДокумент(); // Создаём объект в цикле!

Док.Контрагент = Справочники.Контрагенты.НайтиПоНаименованию(Строка.Контрагент);

Док.Записать();

КонецЦикла;

Правильно:
// Подготавливаем ссылки на контрагентов заранее

Контрагенты = Новый Соответствие;

Для Каждого Строка Из ДанныеИзФайла Цикл

Если НЕ Контрагенты.Получить(Строка.Контрагент) Тогда

Контрагенты.Вставить(Строка.Контрагент, Справочники.Контрагенты.НайтиПоНаименованию(Строка.Контрагент));

КонецЕсли;

КонецЦикла;

// Создаём документы

НачатьТранзакцию();

Попытка

Для Каждого Строка Из ДанныеИзФайла Цикл

Док = Документы.ЗаказПокупателя.СоздатьДокумент();

Док.Контрагент = Контрагенты.Получить(Строка.Контрагент); // Используем готовую ссылку

Док.Записать();

КонецЦикла;

ЗафиксироватьТранзакцию();

Исключение

ОтменитьТранзакцию();

ВызватьИсключение;

КонецПопытки;

Выигрыш: Сокращение количества обращений к базе в 100 раз (один поиск контрагента вместо 100).

Пример 3. Работа с удалёнными объектами

Задача: Проверить, не удалена ли номенклатура перед добавлением в документ.

Функция ПроверитьАктуальностьНоменклатуры(СсылкаНаНоменклатуру)

Если СсылкаНаНоменклатуру.ЭтоУдаленный() Тогда

Возврат Ложь;

Иначе

Возврат Истина;

КонецЕсли;

КонецФункции;

Важно: Метод ЭтоУдаленный() работает только со ссылками, а не с объектами!

7. Особенности в разных версиях 1С

Платформа 1С:Предприятие эволюционирует, и работа со ссылками/объектами тоже претерпела изменения:

Версия платформы Изменения в работе со ссылками/объектами
8.0-8.1 Отсутствие метода ПолучитьРеквизит() у ссылок — приходилось загружать объект даже для чтения.
8.2 Появление ПолучитьРеквизит(), но работа с динамическими списками ещё не оптимизирована.
8.3.6+ Введены управляемые блокировки для объектов, улучшена работа с большими выборками ссылок.
8.3.18+ Оптимизирована память при работе с массивами ссылок (уменьшено дублирование UID).

В 1С:Предприятие 8.3.20+ появилась возможность использовать отложенную загрузку объектов через механизм ПланыОбмена. Это позволяет:

  • 🔄 Отложить загрузку полных данных до момента реальной необходимости
  • 🔄 Снизить нагрузку на сеть в распределённых базах

⚠️ Внимание: В версиях ниже 8.3.10 метод СравнитьСсылок() может работать некорректно с ссылками на объекты из разных баз в распределённой системе. Всегда проверяйте актуальность механизмов синхронизации.

FAQ: Частые вопросы по ссылкам и объектам в 1С

Можно ли преобразовать объект обратно в ссылку?

Да, у любого объекта есть свойство Ссылка, которое возвращает его ссылку. Пример:

Объект = Справочники.Номенклатура.СоздатьЭлемент();

Объект.Наименование = "Тестовый товар";

СсылкаНаОбъект = Объект.Ссылка; // Получаем ссылку до записи!

Важно: Ссылка будет пустой (ПустаяСсылка()), если объект ещё не записан в базу.

Почему при сравнении двух ссылок на один объект возвращается Ложь?

Это типичная ошибка при работе с распределёнными базами. Ссылки считаются равными только если:

  • 🔹 Они указывают на один и тот же объект в одной базе данных
  • 🔹 Имеют одинаковый UID (внутренний идентификатор)

Для сравнения ссылок из разных баз используйте реквизиты (например, Наименование или Код).

Если Ссылка1.УникальныйИдентификатор() = Ссылка2.УникальныйИдентификатор() Тогда

// Ссылки указывают на один объект

КонецЕсли;

Как узнать, какой тип объекта скрывается за ссылкой?

Используйте метод ТипЗначения() или свойство Метаданные():

ТипСсылки = ТипЗначения(Ссылка); // Вернёт, например, "СправочникСсылка.Номенклатура"

ИмяСправочника = Ссылка.Метаданные().Имя; // Вернёт "Номенклатура"

Для документов аналогично работает Ссылка.Метаданные().Имя.

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

Нет, это принципиально невозможно. Ссылка — это лишь указатель. Для изменения данных необходимо:

  1. Получить объект по ссылке (ПолучитьОбъект())
  2. Изменить реквизит
  3. Записать объект (Записать())
Исключение: В некоторых конфигурациях (например, УТ 11) есть механизмы "быстрого изменения" реквизитов через ссылки, но они реализованы на уровне прикладных решений, а не платформы.

Что быстрее: получить объект по ссылке или найти его по реквизитам?

Получение объекта по существующей ссылке всегда быстрее, чем поиск по реквизитам (например, по наименованию). Сравнение:

  • 🔹 Объект = Ссылка.ПолучитьОбъект() — ~0.001 сек (одно обращение к кешу)
  • 🔹 Объект = Справочники.Номенклатура.НайтиПоНаименованию("Товар 1") — ~0.05-0.2 сек (полнотекстовый поиск)
Рекомендация: Всегда храните ссылки на часто используемые объекты (например, в реквизитах документов) вместо текстового наименования.