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