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

Ссылки в — это не просто идентификаторы, а полноценные объекты со своими методами. Например, ссылка на документ Документ.ПоступлениеТоваров.Ссылка123 содержит информацию о типе объекта, его уникальном идентификаторе и даже о базе данных. Умение правильно работать с такими ссылками позволяет оптимизировать код и избегать лишних обращений к базе.

Статья будет полезна как начинающим разработчикам , так и опытным специалистам, которые хотят систематизировать знания о работе с метаданными через ссылки.

Что такое ссылка на объект метаданных в 1С

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

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

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

Ссылки в бывают:

  • 📌 Пустые (значение Неопределено или Ссылка.ПустаяСсылка())
  • 📌 Непустые (указывают на существующий объект)
  • 📌 Удаленные (указывают на объект, который был удален, но ссылка сохранена)
⚠️ Внимание: При работе с распределёнными базами данных ссылки могут быть локальными (указывают на объект в текущей базе) или глобальными (указывают на объект в другой базе РИБ). Методы получения объекта по ссылке могут работать по-разному в зависимости от типа ссылки.

Основные методы получения объекта по ссылке

В 1С:Предприятие есть несколько способов получить объект метаданных по его ссылке. Рассмотрим основные методы и их особенности.

1. Метод ПолучитьОбъект()

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

Пример использования:

СсылкаНаДокумент = Документы.ПоступлениеТоваров.НайтиПоНомеру("ПТ-000001");

Если Не СсылкаНаДокумент.Пустая() Тогда

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

Сообщить("Дата документа: " + ДокументОбъект.Дата);

КонецЕсли;

Особенности метода ПолучитьОбъект():

  • 🔸 Работает для документов, справочников, планов счетов, планов видов характеристик, планов видов расчёта
  • 🔸 Возвращает объект в режиме чтения/изменения (в зависимости от прав пользователя)
  • 🔸 Может вызвать исключение, если объект удалён или недоступен

2. Метод ПолучитьСсылку()

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

Пример:

ЭлементСправочника = Справочники.Номенклатура.НайтиПоНаименованию("Товар 1");

Если ЭлементСправочника <> Неопределено Тогда

СсылкаНаЭлемент = ЭлементСправочника.Ссылка;

Сообщить("Ссылка получена: " + СсылкаНаЭлемент);

КонецЕсли;

3. Функция СсылкаНаОбъект()

Для создания ссылки на объект по его типу и идентификатору используется функция СсылкаНаОбъект(). Это полезно, когда вы знаете тип и ID объекта, но не хотите выполнять поиск по базе.

Пример:

Ссылка = СсылкаНаОбъект("Документ.ПоступлениеТоваров", Новый УникальныйИдентификатор("123e4567-e89b-12d3-a456-426614174000"));

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

⚠️ Внимание: При использовании СсылкаНаОбъект() с несуществующим идентификатором метод ПолучитьОбъект() вызовет ошибку. Всегда проверяйте существование объекта через Ссылка.Пустая() или Ссылка.Существует() (если доступен).
📊 Какой метод вы используете чаще всего для получения объекта по ссылке?
ПолучитьОбъект()
ПолучитьСсылку()
СсылкаНаОбъект()
Другой метод

Работа с разными типами объектов

Способы получения объектов по ссылке могут отличаться в зависимости от типа метаданных. Рассмотрим особенности работы с наиболее распространёнными типами.

1. Документы

Для документов метод ПолучитьОбъект() возвращает объект документа в режиме чтения или редактирования (в зависимости от прав). РеализацияТоваровУслуг.НайтиПоНомеру("РТУ-00001");

Если Не СсылкаНаДокумент.Пустая() Тогда

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

Если ДокументОбъект.Проведен Тогда

ДокументОбъект.ОтменитьПроведение();

КонецЕсли;

ДокументОбъект.Дата = ТекущаяДата();

ДокументОбъект.Записать();

КонецЕсли;

2. Справочники

Для элементов справочников метод ПолучитьОбъект() возвращает объект элемента справочника. Особенности:

  • 📋 Можно получать как элементы, так и группы справочника
  • 📋 Для иерархических справочников доступны методы ЭтоГруппа() и Родитель
  • 📋 При работе с подчинёнными справочниками (например, Справочник.Номенклатура.Баркоды) требуется указывать полный путь

Пример:

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

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

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

Сообщить("ИНН контрагента: " + ЭлементОбъект.ИНН);

КонецЕсли;

3. Регистры сведений и накопления

Для регистров метод ПолучитьОбъект() не применяется. Вместо этого используются:

  • 📊 ПолучитьПоследний() — для регистров сведений
  • 📊 СоздатьМенеджерЗаписи() — для создания записи
  • 📊 Выбрать() — для выборки данных

Пример работы с регистром сведений:

МенеджерЗаписи = РегистрыСведений.ЦеныНоменклатуры.СоздатьМенеджерЗаписи();

МенеджерЗаписи.Номенклатура = Справочники.Номенклатура.НайтиПоНаименованию("Товар 1");

МенеджерЗаписи.Цена = 1000;

МенеджерЗаписи.Записать();

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

Типичные ошибки и их решение

При работе со ссылками и получением объектов разработчики часто сталкиваются с ошибками. Рассмотрим наиболее распространённые из них и способы их избежать.

1. Ошибка "Объект не найден"

Эта ошибка возникает, когда вы пытаетесь получить объект по ссылке, которая:

  • 🚫 Указывает на удаленный объект
  • 🚫 Содержит неверный идентификатор
  • 🚫 Ссылается на объект в другой базе РИБ, который недоступен

Решение:

Ссылка =..; // Ваша ссылка

Если Не Ссылка.Пустая() И Ссылка.Существует() Тогда

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

Иначе

Сообщить("Объект не существует или недоступен!");

КонецЕсли;

2. Ошибка "Недостаточно прав"

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

Если ПраваДоступа.ПроверкаПравНаОбъект(Ссылка, "Чтение") Тогда

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

Иначе

Сообщить("У вас нет прав на просмотр этого объекта!");

КонецЕсли;

3. Ошибка "Объект заблокирован"

В многопользовательском режиме объект может быть заблокирован другим пользователем. В этом случае попытка получить объект вызовет ошибку. Решения:

  • 🔓 Использовать ПолучитьОбъектДляИзменения() с таймаутом
  • 🔓 Повторять попытку через некоторое время
  • 🔓 Уведомить пользователя о блокировке

Пример:

Попытка

Объект = Ссылка.ПолучитьОбъектДляИзменения(10); // Таймаут 10 секунд

Исключение

Сообщить("Объект заблокирован. Попробуйте позже.");

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

⚠️ Внимание: В 1С:Предприятие 8.3.20+ появился метод ПолучитьОбъектБезОжидания(), который не блокируется на ожидании освобождения объекта, а сразу возвращает ошибку, если объект занят. Это удобно для фоновых задач.

Проверьте, что ссылка не пустая|Убедитесь, что объект существует|Проверьте права доступа|Обработайте возможную блокировку объекта-->

Оптимизация работы со ссылками

При интенсивной работе со ссылками и объектами важно оптимизировать код, чтобы избежать лишних обращений к базе данных. Вот несколько советов:

1. Кэширование объектов

Если вам нужно многократно обращаться к одному и тому же объекту, имеет смысл кэшировать его в памяти:

Если Не ЗначениеЗаполнено(КэшОбъектов) Тогда

КэшОбъектов = Новый Соответствие;

КонецЕсли;

Если Не КэшОбъектов.Содержит(Ссылка.УникальныйИдентификатор()) Тогда

КэшОбъектов.Вставить(Ссылка.УникальныйИдентификатор(), Ссылка.ПолучитьОбъект());

КонецЕсли;

Объект = КэшОбъектов.Получить(Ссылка.УникальныйИдентификатор());

2. Массовое получение объектов

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

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

СписокСсылок.Добавить(Ссылка1);

СписокСсылок.Добавить(Ссылка2);

СписокОбъектов = ПолучитьОбъектыПоСсылкам(СписокСсылок);

3. Использование менеджеров объектов

Для некоторых типов объектов (например, документов) удобно использовать менеджеры:

МенеджерДокументов = Документы.ПоступлениеТоваров.ПолучитьМенеджерЗаписи();

МенеджерДокументов.Загрузить(Ссылка);

Объект = МенеджерДокументов.Объект;

Преимущества такого подхода:

  • ⚡ Уменьшение количества обращений к базе
  • ⚡ Возможность пакетной обработки
  • ⚡ Упрощение кода при работе с большими объёмами данных
💡

Если вам нужно получить объекты по ссылкам в цикле, сначала соберите все ссылки в массив, а затем получите объекты пакетом. Это сократит количество транзакций и ускорит выполнение.

Работа со ссылками в распределённых базах (РИБ)

В распределённых информационных базах (РИБ) ссылки могут быть локальными (указывают на объект в текущей базе) или глобальными (указывают на объект в другой базе узла РИБ). Это добавляет сложности при получении объектов.

1. Проверка типа ссылки

Перед получением объекта по ссылке в РИБ необходимо проверить, является ли ссылка локальной:

Если Ссылка.ЭтоЛокальная() Тогда

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

Иначе

Сообщить("Ссылка на объект в другой базе РИБ. Невозможно получить напрямую.");

КонецЕсли;

2. Получение объекта из другой базы РИБ

Для работы с глобальными ссылками используйте механизмы обмена данными РИБ:

Если Не Ссылка.ЭтоЛокальная() Тогда

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

// Обработка полученных данных

КонецЕсли;

3. Особенности работы с РИБ

При работе в РИБ учитывайте:

  • 🌐 Задержки синхронизации — объект может ещё не существовать в текущей базе
  • 🌐 Конфликты версий — объект мог быть изменён в другой базе
  • 🌐 Ограничения прав — доступ к объектам других баз может быть ограничен
⚠️ Внимание: В 1С:Предприятие 8.3.18+ появилась возможность работы с универсальными ссылками, которые автоматически разрешаются в локальные при получении объекта. Это упрощает работу в РИБ, но требует настройки плана обмена.
Как узнать, из какой базы РИБ пришла ссылка?

Чтобы определить узел РИБ, из которого пришла глобальная ссылка, используйте метод Ссылка.ПолучитьИдентификаторУзла(). Он возвращает идентификатор узла РИБ, в котором был создан объект. Например:

Если Не Ссылка.ЭтоЛокальная() Тогда

ИдентификаторУзла = Ссылка.ПолучитьИдентификаторУзла();

Сообщить("Объект создан в узле: " + ИдентификаторУзла);

КонецЕсли;

Практические примеры использования

Рассмотрим несколько реальных сценариев, в которых требуется получить объект по ссылке.

1. Получение и изменение документа

Допустим, нам нужно найти документ по номеру, получить его объект и изменить дату:

СсылкаНаДокумент = Документы.ЗаказПокупателя.НайтиПоНомеру("ЗП-00042");

Если Не СсылкаНаДокумент.Пустая() Тогда

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

Если ДокументОбъект.Проведен Тогда

ДокументОбъект.ОтменитьПроведение();

КонецЕсли;

ДокументОбъект.Дата = ТекущаяДата() + 1; // Завтрашняя дата

ДокументОбъект.Записать();

Сообщить("Документ успешно изменён!");

Иначе

Сообщить("Документ не найден!");

КонецЕсли;

2. Проверка и получение элемента справочника

Пример проверки существования элемента справочника и получения его объекта:

СсылкаНаЭлемент = Справочники.Контрагенты.НайтиПоНаименованию("ООО Весна");

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

Сообщить("Контрагент не найден!");

ИначеЕсли Не СсылкаНаЭлемент.Существует() Тогда

Сообщить("Контрагент помечен на удаление!");

Иначе

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

Сообщить("ИНН контрагента: " + ЭлементОбъект.ИНН);

КонецЕсли;

3. Массовая обработка ссылок

Пример обработки списка ссылок с оптимизацией:

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

СписокСсылок.Добавить(Справочники.Номенклатура.НайтиПоНаименованию("Товар 1"));

СписокСсылок.Добавить(Справочники.Номенклатура.НайтиПоНаименованию("Товар 2"));

Для Каждого Ссылка Из СписокСсылок Цикл

Если Не Ссылка.Пустая() Тогда

Попытка

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

Объект.Комментарий = "Обработано " + ТекущаяДата();

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

Исключение

Сообщить("Ошибка при обработке: " + ОписаниеОшибки());

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

КонецЕсли;

КонецЦикла;

💡

Всегда обрабатывайте исключения при массовой обработке ссылок. Одна "битая" ссылка не должна прерывать выполнение всего процесса.

FAQ: Часто задаваемые вопросы

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

Да, но только если у вас есть соответствующие права. Метод ПолучитьОбъект() вернёт объект, но при попытке записи может возникнуть ошибка, если объект уже удалён физически. Чтобы избежать проблем, проверяйте статус объекта через Ссылка.ПометкаУдаления():

Если Не Ссылка.ПометкаУдаления() Тогда

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

КонецЕсли;

Как получить объект по ссылке в фоновом задании?

В фоновом задании метод ПолучитьОбъект() работает так же, как и в обычном режиме, но важно учитывать:

  • 🔄 Фоновые задания выполняются в отдельной транзакции
  • 🔄 Объекты, заблокированные в основной сессии, могут быть недоступны
  • 🔄 Рекомендуется использовать ПолучитьОбъектБезОжидания(), чтобы избежать блокировок
Чем отличаются методы ПолучитьОбъект() и ПолучитьОбъектДляИзменения()?

Основные различия:

Метод Режим доступа Блокировка Использование
ПолучитьОбъект() Чтение Не блокирует объект Для просмотра данных
ПолучитьОбъектДляИзменения() Чтение + изменение Блокирует объект Для редактирования данных

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

Как получить объект по ссылке в управляемом приложении (тонкий клиент, веб-клиент)?

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

  • 🖥️ Объекты передаются между клиентом и сервером автоматически
  • 🖥️ Для сложных операций используйте серверные процедуры
  • 🖥️ В веб-клиенте может быть ограничение на размер передаваемых данных

Пример серверной функции для получения объекта:

&НаСервере

Функция ПолучитьОбъектПоСсылке(Ссылка)

Возврат Ссылка.ПолучитьОбъект();

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

Можно ли получить объект по ссылке из другой конфигурации (например, из БП в УТ)?

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

  • 🔗 Планы обмена (для связанных баз)
  • 🔗 Внешние обработки с передачей данных через параметры
  • 🔗 Файловый обмен (XML, JSON)
  • 🔗 Web-сервисы (для интеграции)